From aa5f8268a34271ce94c89bc66ab0123fccb79f85 Mon Sep 17 00:00:00 2001 From: "Kirill Lipatov (Leency)" Date: Tue, 22 May 2018 12:04:44 +0000 Subject: [PATCH] speedup kfonts completely rewriting Aelia #2 git-svn-id: svn://kolibrios.org@7286 a494cfbc-eb01-0410-851d-a64ba20cac60 --- programs/cmm/aelia/aelia.c | 4 +- programs/cmm/aelia/canvas.h | 5 +- programs/cmm/aelia/gui.h | 25 +--- programs/cmm/aelia/prepare_page.h | 171 ++++++++++++++++++---------- programs/cmm/lib/collection.h | 26 +++-- programs/cmm/lib/debug.h | 1 - programs/cmm/lib/kfont.h | 55 ++++++--- programs/cmm/lib/strings.h | 31 ++++- programs/cmm/txtread/gui.h | 18 --- programs/cmm/txtread/prepare_page.h | 10 +- programs/cmm/txtread/txtread.c | 30 ++++- 11 files changed, 225 insertions(+), 151 deletions(-) delete mode 100644 programs/cmm/txtread/gui.h diff --git a/programs/cmm/aelia/aelia.c b/programs/cmm/aelia/aelia.c index 8dc7ef4207..0daff3c35d 100644 --- a/programs/cmm/aelia/aelia.c +++ b/programs/cmm/aelia/aelia.c @@ -1,4 +1,4 @@ -#define MEMSIZE 4096*80 +#define MEMSIZE 4096*100 #include "../lib/kfont.h" #include "../lib/io.h" @@ -88,9 +88,9 @@ void main() { InitDlls(); OpenDialog_init stdcall (#o_dialog); + LoadIniSettings(); kfont.init(DEFAULT_FONT); Libimg_LoadImage(#skin, abspath("toolbar.png")); - LoadIniSettings(); list.no_selection = true; SetEventMask(10000000000000000000000001100111b); loop() diff --git a/programs/cmm/aelia/canvas.h b/programs/cmm/aelia/canvas.h index 313a6ad6cd..186de6dcc9 100644 --- a/programs/cmm/aelia/canvas.h +++ b/programs/cmm/aelia/canvas.h @@ -2,12 +2,13 @@ struct _canvas { void write_text(); - void draw_bar(); + void draw_hor_line(); }; void _canvas::write_text(int _x, _y; dword _text_col, _text_off) { char error_message[128]; + if (_x > list.w) { sprintf(#error_message, "ERROR: canvas.x overflow: H %d X %d", kfont.size.height, _x); debugln(#error_message); @@ -22,7 +23,7 @@ void _canvas::write_text(int _x, _y; dword _text_col, _text_off) } -void _canvas::draw_bar(dword _x, _y, _w, _color) +void _canvas::draw_hor_line(dword _x, _y, _w, _color) { int i; for (i = _y*list.w+_x*KFONT_BPP+kfont.raw ; i<_y*list.w+_x+_w*KFONT_BPP+kfont.raw ; i+=KFONT_BPP) diff --git a/programs/cmm/aelia/gui.h b/programs/cmm/aelia/gui.h index 2e68d10813..2c6c581fbf 100644 --- a/programs/cmm/aelia/gui.h +++ b/programs/cmm/aelia/gui.h @@ -1,7 +1,7 @@ -void DrawToolbarButton(char image_id, int x) +void DrawToolbarButton(dword image_id, x) { DefineButton(x+1, 7, TOOLBAR_ICON_WIDTH-2, TOOLBAR_ICON_HEIGHT-2, 10+image_id + BT_HIDE, 0); - img_draw stdcall(skin.image, x, 6, TOOLBAR_ICON_WIDTH, TOOLBAR_ICON_HEIGHT, 0, image_id*TOOLBAR_ICON_HEIGHT); + DrawLibImage(skin.image, x, 6, TOOLBAR_ICON_WIDTH, TOOLBAR_ICON_HEIGHT, 0, image_id*TOOLBAR_ICON_HEIGHT); } @@ -39,27 +39,6 @@ dword MakePageWithHistory() return history_page; } -char char_width[255]; - -void get_label_symbols_size() -{ - int i; - kfont.changeSIZE(); - for (i=0; i<256; i++) char_width[i] = kfont.symbol_size(i); -} - -int get_label_len(dword _text) -{ - int len=0; - byte ch; - loop () { - ch = ESBYTE[_text]; - if (!ch) return len; - len += char_width[ch]; - _text++; - } -} - enum { STEP_1_DOWNLOAD_PAGE = 0, STEP_2_COUNT_PAGE_HEIGHT = 35, diff --git a/programs/cmm/aelia/prepare_page.h b/programs/cmm/aelia/prepare_page.h index 29c948ef2f..083bfac4fc 100644 --- a/programs/cmm/aelia/prepare_page.h +++ b/programs/cmm/aelia/prepare_page.h @@ -1,44 +1,3 @@ -void ParseTxt() -{ -_canvas canvas; -byte ch, zeroch=0; -dword bufoff, buflen, line_start, srch_pos; -int stroka_y=5, line_length=0; - - line_start=io.buffer_data; - buflen = strlen(io.buffer_data) + io.buffer_data; - for (bufoff=io.buffer_data; bufoff=list.w-30) || (ch==10) { - srch_pos = bufoff; - loop() - { - if (__isWhite(ESBYTE[srch_pos])) { bufoff=srch_pos+1; break; } //normal word-break - if (srch_pos == line_start) break; //no white space found in whole line - srch_pos--; - } - if (kfont.size.height) { - ESBYTE[bufoff] >< zeroch; //set line end - canvas.write_text(8, stroka_y, 0x000000, line_start); - ESBYTE[bufoff] >< zeroch; //restore line - } - stroka_y += list.item_h; - line_start = bufoff; - line_length = 0; - } - } - if (!kfont.size.height) { - list.count = stroka_y/list.item_h+3; - if (list.count < list.visible) list.count = list.visible; - kfont.size.height = list.count+5*list.item_h; - kfont.raw_size = 0; - ParseTxt(); - } - else canvas.write_text(8, stroka_y, 0x000000, line_start); -} - /*======================================================== = = = STYLE = @@ -48,23 +7,25 @@ int stroka_y=5, line_length=0; #define HTML_PADDING_Y 5; struct _style { - bool b, u, i, s; + bool bold, underlined, italic, strike; bool h1, h2, h3, h4, h5, h6; bool a; bool pre; bool ignore; + bool body; dword color; void clear(); }; void _style::clear() { - b=u=i=s=0; + bold=underlined=italic=strike=0; h1=h2=h3=h4=h5=h6=0; a=0; pre=0; ignore=0; color=0; + body=0; } /*======================================================== @@ -76,20 +37,43 @@ struct _tag { dword start; dword end; dword name; - dword param[10]; - dword value[10]; + + bool opens; + + dword param; + dword value; + void parse(); int nameis(); }; void _tag::parse() { + dword START = start; + + calc(1); //WTF + + if (ESBYTE[START]=='/') { + START++; + opens = false; + } else opens = true; + + name = START; + + while ( (START < end) && (!__isWhite(ESBYTE[START])) ) { + START++; + } + if (START!=end) ESBYTE[START] = '\0'; + START++; + strlwr(name); + + start = START; } int _tag::nameis(dword _in_tag_name) { - if (name) && (strcmp(_in_tag_name, start)==0) return true; + if (name) && (streq(_in_tag_name, name)) return true; return false; } @@ -149,6 +133,8 @@ struct _text { int size_pt_change; dword start; dword end; + + dword width; }; /* @@ -209,9 +195,9 @@ struct _dom _text text; _canvas canvas; void init(); + void apply_text(); void set_style(); void parse(); - void apply_text(); }; void _dom::init() @@ -223,14 +209,17 @@ void _dom::init() void _dom::set_style() { - /* - if (tag.nameis("pre")) style.pre = true; - if (tag.nameis("/pre")) style.pre = false; - if (tag.nameis("script")) || (tag.nameis("style")) style.ignore = true; - if (tag.nameis("/script")) || (tag.nameis("/style")) style.ignore = false; - if (tag.nameis("a")) { style.a = true; style.color=0x0000FF; } - if (tag.nameis("/a")) { style.a = false; style.color=0x000000; } - + if (tag.nameis("body")) style.body = tag.opens; + if (tag.nameis("b")) style.bold = tag.opens; + if (tag.nameis("i")) style.italic = tag.opens; + if (tag.nameis("s")) style.strike = tag.opens; + if (tag.nameis("pre")) style.pre = tag.opens; + if (tag.nameis("style")) style.ignore = tag.opens; + if (tag.nameis("a")) { + style.a = tag.opens; + if (tag.opens) style.color=0x0000FF; else style.color=0; + } + if (tag.nameis("br")) || (tag.nameis("p")) || (tag.nameis("div")) @@ -239,12 +228,25 @@ void _dom::set_style() return; } - if (dom.tag.nameis("title")) { + if (tag.nameis("li")) && (tag.opens) { + draw.line_break(); + return; + } + + if (tag.nameis("td")) && (tag.opens) { + draw.line_break(); + return; + } + + /* + if (tag.nameis("title")) { strcpy(#title, text.start); strcat(#title, " - Aelia"); DrawTitle(#title); } + + if (tag.nameis("h1")) || (tag.nameis("/h1")) || (tag.nameis("h2")) || (tag.nameis("/h2")) || (tag.nameis("h3")) || (tag.nameis("/h3")) { @@ -277,8 +279,13 @@ void _dom::set_style() void _dom::apply_text() { - if (kfont.size.height) canvas.write_text(draw.x, draw.y, style.color, text.start); - draw.line_break(); + if (kfont.size.height) && (style.body) { + kfont.bold = style.bold; + canvas.write_text(draw.x, draw.y, style.color, text.start); + if (style.a) { + canvas.draw_hor_line(draw.x+1, draw.y + list.item_h-2, kfont.get_label_width(text.start), style.color); + } + } } void _dom::parse() @@ -294,16 +301,14 @@ void _dom::parse() tag.start = i+1; text.end = i-1; ESBYTE[i] = '\0'; - debug("TXT "); debugln(text.start); apply_text(); } if (ESBYTE[i]=='>') { tag.end = i-1; text.start = i+1; ESBYTE[i] = '\0'; - debug("TAG "); debugln(tag.start); - //tag.parse(); - //set_style(); + tag.parse(); + set_style(); } } @@ -329,7 +334,6 @@ void PreparePage() _dom dom; list.SetSizes(0, TOOLBAR_H, Form.cwidth-scroll.size_x-1, Form.cheight-TOOLBAR_H, kfont.size.pt+4); strcpy(#title, history.current()+strrchr(history.current(),'/')); - get_label_symbols_size(); //get font chars width, need to increase performance ChangeCharset(charsets[encoding], "CP866", io.buffer_data); link.clear(); @@ -340,4 +344,45 @@ void PreparePage() kfont.ApplySmooth(); DrawPage(); +} + +void ParseTxt() +{ +_canvas canvas; +byte ch, zeroch=0; +dword bufoff, buflen, line_start, srch_pos; +int stroka_y=5, line_length=0; + + line_start=io.buffer_data; + buflen = strlen(io.buffer_data) + io.buffer_data; + for (bufoff=io.buffer_data; bufoff=list.w-30) || (ch==10) { + srch_pos = bufoff; + loop() + { + if (__isWhite(ESBYTE[srch_pos])) { bufoff=srch_pos+1; break; } //normal word-break + if (srch_pos == line_start) break; //no white space found in whole line + srch_pos--; + } + if (kfont.size.height) { + ESBYTE[bufoff] >< zeroch; //set line end + canvas.write_text(8, stroka_y, 0x000000, line_start); + ESBYTE[bufoff] >< zeroch; //restore line + } + stroka_y += list.item_h; + line_start = bufoff; + line_length = 0; + } + } + if (!kfont.size.height) { + list.count = stroka_y/list.item_h+3; + if (list.count < list.visible) list.count = list.visible; + kfont.size.height = list.count+5*list.item_h; + kfont.raw_size = 0; + ParseTxt(); + } + else canvas.write_text(8, stroka_y, 0x000000, line_start); } \ No newline at end of file diff --git a/programs/cmm/lib/collection.h b/programs/cmm/lib/collection.h index 468d12dd39..481a96d89a 100644 --- a/programs/cmm/lib/collection.h +++ b/programs/cmm/lib/collection.h @@ -21,7 +21,7 @@ struct collection void increase_data_size(); }; -void collection::increase_data_size() { +:void collection::increase_data_size() { int filled_size; if (realloc_size<4096) realloc_size = 4096; if (!data_size) { @@ -34,11 +34,11 @@ void collection::increase_data_size() { } } -int collection::add(dword in) { +:int collection::add(dword in) { return addn(in, strlen(in)); } -int collection::addn(dword in, len) { +:int collection::addn(dword in, len) { if (count >= 4000) return 0; if (element_offset[count]+len+2 > data_size) { increase_data_size(); @@ -51,12 +51,12 @@ int collection::addn(dword in, len) { return 1; } -dword collection::get(dword pos) { +:dword collection::get(dword pos) { if (pos<0) || (pos>=count) return 0; return data_start + element_offset[pos]; } -void collection::drop() { +:void collection::drop() { if (data_start) free(data_start); data_size = data_start = element_offset[count] = count = 0; } @@ -74,22 +74,32 @@ struct collection_int dword element[4096*3]; int add(); dword get(); + dword get_last(); + void pop(); void drop(); }; -int collection_int::add(dword in) { +:int collection_int::add(dword in) { if (count >= 4096*3) return 0; element[count] = in; count++; return 1; } -dword collection_int::get(dword pos) { +:dword collection_int::get(dword pos) { if (pos<0) || (pos>=count) return 0; return element[pos]; } -void collection_int::drop() { +:dword collection_int::get_last() { + return element[count]; +} + +:void collection_int::pop() { + if (count>0) count--; +} + +:void collection_int::drop() { element[0] = count = 0; } diff --git a/programs/cmm/lib/debug.h b/programs/cmm/lib/debug.h index dfcf2522d5..211beb9506 100644 --- a/programs/cmm/lib/debug.h +++ b/programs/cmm/lib/debug.h @@ -40,7 +40,6 @@ inline fastcall void debugln( EDX) { debug( EDX); debugch(10); - debugch(13); } inline void debugi(dword d_int) diff --git a/programs/cmm/lib/kfont.h b/programs/cmm/lib/kfont.h index d2768a9d0a..a9724c6259 100644 --- a/programs/cmm/lib/kfont.h +++ b/programs/cmm/lib/kfont.h @@ -13,8 +13,8 @@ // [Название шрифта:"Times New Roman"] -#ifndef INCLUDE_LABEL_H -#define INCLUDE_LABEL_H +#ifndef INCLUDE_KFONT_H +#define INCLUDE_KFONT_H #ifndef INCLUDE_MATH_H #include "../lib/math.h" @@ -33,13 +33,15 @@ #define KFONT_BPP 4 #endif +int kfont_char_width[255]; + :struct __SIZE { dword width,height; signed offset_x, offset_y; byte pt; }; -:struct LABEL +:struct KFONT { __SIZE size; int width,height; @@ -49,13 +51,13 @@ word block; dword raw; dword raw_size; - //dword palette[256]; bool init(); bool changeSIZE(); byte symbol(); byte symbol_size(); dword getsize(); + int get_label_width(); void ApplySmooth(); int WriteIntoWindow(); @@ -65,7 +67,7 @@ void ShowBufferPart(); } kfont; -:bool LABEL::init(dword font_path) +:bool KFONT::init(dword font_path) { IO label_io; if(font)free(font); @@ -81,8 +83,9 @@ return true; } -:bool LABEL::changeSIZE() +:bool KFONT::changeSIZE() { + int i; dword file_size; dword ofs; if(size.pt<9) size.pt = 9; @@ -94,15 +97,20 @@ height = DSBYTE[calc(font+file_size) - 1]; width = DSBYTE[calc(font+file_size) - 2]; block = math.ceil(height*width/32); + for (i=0; i<256; i++) { + kfont_char_width[i] = symbol_size((byte) i); + } return true; } -:dword LABEL::getsize(byte fontSizePoints, dword text1) +:dword KFONT::getsize(byte fontSizePoints, dword text1) { size.height = size.width = 0; size.offset_x = size.offset_y = -1; - size.pt = fontSizePoints; - if(size.pt)if(!changeSIZE())return 0; + if (size.pt != fontSizePoints) { + size.pt = fontSizePoints; + if(!changeSIZE())return 0; + } WHILE(DSBYTE[text1]) { size.width += symbol_size(DSBYTE[text1]); @@ -115,7 +123,19 @@ return size.width; } -:byte LABEL::symbol_size(byte s) +//WILL NOT WORK if requested fontSizePoints +//is differ from precalculated kfont_char_width[] +:int KFONT::get_label_width(dword _label) +{ + int len=0; + while (ESBYTE[_label]) { + len += kfont_char_width[ ESBYTE[_label] ]; + _label++; + } + return len; +} + +:byte KFONT::symbol_size(byte s) { int chaw_width; chaw_width = symbol(0,0, s, 0); @@ -123,7 +143,7 @@ return chaw_width; } -:byte LABEL::symbol(signed x,y; byte s; dword image_raw) +:byte KFONT::symbol(signed x,y; byte s; dword image_raw) { dword xi,yi; dword iii = 0; @@ -190,7 +210,7 @@ inline fastcall Cp866ToAnsi(AL) { =====================================================================================*/ inline fastcall dword b32(EAX) { return DSDWORD[EAX]; } -:void LABEL::ApplySmooth() +:void KFONT::ApplySmooth() { dword i,line_w,to,dark_background; line_w = size.width * KFONT_BPP; @@ -222,11 +242,10 @@ inline fastcall dword b32(EAX) { return DSDWORD[EAX]; } } } -:void LABEL::WriteIntoBuffer(int x,y,w,h; dword _background, _color; byte fontSizePoints; dword text1) +:void KFONT::WriteIntoBuffer(int x,y,w,h; dword _background, _color; byte fontSizePoints; dword text1) { dword new_raw_size; if(!text1)return; - if(size.pt)if(!changeSIZE())return; if (size.pt != fontSizePoints) { getsize(fontSizePoints, text1); @@ -258,7 +277,7 @@ inline fastcall dword b32(EAX) { return DSDWORD[EAX]; } return; } -:int LABEL::WriteIntoWindow(int x,y; dword _background, _color; byte fontSizePoints; dword text1) +:int KFONT::WriteIntoWindow(int x,y; dword _background, _color; byte fontSizePoints; dword text1) { if(!text1)return 0; getsize(fontSizePoints, text1); @@ -270,19 +289,19 @@ inline fastcall dword b32(EAX) { return DSDWORD[EAX]; } return size.offset_x + size.width; } -:int LABEL::WriteIntoWindowCenter(dword x,y,w,h; dword _background, _color; byte fontSizePoints; dword text1) +:int KFONT::WriteIntoWindowCenter(dword x,y,w,h; dword _background, _color; byte fontSizePoints; dword text1) { getsize(fontSizePoints, text1); return WriteIntoWindow(w-size.width/2+x-1,y, _background, _color, fontSizePoints, text1); } -:void LABEL::ShowBuffer(dword _x, _y) +:void KFONT::ShowBuffer(dword _x, _y) { if (4==KFONT_BPP) PutPaletteImage(raw, size.width, size.height, _x, _y, 32, 0); //if (1==KFONT_BPP) PutPaletteImage(raw, size.width, size.height, _x, _y, 8, #palette); } -:void LABEL::ShowBufferPart(dword _x, _y, _w, _h, _buf_offset) +:void KFONT::ShowBufferPart(dword _x, _y, _w, _h, _buf_offset) { if (4==KFONT_BPP) PutPaletteImage(_buf_offset * KFONT_BPP + raw, _w, _h, _x, _y, 32, 0); //if (1==KFONT_BPP) PutPaletteImage(_buf_offset * KFONT_BPP + raw, _w, _h, _x, _y, 8, #palette); diff --git a/programs/cmm/lib/strings.h b/programs/cmm/lib/strings.h index 3e6383654b..3a7dece780 100644 --- a/programs/cmm/lib/strings.h +++ b/programs/cmm/lib/strings.h @@ -180,8 +180,35 @@ inline signed int strcmp(dword text1, text2) return 0; } -:bool strequ(dword text1, text2) { - if (!strcmp(text1,text2)) return true; else return false; +/* +TODO: rewrite streq() using pure assembliy + +inline fastcall void strcpy( EDI, ESI) +{ + $cld +L2: + $lodsb + $stosb + $test al,al + $jnz L2 +} +*/ + +inline fastcall streq(ESI, EDI) +{ + loop() + { + if(DSBYTE[ESI]==DSBYTE[EDI]) + { + if(DSBYTE[ESI]==0) return true; + } + else { + return false; + } + ESI++; + EDI++; + } + return true; } /* diff --git a/programs/cmm/txtread/gui.h b/programs/cmm/txtread/gui.h deleted file mode 100644 index 349d3f81df..0000000000 --- a/programs/cmm/txtread/gui.h +++ /dev/null @@ -1,18 +0,0 @@ -void DrawToolbarButton(char image_id, int x) -{ - DefineButton(x+1, 6, TOOLBAR_ICON_WIDTH-2, TOOLBAR_ICON_HEIGHT-2, 10+image_id + BT_HIDE, 0); - img_draw stdcall(skin.image, x, 5, TOOLBAR_ICON_WIDTH, TOOLBAR_ICON_HEIGHT, 0, image_id*TOOLBAR_ICON_HEIGHT); -} - - -void DrawScroller() -{ - scroll.max_area = list.count; - scroll.cur_area = list.visible; - scroll.position = list.first; - scroll.all_redraw = 0; - scroll.start_x = list.x + list.w; - scroll.start_y = list.y; - scroll.size_y = list.h; - scrollbar_v_draw(#scroll); -} \ No newline at end of file diff --git a/programs/cmm/txtread/prepare_page.h b/programs/cmm/txtread/prepare_page.h index 452da85540..a6817f36d6 100644 --- a/programs/cmm/txtread/prepare_page.h +++ b/programs/cmm/txtread/prepare_page.h @@ -1,5 +1,3 @@ -char char_width[255]; - enum { COUNT_BUF_HEIGHT, DRAW_BUF @@ -19,7 +17,7 @@ dword line_start=io.buffer_data; for (bufoff=io.buffer_data; bufoff=list.w) || (ch==10) { srch_pos = bufoff; loop() @@ -49,12 +47,6 @@ dword line_start=io.buffer_data; void PreparePage() { - //get font chars width, need to increase performance - int i; - kfont.changeSIZE(); - for (i=0; i<256; i++) char_width[i] = kfont.symbol_size(i); - - //get font buffer height list.w = Form.cwidth-scroll.size_x-1; list.count=0; Parcer(COUNT_BUF_HEIGHT); diff --git a/programs/cmm/txtread/txtread.c b/programs/cmm/txtread/txtread.c index f2524d9bc0..2d44f6a213 100644 --- a/programs/cmm/txtread/txtread.c +++ b/programs/cmm/txtread/txtread.c @@ -1,10 +1,10 @@ #define MEMSIZE 4096*25 -#include "../lib/kfont.h" #include "../lib/io.h" #include "../lib/gui.h" #include "../lib/list_box.h" #include "../lib/menu.h" +#include "../lib/kfont.h" #include "../lib/obj/box_lib.h" #include "../lib/obj/libini.h" @@ -36,7 +36,7 @@ Ctrl+E - edit current document Press any key..." char default_dir[] = "/rd/1"; -od_filter filter2 = {0,0}; +od_filter filter2 = { 8, "TXT\0\0" }; scroll_bar scroll = { 15,200,398,44,0,2,115,15,0,0xeeeeee,0xBBBbbb,0xeeeeee,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1}; llist list; @@ -79,9 +79,9 @@ void main() { InitDlls(); OpenDialog_init stdcall (#o_dialog); + LoadIniSettings(); kfont.init(DEFAULT_FONT); Libimg_LoadImage(#skin, abspath("toolbar.png")); - LoadIniSettings(); OpenFile(#param); list.no_selection = true; SetEventMask(EVM_REDRAW + EVM_KEY + EVM_BUTTON + EVM_MOUSE + EVM_MOUSE_FILTER); @@ -209,8 +209,10 @@ void HandleMouseEvent() void EventOpenFile() { OpenDialog_start stdcall (#o_dialog); - OpenFile(#openfile_path); - PreparePage(); + if (o_dialog.status) { + OpenFile(#openfile_path); + PreparePage(); + } } void EventShowFileProperties() @@ -322,4 +324,22 @@ void DrawPage() { kfont.ShowBufferPart(list.x, list.y, list.w, list.h, list.first*list.item_h*list.w); DrawScroller(); +} + +void DrawToolbarButton(char image_id, int x) +{ + DefineButton(x+1, 6, TOOLBAR_ICON_WIDTH-2, TOOLBAR_ICON_HEIGHT-2, 10+image_id + BT_HIDE, 0); + img_draw stdcall(skin.image, x, 5, TOOLBAR_ICON_WIDTH, TOOLBAR_ICON_HEIGHT, 0, image_id*TOOLBAR_ICON_HEIGHT); +} + +void DrawScroller() +{ + scroll.max_area = list.count; + scroll.cur_area = list.visible; + scroll.position = list.first; + scroll.all_redraw = 0; + scroll.start_x = list.x + list.w; + scroll.start_y = list.y; + scroll.size_y = list.h; + scrollbar_v_draw(#scroll); } \ No newline at end of file