From 361657b32630bb9cd1c2f82827a921e9ae37187c Mon Sep 17 00:00:00 2001 From: "Kirill Lipatov (Leency)" Date: Sat, 15 Jan 2022 20:30:04 +0000 Subject: [PATCH] ImgEdit: add scale feature git-svn-id: svn://kolibrios.org@9644 a494cfbc-eb01-0410-851d-a64ba20cac60 --- programs/cmm/appearance/ui_elements_preview.h | 2 +- programs/cmm/browser/WebView.c | 4 +- programs/cmm/downloader/dl.c | 4 +- programs/cmm/experimental/liza/settings.c | 8 +- programs/cmm/imgedit/data.h | 14 ++- programs/cmm/imgedit/imgedit.c | 115 +++++++++++++++--- programs/cmm/lib/obj/box_lib.h | 41 ++----- programs/cmm/lib/obj/libimg.h | 53 ++++++-- 8 files changed, 175 insertions(+), 66 deletions(-) diff --git a/programs/cmm/appearance/ui_elements_preview.h b/programs/cmm/appearance/ui_elements_preview.h index a8d9a58bda..04a741d7d2 100644 --- a/programs/cmm/appearance/ui_elements_preview.h +++ b/programs/cmm/appearance/ui_elements_preview.h @@ -27,7 +27,7 @@ void DrawUiElementsPreview(dword x,y,h) ESI = edit_box_pointer; ESI.edit_box.left = x; ESI.edit_box.top = y; - ESI.edit_box.blur_border_color = c_inactive; + ESI.edit_box.border_color = c_inactive; ESI.edit_box.focus_border_color = c_active; edit_box_draw stdcall (edit_box_pointer); } \ No newline at end of file diff --git a/programs/cmm/browser/WebView.c b/programs/cmm/browser/WebView.c index fcc0b7a425..96a9b74a2f 100644 --- a/programs/cmm/browser/WebView.c +++ b/programs/cmm/browser/WebView.c @@ -904,8 +904,8 @@ void DrawOmnibox() DrawOvalBorder(omnibox_edit.left-2, omnibox_edit.top-3, omnibox_edit.width+18, 24, sc.line, sc.line, sc.line, sc.dark); DrawBar(omnibox_edit.left-1, omnibox_edit.top-2, omnibox_edit.width+18, 1, 0xD8DCD8); - DrawBar(omnibox_edit.left-1, omnibox_edit.top-1, omnibox_edit.width+18, 1, omnibox_edit.color); - DrawBar(omnibox_edit.left-1, omnibox_edit.top, 1, 22, omnibox_edit.color); + DrawBar(omnibox_edit.left-1, omnibox_edit.top-1, omnibox_edit.width+18, 1, omnibox_edit.bg_color); + DrawBar(omnibox_edit.left-1, omnibox_edit.top, 1, 22, omnibox_edit.bg_color); if (omnibox_edit.flags & ed_focus) omnibox_edit.flags = ed_focus; else omnibox_edit.flags = 0; EditBox_UpdateText(#omnibox_edit, omnibox_edit.flags); diff --git a/programs/cmm/downloader/dl.c b/programs/cmm/downloader/dl.c index c87ce75717..017e3c08c0 100644 --- a/programs/cmm/downloader/dl.c +++ b/programs/cmm/downloader/dl.c @@ -132,7 +132,7 @@ void StartDownloading() strcpy(#get_url, #uEdit); } if (http.get(#get_url)) { - ed.blur_border_color = 0xCACACA; + ed.border_color = 0xCACACA; EditBox_UpdateText(#ed, ed_disabled); pb.value = 0; DrawWindow(); @@ -166,7 +166,7 @@ void StopDownloading() if (http.content_pointer) http.content_pointer = free(http.content_pointer); http.content_received = http.content_length = 0; - ed.blur_border_color = 0xFFFfff; + ed.border_color = 0xFFFfff; EditBox_UpdateText(#ed, ed_focus); DrawWindow(); } diff --git a/programs/cmm/experimental/liza/settings.c b/programs/cmm/experimental/liza/settings.c index bd68f81cb2..5f07174517 100644 --- a/programs/cmm/experimental/liza/settings.c +++ b/programs/cmm/experimental/liza/settings.c @@ -43,14 +43,14 @@ void SettingsDialog() { if (automatic.checked) { UpdateEditboxFlags(ed_disabled); - POP_server_box.blur_border_color = POP_server_port_box.blur_border_color = - SMTP_server_box.blur_border_color = SMTP_server_port_box.blur_border_color = 0xCACACA; + POP_server_box.border_color = POP_server_port_box.border_color = + SMTP_server_box.border_color = SMTP_server_port_box.border_color = 0xCACACA; } else { UpdateEditboxFlags(0); POP_server_box.flags = 0b10; - POP_server_box.blur_border_color = POP_server_port_box.blur_border_color = - SMTP_server_box.blur_border_color = SMTP_server_port_box.blur_border_color = 0xFFFfff; + POP_server_box.border_color = POP_server_port_box.border_color = + SMTP_server_box.border_color = SMTP_server_port_box.border_color = 0xFFFfff; } DrawOptionsWindow(); } diff --git a/programs/cmm/imgedit/data.h b/programs/cmm/imgedit/data.h index 0c48e38ddb..308ba1ec61 100644 --- a/programs/cmm/imgedit/data.h +++ b/programs/cmm/imgedit/data.h @@ -36,6 +36,13 @@ libimg_image main_image; scroll_bar scroll_v = { 15,NULL,NULL,HEADERH+1,15,2,NULL,0,0,COL_DARK,COL_LIGHT,COL_LINE}; scroll_bar scroll_h = { NULL,TOOLBAR_W+PAD+PAD,15,NULL,15,2,NULL,0,0,COL_DARK,COL_LIGHT,COL_LINE}; +#define DIMTS 6 //dimenshion text size +char text_w[DIMTS+10], text_h[DIMTS+10]; +edit_box edit_w = {DIMTS+1*8,08*8+CANVASX+PAD+PAD,HEADER_TEXTY-3,0xEEEeee,0x94AECE, + 0xEEEeee,0xEEEeee,0x10000000,4,#text_w,0,ed_focus+ed_figure_only}; +edit_box edit_h = {DIMTS+1*8,17*8+CANVASX+PAD+PAD+PAD-1,HEADER_TEXTY-3,0xEEEeee, + 0x94AECE,0xEEEeee,0xEEEeee,0x10000000,4,#text_h,0,ed_figure_only}; + enum { SAVE_AS_PNG=1, SAVE_AS_BMP=2, SAVE_AS_RAW=4, SAVE_AS_PNM=8 }; int saving_type = NULL; @@ -46,9 +53,10 @@ int color_depth_btnid_1; enum { TOOL_EXPORT=1, TOOL_CROP=2, - TOOL_RESIZE=4, - TOOL_COLOR_DEPTH=8, - TOOL_FLIP_ROTATE=16 + TOOL_COLOR_DEPTH=4, + TOOL_FLIP_ROTATE=8, + TOOL_SCALE=16, }; int active_tool = NULL; +:checkbox keep_ratio = { "Keep ratio", true }; diff --git a/programs/cmm/imgedit/imgedit.c b/programs/cmm/imgedit/imgedit.c index e6a7181f1a..c38954af30 100644 --- a/programs/cmm/imgedit/imgedit.c +++ b/programs/cmm/imgedit/imgedit.c @@ -51,6 +51,13 @@ void main() pixie_skin.load("/sys/media/pixieskn.png"); Form.width = screen.w/6*5; Form.height = screen.h/6*5; + sc.work = COL_WORK; + sc.work_text = COL_WORK_TEXT; + sc.light = COL_LIGHT; + sc.dark = COL_DARK; + sc.line = COL_LINE; + sc.button = COL_BUTTON; + sc.button_text = COL_BUTTON_TEXT; /* Handle application parameters */ //if (!param) open_image("/sys/home.png"); @@ -63,6 +70,10 @@ void main() mouse.get(); if (main_image.h > canvas.h) scrollbar_v_mouse stdcall(#scroll_v); if (main_image.w > canvas.w) scrollbar_h_mouse stdcall(#scroll_h); + if (active_tool == TOOL_SCALE) { + edit_box_mouse stdcall (#edit_w); + edit_box_mouse stdcall (#edit_h); + } if (scroll_v.delta) || (scroll_h.delta) draw_canvas(); if (EAX = mouse.vert) { if (EAX<10) event_scroll_canvas(SCAN_CODE_DOWN); @@ -76,11 +87,36 @@ void main() case evButton: pressed_button_id = GetButtonID(); if (pressed_button_id==1) ExitProcess(); + keep_ratio.click(pressed_button_id); button.press(pressed_button_id); break; case evKey: GetKeys(); + if (active_tool == TOOL_SCALE) + && (edit_w.flags & ed_focus) || (edit_h.flags & ed_focus) { + if (key_scancode == SCAN_CODE_TAB) { + edit_w.flags >< edit_h.flags; + draw_acive_panel(); + break; + } + if (edit_w.flags & ed_focus) { + edit_box_key_c stdcall (#edit_w, key_editbox); + if (keep_ratio.checked) && (text_w) && (atoi(#text_w)) { + EDI = main_image.h*100 / calc(main_image.w*100 / atoi(#text_w)); + edit_box_set_text stdcall (#edit_h, itoa(EDI)); + edit_box_draw stdcall (#edit_h); + } + } else { + edit_box_key_c stdcall (#edit_h, key_editbox); + if (keep_ratio.checked) && (text_h) && (atoi(#text_h)) { + EDI = main_image.h*100 / calc(main_image.w*100 / atoi(#text_h)); + edit_box_set_text stdcall (#edit_w, itoa(EDI)); + edit_box_draw stdcall (#edit_w); + } + } + break; + } if (key_scancode == SCAN_CODE_DOWN) event_scroll_canvas(SCAN_CODE_DOWN); if (key_scancode == SCAN_CODE_UP) event_scroll_canvas(SCAN_CODE_UP); if (key_scancode == SCAN_CODE_LEFT) event_scroll_canvas(SCAN_CODE_LEFT); @@ -152,9 +188,9 @@ void draw_content() if (main_image.image) { draw_tool_btn(#event_activate_export, ECTRL + SCAN_CODE_KEY_S, PAD, tx.inc(GAP_S), 05, "Export image", active_tool & TOOL_EXPORT); //draw_tool_btn(#event_activate_crop, 0, PAD, tx.inc(GAP_B), 46, "Crop", active_tool & TOOL_CROP); - //draw_tool_btn(#event_activate_resize,0, PAD, tx.inc(GAP_B), 06, "Resize ", active_tool & TOOL_RESIZE); draw_tool_btn(#event_activate_depth, 0, PAD, tx.inc(GAP_B), 52, "Color depth ", active_tool & TOOL_COLOR_DEPTH); draw_tool_btn(#event_activate_flprot,0, PAD, tx.inc(GAP_S), 36, "Flip/Rotate ", active_tool & TOOL_FLIP_ROTATE); + draw_tool_btn(#event_activate_scale, 0, PAD, tx.inc(GAP_S), 06, "Scale ", active_tool & TOOL_SCALE); } draw_status_bar(); draw_canvas(); @@ -279,11 +315,9 @@ void event_set_color_depth() { } } -void WritePanelText(int _x, _text) { WriteTextWithBg(_x, HEADER_TEXTY, 0xD0, COL_WORK_TEXT, _text, COL_WORK); } +void WritePanelText(int _x, _text) { WriteText(_x, HEADER_TEXTY, 0x90, COL_WORK_TEXT, _text); } void draw_acive_panel() { - char edit_width_text[8]; - edit_box edit_width; int i, x = CANVASX + PAD; bool a; DrawBar(CANVASX+1, 2, Form.width-CANVASX-64, HEADERH-1, COL_WORK); @@ -294,17 +328,18 @@ void draw_acive_panel() x += draw_tool_btn(#event_save_png, 0, x, 7, -1, "PNG", saving_type & SAVE_AS_PNG) + PAD; x += draw_tool_btn(#event_save_pnm, 0, x, 7, -1, "PNM", saving_type & SAVE_AS_PNM) + PAD; x += draw_tool_btn(#event_save_bmp, 0, x, 7, -1, "BMP", saving_type & SAVE_AS_BMP) + PAD + PAD; - if (saving_type) draw_tool_btn(#event_save, 0, x, 7, 53, "Export", false); + if (saving_type) draw_tool_btn(#event_save, 0, x, 7, 53, "Export", false); break; case TOOL_CROP: WritePanelText(CANVASX+PAD, "Crop tool"); break; - case TOOL_RESIZE: - WritePanelText(CANVASX+PAD, "New width"); - WritePanelText(CANVASX+PAD+150, "New height"); - draw_tool_btn(#event_rotate_left, SCAN_CODE_ENTER, CANVASX + PAD + 300, 7, -1, "Apply", false); - EditBox_Create(#edit_width, 9*8+CANVASX+PAD+PAD, HEADER_TEXTY-3, 50, sizeof(edit_width_text), #edit_width_text, 0b); - edit_box_draw stdcall (#edit_width); + case TOOL_SCALE: + WritePanelText(CANVASX+PAD, "New size x"); + DefineHiddenButton(edit_w.left-2, edit_w.top-2, 148, 25, 2+BT_NOFRAME); + DrawEditBox(#edit_w); + DrawEditBox(#edit_h); + keep_ratio.draw(CANVASX + PAD + 233, HEADER_TEXTY); + draw_tool_btn(#event_scale, SCAN_CODE_ENTER, CANVASX + PAD + 370, 7, -1, "Apply", false); break; case TOOL_COLOR_DEPTH: WritePanelText(CANVASX+PAD, "Color depth"); @@ -323,13 +358,13 @@ void draw_acive_panel() img_destroy stdcall(EAX); } else { a = -1; - if (Form.width-CANVASX-64 < 652) { + if (Form.width-CANVASX-64 < 600) { button.add(1); continue; } } } - x += draw_tool_btn(#event_set_color_depth, SCAN_CODE_ENTER, x, 7, -1, libimg_bpp[i], a) + PAD; + x += draw_tool_btn(#event_set_color_depth, SCAN_CODE_ENTER, x, 7, -1, libimg_bpp[i], a) + 6; } break; case TOOL_FLIP_ROTATE: @@ -362,16 +397,68 @@ void event_save_raw() { saving_type = SAVE_AS_RAW; draw_acive_panel(); } void event_save_pnm() { saving_type = SAVE_AS_PNM; draw_acive_panel(); } void event_activate_export() { active_tool = TOOL_EXPORT; draw_content(); } void event_activate_crop() { active_tool = TOOL_CROP; draw_content(); } -void event_activate_resize() { active_tool = TOOL_RESIZE; draw_content(); } +void event_activate_scale() { active_tool = TOOL_SCALE; set_text_scale_edits(); draw_content(); } void event_activate_depth() { active_tool = TOOL_COLOR_DEPTH; draw_content(); } void event_activate_flprot() { active_tool = TOOL_FLIP_ROTATE; draw_content(); } +void set_text_scale_edits() +{ + edit_box_set_text stdcall (#edit_w, itoa(main_image.w)); + edit_box_set_text stdcall (#edit_h, itoa(main_image.h)); +} + +/* +;;================================================================================================;; +proc img.scale _src, _crop_x, _crop_y, _crop_width, _crop_height, _dst, _scale, _inter, _param1, _param2 ;; +;;------------------------------------------------------------------------------------------------;; +;? scale _image ;; +;;------------------------------------------------------------------------------------------------;; +;> [_src] = pointer to source image ;; +;> [_crop_x] = left coord of cropping rect ;; +;> [_crop_y] = top coord of cropping rect ;; +;> [_crop_width] = width of cropping rect ;; +;> [_crop_height] = height of cropping rect ;; +;> [_dst] = pointer to resulting image, 0 to create new one ;; +;> [_scale] = scaling method, see libimg.inc (LIBIMG_SCALE_*) ;; +;> [_inter] = interpolation algorithm, see libimg.inc (LIBIMG_INTER_*) ;; +;> [_param1] = depends on _scale, see libimg.inc ;; +;> [_param2] = depends on _scale, see libimg.inc ;; +;;------------------------------------------------------------------------------------------------;; +;< eax = 0 / pointer to scaled image ;; +;< ecx = error code / undefined ;; +;;================================================================================================;; +*/ + +//invoke img.scale, eax, 0, 0, [eax+Image.Width], [eax+Image.Height], 0, LIBIMG_SCALE_STRETCH, LIBIMG_INTER_DEFAULT, [view.width], [view.height] + +void event_scale() +{ + img_scale stdcall (main_image.image, 0, 0, main_image.w, main_image.h, 0, + LIBIMG_SCALE_STRETCH, LIBIMG_INTER_DEFAULT, atoi(#text_w), atoi(#text_h)); + if (!EAX) { + if (ECX == 4) { + notify("'ImageEdit Pro\nThis color depth is not supported by Scale feature.\nPlease change color depth to 24 / 32 / 8grey.' -Et"); + } else { + debugval("Error code", ECX); + notify("'ImageEdit Pro\nImage scale failed :(' -Et"); + } + } else { + $push eax + img_destroy stdcall (main_image.image); + $pop eax + main_image.image = EAX; + main_image.set_vars(); + draw_canvas(); + } +} + void event_open() { o_dialog.type = 0; //open file OpenDialog_start stdcall (#o_dialog); if (o_dialog.status) { open_image(#openfile_path); + active_tool = NULL; draw_window(); } } diff --git a/programs/cmm/lib/obj/box_lib.h b/programs/cmm/lib/obj/box_lib.h index 19f3957296..3e75fba1b8 100644 --- a/programs/cmm/lib/obj/box_lib.h +++ b/programs/cmm/lib/obj/box_lib.h @@ -17,6 +17,7 @@ dword box_lib_init = #aboxlib_init; dword edit_box_draw = #aEdit_box_draw; dword edit_box_key = #aEdit_box_key; +dword edit_box_key_c = #aEdit_box_key_c; dword edit_box_mouse = #aEdit_box_mouse; dword edit_box_set_text = #aEdit_box_set_text; @@ -37,6 +38,7 @@ $DD 2 dup 0 char aEdit_box_draw [] = "edit_box"; char aEdit_box_key [] = "edit_box_key"; +char aEdit_box_key_c[] = "edit_box_key_safe"; char aEdit_box_mouse[] = "edit_box_mouse"; char aEdit_box_set_text[] = "edit_box_set_text"; @@ -102,27 +104,16 @@ PathShow_draw stdcall(#PathShow); #define ed_mouse_on_off 1111111011111111b struct edit_box{ -dword width, - left, - top, - color, - shift_color, - focus_border_color, - blur_border_color, - text_color, +dword width, left, top, + bg_color, selec_color, focus_border_color, border_color, text_color, max, text, mouse_variable, flags, - size, - pos, - offset, - cl_curs_x, - cl_curs_y, - shift, - shift_old, - height, - char_width; + size, pos, offset, + cl_curs_x, cl_curs_y, + shift, shift_old, + height, char_width; }; :void EditBox_UpdateText(dword ed, _flags) @@ -165,18 +156,12 @@ struct scroll_bar struct progress_bar { - dword - value, - left, - top, - width, - height, + dword value, + left, top, + width, height, style, - min, - max, - back_color, - progress_color, - frame_color; + min, max, + back_color, progress_color, frame_color; }; struct frame diff --git a/programs/cmm/lib/obj/libimg.h b/programs/cmm/lib/obj/libimg.h index c259764881..b9d9fba680 100644 --- a/programs/cmm/lib/obj/libimg.h +++ b/programs/cmm/lib/obj/libimg.h @@ -27,13 +27,12 @@ dword img_encode = #aimg_encode; dword img_convert = #aimg_convert; dword img_from_file = #aimg_from_file; dword img_blend = #aimg_blend; -//dword img_is_img = #aimg_is_img; -//dword img_to_rgb2 = #aimg_to_rgb2; -//dword img_scale = #aimg_scale; dword img_flip = #aimg_flip; dword img_rotate = #aimg_rotate; -dword img_to_rgb = #aimg_to_rgb; -dword resize = #aresize; +dword img_scale = #aimg_scale; +//dword img_is_img = #aimg_is_img; +//dword img_to_rgb = #aimg_to_rgb; +//dword img_to_rgb2 = #aimg_to_rgb2; $DD 2 dup 0 @@ -47,13 +46,12 @@ char aimg_encode[] = "img_encode"; char aimg_convert[] = "img_convert"; char aimg_from_file[] = "img_from_file"; char aimg_blend[] = "img_blend"; -//char aimg_is_img[] = "img_is_img"; -//char aimg_to_rgb2[] = "img_to_rgb2"; -//char aimg_scale[] = "img_scale"; char aimg_flip[] = "img_flip"; char aimg_rotate[] = "img_rotate"; -char aimg_to_rgb[] = "img_to_rgb"; -char aresize[] = "img_resize_data"; +char aimg_scale[] = "img_scale"; +//char aimg_is_img[] = "img_is_img"; +//char aimg_to_rgb[] = "img_to_rgb"; +//char aimg_to_rgb2[] = "img_to_rgb2"; #define LIBIMG_FORMAT_BMP 1 #define LIBIMG_FORMAT_ICO 2 @@ -85,18 +83,49 @@ char aresize[] = "img_resize_data"; // kernel doesn't handle this image type, // libimg can only create and destroy such images +//flip and rotate #define FLIP_VERTICAL 0x01 #define FLIP_HORIZONTAL 0x02 - #define ROTATE_90_CW 0x01 #define ROTATE_180 0x02 #define ROTATE_270_CW 0x03 #define ROTATE_90_CCW ROTATE_270_CW #define ROTATE_270_CCW ROTATE_90_CW +//scale type //corresponding img.scale params +#define LIBIMG_SCALE_NONE 0 //do not scale +#define LIBIMG_SCALE_INTEGER 1 //scale factor, reserved 0 +#define LIBIMG_SCALE_TILE 2 //new width, new height +#define LIBIMG_SCALE_STRETCH 3 //new width, new height +#define LIBIMG_SCALE_FIT_BOTH LIBIMG_SCALE_STRETCH +#define LIBIMG_SCALE_FIT_MIN 4 //new width, new height +#define LIBIMG_SCALE_FIT_RECT LIBIMG_SCALE_FIT_MIN +#define LIBIMG_SCALE_FIT_WIDTH 5 //new width, new height +#define LIBIMG_SCALE_FIT_HEIGHT 6 //new width, new height +#define LIBIMG_SCALE_FIT_MAX 7 //new width, new height + +//interpolation algorithm +#define LIBIMG_INTER_NONE 0 //use it with LIBIMG_SCALE_INTEGER, LIBIMG_SCALE_TILE, etc +#define LIBIMG_INTER_BILINEAR 1 +#define LIBIMG_INTER_DEFAULT LIBIMG_INTER_BILINEAR + +/* +// error codes +LIBIMG_ERROR_OUT_OF_MEMORY = 1 +LIBIMG_ERROR_FORMAT = 2 +LIBIMG_ERROR_CONDITIONS = 3 +LIBIMG_ERROR_BIT_DEPTH = 4 +LIBIMG_ERROR_ENCODER = 5 +LIBIMG_ERROR_SRC_TYPE = 6 +LIBIMG_ERROR_SCALE = 7 +LIBIMG_ERROR_INTER = 8 +LIBIMG_ERROR_NOT_INPLEMENTED = 9 +LIBIMG_ERROR_INVALID_INPUT = 10 +*/ + struct libimg_image { - dword checksum; // ((Width ROL 16) OR Height) XOR Data[0] ; ignored so far + dword checksum; // ((Width ROL 16) OR Height) XOR Data[0] ; ignored so far dword w; dword h; dword next;