From f1c476beb9e54966c7bd7a844ba2c9c4b7a5d12b Mon Sep 17 00:00:00 2001 From: IgorA Date: Mon, 24 Sep 2018 16:42:54 +0000 Subject: [PATCH] fix function calculate scale, add new buttons to align select points git-svn-id: svn://kolibrios.org@7415 a494cfbc-eb01-0410-851d-a64ba20cac60 --- programs/other/cnc_editor/cnc_editor.asm | 371 ++++++++++++++++++-- programs/other/cnc_editor/cnc_editor.inc | 40 +-- programs/other/cnc_editor/doc/but_16.png | Bin 0 -> 537 bytes programs/other/cnc_editor/doc/readme_ru.htm | 3 +- programs/other/cnc_editor/toolbar.png | Bin 3095 -> 3318 bytes 5 files changed, 371 insertions(+), 43 deletions(-) create mode 100644 programs/other/cnc_editor/doc/but_16.png diff --git a/programs/other/cnc_editor/cnc_editor.asm b/programs/other/cnc_editor/cnc_editor.asm index be7d387d40..840adebac9 100644 --- a/programs/other/cnc_editor/cnc_editor.asm +++ b/programs/other/cnc_editor/cnc_editor.asm @@ -14,7 +14,7 @@ include 'cnc_editor.inc' include '../../develop/info3ds/info_fun_float.inc' @use_library_mem mem.Alloc,mem.Free,mem.ReAlloc,dll.Load -caption db 'CNC editor 14.09.18',0 ;подпись окна +caption db 'CNC editor 24.09.18',0 ;подпись окна run_file_70 FileInfoBlock @@ -380,7 +380,6 @@ pushad add ebx,25 shl 16 mov edx,7 int 0x40 ;figure move up - add ebx,25 shl 16 mov edx,8 int 0x40 ;figure move down @@ -392,33 +391,44 @@ pushad add ebx,25 shl 16 mov edx,10 int 0x40 ;sel points move up - add ebx,25 shl 16 mov edx,11 int 0x40 ;sel points move down add ebx,25 shl 16 mov edx,12 - int 0x40 ;copy to clipboard - + int 0x40 ;align sel points left add ebx,25 shl 16 mov edx,13 + int 0x40 ;align sel points right + add ebx,25 shl 16 + mov edx,14 + int 0x40 ;align sel points top + add ebx,25 shl 16 + mov edx,15 + int 0x40 ;align sel points bottom + + add ebx,25 shl 16 + mov edx,16 + int 0x40 ;copy to clipboard + add ebx,25 shl 16 + mov edx,17 int 0x40 ;paste from clipboard add ebx,25 shl 16 - mov edx,14 + mov edx,18 int 0x40 ;sel points del add ebx,30 shl 16 - mov edx,15 + mov edx,19 int 0x40 ;restore zoom add ebx,30 shl 16 - mov edx,16 + mov edx,20 int 0x40 ;.png add ebx,25 shl 16 - mov edx,17 + mov edx,21 int 0x40 ;options scale ; *** рисование иконок на кнопках *** @@ -450,6 +460,18 @@ pushad add edx,(25 shl 16) ;sel points move down int 0x40 add ebx,IMAGE_TOOLBAR_ICON_SIZE + add edx,(25 shl 16) ;aling sel points left + int 0x40 + add ebx,IMAGE_TOOLBAR_ICON_SIZE + add edx,(25 shl 16) ;aling sel points right + int 0x40 + add ebx,IMAGE_TOOLBAR_ICON_SIZE + add edx,(25 shl 16) ;aling sel points top + int 0x40 + add ebx,IMAGE_TOOLBAR_ICON_SIZE + add edx,(25 shl 16) ;aling sel points bottom + int 0x40 + add ebx,IMAGE_TOOLBAR_ICON_SIZE add edx,(25 shl 16) ;copy to clipboard int 0x40 add ebx,IMAGE_TOOLBAR_ICON_SIZE @@ -589,36 +611,55 @@ button: @@: cmp ah,12 jne @f - call but_clipboard_copy_points + call but_sel_points_align_coord_xmin jmp still @@: cmp ah,13 jne @f - call but_clipboard_paste_points + call but_sel_points_align_coord_xmax jmp still @@: cmp ah,14 jne @f - call but_sel_points_del + call but_sel_points_align_coord_ymax jmp still @@: cmp ah,15 + jne @f + call but_sel_points_align_coord_ymin + @@: + cmp ah,16 + jne @f + call but_clipboard_copy_points + jmp still + @@: + cmp ah,17 + jne @f + call but_clipboard_paste_points + jmp still + @@: + cmp ah,18 + jne @f + call but_sel_points_del + jmp still + @@: + cmp ah,19 jne @f call but_restore_zoom jmp still @@: - cmp ah,16 + cmp ah,20 jne @f call but_save_png jmp still @@: - cmp ah,17 + cmp ah,21 jne @f call but_dlg_opt_scale jmp still @@: - ;cmp ah,18 + ;cmp ah,22 ;jne @f ;call but_... ;jmp still @@ -665,11 +706,6 @@ but_open_file: mov dword[run_file_70.FileName], openfile_path mcall SF_FILE,run_file_70 - ;mov eax,dword[open_b+32] - ;mov edi,txt_buf - ;stdcall convert_int_to_str,20 - ;notify_window_run txt_buf - mov ecx,dword[open_b+32] ;+32 qword: размер файла в байтах inc ecx ;for text files stdcall mem.ReAlloc,[open_file_data],ecx @@ -1456,12 +1492,11 @@ proc but_sel_points_all uses eax ecx cmp [eax+Figure.OType],'Fig' jne .no_point - ;проверяем выделенные точки mov ecx,[eax+Figure.PoiCount] or ecx,ecx jz .no_point mov eax,[eax+Figure.PoiData] - .cycle0: ;1-я выделенная точка + .cycle0: ;цикл для выделенния точек bts dword[eax+Point.Prop],PROP_BIT_SELECT add eax,sizeof.Point loop .cycle0 @@ -1471,6 +1506,298 @@ proc but_sel_points_all uses eax ecx ret endp +align 4 +proc but_sel_points_align_coord_xmin +pushad + stdcall [tl_node_get_data],tree1 + or eax,eax + jz .no_point + cmp [eax+Figure.OType],'Fig' + jne .no_point + + mov ebx,eax + stdcall sel_points_get_count,eax + cmp eax,1 + jle .no_point + mov ecx,[ebx+Figure.PoiCount] + or ecx,ecx + jz .no_point + cmp eax,ecx + je .no_point ;если выделенны все точки, что-бы не портить контур + + mov edx,ecx + imul edx,sizeof.Point + mov ebx,[ebx+Figure.PoiData] + add edx,ebx +align 4 + .cycle0: ;1-я выделенная точка + cmp ebx,edx + jge .no_point + bt dword[ebx+Point.Prop],PROP_BIT_SELECT + jc .cycle0end + add ebx,sizeof.Point + jmp .cycle0 + .cycle0end: + lea esi,[ebx+Point.CoordX] + mov edi,Data_Double + movsd + movsd + finit + fld qword[Data_Double] +align 4 + .cycle1: ;цикл для нахождения min(Point.CoordX) + bt dword[ebx+Point.Prop],PROP_BIT_SELECT + jnc .no_sel + fcom qword[ebx+Point.CoordX] + fstsw ax + sahf + jbe .no_sel + ;if (st0>Point.CoordX) + ffree st0 + fincstp + fld qword[ebx+Point.CoordX] + .no_sel: + add ebx,sizeof.Point + cmp ebx,edx + jl .cycle1 + fstp qword[Data_Double] +align 4 + .cycle2: ;цикл для присваивания всем Point.CoordX = min(Point.CoordX) + sub edx,sizeof.Point + bt dword[edx+Point.Prop],PROP_BIT_SELECT + jnc @f + mov esi,Data_Double + lea edi,[edx+Point.CoordX] + movsd + movsd + @@: + loop .cycle2 + ;для обновления по таймеру + mov dword[offs_last_timer],0 + .no_point: +popad + ret +endp + +align 4 +proc but_sel_points_align_coord_ymin +pushad + stdcall [tl_node_get_data],tree1 + or eax,eax + jz .no_point + cmp [eax+Figure.OType],'Fig' + jne .no_point + + mov ebx,eax + stdcall sel_points_get_count,eax + cmp eax,1 + jle .no_point + mov ecx,[ebx+Figure.PoiCount] + or ecx,ecx + jz .no_point + cmp eax,ecx + je .no_point ;если выделенны все точки, что-бы не портить контур + + mov edx,ecx + imul edx,sizeof.Point + mov ebx,[ebx+Figure.PoiData] + add edx,ebx +align 4 + .cycle0: ;1-я выделенная точка + cmp ebx,edx + jge .no_point + bt dword[ebx+Point.Prop],PROP_BIT_SELECT + jc .cycle0end + add ebx,sizeof.Point + jmp .cycle0 + .cycle0end: + lea esi,[ebx+Point.CoordY] + mov edi,Data_Double + movsd + movsd + finit + fld qword[Data_Double] +align 4 + .cycle1: ;цикл для нахождения min(Point.CoordY) + bt dword[ebx+Point.Prop],PROP_BIT_SELECT + jnc .no_sel + fcom qword[ebx+Point.CoordY] + fstsw ax + sahf + jbe .no_sel + ;if (st0>Point.CoordY) + ffree st0 + fincstp + fld qword[ebx+Point.CoordY] + .no_sel: + add ebx,sizeof.Point + cmp ebx,edx + jl .cycle1 + fstp qword[Data_Double] +align 4 + .cycle2: ;цикл для присваивания всем Point.CoordY = min(Point.CoordY) + sub edx,sizeof.Point + bt dword[edx+Point.Prop],PROP_BIT_SELECT + jnc @f + mov esi,Data_Double + lea edi,[edx+Point.CoordY] + movsd + movsd + @@: + loop .cycle2 + ;для обновления по таймеру + mov dword[offs_last_timer],0 + .no_point: +popad + ret +endp + +align 4 +proc but_sel_points_align_coord_xmax +pushad + stdcall [tl_node_get_data],tree1 + or eax,eax + jz .no_point + cmp [eax+Figure.OType],'Fig' + jne .no_point + + mov ebx,eax + stdcall sel_points_get_count,eax + cmp eax,1 + jle .no_point + mov ecx,[ebx+Figure.PoiCount] + or ecx,ecx + jz .no_point + cmp eax,ecx + je .no_point ;если выделенны все точки, что-бы не портить контур + + mov edx,ecx + imul edx,sizeof.Point + mov ebx,[ebx+Figure.PoiData] + add edx,ebx +align 4 + .cycle0: ;1-я выделенная точка + cmp ebx,edx + jge .no_point + bt dword[ebx+Point.Prop],PROP_BIT_SELECT + jc .cycle0end + add ebx,sizeof.Point + jmp .cycle0 + .cycle0end: + lea esi,[ebx+Point.CoordX] + mov edi,Data_Double + movsd + movsd + finit + fld qword[Data_Double] +align 4 + .cycle1: ;цикл для нахождения max(Point.CoordX) + bt dword[ebx+Point.Prop],PROP_BIT_SELECT + jnc .no_sel + fcom qword[ebx+Point.CoordX] + fstsw ax + sahf + jae .no_sel + ;if (st0N2bZe?^J zG%hhr@5TQB00EgvL_t(&L+zL`a>6hWMST#;9D-9&WRinW&{O0ZxkBokfSEKgbRw(@sKf*BQujDGZRHtELUlSCJHq0fR6wTJm4ch z15adft(L3p_dX3YowXH4b~371e->|>#^GECt*KZwM0Q@h2)|!H`kr=m98ONrNCY?GGQ#?O1vE%P;XjPZ^ zgu}@xWMn2iIx>*j^&45^e1m?@9u{ivMAjlIGLr@!uH7m*GWnkLLNEmt+3atbKanYB6WM* -

