From 357dec4cea52c4e98dc484ce011a88f032e5ea7a Mon Sep 17 00:00:00 2001 From: "Kirill Lipatov (Leency)" Date: Sat, 4 Dec 2021 23:24:31 +0000 Subject: [PATCH] ImageEditor: upload pre-alpha version (written entirely in Kolibri) git-svn-id: svn://kolibrios.org@9396 a494cfbc-eb01-0410-851d-a64ba20cac60 --- programs/cmm/imgedit/Tupfile.lua | 6 + programs/cmm/imgedit/build.bat | 5 + programs/cmm/imgedit/build.sh | 7 + programs/cmm/imgedit/imgedit.c | 305 ++++++++++++++++++ programs/cmm/lib/obj/box_lib.h | 60 ++-- programs/cmm/lib/obj/libimg.h | 42 ++- .../cmm/lib/patterns/simple_open_dialog.h | 28 +- 7 files changed, 382 insertions(+), 71 deletions(-) create mode 100644 programs/cmm/imgedit/Tupfile.lua create mode 100644 programs/cmm/imgedit/build.bat create mode 100644 programs/cmm/imgedit/build.sh create mode 100644 programs/cmm/imgedit/imgedit.c diff --git a/programs/cmm/imgedit/Tupfile.lua b/programs/cmm/imgedit/Tupfile.lua new file mode 100644 index 0000000000..d1a48b378b --- /dev/null +++ b/programs/cmm/imgedit/Tupfile.lua @@ -0,0 +1,6 @@ +if tup.getconfig("NO_CMM") ~= "" then return end +if tup.getconfig("LANG") == "ru" +then C_LANG = "LANG_RUS" +else C_LANG = "LANG_ENG" -- this includes default case without config +end +tup.rule("imgedit.c", "c-- %f" .. tup.getconfig("KPACK_CMD"), "imgedit.com") diff --git a/programs/cmm/imgedit/build.bat b/programs/cmm/imgedit/build.bat new file mode 100644 index 0000000000..8d79a654cf --- /dev/null +++ b/programs/cmm/imgedit/build.bat @@ -0,0 +1,5 @@ +@del *. +@For /R %%i In (*.c) Do c-- "%%i" +@rename *.com *. +@pause +@del warning.txt diff --git a/programs/cmm/imgedit/build.sh b/programs/cmm/imgedit/build.sh new file mode 100644 index 0000000000..7c9ee950e0 --- /dev/null +++ b/programs/cmm/imgedit/build.sh @@ -0,0 +1,7 @@ +#SHS +rm imgedit.kex +../c--/c-- "/sd0/5/cmm/imgedit/imgedit.c" +sleep 10 +kill c-- +imgedit.kex +exit \ No newline at end of file diff --git a/programs/cmm/imgedit/imgedit.c b/programs/cmm/imgedit/imgedit.c new file mode 100644 index 0000000000..9fed23e488 --- /dev/null +++ b/programs/cmm/imgedit/imgedit.c @@ -0,0 +1,305 @@ +#define MEMSIZE 1024*100 + +#include "../lib/gui.h" +#include "../lib/random.h" +#include "../lib/mem.h" +#include "../lib/cursor.h" +#include "../lib/list_box.h" +#include "../lib/events.h" + +#include "../lib/obj/libimg.h" +#include "../lib/obj/box_lib.h" +#include "../lib/obj/proc_lib.h" + +#include "../lib/patterns/rgb.h" +#include "../lib/patterns/toolbar_button.h" +#include "../lib/patterns/simple_open_dialog.h" + +//===================================================// +// // +// DATA // +// // +//===================================================// + +#define PAD 12 +#define TOOLBAR_ITEM_H PAD+PAD +#define TOOLBAR_W 110 +#define ISIZE 18 + +block canvas = { TOOLBAR_W + PAD + PAD, 0, NULL, NULL }; + +EVENTS button; +EVENTS key; + +proc_info Form; +dword semi_white; +bool bg_dark=false; + +char default_dir[4096] = "/rd/1"; +od_filter filter2 = { 69, "BMP\0GIF\0ICO\0CUR\0JPEG\0JPG\0PNG\0PNM\0TGA\0TIFF\0TIF\0WBMP\0XBM\0XCF\Z80\0\0" }; + +libimg_image icons18; +libimg_image main_image; + +char win_title[256] = "ImageEdit"; + +scroll_bar scroll_v = { 15,NULL,NULL,NULL,15,2,NULL,0,0,0xeeeeee,0xBBBbbb,0xeeeeee}; +scroll_bar scroll_h = { NULL,NULL,15,NULL,15,2,NULL,0,0,0xeeeeee,0xBBBbbb,0xeeeeee}; + +/* +struct scroll_bar +{ + word size_x, start_x, size_y, start_y; + dword btn_height, type, max_area, cur_area, position, + bckg_col, frnt_col, line_col, redraw; + word delta, delta2, r_size_x, r_start_x, r_size_y, r_start_y; + dword m_pos, m_pos_2, m_keys, run_size, position2, work_size, all_redraw, ar_offset; +}; +*/ + +//===================================================// +// // +// CODE // +// // +//===================================================// + +void init_ui() +{ + sc.get(); + semi_white = MixColors(sc.work, 0xFFFfff, bg_dark*90 + 96); + bg_dark = skin_is_dark(); + icons18.load("/sys/icons16.png"); + icons18.replace_color(0xffFFFfff, semi_white); + icons18.replace_color(0xffCACBD6, MixColors(sc.work, 0, 200)); +} + +void main() +{ + int pressed_button_id; + load_dll(libimg, #libimg_init, 1); + load_dll(boxlib, #box_lib_init,0); + load_dll(Proc_lib, #OpenDialog_init,0); + OpenDialog_init stdcall (#o_dialog); + + init_ui(); + open_image("/sys/home.png"); + + SetEventMask(EVM_REDRAW+EVM_KEY+EVM_BUTTON+EVM_MOUSE+EVM_MOUSE_FILTER); + loop() switch(WaitEvent()) + { + case evMouse: + mouse.get(); + scrollbar_v_mouse stdcall(#scroll_v); + scrollbar_h_mouse stdcall(#scroll_h); + if (scroll_v.delta) || (scroll_h.delta) draw_canvas(); + break; + + case evButton: + pressed_button_id = GetButtonID(); + if (pressed_button_id==1) ExitProcess(); + button.press(pressed_button_id); + break; + + case evKey: + GetKeys(); + if (key_scancode == SCAN_CODE_DOWN) { + scroll_v.position = math.min(scroll_v.position+25, scroll_v.max_area - scroll_v.cur_area); + draw_canvas(); + } + if (key_scancode == SCAN_CODE_UP) { + scroll_v.position = math.max(scroll_v.position-25, 0); + draw_canvas(); + } + break; + + case evReDraw: + draw_window(); + break; + } +} + +void draw_window() +{ + incn tx; + DefineAndDrawWindow(random(100)+40, 40+random(100), screen.width/3*2, screen.height/3*2, 0x73, NULL, #win_title, 0); + GetProcessInfo(#Form, SelfInfo); + if (Form.status_window&ROLLED_UP) return; + if (Form.width < 560) { MoveSize(OLD,OLD,560,OLD); return; } + if (Form.height < 430) { MoveSize(OLD,OLD,OLD,430); return; } + button.init(40); + key.init(40); + + DrawBar(0, 0, canvas.x, Form.cheight, sc.work); + + canvas.w = Form.cwidth - canvas.x; + canvas.h = Form.cheight; + if (main_image.h > canvas.h) canvas.w -= scroll_v.size_x + 1; + if (main_image.w > canvas.w) canvas.h -= scroll_h.size_y + 1; + + DrawBar(canvas.x, 0, 1, canvas.h, sc.work_graph); + if (main_image.h > canvas.h) && (main_image.w > canvas.w) { + DrawBar(canvas.x+canvas.w, canvas.y+canvas.h, scroll_v.size_x+1, scroll_h.size_y+1, sc.work); + } + + scroll_v.all_redraw = scroll_h.all_redraw = 1; + scroll_v.bckg_col = scroll_h.bckg_col = MixColors(sc.work, 0xBBBbbb, 80); + scroll_v.frnt_col = scroll_h.frnt_col = MixColors(sc.work,0xFFFfff,120); + scroll_v.line_col = scroll_h.line_col = sc.work_graph; + + #define GAP_S 24+7 + #define GAP_B 24+23 + tx.set(PAD-GAP_S); + //draw_icon(10, ECTRL + SCAN_CODE_KEY_N, PAD, tx.inc(GAP_S), 02, "Create image"); + draw_icon(#event_open, ECTRL + SCAN_CODE_KEY_O, PAD, tx.inc(GAP_S), 00, "Open image"); + //draw_icon(13, ECTRL + SCAN_CODE_LEFT, PAD, tx.inc(GAP_B), 30); + //draw_icon(14, ECTRL + SCAN_CODE_RIGHT, PAD, tx.inc(GAP_S), 31); + //draw_icon(15, ECTRL + SCAN_CODE_UP, PAD, tx.inc(GAP_S), 32); + //draw_icon(16, ECTRL + SCAN_CODE_DOWN, PAD, tx.inc(GAP_S), 33); + + //draw_icon(#event_save, ECTRL + SCAN_CODE_KEY_S, PAD, tx.inc(GAP_B), 05, "Save file"); + //draw_icon(12, 0, PAD, tx.inc(GAP_B), 05, "PNG"); + //draw_icon(12, 0, PAD, tx.inc(GAP_S), 05, "BMP"); + //draw_icon(12, 0, PAD, tx.inc(GAP_S), 05, "RAW"); + draw_icon(#event_save, ECTRL + SCAN_CODE_KEY_S, PAD, tx.inc(GAP_S), 05, "Save as PNG"); + + draw_icon(0, 0, PAD, tx.inc(GAP_B), 46, "Crop"); + draw_icon(0, 0, PAD, tx.inc(GAP_S), 06, "Resize"); + draw_icon(0, 0, PAD, tx.inc(GAP_S), 52, "Color depth"); + draw_icon(#event_flip_hor, ECTRL + SCAN_CODE_KEY_H, PAD, tx.inc(GAP_S), 34, NULL); + draw_icon(#event_flip_ver, ECTRL + SCAN_CODE_KEY_V, PAD*4+3, tx.n, 35, NULL); + draw_icon(#event_rotate, ECTRL + SCAN_CODE_KEY_R, PAD*7+6, tx.n, 36, NULL); + + draw_image_info(tx.inc(GAP_B)); + draw_canvas(); +} + +char* libimg_bpp[] = { "8 pal", "24", "32", "15", "16", +"1 mono", "8 gray", "2 pal", "4 pal", "8 pal" }; + +void draw_image_info(int _y) +{ + WriteText(PAD, _y, 0x90, sc.work_text, "Properties"); + DrawBar(PAD, _y+14, TOOLBAR_W, 1, sc.work_graph); + WriteText(PAD, _y+22, 0x90, sc.work_text, "Width:"); + WriteText(PAD, _y+42, 0x90, sc.work_text, "Heigh:"); + WriteText(PAD, _y+62, 0x90, sc.work_text, "Depth:"); + + WriteText(PAD+60, _y+22, 0x90, sc.work_text, itoa(main_image.w)); + WriteText(PAD+60, _y+42, 0x90, sc.work_text, itoa(main_image.h)); + WriteText(PAD+60, _y+62, 0x90, sc.work_text, libimg_bpp[main_image.type-1]); +} + +void draw_icon(dword _event, _key, _x, _y, _icon_n, _text) +{ + int w; + if (_text) w = TOOLBAR_W; else w = PAD + PAD + 8; + DrawBar(_x, _y, w, TOOLBAR_ITEM_H+1, semi_white); + PutPixel(_x,_y,sc.work); + PutPixel(_x,_y+TOOLBAR_ITEM_H,sc.work); + PutPixel(_x+w-1,_y,sc.work); + PutPixel(_x+w-1,_y+TOOLBAR_ITEM_H,sc.work); + if (_event) DefineHiddenButton(_x, _y, w, TOOLBAR_ITEM_H, button.add(_event)); + if (_text) WriteText(_x+PAD+ISIZE+2, _y+9, 0x80, sc.work_text, _text); + img_draw stdcall(icons18.image, _x+7, _y+3, ISIZE, ISIZE, 0, _icon_n*ISIZE); +} + +void draw_scroll_v() +{ + scroll_v.max_area = main_image.h; + scroll_v.cur_area = scroll_v.size_y = canvas.h; + scroll_v.start_x = canvas.x + canvas.w; + scroll_v.start_y = 0; + if (main_image.h > canvas.h) scrollbar_v_draw stdcall (#scroll_v); +} + +void draw_scroll_h() +{ + scroll_h.max_area = main_image.w; + scroll_h.cur_area = scroll_h.size_x = canvas.w; + scroll_h.start_x = canvas.x; + scroll_h.start_y = canvas.y + canvas.h; + if (main_image.w > canvas.w) scrollbar_h_draw stdcall (#scroll_h); +} + +void draw_canvas() +{ + int content_w, content_h; + content_w = math.min(main_image.w, canvas.w-1); + content_h = math.min(main_image.h, canvas.h); + + if (main_image.image) { + img_draw stdcall(main_image.image, canvas.x+1, canvas.y, + content_w, content_h, scroll_h.position, scroll_v.position); + } + + DrawBar(canvas.x+1+content_w, canvas.y, canvas.w - content_w - 1, content_h, 0xBFCAD2); + DrawBar(canvas.x+1, canvas.y+content_h, canvas.w - 1, canvas.h - content_h, 0xBFCAD2); + + draw_scroll_v(); + draw_scroll_h(); +} + +void update_title(char* _new_title) +{ + strcpy(#win_title+9, " - "); + strlcpy(#win_title+12, _new_title, sizeof(win_title)); + DrawTitle(#win_title); +} + +void open_image(char* _path) +{ + main_image.load(_path); + update_title(_path); + scroll_v.position = 0; + scroll_h.position = 0; +} + +//===================================================// +// // +// EVENTS // +// // +//===================================================// + +void event_open() +{ + o_dialog.type = 0; //open file + OpenDialog_start stdcall (#o_dialog); + if (o_dialog.status) { + open_image(#openfile_path); + draw_canvas(); + } +} + +void event_flip_hor() +{ + img_flip stdcall (main_image.image, FLIP_HORIZONTAL); + draw_canvas(); +} + +void event_flip_ver() +{ + img_flip stdcall (main_image.image, FLIP_VERTICAL); + draw_canvas(); +} + +void event_rotate() +{ + img_rotate stdcall (main_image.image, ROTATE_90_CW); + main_image.w >< main_image.h; + draw_window(); +} + +void event_save() +{ + o_dialog.type = 1; //save file + strcpy(#filename_area, "image.png"); + OpenDialog_start stdcall (#o_dialog); + if (o_dialog.status) { + update_title(#openfile_path); + img_to_rgb stdcall (main_image.image); + save_image(main_image.imgsrc, main_image.w, main_image.h, #openfile_path); + } +} + +stop: + diff --git a/programs/cmm/lib/obj/box_lib.h b/programs/cmm/lib/obj/box_lib.h index 05054cc1eb..4b3b51eb0b 100644 --- a/programs/cmm/lib/obj/box_lib.h +++ b/programs/cmm/lib/obj/box_lib.h @@ -102,12 +102,12 @@ PathShow_draw stdcall(#PathShow); #define ed_mouse_on_off 1111111011111111b struct edit_box{ -dword width, +dword width, left, - top, - color, - shift_color, - focus_border_color, + top, + color, + shift_color, + focus_border_color, blur_border_color, text_color, max, @@ -160,33 +160,11 @@ dword width, struct scroll_bar { - word size_x, - start_x, - size_y, - start_y; - dword btn_height, - type, - max_area, - cur_area, - position, - bckg_col, - frnt_col, - line_col, - redraw; - word delta, - delta2, - r_size_x, - r_start_x, - r_size_y, - r_start_y; - dword m_pos, - m_pos_2, - m_keys, - run_size, - position2, - work_size, - all_redraw, - ar_offset; + word size_x, start_x, size_y, start_y; + dword btn_height, type, max_area, cur_area, position, + bckg_col, frnt_col, line_col, redraw; + word delta, delta2, r_size_x, r_start_x, r_size_y, r_start_y; + dword m_pos, m_pos_2, m_keys, run_size, position2, work_size, all_redraw, ar_offset; }; struct progress_bar @@ -208,18 +186,18 @@ struct progress_bar struct frame { dword type; - word size_x; //start_x, size_x => Mario, WTF? Is this so complex to use x/y/w/h ? - word start_x; - word size_y; - word start_y; - dword ext_col; - dword int_col; + word size_x; //start_x, size_x => Mario, WTF? Is this so complex to use x/y/w/h ? + word start_x; + word size_y; + word start_y; + dword ext_col; + dword int_col; dword flags; // see FR_FLAGS - dword text_pointer; + dword text_pointer; dword text_position; // 0-up,1-bottom dword font_number; // 0-monospace,1-variable - dword font_size_y; - dword font_color; + dword font_size_y; + dword font_color; dword font_backgr_color; }; diff --git a/programs/cmm/lib/obj/libimg.h b/programs/cmm/lib/obj/libimg.h index 7ec851490c..9d3d598f4f 100644 --- a/programs/cmm/lib/obj/libimg.h +++ b/programs/cmm/lib/obj/libimg.h @@ -17,7 +17,7 @@ //library dword libimg = #alibimg; char alibimg[] = "/sys/lib/libimg.obj"; - + dword libimg_init = #alibimg_init; dword img_decode = #aimg_decode; dword img_destroy = #aimg_destroy; @@ -27,12 +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_resize = #aimg_resize; //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_flip = #aimg_flip; +dword img_rotate = #aimg_rotate; +dword img_to_rgb = #aimg_to_rgb; $DD 2 dup 0 @@ -46,12 +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_resize[] = "img_resize"; //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_flip[] = "img_flip"; +char aimg_rotate[] = "img_rotate"; +char aimg_to_rgb[] = "img_to_rgb"; #define LIBIMG_FORMAT_BMP 1 #define LIBIMG_FORMAT_ICO 2 @@ -79,10 +79,19 @@ char aimg_blend[] = "img_blend"; #define IMAGE_BPP8g 7 // grayscale #define IMAGE_BPP2i 8 #define IMAGE_BPP4i 9 -#define IMAGE_BPP8a 10 // grayscale with alpha channel; application layer only!!! - // kernel doesn't handle this image type, +#define IMAGE_BPP8a 10 // grayscale with alpha channel; application layer only!!! + // kernel doesn't handle this image type, // libimg can only create and destroy such images +#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 + struct libimg_image { dword checksum; // ((Width ROL 16) OR Height) XOR Data[0] ; ignored so far @@ -114,11 +123,12 @@ struct libimg_image h = ESDWORD[EDI+8]; //next = ESDWORD[EDI+12]; //previous = ESDWORD[EDI+16]; - imgsrc = ESDWORD[EDI+24]; - //palette = ESDWORD[EDI+28]; - //extended = ESDWORD[EDI+32]; - //flags = ESDWORD[EDI+36]; - //delay = ESDWORD[EDI+40]; + type = ESDWORD[EDI+20]; + imgsrc = ESDWORD[EDI+24]; + //palette = ESDWORD[EDI+28]; + //extended = ESDWORD[EDI+32]; + //flags = ESDWORD[EDI+36]; + //delay = ESDWORD[EDI+40]; $pop edi } @@ -183,7 +193,7 @@ struct libimg_image :dword encode_image(dword image_ptr, dword options, dword specific_options, dword* size) { img_encode stdcall(image_ptr, options, specific_options); ESDWORD[size] = ECX; - + return EAX; } @@ -192,7 +202,7 @@ struct libimg_image dword encoded_data=0; dword encoded_size=0; dword image_ptr = 0; - + image_ptr = create_image(IMAGE_BPP24, _w, _h); if (!image_ptr) { diff --git a/programs/cmm/lib/patterns/simple_open_dialog.h b/programs/cmm/lib/patterns/simple_open_dialog.h index a64c552e4f..86e6899c5a 100644 --- a/programs/cmm/lib/patterns/simple_open_dialog.h +++ b/programs/cmm/lib/patterns/simple_open_dialog.h @@ -1,7 +1,7 @@ struct od_filter { dword size; //size = len(#ext) + sizeof(dword) - char ext[25]; + char ext[90]; }; proc_info pr_inf; @@ -11,21 +11,21 @@ char filename_area[1024]; opendialog o_dialog = { 0, - #pr_inf, - #communication_area_name, - 0, - #opendir_path, - #default_dir, + #pr_inf, + #communication_area_name, + 0, + #opendir_path, + #default_dir, #open_dialog_path, - #draw_window, - 0, - #openfile_path, - #filename_area, - #filter2, + #draw_window, + 0, + #openfile_path, + #filename_area, + #filter2, - 420, - 200, + 420, + 200, - 320, + 320, 120 };