WebView 3.0 Gold: IMG support!

No page blinking on scroll, proper alpha-channel blend (PNG 32bpp), local images support, base64 images support* (only small ones yet). Need code refactoring.

git-svn-id: svn://kolibrios.org@8396 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Kirill Lipatov (Leency) 2020-12-13 20:52:56 +00:00
parent 11e69b4021
commit adea6f05e9
8 changed files with 102 additions and 169 deletions

View File

@ -2,7 +2,6 @@
#include "TWB\anchors.h"
#include "TWB\parse_tag.h"
#include "TWB\special.h"
#include "TWB\img.h"
#include "TWB\tag_list.h"
dword page_bg;
dword link_color_default;
@ -31,7 +30,6 @@ struct _style {
struct TWebBrowser {
llist list;
_style style;
_img img;
dword draw_y, stolbec;
int zoom;
dword o_bufpointer;
@ -40,6 +38,7 @@ struct TWebBrowser {
dword bufpointer;
dword bufsize;
dword is_html;
collection img_url;
void Paint();
void SetPageDefaults();
@ -124,12 +123,12 @@ void TWebBrowser::SetPageDefaults()
style.tag_list.reset();
link_color_default = 0x0000FF;
link_color_active = 0xFF0000;
page_bg = 0xEBE8E9; //E0E3E3 EBE8E9
page_bg = 0xffEBE8E9; //E0E3E3 EBE8E9
style.bg_color = page_bg;
DrawBuf.Fill(0, page_bg);
links.clear();
anchors.clear();
img.clear();
img_url.drop();
text_colors.drop();
text_colors.add(0);
header = NULL;
@ -333,6 +332,9 @@ bool TWebBrowser::CheckForLineBreak()
//============================================================================================
void TWebBrowser::SetStyle() {
char img_path[4096]=0;
dword imgbuf[44];
dword cur_img;
int img_x, img_y, img_w, img_h;
dword value;
@ -452,65 +454,81 @@ void TWebBrowser::SetStyle() {
}
if (tag.is("img")) {
value = tag.get_value_of("src=");
if (!value) value = tag.get_value_of("data-src=");
if (!value) goto NOIMG;
if (!strcmp(value + strrchr(value, '.'), "svg")) goto NOIMG;
if (streqrp(value, "data:")) {
if (!strstr(value, "base64,")) goto NOIMG;
value = EAX+7;
if (ESBYTE[value]==' ') value++;
cur_img = malloc(strlen(value));
base64_decode stdcall (value, cur_img, strlen(value));
img_decode stdcall (cur_img, EAX, 0);
$push eax
free(cur_img);
$pop eax
if (EAX) goto IMGOK; else goto NOIMG;
}
strlcpy(#img_path, value, sizeof(img_path)-1);
get_absolute_url(#img_path, history.current());
//if (check_is_the_adress_local(#img_path)) <== load local files
if (check_is_the_adress_local(#img_path)) {
img_from_file stdcall(#img_path);
if (EAX) goto IMGOK; else goto NOIMG;
}
if (cache.has(#img_path)) && (cache.current_size)
{
img_decode stdcall (cache.current_buf, cache.current_size, 0);
if (!EAX) goto NOIMG;
IMGOK:
EDI = EAX;
img.w.add(ESDWORD[EDI+4]);
img.h.add(ESDWORD[EDI+8]);
img_destroy stdcall(EDI);
cur_img = EAX;
img_h = ESDWORD[cur_img+8];
img_w = ESDWORD[cur_img+4];
img.url.add(#img_path);
if (img.w.get_last() / 6 + stolbec > list.column_max) {
if (img_w / 6 + stolbec > list.column_max) {
NewLine();
}
img.x.add(stolbec*list.font_w+3);
img.y.add(draw_y);
img_x = stolbec*list.font_w+3;
img_y = draw_y;
stolbec += img.w.get_last() / 6;
img_w = math.min(img_w, DrawBuf.bufw - img_x);
stolbec += img_w / 6;
if (stolbec > list.column_max) NewLine();
if (img.h.get_last() > list.item_h) {
draw_y += img.h.get_last() - list.item_h;
if (img_h > list.item_h + 5) {
draw_y += img_h - list.item_h;
NewLine();
}
if (link) links.add_text(
img.x.get_last() + list.x,
img.y.get_last() + list.y,
img.w.get_last(),
img.h.get_last(),
0);
if (link) links.add_text(img_x + list.x, img_y + list.y, img_w, img_h, 0);
if (img_y + img_h >= DrawBuf.bufh) DrawBuf.IncreaseBufSize();
if (ESDWORD[cur_img+20] != IMAGE_BPP32) {
img_convert stdcall(cur_img, 0, IMAGE_BPP32, 0, 0);
$push eax
img_destroy stdcall(cur_img);
$pop eax
cur_img = EAX;
if (!EAX) goto NOIMG;
}
imgbuf[04] = DrawBuf.bufw;
imgbuf[08] = DrawBuf.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_destroy stdcall(cur_img);
return;
} else {
img.url.add(#img_path);
img_url.add(#img_path);
}
NOIMG:
/*
if (streqrp(value, "data:")) {
EAX = strstr(value, "base64,");
if (value == EAX) return;
value = EAX;
//cache.add(history.current(), http.content_pointer, http.content_received, PAGE);
base64_decode stdcall (#pass_b64, value, strlen(value));
} else
*/
if (value = tag.get_value_of("title=")) && (strlen(value)<sizeof(line)-3) && (value) sprintf(#line, "[%s]", value);
if (value = tag.get_value_of("alt=")) && (strlen(value)<sizeof(line)-3) && (value) sprintf(#line, "[%s]", value);
if (!line) {
@ -675,16 +693,6 @@ void TWebBrowser::NewLine()
//============================================================================================
void TWebBrowser::DrawPage()
{
int i, img_y;
PutPaletteImage(list.first * DrawBuf.bufw * 4 + buf_data+8, DrawBuf.bufw, list.h, DrawBuf.bufx, DrawBuf.bufy, 32, 0);
DrawBuf.Show(list.first, list.h);
DrawScroller();
//img.draw_all(list.x, list.y, list.w, list.h, list.first);
for (i=0; i<img.url.count; i++)
{
img_y = img.y.get(i);
if (img_y + img.h.get(i) > list.first) && (img_y - list.h < list.first)
&& (cache.has(img.url.get(i))) img.draw(list.x, list.y, list.w, list.h, list.first, i);
}
}

View File

@ -1,52 +0,0 @@
struct _img
{
collection url;
collection_int x,y,w,h;
void clear();
void add();
void draw_all();
bool draw();
};
void _img::clear()
{
url.drop();
x.drop();
y.drop();
w.drop();
h.drop();
}
void _img::add(dword _path, _x, _y, _w, _h)
{
url.add(_path);
x.add(_x);
y.add(_y);
w.add(_w);
h.add(_h);
}
bool _img::draw(int _x, _y, _w, _h, _start, i)
{
int img_x, img_y, img_w, img_h, invisible_h=0;
char* img_ptr;
img_x = x.get(i);
img_y = y.get(i);
img_w = math.min(w.get(i), _w - img_x);
img_h = math.min(h.get(i), _h + _start - img_y);
if (_start > img_y) {
invisible_h = _start - img_y;
img_y = _start;
}
img_decode stdcall (cache.current_buf, cache.current_size, 0);
img_ptr = EAX;
img_draw stdcall(img_ptr, img_x + _x, img_y - _start + _y, img_w, img_h - invisible_h, 0, invisible_h);
img_destroy stdcall(img_ptr);
}

View File

@ -3,7 +3,7 @@ struct _tag
{
char name[32];
char prior[32];
char params[5000];
char params[6000];
bool opened;
collection attributes;
collection values;
@ -58,8 +58,8 @@ bool _tag::get_next_param()
{
byte quotes = NULL;
int i;
unsigned char val[4000];
unsigned char attr[4000];
unsigned char val[6000];
unsigned char attr[6000];
if (!params) return false;

View File

@ -11,7 +11,7 @@
// //
//===================================================//
#define MEMSIZE 1024 * 1000
#define MEMSIZE 1024 * 200
#include "..\lib\gui.h"
#include "..\lib\draw_buf.h"
#include "..\lib\list_box.h"
@ -41,12 +41,12 @@
// DATA //
// //
//===================================================//
char version[]="WebView 2.8 BETA 5";
char version[]="WebView 3 GOLD";
#define DEFAULT_URL URL_SERVICE_HOMEPAGE
#define DEFAULT_URL URL URL_SERVICE_HOMEPAG
bool debug_mode = false;
bool show_images = false;
bool show_images = true;
_history history;
@ -714,7 +714,7 @@ void LoadInternalPage(dword _bufdata, _in_bufsize){
} else {
WB1.DrawPage();
}
GetImg(true);
if (WB1.img_url.count) GetImg(true);
}
}
@ -924,11 +924,11 @@ dword GetImg(bool _new)
if (!show_images) return;
http_get_type = IMG;
for (i = 0; i < WB1.img.url.count; i++)
for (i = 0; i < WB1.img_url.count; i++)
{
cur_img_url = WB1.img.url.get(i);
cur_img_url = WB1.img_url.get(i);
if (cache.has(cur_img_url)==false) {
prbar.max = WB1.img.url.count;
prbar.max = WB1.img_url.count;
prbar.value = i;
if (GetUrl(cur_img_url)) {DrawProgress(); return;}
}

View File

@ -43,7 +43,7 @@ ShowHistory()
for (i=1; i<cache.url.count; i++) if (cache.type.get(i) == IMG)
{
strcat(history_pointer, cache.url.get(i));
strcat(history_pointer, "<img src='");
strcat(history_pointer, " <img src='");
strcat(history_pointer, cache.url.get(i));
strcat(history_pointer, "'><br>");
}

View File

@ -44,10 +44,9 @@ bool DrawBufer::Init(dword i_bufx, i_bufy, i_bufw, i_bufh)
void DrawBufer::Fill(dword start_pointer, i_fill_color)
{
dword i;
dword max_i = bufw * bufh * 4 + buf_data + 8;
dword max_i = bufw * bufh * 4 - start_pointer/4;
fill_color = i_fill_color;
@MEMSETD(buf_data+start_pointer+8, max_i-buf_data-start_pointer-8/4, fill_color);
@MEMSETD(buf_data+start_pointer+8, max_i, fill_color);
}
void DrawBufer::DrawBar(dword x, y, w, h, color)
@ -122,45 +121,9 @@ void DrawBufer::AlignCenter(dword x,y,w,h, content_width)
}
}
/*
void DrawBufer::Zoom2x(int zoom)
void DrawBufer::Show(dword _y_offset, _h)
{
int i, s;
dword point_x, max_i, zline_w, s_inc;
point_x = 0;
max_i = bufw * bufh * 4 + buf_data+8;
s_inc = zoom * 4;
zline_w = zbufw * 4;
for (i=buf_data+8, s=zbuf_data+8; i<max_i; i+=4, s+= s_inc) {
ESDWORD[s] = ESDWORD[i];
ESDWORD[s+4] = ESDWORD[i];
ESDWORD[s+zline_w] = ESDWORD[i];
ESDWORD[s+zline_w+4] = ESDWORD[i];
if (zoom==3)
{
ESDWORD[s+8] = ESDWORD[i];
ESDWORD[zline_w+s+8] = ESDWORD[i];
ESDWORD[zline_w*2+s] = ESDWORD[i];
ESDWORD[zline_w*2+s+4] = ESDWORD[i];
ESDWORD[zline_w*2+s+8] = ESDWORD[i];
}
point_x++;
if (point_x >= bufw)
{
s += zoom - 1 * zline_w;
point_x = 0;
}
}
}
*/
void DrawBufer::Show(dword _y_offset)
{
PutPaletteImage(_y_offset * bufw * 4 + buf_data+8, bufw, bufh, bufx, bufy, 32, 0);
PutPaletteImage(_y_offset * bufw * 4 + buf_data+8, bufw, _h, bufx, bufy, 32, 0);
}
void DrawBufer::IncreaseBufSize()

View File

@ -120,6 +120,16 @@ inline fastcall word GetButtonID()
$shr eax,8
}
inline fastcall int GetKernelRev()
{
char buf[16];
EAX = 18;
EBX = 13;
ECX = #buf;
$int 0x40
EAX = ESDWORD[#buf+5];
}
inline fastcall dword GetFreeRAM()
{
$mov eax, 18

View File

@ -19,8 +19,6 @@ dword libimg = #alibimg;
char alibimg[] = "/sys/lib/libimg.obj";
dword libimg_init = #alibimg_init;
dword img_is_img = #aimg_is_img;
dword img_to_rgb2 = #aimg_to_rgb2;
dword img_decode = #aimg_decode;
dword img_destroy = #aimg_destroy;
dword img_draw = #aimg_draw;
@ -28,15 +26,18 @@ dword img_create = #aimg_create;
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;
$DD 2 dup 0
//import libimg , \
//import
char alibimg_init[] = "lib_init";
char aimg_is_img[] = "img_is_img";
char aimg_to_rgb2[] = "img_to_rgb2";
char aimg_decode[] = "img_decode";
char aimg_destroy[] = "img_destroy";
char aimg_draw[] = "img_draw";
@ -44,10 +45,13 @@ char aimg_create[] = "img_create";
char aimg_encode[] = "img_encode";
char aimg_convert[] = "img_convert";
char aimg_from_file[] = "img_from_file";
//char aimg_flip[] = "img_flip";
//char aimg_rotate[] = "img_rotate ";
//invoke img.scale, ebx, 0, 0, [ebx + Image.Width], [ebx + Image.Height], 0, LIBIMG_SCALE_TYPE_STRETCH, LIBIMG_SCALE_ALG_BILINEAR, edx, ecx
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";
#define LIBIMG_FORMAT_BMP 1
#define LIBIMG_FORMAT_ICO 2
@ -104,16 +108,16 @@ struct libimg_image
{
$push edi
EDI = image;
checksum = DSWORD[EDI];
//checksum = ESDWORD[EDI];
w = ESDWORD[EDI+4];
h = ESDWORD[EDI+8];
next = ESDWORD[EDI+12];
previous = ESDWORD[EDI+16];
//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];
//palette = ESDWORD[EDI+28];
//extended = ESDWORD[EDI+32];
//flags = ESDWORD[EDI+36];
//delay = ESDWORD[EDI+40];
$pop edi
}