CNC_editor тхЁёш  14.09.18

+

CNC_editor тхЁёш  24.09.18

╬уыртыхэшх

    @@ -88,6 +88,7 @@ ol, ul, dl{

    ╨шё. 5. ╬ъэю ЁхфръЄшЁютрэш  Єюўъш

    , яхЁхьх∙хэшх т√фхыхээ√ї Єюўхъ ттхЁї шыш тэшч т яЁхфхырї т√сЁрээющ ЄЁр¤ъЄюЁшш

    +

    т√Ёртэштрэшх т√фхыхээ√ї Єюўхъ яю ыхтюьє, яЁртюьє, тхЁїэхьє ш эшцэхьє ъЁр■

    ъюяшЁютрэшх ъююЁфшэрЄ т√фхыхээ√ї Єюўхъ т сєЇхЁр юсьхэр

    тёЄртър Єюўхъ шч сєЇхЁр юсьхэр. ╘юЁьрЄ ЄхъёЄр фы  тёЄртъш т сєЇхЁх юсьхэр: 'X_ Y_\n...\0'.

    єфрыхэшх т√фхыхээ√ї Єюўхъ

    diff --git a/programs/other/cnc_editor/toolbar.png b/programs/other/cnc_editor/toolbar.png index a7979ca2cd10912a169c8856c70b4939a48b0264..66ac3bc55787516ed2d49e2d591f8be150308fe3 100644 GIT binary patch delta 3240 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