enum BlockType
{
+ HTML,
TEXT = 1,
IMAGE,
BR,
TD,
ANCHOR,
INPUT,
- FORM
+ FORM,
+ TITLE,
+ HEAD
};
define LEFT_MARGIN = 10;
class RenderFlags { bool lineW:1,width:1,render:1,minW:1; };
-enum InputType { text, submit, radio, hidden };
+enum InputType { text, submit, checkbox, radio, hidden };
class ImageEntry : struct
{
{
HTTPFile httpFile {};
file = httpFile;
+ incref file;
//printf("Opening URL\n");
//((GuiApplication)__thisModule).PauseNetworkEvents();
char extension[MAX_EXTENSION];
entry.bitmap = Bitmap { alphaBlend = true };
entry.bitmap.LoadFromFile(file, GetExtension(path, extension), null);
+ incref file;
}
}
delete file;
browserWindow.Update(null);
// ((GuiApplication)__thisModule).UpdateDisplay();
+ display.Unlock();
}
- display.Unlock();
+
// TRIED MOVING THIS HERE BECAUSE OF printf("bug") in GuiApplication if(window.display.current)
((GuiApplication)__thisModule).UpdateDisplay();
}
ComputeImageSize(child);
}
+// Resources Cache
+Window sharedWindow
+{
+ visible = false;
+
+ bool OnLoadGraphics()
+ {
+ ImageEntry entry;
+ FontEntry fEntry;
+ for(entry = imageCache.first; entry; entry = entry.next)
+ {
+ entry.bitmap.MakeDD(displaySystem);
+ if(entry.bitmap && entry.bitmap.alphaBlend)
+ {
+ entry.bitmap.Convert(null, pixelFormat888, null);
+ // entry.bitmap.displaySystem = displaySystem;
+ }
+ }
+ for(fEntry = fontCache.first; fEntry; fEntry = fEntry.next)
+ {
+ if(!fEntry.font)
+ fEntry.font = displaySystem.LoadFont(fEntry.face, fEntry.size, fEntry.attribs);
+ }
+ return true;
+ }
+
+ void OnUnloadGraphics()
+ {
+ ImageEntry entry;
+ FontEntry fontEntry;
+ while((entry = imageCache.first))
+ {
+ imageCache.Remove(entry);
+ delete entry;
+ }
+ while((fontEntry = fontCache.first))
+ {
+ displaySystem.UnloadFont(fontEntry.font);
+ fontCache.Remove(fontEntry);
+ delete fontEntry;
+ }
+ }
+};
+
class HTMLView : Window
{
HTMLFile html {};
- BitmapResource missing { "<:ecere>emblems/unreadable.png", window = this };
+ BitmapResource missing { "<:ecere>emblems/unreadable.png", window = sharedWindow /*this*/ };
char * location;
Block overLink, clickedLink;
Block overBlock;
{
case submit:
block.window = Button { this, text = block.value, position = Point { 10, 50 }, id = (int64)block, NotifyClicked = ButtonClicked, isDefault = true };
+ if(block.size)
+ block.window.size = { w = (int)(block.size * 8) };
+ if(block.src)
+ {
+ ((Button)block.window).bitmap = { block.src };
+ ((Button)block.window).bevel = false;
+ }
eInstance_IncRef(block.window);
block.window.Create();
block.window.cursor = ((GuiApplication)__thisModule).GetCursor(arrow);
//if(!html.defaultButton) html.defaultButton = block.window;
break;
+ case checkbox:
+ block.window = Button { this, isCheckbox = true, position = Point { 10, 100 }, id = (int64)block, NotifyClicked = ButtonClicked };
+ eInstance_IncRef(block.window);
+ block.window.Create();
+ block.window.cursor = ((GuiApplication)__thisModule).GetCursor(arrow);
+ break;
case radio:
block.window = Button { this, isRadio = true, position = Point { 10, 100 }, id = (int64)block, NotifyClicked = ButtonClicked };
eInstance_IncRef(block.window);
block.window.cursor = ((GuiApplication)__thisModule).GetCursor(arrow);
break;
case text:
- block.window = EditBox { this, position = Point { 10, 20 }, id = (int64)block };
+ block.window = EditBox { this, contents = block.value, size = { w = (int)(block.size * 8) }, position = Point { 10, 20 }, id = (int64)block };
+ if(!block.size)
+ {
+ ((EditBox)block.window).size.w = block.parent.width;
+ }
eInstance_IncRef(block.window);
block.window.Create();
break;
if(block.src && (block.type == IMAGE || block.type == TD || block.type == TABLE))
{
char path[MAX_LOCATION];
- ImageEntry entry;
+ ImageEntry entry = null;
strcpy(path, location ? location : "");
if(location && path[strlen(path)-1] != '/')
else
PathCat(path, block.src);
- for(entry = imageCache.first; entry; entry = entry.next)
- if(!strcmp(entry.src, path))
- break;
+ if(!strstr(path, "File://"))
+ {
+ for(entry = imageCache.first; entry; entry = entry.next)
+ if(!strcmp(entry.src, path))
+ break;
+ }
if(!entry)
{
char extension[MAX_EXTENSION];
entry.bitmap = Bitmap { alphaBlend = true };
entry.bitmap.LoadFromFile(file, GetExtension(path, extension), null);
+ display.Lock(false);
+ entry.bitmap.MakeDD(displaySystem);
+ display.Unlock();
}
delete file;
for(bitmapPtr = entry.bitmapPtrs.first; bitmapPtr; bitmapPtr = bitmapPtr.next)
}
}
block.font = block.parent.font;
+ block.textColor = block.parent.textColor;
}
else if(block.type == FONT || block.type == ANCHOR)
{
if(!entry)
{
display.Lock(false);
- entry = FontEntry { /*font = displaySystem.LoadFont(block.face, block.size, block.attribs), */size = block.size, attribs = block.attribs, face = CopyString(block.face) };
+ entry = FontEntry { font = displaySystem.LoadFont(block.face, block.size, block.attribs), size = block.size, attribs = block.attribs, face = CopyString(block.face) };
fontCache.Add(entry);
display.Unlock();
}
if(entry)
- {
- // ?
block.font = entry;
- }
}
else if(block.parent)
- block.font = block.parent.font;
-
- for(child = block.subBlocks.first; child; child = child.next)
- LoadGraphics(child, previous);
- }
-
- bool OnLoadGraphics()
- {
- ImageEntry entry;
- FontEntry fEntry;
- for(entry = imageCache.first; entry; entry = entry.next)
{
- entry.bitmap.MakeDD(displaySystem);
- if(entry.bitmap && entry.bitmap.alphaBlend)
- {
- entry.bitmap.Convert(null, pixelFormat888, null);
- // entry.bitmap.displaySystem = displaySystem;
- }
+ block.font = block.parent.font;
+ block.textColor = block.parent.textColor;
}
- for(fEntry = fontCache.first; fEntry; fEntry = fEntry.next)
- fEntry.font = browserWindow.displaySystem.LoadFont(fEntry.face, fEntry.size, fEntry.attribs);
- return true;
- }
-
- void OnUnloadGraphics()
- {
- FontEntry entry;
- for(entry = fontCache.first; entry; entry = entry.next)
+ else
{
- browserWindow.displaySystem.UnloadFont(entry.font);
- entry.font = null;
+ block.textColor = black;
}
+
+ for(child = block.subBlocks.first; child; child = child.next)
+ LoadGraphics(child, previous);
}
void NormalizeSelection(Block * startBlock, int * startSel, Block * endBlock, int * endSel)
Surface surface = display.GetSurface(0,0,null);
if(surface)
{
+ Font font;
if(html.defaultFont.font)
surface.TextFont(html.defaultFont.font.font);
+
+ font = surface.font;
for(;block;)
{
Block nextBlock;
int left, right;
int x, maxW;
int thisLineCentered = centered;
- Font font = surface.GetFont();
bool changeLine;
left = LEFT_MARGIN;
maxW = right - left;
newH = ComputeLine(surface, block, textPos, &nextBlock, &nextTextPos, ¢ered, &w, maxW, maxH - y, RenderFlags {}, y, &leftObjects, &rightObjects, &changeLine, true, 0 /*y*/, LEFT_MARGIN);
+
if(thisLineCentered)
x = Max(left,(left + right - w) / 2);
else
x = left;
- surface.TextFont(font);
+ surface.font = font;
PositionLine(this, surface, x - scroll.x, y - scroll.y,
maxW, newH, block, textPos, nextBlock, nextTextPos,
void Open(char * location, char * firstReferer)
{
- HTTPFile f {};
+ HTTPFile f { /*reuseConnection = false*/ };
char referer[MAX_LOCATION] = "";
char relocation[MAX_LOCATION];
bool opened = false;
strcpy(relocation, location);
+ // PrintLn("\n\n\nOpening new location: ", location, "\n");
+
if(strstr(location, "http://") != location)
{
if(!FileExists(location))
if(opened)
{
+ bool isHTTP = eClass_IsDerived(f._class, class(HTTPFile));
void * previous = null;
- html.Parse(f);
+ bool isImage = false;
+ bool isPlain = isHTTP ? false : true;
+
+ // Handle known types
+ if(isHTTP && f.contentType)
+ {
+ if(strstr(f.contentType, "image/") == f.contentType)
+ isImage = true;
+ else if(strstr(f.contentType, "text/") == f.contentType && strnicmp(f.contentType + 5, "html", 4))
+ isPlain = true;
+ }
+ else
+ {
+ const String imageExt[] = { "jpg", "jpeg", "bmp", "pcx", "png", "gif" };
+ const String htmlExt[] = { "html", "htm", "php" };
+ const String textExt[] = { "c", "h", "ec", "eh", "epj", "cpp", "cxx", "cc", "hpp", "hxx", "hh", "m", "java", "cs", "py", "Makefile", "mk", "cf" };
+ char ext[MAX_EXTENSION];
+ int i;
+ GetExtension(fileName, ext);
+ for(i = 0; i < sizeof(imageExt) / sizeof(imageExt[0]); i++)
+ if(!strcmpi(ext, imageExt[i]))
+ {
+ isImage = true;
+ break;
+ }
+
+ for(i = 0; i < sizeof(htmlExt) / sizeof(htmlExt[0]); i++)
+ if(!strcmpi(ext, htmlExt[i]))
+ {
+ isPlain = false;
+ break;
+ }
+
+ for(i = 0; i < sizeof(textExt) / sizeof(textExt[0]); i++)
+ if(!strcmpi(ext, textExt[i]))
+ {
+ isPlain = true;
+ break;
+ }
+ }
+
+ if(isImage)
+ {
+ Block subBlock;
+ html.body = HTMLFile::AddBlock(html.block, BODY);
+
+ subBlock = HTMLFile::AddBlock(html.body, IMAGE);
+ subBlock.valign = bottom;
+ subBlock.halign = middle;
+ subBlock.src = CopyString(fileName);
+ html.defaultFont.type = FONT;
+ html.defaultFont.face = CopyString("Times New Roman");
+ }
+ else if(isPlain)
+ {
+ uint size;
+ TempFile tmp { };
+ Block subBlock;
+ char * text;
+ int len;
+ String cd = eClass_IsDerived(f._class, class(HTTPFile)) ? f.contentDisposition : null;
+
+ String tmpPath = PrintString("File://", (uintptr)tmp);
+ f.CopyTo(tmpPath);
+ size = tmp.GetSize();
+ tmp.Seek(0, start);
+
+ html.defaultFont.type = FONT;
+ html.defaultFont.face = CopyString("Courier New");
+
+ if(cd)
+ {
+ char fn[MAX_LOCATION];
+ while(GetKeyWordEx(&cd, fn, sizeof(fn), true, false))
+ {
+ if(!strcmp(fn, "filename") && GetKeyWordEx(&cd, fn, sizeof(fn), true, true))
+ {
+ html.titleBlock = HTMLFile::AddBlock(html.block, TITLE);
+ subBlock = HTMLFile::AddBlock(html.titleBlock, TEXT);
+ subBlock.text = CopyString(fn);
+ subBlock.textLen = strlen(fn);
+ }
+ }
+ }
+
+ html.body = HTMLFile::AddBlock(html.block, BODY);
+ html.block = html.body;
+
+ text = new char[size + 1];
+ len = tmp.Read(text, 1, size);
+ text[len] = 0;
+
+ {
+ int c;
+ char ch;
+ int start = 0;
+ Block textBlock = HTMLFile::AddBlock(html.block, TEXT);
+
+ for(c = 0; ; c++)
+ {
+ ch = text[c];
+ if(ch == '\n' || ch == '\r' || !ch)
+ {
+ int len = c - start;
+ textBlock.text = renew textBlock.text char[textBlock.textLen + 1 + len];
+ memmove(textBlock.text + len, textBlock.text, textBlock.textLen + 1);
+ memcpy(textBlock.text, text + start, len);
+ textBlock.textLen += len;
+ if(!ch) break;
+ {
+ Block block { type = BR, parent = textBlock.parent };
+ Block newBlock { type = TEXT, parent = textBlock.parent };
+
+ textBlock.parent.subBlocks.Insert(textBlock, block);
+ textBlock.parent.subBlocks.Insert(block, newBlock);
+
+ newBlock.textLen = 0;
+ newBlock.text = new char[1];
+ newBlock.text[0] = 0;
+
+ textBlock = newBlock;
+ }
+ if(ch == '\r' && text[c+1] == '\n') c++;
+ start = c + 1;
+ }
+ }
+
+ html.block = html.block.parent;
+ delete text;
+ }
+ delete tmp;
+ delete tmpPath;
+
+ }
+ else
+ {
+ html.Parse(f);
+ if(html.baseHRef)
+ {
+ delete this.location;
+ this.location = CopyString(html.baseHRef);
+ }
+ }
LoadGraphics(html.defaultFont, &previous);
+ html.block.font = html.defaultFont.font;
LoadGraphics(html.block, &previous);
CreateForms(html.block);
*/
}
+ ((GuiApplication)__thisModule.application).Unlock();
+ // PrintLn("At position ", f.Tell(), " for ", fileName);
delete f;
+ ((GuiApplication)__thisModule.application).Lock();
NotifyPageOpened(master);
}
void * previous = null;
html.Parse(f);
LoadGraphics(html.defaultFont, &previous);
+ html.block.font = html.defaultFont.font;
LoadGraphics(html.block, &previous);
CreateForms(html.block);
int maxH = clientSize.h - BOTTOM_MARGIN;
OldList leftObjects { };
OldList rightObjects { };
+ Font font;
AlignedObject object, nextObject;
int h = 0;
int left, right;
int x, maxW;
int thisLineCentered = centered;
- Font font = surface.GetFont();
bool changeLine;
left = LEFT_MARGIN;
right = Max(left, right);
maxW = right - left;
+ font = surface.font;
newH = ComputeLine(surface, block, textPos, &nextBlock, &nextTextPos, ¢ered, &w, maxW, maxH - y, RenderFlags {}, y, &leftObjects, &rightObjects, &changeLine, false, 0, 0);
+ surface.font = font;
if(thisLineCentered)
x = Max(left,(left + right - w) / 2);
else
int left, right;
int x, maxW;
int thisLineCentered = centered;
- Font font = surface.GetFont();
+ Font font = surface.font;
bool changeLine;
left = LEFT_MARGIN;
else
x = left;
- surface.TextFont(font);
+ surface.font = font;
if(PickLine(this, surface, x - scroll.x, y - scroll.y,
maxW, newH, block, textPos, nextBlock, nextTextPos,
}
delete surface;
}
+
+ for(object = leftObjects.last; object; object = nextObject)
+ {
+ nextObject = object.prev;
+ leftObjects.Delete(object);
+ }
+ for(object = rightObjects.last; object; object = nextObject)
+ {
+ nextObject = object.prev;
+ rightObjects.Delete(object);
+ }
return result;
}
}
if(linkBlock)
{
- if(strstr(linkBlock.href, "edit://") == linkBlock.href)
+ if(linkBlock.href && strstr(linkBlock.href, "edit://") == linkBlock.href)
cursor = ((GuiApplication)__thisModule).GetCursor(iBeam);
else
cursor = ((GuiApplication)__thisModule).GetCursor(hand);
{
delete this.location;
- {
- ImageEntry entry;
- FontEntry fontEntry;
- while((entry = imageCache.first))
- {
- imageCache.Remove(entry);
- delete entry;
- }
- while((fontEntry = fontCache.first))
- {
- fontCache.Remove(fontEntry);
- delete fontEntry;
- }
- html.block.ClearEntries();
- }
+ html.block.ClearEntries();
}
property char * location
}
get { return location; }
}
+
+ property String title
+ {
+ get
+ {
+ String title = html.title;
+ return title ? title : location;
+ }
+ }
}
import "HTMLView"
-#define MAX_TAG_LEN 204800
-#define MAX_SYMBOL_LEN 1000
+#define MAX_TAG_LEN 256
+#define MAX_SYMBOL_LEN 256
#define WORD_NONE 0
#define WORD_NORMAL 1
}
};
-static bool GetKeyWordEx(char ** input, char * keyWord, int maxSize, bool treatEqual)
+String ParseURL(String input)
+{
+ int c;
+ char ch;
+ int len = strlen(input);
+ String output = new char[len+1];
+ len = 0;
+ for(c = 0; (ch = input[c]); c++)
+ {
+ if(ch == '%' && isalnum(input[c+1]) && isalnum(input[c+2]))
+ {
+ char hex[3] = { input[c+1], input[c+2], 0 };
+ char * end;
+ int v = (int)strtoul(hex, &end, 16);
+ if(v && end == hex + 2)
+ {
+ output[len++] = (char)v;
+ c += 2;
+ continue;
+ }
+ }
+ output[len++] = ch;
+ }
+ output[len++] = 0;
+ return renew output char[len];
+}
+
+/*static */bool GetKeyWordEx(char ** input, char * keyWord, int maxSize, bool treatEqual, bool acceptSingleQuote)
{
char * string = *input;
char ch;
int c = 0;
bool quoted = false, start = true, wasQuoted = false;
+ char quoteChar = 0;
for(; (ch = *string); string++)
{
{
if(!quoted && ((ch == ',' || (treatEqual && ch == '=')) || ch == '>') )
break;
- else if(ch == '\"' /*|| ch == '\''*/)
+ else if((ch == '\"' || (acceptSingleQuote && ch == '\'')) && (!quoteChar || quoteChar == ch))
{
+ if(!wasQuoted)
+ quoteChar = ch;
quoted ^= true;
wasQuoted = true;
start = false;
static bool GetKeyWord(char ** input, char * keyWord, int maxSize)
{
- return GetKeyWordEx(input, keyWord, maxSize, true);
+ return GetKeyWordEx(input, keyWord, maxSize, true, false);
}
static char * GetString(char * string, char * what, int count)
return string + sc;
}
-static Block AddBlock(Block parent, BlockType type)
+#include <stdio.h>
+
+String EncodeString(String input, int * lenPtr)
{
- Block block = Block { parent = parent, type = type };
- parent.subBlocks.Add(block);
- return block;
+ if(UTF8Validate(input))
+ {
+ return CopyString(input);
+ }
+ else
+ {
+ int len = strlen(input);
+ String s = new char[len*4+1];
+ len = ISO8859_1toUTF8(input, s, len*4);
+ if(lenPtr) *lenPtr = len;
+ return renew s char[len+1];
+ }
}
-#include <stdio.h>
-
class HTMLFile
{
Block block {};
Block defaultFont { };
Block body;
+ Block titleBlock;
ColorAlpha background { 255, white };
+ String baseHRef;
//Button defaultButton;
+ Block ::AddBlock(Block parent, BlockType type)
+ {
+ Block block = Block { parent = parent, type = type };
+ parent.subBlocks.Add(block);
+ return block;
+ }
+
+ ~HTMLFile()
+ {
+ delete baseHRef;
+ }
+
bool Parse(File f)
{
+ bool result = true;
bool insideTag = false;
char tag[MAX_TAG_LEN];
char symbol[MAX_SYMBOL_LEN];
- int tagLen;
+ int tagLen = 0;
Block block = this.block, subBlock;
char * text;
int textLen = 0;
byte lastCh = ' ';
bool code = false;
bool quoted = false;
+ bool lastBR = true;
Block fontBlock = defaultFont;
fontBlock.type = FONT;
fontBlock.textColor = black;
fontBlock.size = 10;
- fontBlock.font = FontEntry { size = fontBlock.size, attribs = fontBlock.attribs, face = CopyString(fontBlock.face) };
- fontCache.Add(fontBlock.font);
+ /*fontBlock.font = FontEntry { size = fontBlock.size, attribs = fontBlock.attribs, face = CopyString(fontBlock.face) };
+ fontCache.Add(fontBlock.font);*/
background = white;
text = new char[32768*4];
+ block.font = fontBlock.font;
body = block;
// Parse entire file
byte ch = 0;
f.Getc(&ch);
+#ifdef _DEBUG
//fwrite(&ch, 1, 1, stdout);
+#endif
if(commented)
{
if((ch == '-' && tagLen < 2) || (ch == '>' && tagLen == 2))
{
if(ch == '\"')
quoted ^= true;
- if(ch == '<' && !quoted)
+ if(ch == '<' && !quoted && !insideScript && !insideStyle)
+ {
insideTag++;
+ }
/*else */if(ch == '>' && !quoted)
{
insideTag--;
}
else if(!strcmpi(keyWord, "img"))
{
+ lastBR = false;
subBlock = AddBlock(block, IMAGE);
subBlock.valign = bottom;
subBlock.halign = middle;
GetKeyWord(&string, keyWord, sizeof(keyWord));
if(!strcmpi(keyWord, "src"))
{
- GetKeyWordEx(&string, keyWord, sizeof(keyWord), false);
+ GetKeyWordEx(&string, keyWord, sizeof(keyWord), false, false);
delete subBlock.src;
subBlock.src = keyWord[0] ? CopyString(keyWord) : null;
}
}
}
}
+ else if(!strcmpi(keyWord, "title"))
+ {
+ block = AddBlock(block, TITLE);
+ titleBlock = block;
+ }
else if(!strcmpi(keyWord, "body"))
{
block = AddBlock(block, BODY);
if(!strcmpi(keyWord, "bgcolor"))
{
GetKeyWord(&string, keyWord, sizeof(keyWord));
- background = strtol((keyWord[0] == '#') ? (keyWord+1) : keyWord, null, 16);
+ background = !strcmpi(keyWord, "#fff") ? white : strtol((keyWord[0] == '#') ? (keyWord+1) : keyWord, null, 16);
if(keyWord[0] != '#' || strlen(keyWord) <= 7)
background |= 0xFF000000;
}
}
}
}
- else if(!strcmpi(keyWord, "br"))
+ else if(!strcmpi(keyWord, "br") || (!lastBR && (!strcmpi(keyWord, "div") || !strcmpi(keyWord, "li"))))
{
- subBlock = AddBlock(block, BR);
- lastCh = ' ';
+ if(!lastBR || (lastCh && lastCh != ' '))
+ {
+ subBlock = AddBlock(block, BR);
+ lastCh = ' ';
+ lastBR = true;
+ }
+ }
+ else if(!strcmpi(keyWord, "/ul"))
+ {
+ lastBR = false;
+ }
+ else if(!strcmpi(keyWord, "/ul"))
+ {
+ lastBR = false;
+ }
+ else if(!strcmpi(keyWord, "/div"))
+ {
+ if(!lastBR)
+ {
+ subBlock = AddBlock(block, BR);
+ lastBR = true;
+ }
+ else
+ lastBR = false;
}
else if(!strcmpi(keyWord, "code"))
{
|| !strcmpi(keyWord, "strong") || !strcmpi(keyWord, "em") ||
!strcmpi(keyWord, "h1") || !strcmpi(keyWord, "h2") || !strcmpi(keyWord, "h3"))
{
+ if((!strcmpi(keyWord, "h1") || !strcmpi(keyWord, "h2") || !strcmpi(keyWord, "h3")))
+ {
+ if(!lastBR || (lastCh && lastCh != ' '))
+ {
+ if(!lastBR)
+ subBlock = AddBlock(block, BR);
+ subBlock = AddBlock(block, BR);
+ lastBR = true;
+ }
+ lastCh = ' ';
+ }
subBlock = AddBlock(block, FONT);
subBlock.attribs = fontBlock.attribs;
if(!strcmpi(keyWord, "font"))
!strcmpi(keyWord, "/h2") ||
!strcmpi(keyWord, "/h3"))
{
- if(block.type == FONT)
+ /*while(block.type != FONT && block.parent && block.parent.type != BODY)
+ block = block.parent;*/
+ if(block.type == FONT || block.type == ANCHOR)
{
fontBlock = block.prevFont;
block = block.parent;
}
+ if(!lastBR && (!strcmpi(keyWord, "/h1") || !strcmpi(keyWord, "/h2") || !strcmpi(keyWord, "/h3")))
+ {
+ subBlock = AddBlock(block, BR);
+ lastBR = true;
+ }
}
else if(!strcmpi(keyWord, "a"))
{
int textDecoration = 0;
- subBlock = AddBlock(block, ANCHOR);
- subBlock.attribs = fontBlock.attribs;
+ Block anchor { type = ANCHOR, parent = block };
for(;string[0];)
{
if(!strcmpi(keyWord, "name"))
{
- GetKeyWordEx(&string, keyWord, sizeof(keyWord), false);
- delete subBlock.anchor;
- subBlock.anchor = CopyString(keyWord);
+ GetKeyWordEx(&string, keyWord, sizeof(keyWord), false, false);
+ delete anchor.anchor;
+ anchor.anchor = CopyString(keyWord);
}
else if(!strcmpi(keyWord, "href"))
{
- GetKeyWordEx(&string, keyWord, sizeof(keyWord), false);
- delete subBlock.href;
- subBlock.href = CopyString(keyWord);
+ GetKeyWordEx(&string, keyWord, sizeof(keyWord), false, true);
+ delete anchor.href;
+ anchor.href = CopyString(keyWord);
if(!textDecoration)
textDecoration = 1;
}
{
//for(;string[0];)
{
- GetKeyWordEx(&string, keyWord, sizeof(keyWord), false);
+ GetKeyWordEx(&string, keyWord, sizeof(keyWord), false, false);
if(strstr(keyWord, "text-decoration:") && strstr(keyWord, "none;"))
textDecoration = 2;
}
}
}
- subBlock.attribs |= FONT_BOLD;
- if(textDecoration == 1) subBlock.attribs |= FONT_UNDERLINE;
+
+ if(anchor.href && (/*lastBR || */isalnum(lastCh)))
+ {
+ subBlock = AddBlock(block, TEXT);
+ subBlock.text = CopyString(" ");
+ subBlock.textLen = 2;
+ subBlock.prevFont = fontBlock;
+ }
+ subBlock = anchor;
+ block.subBlocks.Add(subBlock);
+
+ subBlock.attribs = fontBlock.attribs | FONT_BOLD;
delete subBlock.face;
subBlock.face = CopyString(fontBlock.face);
subBlock.size = fontBlock.size;
subBlock.textColor = Color { 85,85,255 };
subBlock.prevFont = fontBlock;
+ if(textDecoration == 1) subBlock.attribs |= FONT_UNDERLINE;
fontBlock = subBlock;
block = subBlock;
+
+ lastCh = 0;
}
+ /*else if(!strcmpi(keyWord, "/span"))
+ {
+ if(isalnum(lastCh))
+ {
+ subBlock = AddBlock(block, TEXT);
+ subBlock.text = CopyString(" ");
+ subBlock.textLen = 2;
+ subBlock.prevFont = block.parent.prevFont;
+ }
+ lastCh = 0;
+ }*/
else if(!strcmpi(keyWord, "/a"))
{
if(block.type == ANCHOR)
if(insideStyle)
insideStyle--;
}
- else if(!strcmpi(keyWord, "input"))
+ else if(!strcmpi(keyWord, "input") || !strcmpi(keyWord, "button"))
{
subBlock = AddBlock(block, INPUT);
for(;string[0];)
if(!strcmpi(keyWord, "type"))
{
- GetKeyWord(&string, keyWord, sizeof(keyWord));
+ GetKeyWordEx(&string, keyWord, sizeof(keyWord), true, true);
if(!strcmpi(keyWord, "text"))
{
subBlock.inputType = InputType::text;
}
- else if(!strcmpi(keyWord, "submit"))
+ else if(!strcmpi(keyWord, "submit") || !strcmpi(keyWord, "image"))
{
subBlock.inputType = submit;
}
{
subBlock.inputType = radio;
}
+ else if(!strcmpi(keyWord, "checkbox"))
+ {
+ subBlock.inputType = checkbox;
+ }
else if(!strcmpi(keyWord, "hidden"))
{
subBlock.inputType = hidden;
}
else if(!strcmpi(keyWord, "size"))
{
- int size;
GetKeyWord(&string, keyWord, sizeof(keyWord));
- size = atoi(keyWord);
+ subBlock.size = atoi(keyWord);
+ }
+ else if(!strcmpi(keyWord, "maxlength"))
+ {
+ int maxlength;
+ GetKeyWord(&string, keyWord, sizeof(keyWord));
+ maxlength = atoi(keyWord);
}
else if(!strcmpi(keyWord, "value"))
{
- GetKeyWordEx(&string, keyWord, sizeof(keyWord), false);
+ GetKeyWordEx(&string, keyWord, sizeof(keyWord), false, true);
delete subBlock.value;
- subBlock.value = CopyString(keyWord);
+ subBlock.value = EncodeString(keyWord, null);
}
else if(!strcmpi(keyWord, "name"))
{
delete subBlock.name;
subBlock.name = CopyString(keyWord);
}
+ else if(!strcmpi(keyWord, "src"))
+ {
+ GetKeyWordEx(&string, keyWord, sizeof(keyWord), false, false);
+ delete subBlock.src;
+ subBlock.src = keyWord[0] ? CopyString(keyWord) : null;
+ }
}
}
else if(!strcmpi(keyWord, "form"))
if(!strcmpi(keyWord, "action"))
{
- GetKeyWordEx(&string, keyWord, sizeof(keyWord), false);
+ GetKeyWordEx(&string, keyWord, sizeof(keyWord), false, false);
delete subBlock.action;
subBlock.action = CopyString(keyWord);
}
block = block.parent;
}
}
+ else if(!strcmpi(keyWord, "base"))
+ {
+ while(string[0])
+ {
+ GetKeyWord(&string, keyWord, sizeof(keyWord));
+
+ if(!strcmpi(keyWord, "href"))
+ {
+ GetKeyWordEx(&string, keyWord, sizeof(keyWord), false, true);
+ delete baseHRef;
+ baseHRef = ParseURL(keyWord);
+ }
+ }
+ }
else if(!strcmpi(keyWord, "table"))
{
lastCh = ' ';
else if(!strcmpi(keyWord, "bgcolor"))
{
GetKeyWord(&string, keyWord, sizeof(keyWord));
- subBlock.bgColor = 0xFF000000 | strtol((keyWord[0] == '#') ? (keyWord+1) : keyWord, null, 16);
+ subBlock.bgColor = !strcmpi(keyWord, "#fff") ? white : (0xFF000000 | strtol((keyWord[0] == '#') ? (keyWord+1) : keyWord, null, 16));
}
else if(!strcmpi(keyWord, "align"))
{
if(block.type == TD)
{
block = block.parent;
- lastCh = ' ';
+ lastCh = 0;//' ';
}
if(block.type == TR)
{
block = block.parent;
- lastCh = ' ';
+ lastCh = 0;//' ';
}
if(block.type == TABLE)
{
block = block.parent;
- lastCh = ' ';
+ lastCh = 0;//' ';
}
}
else if(!strcmpi(keyWord, "tr"))
else if(!strcmpi(keyWord, "bgcolor"))
{
GetKeyWord(&string, keyWord, sizeof(keyWord));
- subBlock.bgColor = 0xFF000000 | strtol((keyWord[0] == '#') ? (keyWord+1) : keyWord, null, 16);
+ subBlock.bgColor = !strcmpi(keyWord, "#fff") ? white : (0xFF000000 |strtol((keyWord[0] == '#') ? (keyWord+1) : keyWord, null, 16));
}
else if(!strcmpi(keyWord, "valign"))
{
if(block.type == TD)
{
block = block.parent;
- lastCh = ' ';
+ lastCh = 0;//' ';
}
}
else if(!strcmpi(keyWord, "/html"))
}
else
{
- tag[tagLen++] = ch;
- tag[tagLen] = '\0';
+ if(tagLen < MAX_TAG_LEN-1)
+ {
+ tag[tagLen++] = ch;
+ tag[tagLen] = '\0';
+ }
}
}
else
{
- tag[tagLen++] = ch;
- tag[tagLen] = '\0';
+ if((insideScript || insideStyle) && !tagLen && ch != '/')
+ {
+ insideTag = false;
+ }
+ else
+ {
+ if(tagLen < MAX_TAG_LEN-1)
+ {
+ tag[tagLen++] = ch;
+ tag[tagLen] = '\0';
+ }
+ }
}
if(!strcmp(tag, "!--"))
{
{
if(ch == '<')
{
- if(textLen)
+ if(!insideScript && !insideStyle)
{
- if(block.type == TABLE)
+ if(textLen)
{
- subBlock = AddBlock(block, TR);
- block = subBlock;
- }
- if(block.type == TR)
- {
- subBlock = AddBlock(block, TD);
- subBlock.span = subBlock.rowSpan = 1;
- subBlock.valign = block.valign;
- subBlock.halign = block.halign;
- block = subBlock;
- }
-
- subBlock = AddBlock(block, TEXT);
- delete subBlock.text;
- subBlock.text = CopyString(text);
- subBlock.textLen = textLen;
-
+ if(block.type == TABLE)
+ {
+ subBlock = AddBlock(block, TR);
+ block = subBlock;
+ }
+ if(block.type == TR)
+ {
+ subBlock = AddBlock(block, TD);
+ subBlock.span = subBlock.rowSpan = 1;
+ subBlock.valign = block.valign;
+ subBlock.halign = block.halign;
+ block = subBlock;
+ }
- textLen = 0;
- text[0] = '\0';
+ subBlock = AddBlock(block, TEXT);
+ delete subBlock.text;
+ subBlock.text = EncodeString(text, &textLen);
+ subBlock.textLen = textLen;
+ if(block.type != TITLE)
+ lastBR = false;
+ textLen = 0;
+ text[0] = '\0';
+ }
}
insideTag = true;
{
unichar unicode = 0;
char utf8[5];
- if(!strcmpi(symbol, "nbsp"))
+ if(symbol[0] == '#' && symbol[1] == 'x')
+ unicode = strtol(symbol+2, null, 16);
+ else if(!strcmpi(symbol, "nbsp"))
unicode = ' ';
else if(!strcmpi(symbol, "copy"))
unicode ='©';
else if(!strcmpi(symbol, "acirc"))
unicode = 'â';
else if(!strcmpi(symbol, "ocirc"))
- unicode = 'ô';
+ unicode = 'ô';
if(unicode)
{
int len = UTF32toUTF8Len(&unicode, 1, utf8, 5);
}
else
{
- symbol[symbolLen++] = ch;
- symbol[symbolLen] = '\0';
+ if(symbolLen < MAX_SYMBOL_LEN-1)
+ {
+ symbol[symbolLen++] = ch;
+ symbol[symbolLen] = '\0';
+ }
}
}
else
subBlock = AddBlock(block, TEXT);
delete subBlock.text;
- subBlock.text = CopyString(text);
+ subBlock.text = EncodeString(text, &textLen);
subBlock.textLen = textLen;
textLen = 0;
text[0] = '\0';
byte ch = 0;
f.Getc(&ch);
}*/
- return true;
+ return result;
+ }
+
+ property String title
+ {
+ get
+ {
+ if(titleBlock && titleBlock.subBlocks.first && ((Block)titleBlock.subBlocks.first).type == TEXT)
+ {
+ Block t = titleBlock.subBlocks.first;
+ return t.text;
+ }
+ return null;
+ }
}
}
{
if(block.type == FONT || block.type == ANCHOR)
{
- surface.TextFont(block.prevFont.font.font);
+ surface.TextFont(block.parent.font.font);
if(flags.render)
- surface.SetForeground(block.prevFont.textColor);
+ surface.SetForeground(block.parent.textColor);
}
block = block.next;
break;
}
+ //if(block)
+ {
+ if(block.type == FONT || block.type == ANCHOR)
+ {
+ surface.TextFont(block.parent.font.font);
+ if(flags.render)
+ surface.SetForeground(block.parent.textColor);
+ }
+ }
block = block.parent;
// Getting out of a block
if(block)
{
- if(block.type == FONT || block.type == ANCHOR)
+ /*if(block.type == FONT || block.type == ANCHOR)
{
surface.TextFont(block.prevFont.font.font);
if(flags.render)
surface.SetForeground(block.prevFont.textColor);
}
- else if(block.type == CENTER)
+ else */if(block.type == CENTER)
{
if(centered)
(*centered)--;
if(block.window)
{
width += block.window.size.w;
- height = Max(height, block.window.size.h);
+ height = Max(height, Max(26, block.window.size.h));
}
break;
}
surface.TextExtent(" ", 1, null, &th);
height = Max(height, th);
-
for(; textPos<block.textLen && !lineComplete;)
{
int w;
}
else if(block.halign == left || block.halign == right)
{
+ Font font = surface.font;
ComputeTable(surface, block, textPos, &width, &height, maxW, maxH, flags, y + sy, x + sx);
+ surface.font = font;
x += width;
*nextBlock = NextBlockUp(surface, block, centered, flags);
}
else
{
+ Font font = surface.font;
ComputeTable(surface, block, textPos, &width, &height, maxW, maxH, flags, y + sy, x + sx);
+ surface.font = font;
lineComplete = true;
*nextBlock = NextBlockUp(surface, block, centered, flags);
*nextTextPos = 0;
int left, right;
int maxW;
bool changeLine;
-
- void * font = surface.GetFont();
+ Font font;
// Compute aligned objects
left = cellX + table.cellPadding; // Add cell border/margins here?
right = Max(left, right);
maxW = right - left;
+ font = surface.font;
newLineH = ComputeLine(surface, block, textPos, &nextCellBlock, &nextCellPos, ¢ered, &lineW, maxW, maxH, RenderFlags {}, y, &leftObjects, &rightObjects, &changeLine, false, 0, 0);
-
- surface.TextFont(font);
+ surface.font = font;
if(cell.halign == middle || thisLineCentered)
{
int maxW;
bool changeLine;
- void * font = surface.GetFont();
+ Font font;
// Compute aligned objects
left = cellX + table.cellPadding; // Add cell border/margins here?
right = Max(left, right);
maxW = right - left;
+ font = surface.font;
newLineH = ComputeLine(surface, block, textPos, &nextCellBlock, &nextCellPos, ¢ered, &lineW, maxW, maxH, RenderFlags {}, y, &leftObjects, &rightObjects, &changeLine, false, 0, 0);
+ surface.font = font;
- surface.TextFont(font);
+ //surface.TextFont(font);
if(cell.halign == middle || thisLineCentered)
{
int maxW;
bool changeLine;
- void * font = surface.GetFont();
+ Font font;
// Compute aligned objects
left = cellX + table.cellPadding; // Add cell border/margins here?
right = Max(left, right);
maxW = right - left;
+ font = surface.font;
newLineH = ComputeLine(surface, block, textPos, &nextCellBlock, &nextCellPos, ¢ered, &lineW, maxW, maxH, RenderFlags {}, y, &leftObjects, &rightObjects, &changeLine, false, 0, 0);
+ surface.font = font;
- surface.TextFont(font);
+ // surface.TextFont(font);
if(cell.halign == middle || thisLineCentered)
{