WebView 3.25: refactoring again and not the last:

- use X coordinate from draw, not column
- make "zoom" var local, mostly use font_w instead
- rework logic of reparsing document when the size of window changed
- new: improve image positioning

git-svn-id: svn://kolibrios.org@8457 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Kirill Lipatov (Leency) 2020-12-20 13:28:50 +00:00
parent 91ae0dee0b
commit 07c794104b
6 changed files with 80 additions and 100 deletions

View File

@ -39,8 +39,7 @@ void STYLE::reset()
struct TWebBrowser {
llist list;
STYLE style;
dword draw_y, stolbec;
int zoom;
dword draw_y, draw_x;
dword o_bufpointer;
int cur_encoding, custom_encoding;
bool link, t_html, t_body;
@ -86,7 +85,8 @@ void TWebBrowser::Paint()
unsigned px; //paint x coordinate
unsigned pw; //paint y coordinate
dword pc; //paint color
int zoom;
if (style.title)
{
strncpy(#header, #line, sizeof(TWebBrowser.header)-1);
@ -102,37 +102,37 @@ void TWebBrowser::Paint()
if (line)
{
px = stolbec * list.font_w + BODY_MARGIN + list.x;
pw = strlen(#line) * zoom * list.font_w;
stolbec += strlen(#line) * zoom;
pw = strlen(#line) * list.font_w;
zoom = list.font_w / BASIC_CHAR_W;
style.cur_line_h = math.max(style.cur_line_h, list.item_h);
if (bg_colors.get_last() - bg_colors.get(0)) {
canvas.DrawBar(px, draw_y, pw, list.item_h, bg_colors.get_last());
canvas.DrawBar(draw_x, draw_y, pw, list.item_h, bg_colors.get_last());
}
if (style.image) {
canvas.DrawBar(px, draw_y, pw, list.item_h-1, 0xF9DBCB);
canvas.DrawBar(draw_x, draw_y, pw, list.item_h-1, 0xF9DBCB);
}
if (style.button) {
canvas.DrawBar(px, draw_y, pw, list.item_h - calc(zoom*2), 0xCCCccc);
canvas.DrawBar(px, draw_y + list.item_h - calc(zoom*2), pw, zoom, 0x999999);
canvas.DrawBar(draw_x, draw_y, pw, list.item_h - calc(zoom*2), 0xCCCccc);
canvas.DrawBar(draw_x, draw_y + list.item_h - calc(zoom*2), pw, zoom, 0x999999);
}
pc = text_colors.get_last();
if (link) && (pc == text_colors.get(0)) pc = link_color_default;
canvas.WriteText(px, draw_y, list.font_type, pc, #line, NULL);
if (style.b) canvas.WriteText(px+1, draw_y, list.font_type, pc, #line, NULL);
if (style.s) canvas.DrawBar(px, list.item_h / 2 - zoom + draw_y, pw, zoom, pc);
if (style.u) canvas.DrawBar(px, list.item_h - zoom - zoom + draw_y, pw, zoom, pc);
canvas.WriteText(draw_x, draw_y, list.font_type, pc, #line, NULL);
if (style.b) canvas.WriteText(draw_x+1, draw_y, list.font_type, pc, #line, NULL);
if (style.s) canvas.DrawBar(draw_x, list.item_h / 2 - zoom + draw_y, pw, zoom, pc);
if (style.u) canvas.DrawBar(draw_x, list.item_h - zoom - zoom + draw_y, pw, zoom, pc);
if (link) {
if (line[0]==' ') && (line[1]==NULL) {} else {
canvas.DrawBar(px, draw_y + list.item_h - calc(zoom*2)-1, pw, zoom, link_color_default);
links.add_text(px, draw_y + list.y, pw, list.item_h - calc(zoom*2)-1, zoom);
canvas.DrawBar(draw_x, draw_y + list.item_h - calc(zoom*2)-1, pw, zoom, link_color_default);
links.add_text(draw_x, draw_y + list.y, pw, list.item_h - calc(zoom*2)-1, zoom);
}
}
draw_x += pw;
if (debug_mode) debugln(#line);
line = NULL;
}
@ -156,9 +156,8 @@ void TWebBrowser::SetPageDefaults()
header = NULL;
cur_encoding = CH_CP866;
draw_y = BODY_MARGIN;
stolbec = 0;
draw_x = BODY_MARGIN;
line = 0;
zoom = 1;
redirect = '\0';
//hold original buffer
if (o_bufpointer) o_bufpointer=free(o_bufpointer);
@ -177,6 +176,8 @@ void TWebBrowser::ParseHtml(dword _bufpointer, _bufsize){
dword bufpos;
bufsize = _bufsize;
if (list.w!=canvas.bufw) canvas.Init(list.x, list.y, list.w, 400*20);
if (bufpointer != _bufpointer) {
bufpointer = malloc(bufsize);
memmov(bufpointer, _bufpointer, bufsize);
@ -206,7 +207,7 @@ void TWebBrowser::ParseHtml(dword _bufpointer, _bufsize){
break;
case 0x09:
if (style.pre) {
tab_len = strlen(#line) + stolbec % 4;
tab_len = draw_x - BODY_MARGIN / list.font_w + strlen(#line) % 4;
if (!tab_len) tab_len = 4; else tab_len = 4 - tab_len;
for (j=0; j<tab_len; j++;) chrcat(#line,' ');
} else {
@ -280,7 +281,7 @@ void TWebBrowser::AddCharToTheLine(unsigned char _char)
if (!style.pre) && (_char == ' ')
{
if (line[line_len-1]==' ') return; //no double spaces
if (!stolbec) && (!line) return; //no paces at the beginning of the line
if (draw_x==BODY_MARGIN) && (!line) return; //no paces at the beginning of the line
if (link) && (line_len==0) return;
}
if (line_len < sizeof(line)) chrcat(#line, _char);
@ -289,52 +290,51 @@ void TWebBrowser::AddCharToTheLine(unsigned char _char)
//============================================================================================
bool TWebBrowser::CheckForLineBreak()
{
int line_break_pos;
char new_line_text[4096];
int break_pos;
char next_line[4096];
int zoom = list.font_w / BASIC_CHAR_W;
//Do we need a line break?
if (strlen(#line)*zoom + stolbec < list.column_max) return false;
if (strlen(#line) * list.font_w + draw_x < list.w) return false;
//Yes, we do. Lets calculate where...
line_break_pos = strrchr(#line, ' ');
break_pos = strrchr(#line, ' ');
//Is a new line fits in the current line?
if (line_break_pos*zoom + stolbec > list.column_max) {
line_break_pos = list.column_max/zoom - stolbec;
while(line_break_pos) && (line[line_break_pos]!=' ') line_break_pos--;
if (break_pos * list.font_w + draw_x > list.w) {
break_pos = list.w - draw_x /list.font_w;
while(break_pos) && (line[break_pos]!=' ') break_pos--;
}
//Maybe a new line is too big for the whole new line? Then we have to split it
if (!line_break_pos) && (style.tag_list.level*5 + strlen(#line) * zoom >= list.column_max) {
line_break_pos = list.column_max/zoom - stolbec;
if (!break_pos) && (style.tag_list.level*5 + strlen(#line) * zoom >= list.column_max) {
break_pos = list.w - draw_x / list.font_w;
}
strcpy(#new_line_text, #line + line_break_pos);
line[line_break_pos] = 0x00;
strcpy(#next_line, #line + break_pos);
line[break_pos] = 0x00;
Paint();
strcpy(#line, #new_line_text);
strcpy(#line, #next_line);
NewLine();
return true;
}
//============================================================================================
void TWebBrowser::NewLine()
{
static int empty_line=0;
static bool empty_line = true;
if (!stolbec) && (draw_y==BODY_MARGIN) return;
if (draw_x==BODY_MARGIN) && (draw_y==BODY_MARGIN) return;
if (t_html) && (!t_body) return;
if (style.tag_list.level) && (stolbec == style.tag_list.level * 5) {
if (empty_line<1) empty_line++;
else return;
} else if (!stolbec) {
if (empty_line<1) empty_line++;
else return;
if (draw_x == style.tag_list.level * 5 * list.font_w + BODY_MARGIN) {
if (!empty_line) empty_line=true; else return;
} else {
empty_line=0;
empty_line = false;
}
if (t_html) && (!t_body) return;
draw_y += style.cur_line_h;
style.cur_line_h = list.item_h;
if (style.blq) stolbec = 6; else stolbec = 0;
stolbec += style.tag_list.level * 5;
if (style.blq) draw_x = 6 * list.font_w; else draw_x = 0;
draw_x += style.tag_list.level * 5 * list.font_w + BODY_MARGIN;
}
//============================================================================================
void TWebBrowser::ChangeEncoding(int _new_encoding)
@ -354,6 +354,11 @@ scroll_bar scroll_wv =
void TWebBrowser::DrawPage()
{
if (list.w!=canvas.bufw) {
ParseHtml(bufpointer, bufsize);
}
canvas.Show(list.first, list.h);
scroll_wv.max_area = list.count;
scroll_wv.cur_area = list.visible;
scroll_wv.position = list.first;
@ -363,5 +368,4 @@ void TWebBrowser::DrawPage()
scroll_wv.size_y = list.h;
scrollbar_v_draw(#scroll_wv);
canvas.Show(list.first, list.h);
}

View File

@ -31,7 +31,7 @@ void TWebBrowser::SetStyle()
if (tag.is("dl")) { if (tag.opened) NewLine(); return; }
if (tag.is("tr")) { if (tag.opened) NewLine(); return; }
if (tag.is("td")) { /*if (tag.opened) AddCharToTheLine(' ');*/ return; }
if (tag.is("button")) { style.button = tag.opened; stolbec++; return; }
if (tag.is("button")) { style.button = tag.opened; draw_x+=10; return; }
if (tag.is("w:r")) { if (!tag.opened) style.b = false; return; }
if (tag.is("h1")) { tag_h1234_caption(); return; }
if (tag.is("h2")) { tag_h1234_caption(); return; }
@ -180,11 +180,11 @@ void TWebBrowser::tag_li()
if (!style.pre) NewLine();
if (style.tag_list.order_type() == 'u') {
strcpy(#line, "\31 ");
stolbec = style.tag_list.level * 5 - 2;
draw_x = style.tag_list.level * 5 - 2 * list.font_w + BODY_MARGIN;
}
if (style.tag_list.order_type() == 'o') {
sprintf(#line, "%i. ", style.tag_list.inc_counter());
stolbec = style.tag_list.level * 5 - strlen(#line);
draw_x = style.tag_list.level * 5 - 1 - strlen(#line) * list.font_w + BODY_MARGIN;
}
}
}
@ -243,15 +243,13 @@ void TWebBrowser::tag_h1234_caption()
if (tag.opened) {
if (!style.pre) NewLine();
draw_y += 10;
zoom=2;
list.font_type |= 10011001b;
list.SetFont(BASIC_CHAR_W*2, 14*2, 10011001b);
list.item_h = BASIC_LINE_H * 2 - 2;
if (tag.is("h1")) style.b = true;
} else {
if (tag.is("h1")) style.b = false;
NewLine();
zoom=1;
list.font_type = 10011000b;
list.SetFont(BASIC_CHAR_W, 14, 10011000b);
style.cur_line_h = list.item_h = BASIC_LINE_H;
}
}
@ -306,26 +304,14 @@ IMGOK:
img_h = ESDWORD[cur_img+8];
img_w = ESDWORD[cur_img+4];
if (img_w / 8 + stolbec > list.column_max) {
NewLine();
}
img_x = stolbec*list.font_w + 3;
if (img_w + draw_x >= list.w) NewLine();
img_y = draw_y;
if (img_h < list.item_h) img_y += list.item_h - img_h / 2 - 1; else img_y -= 2;
style.cur_line_h = math.max(style.cur_line_h, img_h);
img_w = math.min(img_w, canvas.bufw - img_x);
img_w = math.min(img_w, canvas.bufw - draw_x);
style.cur_line_h = math.max(list.item_h, img_h);
stolbec += img_w / 8;
if (img_w % 8) stolbec++;
if (stolbec > list.column_max) {
NewLine();
}
if (link) links.add_text(img_x + list.x, img_y + list.y, img_w, img_h, 0);
if (link) links.add_text(draw_x + list.x, img_y + list.y, img_w, img_h, 0);
if (img_y + img_h >= canvas.bufh) canvas.IncreaseBufSize();
@ -341,8 +327,11 @@ IMGOK:
imgbuf[08] = canvas.bufh;
imgbuf[20] = IMAGE_BPP32;
imgbuf[24] = buf_data+8;
img_blend stdcall(#imgbuf, cur_img, img_x, img_y, 0, 0, img_w, img_h);
img_blend stdcall(#imgbuf, cur_img, draw_x, img_y, 0, 0, img_w, img_h);
img_destroy stdcall(cur_img);
draw_x += img_w;
if (draw_x >= list.w) NewLine();
return;
NOIMG:

View File

@ -41,7 +41,7 @@
// DATA //
// //
//===================================================//
char version[]="WebView 3.21";
char version[]="WebView 3.25";
#define DEFAULT_URL URL_SERVICE_HOMEPAGE
@ -220,10 +220,10 @@ void main()
redirect_count++;
HandleRedirect();
} else {
notify("'Too many redirects.' -E");
StopLoading();
redirect_count = 0;
if (http_get_type==IMG) goto _IMG_RES;
notify("'Too many redirects.' -E");
}
} else {
// Loading the page is complete, free resources
@ -335,7 +335,7 @@ bool ProcessKeyEvent()
void SetElementSizes()
{
omnibox_edit.width = Form.cwidth - omnibox_edit.left - 52 - 16;
WB1.list.SetSizes(0, TOOLBAR_H+TAB_H, Form.width - 10 - scroll_wv.size_x,
WB1.list.SetSizes(0, TOOLBAR_H+TAB_H, Form.cwidth - scroll_wv.size_x,
Form.cheight - TOOLBAR_H - STATUSBAR_H - TAB_H, BASIC_LINE_H);
WB1.list.wheel_size = 7 * BASIC_LINE_H;
WB1.list.column_max = WB1.list.w - scroll_wv.size_x / WB1.list.font_w + 1;
@ -366,33 +366,17 @@ void draw_window()
DrawRectangle(WB1.list.x + WB1.list.w, WB1.list.y, scroll_wv.size_x,
WB1.list.h-1, scroll_wv.bckg_col);
if (!BrowserWidthChanged()) {
if (!canvas.bufw) {
OpenPage(history.current());
} else {
WB1.DrawPage();
DrawOmnibox();
DrawOmnibox();
}
DrawProgress();
DrawStatusBar(NULL);
DrawTabsBar();
}
bool BrowserWidthChanged()
{
dword source_mode_holder;
if (WB1.list.w!=canvas.bufw) {
canvas.Init(WB1.list.x, WB1.list.y, WB1.list.w, 400*20);
if (!strncmp(history.current(),"http",4)) {
//nihuya ne izyashnoe reshenie, no pust' poka butet tak
source_mode_holder = source_mode;
LoadInternalPage(#loading_text, sizeof(loading_text));
source_mode = source_mode_holder;
}
OpenPage(history.current());
return true;
}
return false;
}
void EventChangeEncodingAndLoadPage(int _new_encoding)
{
dword newbuf, newsize;
@ -561,6 +545,7 @@ void OpenPage(dword _open_URL)
history.add(#new_url);
if (streq(#new_url, URL_SERVICE_HOMEPAGE)) LoadInternalPage(#buildin_page_home, sizeof(buildin_page_home));
else if (streq(#new_url, URL_SERVICE_HELP)) LoadInternalPage(#buildin_page_help, sizeof(buildin_page_help));
else if (streq(#new_url, URL_SERVICE_TEST)) LoadInternalPage(#buildin_page_test, sizeof(buildin_page_test));
else if (streq(#new_url, URL_SERVICE_HISTORY)) ShowHistory();
else LoadInternalPage(#buildin_page_error, sizeof(buildin_page_error));
@ -950,7 +935,7 @@ dword GetImg(bool _new)
if (_new) return;
DrawOmnibox();
DrawStatusBar(T_RENDERING);
WB1.ParseHtml(WB1.o_bufpointer, WB1.bufsize);
WB1.ParseHtml(WB1.bufpointer, WB1.bufsize);
WB1.DrawPage();
debugln(sprintf(#param, T_DONE_IN_SEC, GetStartTime()-render_start_time/100));
DrawStatusBar(NULL);

View File

@ -2,6 +2,7 @@
char buildin_page_error[] = FROM "res/page_not_found_ru.htm""\0";
char buildin_page_home[] = FROM "res/homepage_ru.htm""\0";
char buildin_page_help[] = FROM "res/help_ru.htm""\0";
char buildin_page_test[] = FROM "res/test.htm""\0";
char accept_language[]= "Accept-Language: ru\n";
char rmb_menu[] =
"<EFBFBD>®á¬®âà¥âì ¨á室­¨ª|Ctrl+U
@ -66,9 +67,12 @@ char clear_cache_ok[] = "'WebView\nThe cache has been cleared.' -tI";
#define URL_SERVICE_HISTORY "WebView:history"
#define URL_SERVICE_HOMEPAGE "WebView:home"
#define URL_SERVICE_HELP "WebView:help"
#define URL_SERVICE_TEST "WebView:test"
char webview_shared[] = "WEBVIEW";
#define BASIC_CHAR_W 8
enum {
NEW_TAB=600,
ENCODINGS=700,

View File

@ -12,5 +12,3 @@
<li>Browser doesn't handled properly server's response.<br>
Please, report an error.<br>
</ul>
</body>
</html>

View File

@ -146,6 +146,7 @@ void EventTabClose(int _id)
if (_id == tab.active) {
tab.close(_id);
tab.restore(tab.active);
SetElementSizes();
WB1.ParseHtml(WB1.bufpointer, WB1.bufsize);
WB1.DrawPage();
SetOmniboxText(history.current());
@ -166,11 +167,10 @@ void EventTabClick(int _id)
if (_id==-1) _id = tab.count-1;
tab.save_state();
tab.restore(_id);
if (!BrowserWidthChanged()) {
DrawTabsBar();
WB1.ParseHtml(WB1.bufpointer, WB1.bufsize);
WB1.DrawPage();
}
DrawTabsBar();
SetElementSizes();
WB1.ParseHtml(WB1.bufpointer, WB1.bufsize);
WB1.DrawPage();
SetOmniboxText(history.current());
}