r6579 vince - /trunk/netsurf/framebuffer/fb_32bpp_plotters.c
by netsurf@semichrome.net
Author: vince
Date: Fri Feb 20 07:20:49 2009
New Revision: 6579
URL: http://source.netsurf-browser.org?rev=6579&view=rev
Log:
stop opaque pixels being alphablended
Modified:
trunk/netsurf/framebuffer/fb_32bpp_plotters.c
Modified: trunk/netsurf/framebuffer/fb_32bpp_plotters.c
URL: http://source.netsurf-browser.org/trunk/netsurf/framebuffer/fb_32bpp_plot...
==============================================================================
--- trunk/netsurf/framebuffer/fb_32bpp_plotters.c (original)
+++ trunk/netsurf/framebuffer/fb_32bpp_plotters.c Fri Feb 20 07:20:49 2009
@@ -302,7 +302,7 @@
abpixel = (pixel[((yoff + yloop) * bp->pitch) + xloop + xoff] << 24) | fgcol;
if ((abpixel & 0xFF000000) != 0) {
/* pixel is not transparent */
- if ((abpixel & 0xFF000000) != 0xFF) {
+ if ((abpixel & 0xFF000000) != 0xFF000000) {
abpixel = fb_plotters_ablend(abpixel,
fb_32bpp_to_colour(*(pvideo + xloop)));
}
@@ -511,7 +511,7 @@
for (xloop = 0; xloop < width; xloop++) {
abpixel = pixel[((yoff + yloop) * bitmap->width) + xloop + xoff];
if ((abpixel & 0xFF000000) != 0) {
- if ((abpixel & 0xFF000000) != 0xFF) {
+ if ((abpixel & 0xFF000000) != 0xFF000000) {
abpixel = fb_plotters_ablend(abpixel,
fb_32bpp_to_colour(*(pvideo + xloop)));
}
14 years, 7 months
r6578 jmb - /trunk/hubbub/src/treebuilder/treebuilder.c
by netsurf@semichrome.net
Author: jmb
Date: Fri Feb 20 07:10:07 2009
New Revision: 6578
URL: http://source.netsurf-browser.org?rev=6578&view=rev
Log:
Actually associate textareas with forms
Modified:
trunk/hubbub/src/treebuilder/treebuilder.c
Modified: trunk/hubbub/src/treebuilder/treebuilder.c
URL: http://source.netsurf-browser.org/trunk/hubbub/src/treebuilder/treebuilde...
==============================================================================
--- trunk/hubbub/src/treebuilder/treebuilder.c (original)
+++ trunk/hubbub/src/treebuilder/treebuilder.c Fri Feb 20 07:10:07 2009
@@ -488,13 +488,6 @@
/** \todo errors */
}
- /* It's a bit nasty having this code deal with textarea->form
- * association, but it avoids having to duplicate the entire rest
- * of this function for textarea processing */
- if (type == TEXTAREA && treebuilder->context.form_element != NULL) {
- /** \todo associate textarea with form */
- }
-
if (treebuilder->context.in_table_foster) {
appended = aa_insert_into_foster_parent(treebuilder, node);
treebuilder->tree_handler->ref_node(
@@ -521,6 +514,16 @@
treebuilder->tree_handler->ctx,
appended);
}
+ }
+
+ /* It's a bit nasty having this code deal with textarea->form
+ * association, but it avoids having to duplicate the entire rest
+ * of this function for textarea processing */
+ if (type == TEXTAREA && treebuilder->context.form_element != NULL) {
+ treebuilder->tree_handler->form_associate(
+ treebuilder->tree_handler->ctx,
+ treebuilder->context.form_element,
+ appended);
}
/* Appended node's reference count is 2 */
14 years, 7 months
r6577 vince - in /trunk/netsurf/framebuffer: fb_32bpp_plotters.c fb_font.h fb_font_freetype.c
by netsurf@semichrome.net
Author: vince
Date: Fri Feb 20 06:57:47 2009
New Revision: 6577
URL: http://source.netsurf-browser.org?rev=6577&view=rev
Log:
run time selectable freetype bitmap depth
add full alpha renderer
Modified:
trunk/netsurf/framebuffer/fb_32bpp_plotters.c
trunk/netsurf/framebuffer/fb_font.h
trunk/netsurf/framebuffer/fb_font_freetype.c
Modified: trunk/netsurf/framebuffer/fb_32bpp_plotters.c
URL: http://source.netsurf-browser.org/trunk/netsurf/framebuffer/fb_32bpp_plot...
==============================================================================
--- trunk/netsurf/framebuffer/fb_32bpp_plotters.c (original)
+++ trunk/netsurf/framebuffer/fb_32bpp_plotters.c Fri Feb 20 06:57:47 2009
@@ -38,6 +38,13 @@
(x << 2));
}
+static inline colour fb_32bpp_to_colour(uint32_t pixel)
+{
+ return ((pixel & 0xFF) << 16) |
+ ((pixel & 0xFF00)) |
+ ((pixel & 0xFF0000) >> 16);
+}
+
#define SIGN(x) ((x<0) ? -1 : ((x>0) ? 1 : 0))
static bool fb_32bpp_line(int x0, int y0, int x1, int y1, int width,
@@ -182,7 +189,7 @@
static bool
-fb_32bpp_draw_ft_bitmap(FT_Bitmap *bp, int x, int y, colour c)
+fb_32bpp_draw_ft_monobitmap(FT_Bitmap *bp, int x, int y, colour c)
{
int height = bp->rows;
int width = bp->width;
@@ -252,6 +259,66 @@
return true;
}
+static bool
+fb_32bpp_draw_ft_bitmap(FT_Bitmap *bp, int x, int y, colour c)
+{
+ uint32_t *pvideo;
+ uint8_t *pixel = (uint8_t *)bp->buffer;
+ colour abpixel; /* alphablended pixel */
+ int xloop, yloop;
+ int x0,y0,x1,y1;
+ int xoff, yoff; /* x and y offset into image */
+ int height = bp->rows;
+ int width = bp->width;
+ uint32_t fgcol;
+
+ /* The part of the scaled image actually displayed is cropped to the
+ * current context.
+ */
+ x0 = x;
+ y0 = y;
+ x1 = x + width;
+ y1 = y + height;
+
+ if (!fb_plotters_clip_rect_ctx(&x0, &y0, &x1, &y1))
+ return true;
+
+ if (height > (y1 - y0))
+ height = (y1 - y0);
+
+ if (width > (x1 - x0))
+ width = (x1 - x0);
+
+ xoff = x0 - x;
+ yoff = y0 - y;
+
+ /* plot the image */
+ pvideo = fb_32bpp_get_xy_loc(x0, y0);
+
+ fgcol = c & 0xFFFFFF;
+
+ for (yloop = 0; yloop < height; yloop++) {
+ for (xloop = 0; xloop < width; xloop++) {
+ abpixel = (pixel[((yoff + yloop) * bp->pitch) + xloop + xoff] << 24) | fgcol;
+ if ((abpixel & 0xFF000000) != 0) {
+ /* pixel is not transparent */
+ if ((abpixel & 0xFF000000) != 0xFF) {
+ abpixel = fb_plotters_ablend(abpixel,
+ fb_32bpp_to_colour(*(pvideo + xloop)));
+ }
+
+ *(pvideo + xloop) = ((abpixel & 0xFF) << 16) |
+ ((abpixel & 0xFF00)) |
+ ((abpixel & 0xFF0000) >> 16);
+
+ }
+ }
+ pvideo += (framebuffer->linelen >> 2);
+ }
+
+ return true;
+}
+
static bool fb_32bpp_text(int x, int y, const struct css_style *style,
const char *text, size_t length, colour bg, colour c)
{
@@ -266,17 +333,26 @@
nxtchr = utf8_next(text, length, nxtchr);
glyph_index = FT_Get_Char_Index(face, ucs4);
- error = FT_Load_Glyph(face, glyph_index, FT_LOAD_RENDER |
- FT_LOAD_MONOCHROME |
- FT_LOAD_FORCE_AUTOHINT);
+ error = FT_Load_Glyph(face,
+ glyph_index,
+ FT_LOAD_RENDER |
+ FT_LOAD_FORCE_AUTOHINT |
+ ft_load_type);
if (error)
continue;
/* now, draw to our target surface */
- fb_32bpp_draw_ft_bitmap( &face->glyph->bitmap,
- x + face->glyph->bitmap_left,
- y - face->glyph->bitmap_top,
- c);
+ if (face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) {
+ fb_32bpp_draw_ft_monobitmap( &face->glyph->bitmap,
+ x + face->glyph->bitmap_left,
+ y - face->glyph->bitmap_top,
+ c);
+ } else {
+ fb_32bpp_draw_ft_bitmap( &face->glyph->bitmap,
+ x + face->glyph->bitmap_left,
+ y - face->glyph->bitmap_top,
+ c);
+ }
x += face->glyph->advance.x >> 6;
@@ -384,12 +460,6 @@
return pixel;
}
-static inline colour fb_32bpp_to_colour(uint32_t pixel)
-{
- return ((pixel & 0xFF) << 16) |
- ((pixel & 0xFF00)) |
- ((pixel & 0xFF0000) >> 16);
-}
static bool fb_32bpp_bitmap(int x, int y, int width, int height,
struct bitmap *bitmap, colour bg,
Modified: trunk/netsurf/framebuffer/fb_font.h
URL: http://source.netsurf-browser.org/trunk/netsurf/framebuffer/fb_font.h?rev...
==============================================================================
--- trunk/netsurf/framebuffer/fb_font.h (original)
+++ trunk/netsurf/framebuffer/fb_font.h Fri Feb 20 06:57:47 2009
@@ -29,6 +29,8 @@
FT_Face fb_get_face(const struct css_style *style);
+extern int ft_load_type;
+
#else
#include "utils/utf8.h"
Modified: trunk/netsurf/framebuffer/fb_font_freetype.c
URL: http://source.netsurf-browser.org/trunk/netsurf/framebuffer/fb_font_freet...
==============================================================================
--- trunk/netsurf/framebuffer/fb_font_freetype.c (original)
+++ trunk/netsurf/framebuffer/fb_font_freetype.c Fri Feb 20 06:57:47 2009
@@ -32,6 +32,7 @@
static FT_Library library;
static FT_Face face_sans_serif;
+int ft_load_type;
utf8_convert_ret utf8_to_local_encoding(const char *string,
size_t len,
@@ -68,6 +69,9 @@
return false;
}
+ /* set the default render mode */
+ // ft_load_type = FT_LOAD_MONOCHROME;
+ ft_load_type = 0;
return true;
}
14 years, 7 months
r6575 jmb - in /trunk/netsurf/render: form.c html.c hubbub_binding.c
by netsurf@semichrome.net
Author: jmb
Date: Fri Feb 20 06:50:34 2009
New Revision: 6575
URL: http://source.netsurf-browser.org?rev=6575&view=rev
Log:
If we have no document charset on completion of parse, retrieve it from the binding.
Make the binding return Windows-1252 if it has no idea (as this is what the parser will have defaulted to).
Fix form_new to not require a document charset to be present -- it may not be known at this point.
Fixup form document charsets post-parse, so that form submission works correctly.
Modified:
trunk/netsurf/render/form.c
trunk/netsurf/render/html.c
trunk/netsurf/render/hubbub_binding.c
Modified: trunk/netsurf/render/form.c
URL: http://source.netsurf-browser.org/trunk/netsurf/render/form.c?rev=6575&r1...
==============================================================================
--- trunk/netsurf/render/form.c (original)
+++ trunk/netsurf/render/form.c Fri Feb 20 06:50:34 2009
@@ -50,7 +50,7 @@
* \param target Target frame of form, or NULL for default
* \param method method and enctype
* \param charset acceptable encodings for form submission, or NULL
- * \param doc_charset encoding of containing document
+ * \param doc_charset encoding of containing document, or NULL
* \return a new structure, or NULL on memory exhaustion
*/
struct form *form_new(void *node, const char *action, const char *target,
@@ -58,8 +58,6 @@
const char *doc_charset)
{
struct form *form;
-
- assert(doc_charset != NULL);
form = calloc(1, sizeof *form);
if (!form)
@@ -88,8 +86,9 @@
return NULL;
}
- form->document_charset = strdup(doc_charset);
- if (form->document_charset == NULL) {
+ form->document_charset = doc_charset != NULL ? strdup(doc_charset)
+ : NULL;
+ if (doc_charset && form->document_charset == NULL) {
free(form->accept_charsets);
free(form->target);
free(form->action);
Modified: trunk/netsurf/render/html.c
URL: http://source.netsurf-browser.org/trunk/netsurf/render/html.c?rev=6575&r1...
==============================================================================
--- trunk/netsurf/render/html.c (original)
+++ trunk/netsurf/render/html.c Fri Feb 20 06:50:34 2009
@@ -333,6 +333,19 @@
return false;
}
+ if (c->data.html.encoding == NULL) {
+ const char *encoding = binding_get_encoding(
+ c->data.html.parser_binding,
+ &c->data.html.encoding_source);
+
+ c->data.html.encoding = talloc_strdup(c, encoding);
+ if (c->data.html.encoding == NULL) {
+ msg_data.error = messages_get("NoMemory");
+ content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ return false;
+ }
+ }
+
/* locate html and head elements */
html = xmlDocGetRootElement(c->data.html.document);
if (html == 0 || strcmp((const char *) html->name, "html") != 0) {
@@ -369,11 +382,11 @@
#ifdef WITH_HUBBUB
/* Retrieve forms from parser */
c->data.html.forms = binding_get_forms(c->data.html.parser_binding);
- /* Make all actions absolute */
for (f = c->data.html.forms; f != NULL; f = f->prev) {
char *action;
url_func_result res;
+ /* Make all actions absolute */
res = url_join(f->action, c->data.html.base_url, &action);
if (res != URL_FUNC_OK) {
msg_data.error = messages_get("NoMemory");
@@ -383,6 +396,17 @@
free(f->action);
f->action = action;
+
+ /* Ensure each form has a document encoding */
+ if (f->document_charset == NULL) {
+ f->document_charset = strdup(c->data.html.encoding);
+ if (f->document_charset == NULL) {
+ msg_data.error = messages_get("NoMemory");
+ content_broadcast(c, CONTENT_MSG_ERROR,
+ msg_data);
+ return false;
+ }
+ }
}
#endif
Modified: trunk/netsurf/render/hubbub_binding.c
URL: http://source.netsurf-browser.org/trunk/netsurf/render/hubbub_binding.c?r...
==============================================================================
--- trunk/netsurf/render/hubbub_binding.c (original)
+++ trunk/netsurf/render/hubbub_binding.c Fri Feb 20 06:50:34 2009
@@ -139,7 +139,8 @@
c->parser = NULL;
c->encoding = charset;
- c->encoding_source = ENCODING_SOURCE_HEADER;
+ c->encoding_source = charset != NULL ? ENCODING_SOURCE_HEADER
+ : ENCODING_SOURCE_DETECTED;
c->document = NULL;
c->owns_doc = true;
c->forms = NULL;
@@ -232,7 +233,7 @@
*source = c->encoding_source;
- return c->encoding;
+ return c->encoding != NULL ? c->encoding : "Windows-1252";
}
xmlDocPtr binding_get_document(void *ctx)
14 years, 7 months
r6574 tlsa - /trunk/netsurf/desktop/browser.c
by netsurf@semichrome.net
Author: tlsa
Date: Fri Feb 20 06:12:32 2009
New Revision: 6574
URL: http://source.netsurf-browser.org?rev=6574&view=rev
Log:
Fix handling of URLs on float boxes (which have no style).
Modified:
trunk/netsurf/desktop/browser.c
Modified: trunk/netsurf/desktop/browser.c
URL: http://source.netsurf-browser.org/trunk/netsurf/desktop/browser.c?rev=657...
==============================================================================
--- trunk/netsurf/desktop/browser.c (original)
+++ trunk/netsurf/desktop/browser.c Fri Feb 20 06:12:32 2009
@@ -2383,9 +2383,15 @@
gui_pointer_shape get_pointer_shape(struct box *box)
{
gui_pointer_shape pointer;
-
- assert(box->style);
- switch (box->style->cursor) {
+ struct css_style *style;
+
+ if (box->type == BOX_FLOAT_LEFT || box->type == BOX_FLOAT_RIGHT)
+ style = box->children->style;
+ else
+ style = box->style;
+
+ assert(style);
+ switch (style->cursor) {
case CSS_CURSOR_AUTO:
if (box->href || (box->gadget &&
(box->gadget->type == GADGET_IMAGE ||
14 years, 7 months
r6573 jmb - in /trunk/netsurf: desktop/browser.c render/box_construct.c render/form.c render/form.h render/html.c render/hubbub_binding.c render/parser_binding.h
by netsurf@semichrome.net
Author: jmb
Date: Fri Feb 20 05:39:25 2009
New Revision: 6573
URL: http://source.netsurf-browser.org?rev=6573&view=rev
Log:
Utilise hubbub's form association callback.
Please can we dispense with the libxml binding? It's causing much #ifdef mess.
Fix encoding of <input type=image> names -- previously were output as raw utf-8, rather than in the submission charset.
Actually bother to destroy forms in a document, and the controls associated with them. We still leak non form-associated controls, but that's too much effort to fix right now.
Modified:
trunk/netsurf/desktop/browser.c
trunk/netsurf/render/box_construct.c
trunk/netsurf/render/form.c
trunk/netsurf/render/form.h
trunk/netsurf/render/html.c
trunk/netsurf/render/hubbub_binding.c
trunk/netsurf/render/parser_binding.h
Modified: trunk/netsurf/desktop/browser.c
URL: http://source.netsurf-browser.org/trunk/netsurf/desktop/browser.c?rev=657...
==============================================================================
--- trunk/netsurf/desktop/browser.c (original)
+++ trunk/netsurf/desktop/browser.c Fri Feb 20 05:39:25 2009
@@ -1574,6 +1574,9 @@
case GADGET_FILE:
status = messages_get("FormFile");
break;
+ case GADGET_BUTTON:
+ /* Do nothing, as this gadget cannot be activated */
+ break;
}
} else if (object && (mouse & BROWSER_MOUSE_MOD_2)) {
Modified: trunk/netsurf/render/box_construct.c
URL: http://source.netsurf-browser.org/trunk/netsurf/render/box_construct.c?re...
==============================================================================
--- trunk/netsurf/render/box_construct.c (original)
+++ trunk/netsurf/render/box_construct.c Fri Feb 20 05:39:25 2009
@@ -140,7 +140,9 @@
static bool box_body(BOX_SPECIAL_PARAMS);
static bool box_br(BOX_SPECIAL_PARAMS);
static bool box_image(BOX_SPECIAL_PARAMS);
+#ifndef WITH_HUBBUB
static bool box_form(BOX_SPECIAL_PARAMS);
+#endif
static bool box_textarea(BOX_SPECIAL_PARAMS);
static bool box_select(BOX_SPECIAL_PARAMS);
static bool box_input(BOX_SPECIAL_PARAMS);
@@ -174,7 +176,9 @@
{"br", box_br},
{"button", box_button},
{"embed", box_embed},
+#ifndef WITH_HUBBUB
{"form", box_form},
+#endif
{"frameset", box_frameset},
{"iframe", box_iframe},
{"image", box_image},
@@ -2158,13 +2162,14 @@
}
+#ifndef WITH_HUBBUB
/**
* Interactive form [17.3].
*/
bool box_form(BOX_SPECIAL_PARAMS)
{
- char *xmlaction, *action, *faction, *method, *enctype, *charset, *target;
+ char *xmlaction, *action, *method, *enctype, *charset, *target;
form_method fmethod;
struct form *form;
url_func_result result;
@@ -2173,25 +2178,21 @@
xmlGetProp(n, (const xmlChar *) "action"))) {
/* the action attribute is required, but many forms fail to
* specify it. In the case where it is _not_ specified,
- * follow other browsers and make the form action the
- * URI of the page the form is contained in. */
- action = strdup("");
+ * follow other browsers and make the form action the URI of
+ * the page the form is contained in. */
+ action = strdup(content->data.html.base_url);
} else {
- action = strdup(xmlaction);
+ result = url_join(xmlaction, content->data.html.base_url,
+ &action);
+
xmlFree(xmlaction);
+
+ if (result != URL_FUNC_OK)
+ return false;
}
if (!action)
return false;
-
- result = url_join(action, content->data.html.base_url, &faction);
- if (result != URL_FUNC_OK) {
- free(action);
- return false;
- }
-
- /* No longer needed */
- free(action);
fmethod = method_GET;
if ((method = (char *) xmlGetProp(n, (const xmlChar *) "method"))) {
@@ -2214,20 +2215,24 @@
/* target for form data */
target = (char *) xmlGetProp(n, (const xmlChar *) "target");
- form = form_new(faction, target, fmethod, charset,
- content->data.html.encoding);
- if (!form) {
- free(faction);
+ form = form_new(n, action, target, fmethod, charset,
+ content->data.html.encoding);
+
+ free(action);
+ if (charset)
+ xmlFree(charset);
+ if (target)
xmlFree(target);
- xmlFree(charset);
+
+ if (!form)
return false;
- }
+
form->prev = content->data.html.forms;
content->data.html.forms = form;
return true;
}
-
+#endif
/**
* Form control [17.4].
@@ -2241,25 +2246,36 @@
type = (char *) xmlGetProp(n, (const xmlChar *) "type");
+#ifdef WITH_HUBBUB
+ gadget = binding_get_control_for_node(content->data.html.parser_binding,
+ n);
+ if (!gadget)
+ goto no_memory;
+ box->gadget = gadget;
+ gadget->box = box;
+#endif
+
if (type && strcasecmp(type, "password") == 0) {
if (!box_input_text(n, content, box, 0, markup_track, author,
true))
goto no_memory;
+#ifndef WITH_HUBBUB
gadget = box->gadget;
gadget->box = box;
-
+#endif
} else if (type && strcasecmp(type, "file") == 0) {
box->type = BOX_INLINE_BLOCK;
- box->gadget = gadget = form_new_control(GADGET_FILE);
+#ifndef WITH_HUBBUB
+ box->gadget = gadget = form_new_control(n, GADGET_FILE);
if (!gadget)
goto no_memory;
gadget->box = box;
-
+#endif
} else if (type && strcasecmp(type, "hidden") == 0) {
/* no box for hidden inputs */
box->style->display = CSS_DISPLAY_NONE;
-
- gadget = form_new_control(GADGET_HIDDEN);
+#ifndef WITH_HUBBUB
+ gadget = form_new_control(n, GADGET_HIDDEN);
if (!gadget)
goto no_memory;
@@ -2270,11 +2286,12 @@
goto no_memory;
gadget->length = strlen(gadget->value);
}
-
+#endif
} else if (type && (strcasecmp(type, "checkbox") == 0 ||
strcasecmp(type, "radio") == 0)) {
- box->gadget = gadget = form_new_control(type[0] == 'c' ||
- type[0] == 'C' ? GADGET_CHECKBOX :
+#ifndef WITH_HUBBUB
+ box->gadget = gadget = form_new_control(n, type[0] == 'c' ||
+ type[0] == 'C' ? GADGET_CHECKBOX :
GADGET_RADIO);
if (!gadget)
goto no_memory;
@@ -2289,9 +2306,10 @@
goto no_memory;
gadget->length = strlen(gadget->value);
}
-
+#endif
} else if (type && (strcasecmp(type, "submit") == 0 ||
- strcasecmp(type, "reset") == 0)) {
+ strcasecmp(type, "reset") == 0 ||
+ strcasecmp(type, "button") == 0)) {
struct box *inline_container, *inline_box;
if (!box_button(n, content, box, 0, markup_track, author))
goto no_memory;
@@ -2310,30 +2328,9 @@
else if (box->gadget->type == GADGET_SUBMIT)
inline_box->text = talloc_strdup(content,
messages_get("Form_Submit"));
- else
+ else if (box->gadget->type == GADGET_RESET)
inline_box->text = talloc_strdup(content,
messages_get("Form_Reset"));
- if (!inline_box->text)
- goto no_memory;
- inline_box->length = strlen(inline_box->text);
- box_add_child(inline_container, inline_box);
- box_add_child(box, inline_container);
-
- } else if (type && strcasecmp(type, "button") == 0) {
- struct box *inline_container, *inline_box;
- if (!box_button(n, content, box, 0, markup_track, author))
- goto no_memory;
- inline_container = box_create(0, 0, 0, 0, 0, content);
- if (!inline_container)
- goto no_memory;
- inline_container->type = BOX_INLINE_CONTAINER;
- inline_box = box_create(box->style, 0, 0, box->title, 0,
- content);
- if (!inline_box)
- goto no_memory;
- inline_box->type = BOX_TEXT;
- if ((s = (char *) xmlGetProp(n, (const xmlChar *) "value")))
- inline_box->text = talloc_strdup(content, s);
else
inline_box->text = talloc_strdup(content, "Button");
if (!inline_box->text)
@@ -2341,12 +2338,13 @@
inline_box->length = strlen(inline_box->text);
box_add_child(inline_container, inline_box);
box_add_child(box, inline_container);
-
} else if (type && strcasecmp(type, "image") == 0) {
- box->gadget = gadget = form_new_control(GADGET_IMAGE);
+#ifndef WITH_HUBBUB
+ box->gadget = gadget = form_new_control(n, GADGET_IMAGE);
if (!gadget)
goto no_memory;
gadget->box = box;
+#endif
gadget->type = GADGET_IMAGE;
if (box->style && box->style->display != CSS_DISPLAY_NONE) {
@@ -2375,19 +2373,21 @@
free(url);
}
}
-
} else {
/* the default type is "text" */
if (!box_input_text(n, content, box, 0, markup_track, author,
false))
goto no_memory;
+#ifndef WITH_HUBBUB
gadget = box->gadget;
gadget->box = box;
+#endif
}
if (type)
xmlFree(type);
+#ifndef WITH_HUBBUB
if (gadget) {
if (content->data.html.forms)
form_add_control(content->data.html.forms, gadget);
@@ -2399,6 +2399,7 @@
goto no_memory;
}
}
+#endif
*convert_children = false;
return true;
@@ -2406,9 +2407,10 @@
no_memory:
if (type)
xmlFree(type);
+#ifndef WITH_HUBBUB
if (gadget)
form_free_control(gadget);
-
+#endif
return false;
}
@@ -2419,14 +2421,17 @@
bool box_input_text(BOX_SPECIAL_PARAMS, bool password)
{
+#ifndef WITH_HUBBUB
char *s;
+#endif
struct box *inline_container, *inline_box;
box->type = BOX_INLINE_BLOCK;
- box->gadget = form_new_control((password) ? GADGET_PASSWORD :
+#ifndef WITH_HUBBUB
+ box->gadget = form_new_control(n, (password) ? GADGET_PASSWORD :
GADGET_TEXTBOX);
if (!box->gadget)
- return 0;
+ return false;
box->gadget->box = box;
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "maxlength"))) {
@@ -2446,6 +2451,7 @@
return NULL;
}
box->gadget->length = strlen(box->gadget->value);
+#endif
inline_container = box_create(0, 0, 0, 0, 0, content);
if (!inline_container)
@@ -2488,19 +2494,16 @@
bool box_button(BOX_SPECIAL_PARAMS)
{
+#ifndef WITH_HUBBUB
xmlChar *s;
char *type = (char *) xmlGetProp(n, (const xmlChar *) "type");
- box->type = BOX_INLINE_BLOCK;
-
if (!type || strcasecmp(type, "submit") == 0) {
- box->gadget = form_new_control(GADGET_SUBMIT);
+ box->gadget = form_new_control(n, GADGET_SUBMIT);
} else if (strcasecmp(type, "reset") == 0) {
- box->gadget = form_new_control(GADGET_RESET);
+ box->gadget = form_new_control(n, GADGET_RESET);
} else {
- /* type="button" or unknown: just render the contents */
- xmlFree(type);
- return true;
+ box->gadget = form_new_control(n, GADGET_BUTTON);
}
if (type)
@@ -2512,6 +2515,7 @@
if (content->data.html.forms)
form_add_control(content->data.html.forms, box->gadget);
box->gadget->box = box;
+
if ((s = xmlGetProp(n, (const xmlChar *) "name")) != NULL) {
box->gadget->name = strdup((char *) s);
xmlFree(s);
@@ -2524,6 +2528,20 @@
if (!box->gadget->value)
return false;
}
+#else
+ struct form_control *gadget;
+
+ gadget = binding_get_control_for_node(content->data.html.parser_binding,
+ n);
+ if (!gadget)
+ return false;
+
+ box->gadget = gadget;
+ gadget->box = box;
+#endif
+ box->type = BOX_INLINE_BLOCK;
+
+ /* Just render the contents */
return true;
}
@@ -2538,23 +2556,24 @@
struct box *inline_container;
struct box *inline_box;
struct form_control *gadget;
- char* s;
+#ifndef WITH_HUBBUB
+ char *s;
+#endif
xmlNode *c, *c2;
- gadget = form_new_control(GADGET_SELECT);
+#ifndef WITH_HUBBUB
+ gadget = form_new_control(n, GADGET_SELECT);
+#else
+ gadget = binding_get_control_for_node(content->data.html.parser_binding,
+ n);
+#endif
if (!gadget)
return false;
- gadget->data.select.multiple = false;
- if ((s = (char *) xmlGetProp(n, (const xmlChar *) "multiple"))) {
- gadget->data.select.multiple = true;
- xmlFree(s);
- }
-
- gadget->data.select.items = NULL;
- gadget->data.select.last_item = NULL;
- gadget->data.select.num_items = 0;
- gadget->data.select.num_selected = 0;
+#ifndef WITH_HUBBUB
+ gadget->data.select.multiple =
+ xmlHasProp(n, (const xmlChar *) "multiple");
+#endif
for (c = n->children; c; c = c->next) {
if (strcmp((const char *) c->name, "option") == 0) {
@@ -2573,16 +2592,20 @@
if (gadget->data.select.num_items == 0) {
/* no options: ignore entire select */
+#ifndef WITH_HUBBUB
form_free_control(gadget);
+#endif
return true;
}
+#ifndef WITH_HUBBUB
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "name"))) {
gadget->name = strdup(s);
xmlFree(s);
if (!gadget->name)
goto no_memory;
}
+#endif
box->type = BOX_INLINE_BLOCK;
box->gadget = gadget;
@@ -2621,14 +2644,18 @@
inline_box->length = strlen(inline_box->text);
+#ifndef WITH_HUBBUB
if (content->data.html.forms)
form_add_control(content->data.html.forms, box->gadget);
+#endif
*convert_children = false;
return true;
no_memory:
+#ifndef WITH_HUBBUB
form_free_control(gadget);
+#endif
return false;
}
@@ -2709,17 +2736,24 @@
size_t len;
box->type = BOX_INLINE_BLOCK;
- box->gadget = form_new_control(GADGET_TEXTAREA);
+#ifndef WITH_HUBBUB
+ box->gadget = form_new_control(n, GADGET_TEXTAREA);
+#else
+ box->gadget = binding_get_control_for_node(
+ content->data.html.parser_binding, n);
+#endif
if (!box->gadget)
return false;
box->gadget->box = box;
+#ifndef WITH_HUBBUB
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "name"))) {
box->gadget->name = strdup(s);
xmlFree(s);
if (!box->gadget->name)
return false;
}
+#endif
inline_container = box_create(0, 0, 0, box->title, 0, content);
if (!inline_container)
@@ -2727,6 +2761,9 @@
inline_container->type = BOX_INLINE_CONTAINER;
box_add_child(box, inline_container);
+ /** \todo Is it really necessary to reparse the content of a
+ * textarea element to remove entities? Hubbub will do that for us.
+ */
n2 = n->children;
buf = xmlBufferCreate();
while(n2) {
@@ -2806,8 +2843,10 @@
xmlFree(string);
xmlBufferFree(buf);
+#ifndef WITH_HUBBUB
if (content->data.html.forms)
form_add_control(content->data.html.forms, box->gadget);
+#endif
*convert_children = false;
return true;
Modified: trunk/netsurf/render/form.c
URL: http://source.netsurf-browser.org/trunk/netsurf/render/form.c?rev=6573&r1...
==============================================================================
--- trunk/netsurf/render/form.c (original)
+++ trunk/netsurf/render/form.c Fri Feb 20 05:39:25 2009
@@ -1,7 +1,7 @@
/*
* Copyright 2004 James Bursa <bursa(a)users.sourceforge.net>
* Copyright 2003 Phil Mellor <monkeyson(a)users.sourceforge.net>
- * Copyright 2005-7 John M Bell <jmb202(a)ecs.soton.ac.uk>
+ * Copyright 2005-9 John-Mark Bell <jmb(a)netsurf-browser.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -45,61 +45,113 @@
/**
* Create a struct form.
*
- * \param action URL to submit form to, used directly (not copied)
+ * \param node DOM node associated with form
+ * \param action URL to submit form to, or NULL for default
+ * \param target Target frame of form, or NULL for default
* \param method method and enctype
- * \param charset acceptable charactersets for form submission (not copied)
- * \param doc_charset characterset of containing document (not copied)
- * \return a new structure, or 0 on memory exhaustion
- */
-
-struct form *form_new(char *action, char *target, form_method method,
- char *charset, char *doc_charset)
+ * \param charset acceptable encodings for form submission, or NULL
+ * \param doc_charset encoding of containing document
+ * \return a new structure, or NULL on memory exhaustion
+ */
+struct form *form_new(void *node, const char *action, const char *target,
+ form_method method, const char *charset,
+ const char *doc_charset)
{
struct form *form;
- form = malloc(sizeof *form);
+ assert(doc_charset != NULL);
+
+ form = calloc(1, sizeof *form);
if (!form)
- return 0;
- form->action = action;
- form->target = target;
+ return NULL;
+
+ form->action = strdup(action != NULL ? action : "");
+ if (form->action == NULL) {
+ free(form);
+ return NULL;
+ }
+
+ form->target = target != NULL ? strdup(target) : NULL;
+ if (target != NULL && form->target == NULL) {
+ free(form->action);
+ free(form);
+ return NULL;
+ }
+
form->method = method;
- form->accept_charsets = charset;
- form->document_charset = doc_charset;
- form->controls = 0;
- form->last_control = 0;
- form->prev = 0;
+
+ form->accept_charsets = charset != NULL ? strdup(charset) : NULL;
+ if (charset != NULL && form->accept_charsets == NULL) {
+ free(form->target);
+ free(form->action);
+ free(form);
+ return NULL;
+ }
+
+ form->document_charset = strdup(doc_charset);
+ if (form->document_charset == NULL) {
+ free(form->accept_charsets);
+ free(form->target);
+ free(form->action);
+ free(form);
+ return NULL;
+ }
+
+ form->node = node;
+
return form;
}
+/**
+ * Free a form, and any controls it owns.
+ *
+ * \param form The form to free
+ *
+ * \note There may exist controls attached to box tree nodes which are not
+ * associated with any form. These will leak at present. Ideally, they will
+ * be cleaned up when the box tree is destroyed. As that currently happens
+ * via talloc, this won't happen. These controls are distinguishable, as their
+ * form field will be NULL.
+ */
+void form_free(struct form *form)
+{
+ struct form_control *c, *d;
+
+ for (c = form->controls; c != NULL; c = d) {
+ d = c->next;
+
+ form_free_control(c);
+ }
+
+ free(form->action);
+ free(form->target);
+ free(form->accept_charsets);
+ free(form->document_charset);
+
+ free(form);
+}
/**
* Create a struct form_control.
*
+ * \param node Associated DOM node
* \param type control type
- * \return a new structure, or 0 on memory exhaustion
- */
-
-struct form_control *form_new_control(form_control_type type)
+ * \return a new structure, or NULL on memory exhaustion
+ */
+struct form_control *form_new_control(void *node, form_control_type type)
{
struct form_control *control;
- if ((control = malloc(sizeof *control)) == NULL)
- return NULL;
+ control = calloc(1, sizeof *control);
+ if (control == NULL)
+ return NULL;
+
+ control->node = node;
control->type = type;
- control->name = NULL;
- control->value = NULL;
- control->initial_value = NULL;
- control->disabled = false;
- control->form = NULL;
- control->box = NULL;
- control->caret_inline_container = NULL;
- control->caret_text_box = NULL;
- control->caret_box_offset = control->caret_form_offset = 0;
- control->length = 0;
+
+ /* Default max length of input to something insane */
control->maxlength = UINT_MAX;
- control->selected = false;
- control->prev = NULL;
- control->next = NULL;
+
return control;
}
@@ -110,12 +162,13 @@
* \param form The form to add the control to
* \param control The control to add
*/
-
void form_add_control(struct form *form, struct form_control *control)
{
control->form = form;
+
if (form->controls != NULL) {
assert(form->last_control);
+
form->last_control->next = control;
control->prev = form->last_control;
control->next = NULL;
@@ -131,14 +184,15 @@
*
* \param control structure to free
*/
-
void form_free_control(struct form_control *control)
{
free(control->name);
free(control->value);
free(control->initial_value);
+
if (control->type == GADGET_SELECT) {
struct form_option *option, *next;
+
for (option = control->data.select.items; option;
option = next) {
next = option->next;
@@ -147,6 +201,7 @@
free(option);
}
}
+
free(control);
}
@@ -160,7 +215,6 @@
* \param selected this option is selected
* \return true on success, false on memory exhaustion
*/
-
bool form_add_option(struct form_control *control, char *value, char *text,
bool selected)
{
@@ -169,13 +223,12 @@
assert(control);
assert(control->type == GADGET_SELECT);
- option = malloc(sizeof *option);
+ option = calloc(1, sizeof *option);
if (!option)
return false;
- option->selected = option->initial_selected = false;
+
option->value = value;
option->text = text;
- option->next = 0;
/* add to linked list */
if (control->data.select.items == 0)
@@ -216,7 +269,6 @@
*
* See HTML 4.01 section 17.13.2.
*/
-
bool form_successful_controls(struct form *form,
struct form_control *submit_button,
struct form_successful_control **successful_controls)
@@ -344,17 +396,23 @@
case GADGET_IMAGE: {
/* image */
size_t len;
+ char *name;
if (control != submit_button)
/* only the activated submit button
* is successful */
continue;
- len = strlen(control->name) + 3;
+ name = ENCODE_ITEM(control->name);
+ if (name == NULL)
+ goto no_memory;
+
+ len = strlen(name) + 3;
/* x */
success_new = malloc(sizeof(*success_new));
if (!success_new) {
+ free(name);
LOG(("malloc failed"));
goto no_memory;
}
@@ -366,11 +424,11 @@
free(success_new->name);
free(success_new->value);
free(success_new);
+ free(name);
LOG(("malloc failed"));
goto no_memory;
}
- sprintf(success_new->name, "%s.x",
- control->name);
+ sprintf(success_new->name, "%s.x", name);
sprintf(success_new->value, "%i",
control->data.image.mx);
success_new->next = 0;
@@ -380,6 +438,7 @@
/* y */
success_new = malloc(sizeof(*success_new));
if (!success_new) {
+ free(name);
LOG(("malloc failed"));
goto no_memory;
}
@@ -391,16 +450,18 @@
free(success_new->name);
free(success_new->value);
free(success_new);
+ free(name);
LOG(("malloc failed"));
goto no_memory;
}
- sprintf(success_new->name, "%s.y",
- control->name);
+ sprintf(success_new->name, "%s.y", name);
sprintf(success_new->value, "%i",
control->data.image.my);
success_new->next = 0;
last_success->next = success_new;
last_success = success_new;
+
+ free(name);
continue;
break;
@@ -450,7 +511,8 @@
}
success_new->file = true;
success_new->name = ENCODE_ITEM(control->name);
- success_new->value = ENCODE_ITEM(control->value ?
+ success_new->value =
+ ENCODE_ITEM(control->value ?
control->value : "");
success_new->next = 0;
last_success->next = success_new;
@@ -462,6 +524,10 @@
}
continue;
+ break;
+
+ case GADGET_BUTTON:
+ /* Ignore it */
break;
default:
@@ -505,7 +571,6 @@
* \param textarea control of type GADGET_TEXTAREA
* \return the value as a UTF-8 string on heap, or 0 on memory exhaustion
*/
-
char *form_textarea_value(struct form_control *textarea)
{
unsigned int len = 0;
Modified: trunk/netsurf/render/form.h
URL: http://source.netsurf-browser.org/trunk/netsurf/render/form.h?rev=6573&r1...
==============================================================================
--- trunk/netsurf/render/form.h (original)
+++ trunk/netsurf/render/form.h Fri Feb 20 05:39:25 2009
@@ -40,14 +40,17 @@
/** HTML form. */
struct form {
- char *action; /**< Absolute URL to submit to. */
- char *target; /**< Target to submit to. */
- form_method method; /**< Method and enctype. */
- char *accept_charsets; /**< Charset to submit form in */
- char *document_charset; /**< Charset of document containing form */
- struct form_control *controls; /**< Linked list of controls. */
+ void *node; /**< Corresponding DOM node */
+
+ char *action; /**< Absolute URL to submit to. */
+ char *target; /**< Target to submit to. */
+ form_method method; /**< Method and enctype. */
+ char *accept_charsets; /**< Charset to submit form in */
+ char *document_charset; /**< Charset of document containing form */
+ struct form_control *controls; /**< Linked list of controls. */
struct form_control *last_control; /**< Last control in list. */
- struct form *prev; /**< Previous form in doc. */
+
+ struct form *prev; /**< Previous form in doc. */
};
/** Type of a struct form_control. */
@@ -62,25 +65,35 @@
GADGET_PASSWORD,
GADGET_SUBMIT,
GADGET_RESET,
- GADGET_FILE
+ GADGET_FILE,
+ GADGET_BUTTON
} form_control_type;
/** Form control. */
struct form_control {
- form_control_type type;
- char *name;
- char *value;
- char *initial_value;
- bool disabled;
- struct form *form;
- struct box *box;
+ void *node; /**< Corresponding DOM node */
+
+ form_control_type type; /**< Type of control */
+
+ struct form *form; /**< Containing form */
+
+ char *name; /**< Control name */
+ char *value; /**< Current value of control */
+ char *initial_value; /**< Initial value of control */
+ bool disabled; /**< Whether control is disabled */
+
+ struct box *box; /**< Box for control */
+ /** Caret details. */
struct box *caret_inline_container;
struct box *caret_text_box;
size_t caret_box_offset, caret_form_offset;
- unsigned int length;
int caret_pixel_offset;
- unsigned int maxlength;
- bool selected;
+
+ unsigned int length; /**< Number of characters in control */
+ unsigned int maxlength; /**< Maximum characters permitted */
+
+ bool selected; /**< Whether control is selected */
+
union {
struct {
int mx, my;
@@ -94,6 +107,7 @@
struct form_option *current;
} select;
} data;
+
struct form_control *prev; /**< Previous control in this form */
struct form_control *next; /**< Next control in this form. */
};
@@ -115,9 +129,11 @@
struct form_successful_control *next; /**< Next in linked list. */
};
-struct form *form_new(char *action, char *target, form_method method, char *charset,
- char *doc_charset);
-struct form_control *form_new_control(form_control_type type);
+struct form *form_new(void *node, const char *action, const char *target,
+ form_method method, const char *charset,
+ const char *doc_charset);
+void form_free(struct form *form);
+struct form_control *form_new_control(void *node, form_control_type type);
void form_add_control(struct form *form, struct form_control *control);
void form_free_control(struct form_control *control);
bool form_add_option(struct form_control *control, char *value, char *text,
Modified: trunk/netsurf/render/html.c
URL: http://source.netsurf-browser.org/trunk/netsurf/render/html.c?rev=6573&r1...
==============================================================================
--- trunk/netsurf/render/html.c (original)
+++ trunk/netsurf/render/html.c Fri Feb 20 05:39:25 2009
@@ -38,6 +38,7 @@
#include "image/bitmap.h"
#include "render/box.h"
#include "render/font.h"
+#include "render/form.h"
#include "render/html.h"
#include "render/imagemap.h"
#include "render/layout.h"
@@ -281,6 +282,9 @@
xmlNode *html, *head;
union content_msg_data msg_data;
unsigned int time_before, time_taken;
+#ifdef WITH_HUBBUB
+ struct form *f;
+#endif
/* finish parsing */
if (c->source_size == 0) {
@@ -321,8 +325,6 @@
c->data.html.document =
binding_get_document(c->data.html.parser_binding);
/*xmlDebugDumpDocument(stderr, c->data.html.document);*/
- binding_destroy_tree(c->data.html.parser_binding);
- c->data.html.parser_binding = NULL;
if (!c->data.html.document) {
LOG(("Parsing failed"));
@@ -363,6 +365,26 @@
/* get stylesheets */
if (!html_find_stylesheets(c, html))
return false;
+
+#ifdef WITH_HUBBUB
+ /* Retrieve forms from parser */
+ c->data.html.forms = binding_get_forms(c->data.html.parser_binding);
+ /* Make all actions absolute */
+ for (f = c->data.html.forms; f != NULL; f = f->prev) {
+ char *action;
+ url_func_result res;
+
+ res = url_join(f->action, c->data.html.base_url, &action);
+ if (res != URL_FUNC_OK) {
+ msg_data.error = messages_get("NoMemory");
+ content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ return false;
+ }
+
+ free(f->action);
+ f->action = action;
+ }
+#endif
/* convert xml tree to box tree */
LOG(("XML to box"));
@@ -404,6 +426,10 @@
LOG(("Scheduling relayout no sooner than %dcs",
c->reformat_time - wallclock()));
/*box_dump(c->data.html.layout->children, 0);*/
+
+ /* Destroy the parser binding */
+ binding_destroy_tree(c->data.html.parser_binding);
+ c->data.html.parser_binding = NULL;
if (c->active == 0)
c->status = CONTENT_STATUS_DONE;
@@ -1654,7 +1680,16 @@
void html_destroy(struct content *c)
{
unsigned int i;
+ struct form *f, *g;
+
LOG(("content %p", c));
+
+ /* Destroy forms */
+ for (f = c->data.html.forms; f != NULL; f = g) {
+ g = f->prev;
+
+ form_free(f);
+ }
imagemap_destroy(c);
Modified: trunk/netsurf/render/hubbub_binding.c
URL: http://source.netsurf-browser.org/trunk/netsurf/render/hubbub_binding.c?r...
==============================================================================
--- trunk/netsurf/render/hubbub_binding.c (original)
+++ trunk/netsurf/render/hubbub_binding.c Fri Feb 20 05:39:25 2009
@@ -30,6 +30,7 @@
#include <hubbub/parser.h>
#include <hubbub/tree.h>
+#include "render/form.h"
#include "render/parser_binding.h"
#include "utils/config.h"
@@ -50,6 +51,8 @@
#undef NUM_NAMESPACES
hubbub_tree_handler tree_handler;
+
+ struct form *forms;
} hubbub_ctx;
static struct {
@@ -91,6 +94,12 @@
static int set_quirks_mode(void *ctx, hubbub_quirks_mode mode);
static int change_encoding(void *ctx, const char *charset);
+static struct form *parse_form_element(xmlNode *node, const char *docenc);
+static struct form_control *parse_input_element(xmlNode *node);
+static struct form_control *parse_button_element(xmlNode *node);
+static struct form_control *parse_select_element(xmlNode *node);
+static struct form_control *parse_textarea_element(xmlNode *node);
+
static hubbub_tree_handler tree_handler = {
create_comment,
create_doctype,
@@ -133,6 +142,7 @@
c->encoding_source = ENCODING_SOURCE_HEADER;
c->document = NULL;
c->owns_doc = true;
+ c->forms = NULL;
error = hubbub_parser_create(charset, true, myrealloc, arena,
&c->parser);
@@ -152,8 +162,7 @@
}
c->document->_private = (void *) 0;
- for (i = 0;
- i < sizeof(c->namespaces) / sizeof(c->namespaces[0]); i++) {
+ for (i = 0; i < sizeof(c->namespaces) / sizeof(c->namespaces[0]); i++) {
c->namespaces[i] = NULL;
}
@@ -236,6 +245,42 @@
return doc;
}
+struct form *binding_get_forms(void *ctx)
+{
+ hubbub_ctx *c = (hubbub_ctx *) ctx;
+
+ return c->forms;
+}
+
+struct form_control *binding_get_control_for_node(void *ctx, xmlNodePtr node)
+{
+ hubbub_ctx *c = (hubbub_ctx *) ctx;
+ struct form *f;
+ struct form_control *ctl = NULL;
+
+ for (f = c->forms; f != NULL; f = f->prev) {
+ for (ctl = f->controls; ctl != NULL; ctl = ctl->next) {
+ if (ctl->node == node)
+ return ctl;
+ }
+ }
+
+ /* No control found. This implies that it's not associated
+ * with any form. In this case, we create a control for it
+ * on the fly. */
+ if (strcasecmp((const char *) node->name, "input") == 0) {
+ ctl = parse_input_element(node);
+ } else if (strcasecmp((const char *) node->name, "button") == 0) {
+ ctl = parse_button_element(node);
+ } else if (strcasecmp((const char *) node->name, "select") == 0) {
+ ctl = parse_select_element(node);
+ } else if (strcasecmp((const char *) node->name, "textarea") == 0) {
+ ctl = parse_textarea_element(node);
+ }
+
+ return ctl;
+}
+
/*****************************************************************************/
char *c_string_from_hubbub_string(hubbub_ctx *ctx, const hubbub_string *str)
@@ -246,8 +291,8 @@
void create_namespaces(hubbub_ctx *ctx, xmlNode *root)
{
uint32_t i;
- for (i = 1;
- i < sizeof(namespaces) / sizeof(namespaces[0]); i++) {
+
+ for (i = 1; i < sizeof(namespaces) / sizeof(namespaces[0]); i++) {
ctx->namespaces[i - 1] = xmlNewNs(root,
BAD_CAST namespaces[i].url,
BAD_CAST namespaces[i].prefix);
@@ -367,6 +412,21 @@
return 1;
}
+ if (strcasecmp(name, "form") == 0) {
+ struct form *form = parse_form_element(n, c->encoding);
+
+ /* Memory exhaustion */
+ if (form == NULL) {
+ xmlFreeNode(n);
+ free(name);
+ return 1;
+ }
+
+ /* Insert into list */
+ form->prev = c->forms;
+ c->forms = form;
+ }
+
*result = (void *) n;
free(name);
@@ -567,6 +627,39 @@
int form_associate(void *ctx, void *form, void *node)
{
+ hubbub_ctx *c = (hubbub_ctx *) ctx;
+ xmlNode *n = (xmlNode *) node;
+ struct form *f;
+ struct form_control *control = NULL;
+
+ /* Find form object to associate with */
+ for (f = c->forms; f != NULL; f = f->prev) {
+ if (f->node == form)
+ break;
+ }
+
+ /* None found -- give up */
+ if (f == NULL)
+ return 0;
+
+ if (strcasecmp((const char *) n->name, "input") == 0) {
+ control = parse_input_element(n);
+ } else if (strcasecmp((const char *) n->name, "button") == 0) {
+ control = parse_button_element(n);
+ } else if (strcasecmp((const char *) n->name, "select") == 0) {
+ control = parse_select_element(n);
+ } else if (strcasecmp((const char *) n->name, "textarea") == 0) {
+ control = parse_textarea_element(n);
+ } else
+ return 0;
+
+ /* Memory exhaustion */
+ if (control == NULL)
+ return 1;
+
+ /* Add the control to the form */
+ form_add_control(f, control);
+
return 0;
}
@@ -654,5 +747,242 @@
return (charset == name) ? 0 : 1;
}
+struct form *parse_form_element(xmlNode *node, const char *docenc)
+{
+ struct form *form;
+ form_method method;
+ xmlChar *action, *meth, *charset, *target;
+
+ action = xmlGetProp(node, (const xmlChar *) "action");
+ charset = xmlGetProp(node, (const xmlChar *) "accept-charset");
+ target = xmlGetProp(node, (const xmlChar *) "target");
+
+ method = method_GET;
+ meth = xmlGetProp(node, (const xmlChar *) "method");
+ if (meth != NULL) {
+ if (strcasecmp((char *) meth, "post") == 0) {
+ xmlChar *enctype;
+
+ method = method_POST_URLENC;
+
+ enctype = xmlGetProp(node, (const xmlChar *) "enctype");
+ if (enctype != NULL) {
+ if (strcasecmp((char *) enctype,
+ "multipart/form-data") == 0)
+ method = method_POST_MULTIPART;
+
+ xmlFree(enctype);
+ }
+ }
+ xmlFree(meth);
+ }
+
+ form = form_new(node, (char *) action, (char *) target, method,
+ (char *) charset, docenc);
+
+ if (target != NULL)
+ xmlFree(target);
+ if (charset != NULL)
+ xmlFree(charset);
+ if (action != NULL)
+ xmlFree(action);
+
+ return form;
+}
+
+struct form_control *parse_input_element(xmlNode *node)
+{
+ struct form_control *control = NULL;
+ xmlChar *type = xmlGetProp(node, (const xmlChar *) "type");
+ xmlChar *name;
+
+ if (type != NULL && strcasecmp((char *) type, "password") == 0) {
+ control = form_new_control(node, GADGET_PASSWORD);
+ } else if (type != NULL && strcasecmp((char *) type, "file") == 0) {
+ control = form_new_control(node, GADGET_FILE);
+ } else if (type != NULL && strcasecmp((char *) type, "hidden") == 0) {
+ control = form_new_control(node, GADGET_HIDDEN);
+ } else if (type != NULL && strcasecmp((char *) type, "checkbox") == 0) {
+ control = form_new_control(node, GADGET_CHECKBOX);
+ } else if (type != NULL && strcasecmp((char *) type, "radio") == 0) {
+ control = form_new_control(node, GADGET_RADIO);
+ } else if (type != NULL && strcasecmp((char *) type, "submit") == 0) {
+ control = form_new_control(node, GADGET_SUBMIT);
+ } else if (type != NULL && strcasecmp((char *) type, "reset") == 0) {
+ control = form_new_control(node, GADGET_RESET);
+ } else if (type != NULL && strcasecmp((char *) type, "button") == 0) {
+ control = form_new_control(node, GADGET_BUTTON);
+ } else if (type != NULL && strcasecmp((char *) type, "image") == 0) {
+ control = form_new_control(node, GADGET_IMAGE);
+ } else {
+ control = form_new_control(node, GADGET_TEXTBOX);
+ }
+
+ xmlFree(type);
+
+ if (control == NULL)
+ return NULL;
+
+ if (control->type == GADGET_CHECKBOX || control->type == GADGET_RADIO) {
+ control->selected =
+ xmlHasProp(node, (const xmlChar *) "checked");
+ }
+
+ if (control->type == GADGET_PASSWORD ||
+ control->type == GADGET_TEXTBOX) {
+ xmlChar *len = xmlGetProp(node, (const xmlChar *) "maxlength");
+ if (len != NULL) {
+ if (len[0] != '\0')
+ control->maxlength = atoi((char *) len);
+ xmlFree(len);
+ }
+ }
+
+ if (control->type != GADGET_FILE && control->type != GADGET_IMAGE) {
+ xmlChar *value = xmlGetProp(node, (const xmlChar *) "value");
+ if (value != NULL) {
+ control->value = strdup((char *) value);
+
+ xmlFree(value);
+
+ if (control->value == NULL) {
+ form_free_control(control);
+ return NULL;
+ }
+
+ control->length = strlen(control->value);
+ }
+
+ if (control->type == GADGET_TEXTBOX ||
+ control->type == GADGET_PASSWORD) {
+ if (control->value == NULL) {
+ control->value = strdup("");
+ if (control->value == NULL) {
+ form_free_control(control);
+ return NULL;
+ }
+
+ control->length = 0;
+ }
+
+ control->initial_value = strdup(control->value);
+ if (control->initial_value == NULL) {
+ form_free_control(control);
+ return NULL;
+ }
+ }
+ }
+
+ name = xmlGetProp(node, (const xmlChar *) "name");
+ if (name != NULL) {
+ control->name = strdup((char *) name);
+
+ xmlFree(name);
+
+ if (control->name == NULL) {
+ form_free_control(control);
+ return NULL;
+ }
+ }
+
+ return control;
+}
+
+struct form_control *parse_button_element(xmlNode *node)
+{
+ struct form_control *control;
+ xmlChar *type = xmlGetProp(node, (const xmlChar *) "type");
+ xmlChar *name;
+ xmlChar *value;
+
+ if (type == NULL || strcasecmp((char *) type, "submit") == 0) {
+ control = form_new_control(node, GADGET_SUBMIT);
+ } else if (strcasecmp((char *) type, "reset") == 0) {
+ control = form_new_control(node, GADGET_RESET);
+ } else {
+ control = form_new_control(node, GADGET_BUTTON);
+ }
+
+ xmlFree(type);
+
+ if (control == NULL)
+ return NULL;
+
+ value = xmlGetProp(node, (const xmlChar *) "value");
+ if (value != NULL) {
+ control->value = strdup((char *) value);
+
+ xmlFree(value);
+
+ if (control->value == NULL) {
+ form_free_control(control);
+ return NULL;
+ }
+ }
+
+ name = xmlGetProp(node, (const xmlChar *) "name");
+ if (name != NULL) {
+ control->name = strdup((char *) name);
+
+ xmlFree(name);
+
+ if (control->name == NULL) {
+ form_free_control(control);
+ return NULL;
+ }
+ }
+
+ return control;
+}
+
+struct form_control *parse_select_element(xmlNode *node)
+{
+ struct form_control *control = form_new_control(node, GADGET_SELECT);
+ xmlChar *name;
+
+ if (control == NULL)
+ return NULL;
+
+ control->data.select.multiple =
+ xmlHasProp(node, (const xmlChar *) "multiple");
+
+ name = xmlGetProp(node, (const xmlChar *) "name");
+ if (name != NULL) {
+ control->name = strdup((char *) name);
+
+ xmlFree(name);
+
+ if (control->name == NULL) {
+ form_free_control(control);
+ return NULL;
+ }
+ }
+
+ return control;
+}
+
+struct form_control *parse_textarea_element(xmlNode *node)
+{
+ struct form_control *control = form_new_control(node, GADGET_TEXTAREA);
+ xmlChar *name;
+
+ if (control == NULL)
+ return NULL;
+
+ name = xmlGetProp(node, (const xmlChar *) "name");
+ if (name != NULL) {
+ control->name = strdup((char *) name);
+
+ xmlFree(name);
+
+ if (control->name == NULL) {
+ form_free_control(control);
+ return NULL;
+ }
+ }
+
+ return control;
+}
+
#endif
Modified: trunk/netsurf/render/parser_binding.h
URL: http://source.netsurf-browser.org/trunk/netsurf/render/parser_binding.h?r...
==============================================================================
--- trunk/netsurf/render/parser_binding.h (original)
+++ trunk/netsurf/render/parser_binding.h Fri Feb 20 05:39:25 2009
@@ -23,6 +23,9 @@
#include <libxml/tree.h>
+struct form;
+struct form_control;
+
typedef enum binding_error {
BINDING_OK,
BINDING_NOMEM,
@@ -45,5 +48,10 @@
const char *binding_get_encoding(void *ctx, binding_encoding_source *source);
xmlDocPtr binding_get_document(void *ctx);
+#ifdef WITH_HUBBUB
+struct form *binding_get_forms(void *ctx);
+struct form_control *binding_get_control_for_node(void *ctx, xmlNodePtr node);
#endif
+#endif
+
14 years, 7 months
r6572 rjek - /trunk/netsurf/framebuffer/fb_32bpp_plotters.c
by netsurf@semichrome.net
Author: rjek
Date: Fri Feb 20 05:21:28 2009
New Revision: 6572
URL: http://source.netsurf-browser.org?rev=6572&view=rev
Log:
Enable autohinter. Greatly improves glyph quality in framebuffer port. Also get FreeType to render at same time as loading.
Modified:
trunk/netsurf/framebuffer/fb_32bpp_plotters.c
Modified: trunk/netsurf/framebuffer/fb_32bpp_plotters.c
URL: http://source.netsurf-browser.org/trunk/netsurf/framebuffer/fb_32bpp_plot...
==============================================================================
--- trunk/netsurf/framebuffer/fb_32bpp_plotters.c (original)
+++ trunk/netsurf/framebuffer/fb_32bpp_plotters.c Fri Feb 20 05:21:28 2009
@@ -266,14 +266,12 @@
nxtchr = utf8_next(text, length, nxtchr);
glyph_index = FT_Get_Char_Index(face, ucs4);
- error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
+ error = FT_Load_Glyph(face, glyph_index, FT_LOAD_RENDER |
+ FT_LOAD_MONOCHROME |
+ FT_LOAD_FORCE_AUTOHINT);
if (error)
continue;
- error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO );
- if (error)
- continue;
-
/* now, draw to our target surface */
fb_32bpp_draw_ft_bitmap( &face->glyph->bitmap,
x + face->glyph->bitmap_left,
14 years, 7 months
r6571 dsilvers - /trunk/netsurf/Makefile
by netsurf@semichrome.net
Author: dsilvers
Date: Fri Feb 20 04:10:32 2009
New Revision: 6571
URL: http://source.netsurf-browser.org?rev=6571&view=rev
Log:
Ensure that the FB frontend sets a subtarget, otherwise error out. This prevents silly mistakes like 'NETSURF_FB_FRONTEND := SDL' which had me stumped for a few minutes.
Modified:
trunk/netsurf/Makefile
Modified: trunk/netsurf/Makefile
URL: http://source.netsurf-browser.org/trunk/netsurf/Makefile?rev=6571&r1=6570...
==============================================================================
--- trunk/netsurf/Makefile (original)
+++ trunk/netsurf/Makefile Fri Feb 20 04:10:32 2009
@@ -608,6 +608,11 @@
LDFLAGS += $(shell $(PKG_CONFIG) --libs libxml-2.0 libcurl openssl)
SUBTARGET := -vnc
endif
+
+ ifeq ($(SUBTARGET),)
+ $(error Unable to proceed, no FB subtarget chosen.)
+ endif
+
endif
# ----------------------------------------------------------------------------
14 years, 7 months
r6570 vince - in /trunk/netsurf: ./ framebuffer/
by netsurf@semichrome.net
Author: vince
Date: Fri Feb 20 03:51:21 2009
New Revision: 6570
URL: http://source.netsurf-browser.org?rev=6570&view=rev
Log:
allow framebuffer port to use freetype2 library
Added:
trunk/netsurf/framebuffer/fb_font_freetype.c (contents, props changed)
- copied, changed from r6569, trunk/netsurf/framebuffer/fb_font.c
trunk/netsurf/framebuffer/fb_font_internal.c
trunk/netsurf/framebuffer/fb_font_internal.h
Removed:
trunk/netsurf/framebuffer/fb_font.c
Modified:
trunk/netsurf/Makefile
trunk/netsurf/Makefile.config
trunk/netsurf/Makefile.sources
trunk/netsurf/framebuffer/fb_16bpp_plotters.c
trunk/netsurf/framebuffer/fb_32bpp_plotters.c
trunk/netsurf/framebuffer/fb_8bpp_plotters.c
trunk/netsurf/framebuffer/fb_font.h
trunk/netsurf/framebuffer/fb_frontend_linuxfb.c
trunk/netsurf/framebuffer/fb_gui.c
trunk/netsurf/framebuffer/fb_rootwindow.c
Modified: trunk/netsurf/Makefile
URL: http://source.netsurf-browser.org/trunk/netsurf/Makefile?rev=6570&r1=6569...
==============================================================================
--- trunk/netsurf/Makefile (original)
+++ trunk/netsurf/Makefile Fri Feb 20 03:51:21 2009
@@ -508,6 +508,11 @@
ifeq ($(TARGET),framebuffer)
$(eval $(call feature_enabled,MNG,-DWITH_MNG,-lmng,PNG support))
+ ifeq ($(NETSURF_FB_FONTLIB),freetype)
+ CFLAGS += -DFB_USE_FREETYPE -I/usr/include/freetype2
+ LDFLAGS += -lfreetype
+ endif
+
# define additional CFLAGS and LDFLAGS requirements for pkg-configed libs here
NETSURF_FEATURE_RSVG_CFLAGS := -DWITH_RSVG
NETSURF_FEATURE_ROSPRITE_CFLAGS := -DWITH_NSSPRITE
Modified: trunk/netsurf/Makefile.config
URL: http://source.netsurf-browser.org/trunk/netsurf/Makefile.config?rev=6570&...
==============================================================================
--- trunk/netsurf/Makefile.config (original)
+++ trunk/netsurf/Makefile.config Fri Feb 20 03:51:21 2009
@@ -223,6 +223,10 @@
# Valid options: YES, NO
NETSURF_USE_HARU_PDF := NO
+ # Library to use for font plotting
+ # Valid options: internal, freetype
+ NETSURF_FB_FONTLIB := internal
+
# Framebuffer frontends may have differing root paths for resources
# As such, these specify the resource path and config path.
NETSURF_FB_RESPATH_linux := /usr/share/netsurf/
Modified: trunk/netsurf/Makefile.sources
URL: http://source.netsurf-browser.org/trunk/netsurf/Makefile.sources?rev=6570...
==============================================================================
--- trunk/netsurf/Makefile.sources (original)
+++ trunk/netsurf/Makefile.sources Fri Feb 20 03:51:21 2009
@@ -92,11 +92,17 @@
# S_FRAMEBUFFER are sources purely for the framebuffer build
S_FRAMEBUFFER := fb_gui.c tree.c history.c hotlist.c fb_schedule.c \
- thumbnail.c misc.c fb_bitmap.c fb_font.c font_8x16.c \
+ thumbnail.c misc.c fb_bitmap.c \
fb_filetype.c login.c fb_cursor.c fb_plotters.c \
fb_8bpp_plotters.c fb_16bpp_plotters.c fb_32bpp_plotters.c \
fb_findfile.c fb_rootwindow.c fb_image_data.c
# fb_1bpp_plotters.c
+
+S_FRAMEBUFFER += fb_font_$(NETSURF_FB_FONTLIB).c
+
+ifeq ($(NETSURF_FB_FONTLIB),internal)
+S_FRAMEBUFFER += font_8x16.c
+endif
ifeq ($(NETSURF_FB_FRONTEND),linux)
S_FRAMEBUFFER += fb_frontend_linuxfb.c
Modified: trunk/netsurf/framebuffer/fb_16bpp_plotters.c
URL: http://source.netsurf-browser.org/trunk/netsurf/framebuffer/fb_16bpp_plot...
==============================================================================
--- trunk/netsurf/framebuffer/fb_16bpp_plotters.c (original)
+++ trunk/netsurf/framebuffer/fb_16bpp_plotters.c Fri Feb 20 03:51:21 2009
@@ -191,7 +191,13 @@
return true;
}
-
+#ifdef FB_USE_FREETYPE
+static bool fb_16bpp_text(int x, int y, const struct css_style *style,
+ const char *text, size_t length, colour bg, colour c)
+{
+ return false;
+}
+#else
static bool fb_16bpp_text(int x, int y, const struct css_style *style,
const char *text, size_t length, colour bg, colour c)
{
@@ -278,6 +284,7 @@
free(buffer);
return true;
}
+#endif
static bool fb_16bpp_disc(int x, int y, int radius, colour c, bool filled)
{
Modified: trunk/netsurf/framebuffer/fb_32bpp_plotters.c
URL: http://source.netsurf-browser.org/trunk/netsurf/framebuffer/fb_32bpp_plot...
==============================================================================
--- trunk/netsurf/framebuffer/fb_32bpp_plotters.c (original)
+++ trunk/netsurf/framebuffer/fb_32bpp_plotters.c Fri Feb 20 03:51:21 2009
@@ -178,7 +178,114 @@
return true;
}
-
+#ifdef FB_USE_FREETYPE
+
+
+static bool
+fb_32bpp_draw_ft_bitmap(FT_Bitmap *bp, int x, int y, colour c)
+{
+ int height = bp->rows;
+ int width = bp->width;
+ uint32_t row;
+ int xloop, yloop;
+
+ uint32_t *pvideo;
+ uint32_t fgcol;
+
+ int x0,y0,x1,y1;
+ int xoff, yoff; /* x and y offset into image */
+
+ unsigned char *fntd;
+
+ if (width == 0) {
+ LOG(("null width char!"));
+ return false;
+ }
+
+
+ y+=1; /* the coord is the bottom-left of the pixels offset by 1 to make
+ * it work since fb coords are the top-left of pixels
+ */
+
+ /* The part of the text displayed is cropped to the current context. */
+ x0 = x;
+ y0 = y;
+ x1 = x + width;
+ y1 = y + height;
+
+ if (!fb_plotters_clip_rect_ctx(&x0, &y0, &x1, &y1)) {
+ return true; /* text lies outside current clipping region */
+ }
+
+ /* find width and height to plot */
+ if (height > (y1 - y0))
+ height = (y1 - y0);
+
+ if (width > (x1 - x0))
+ width = (x1 - x0);
+
+ xoff = x0 - x;
+ yoff = y0 - y;
+
+ fgcol = ((c & 0xff0000) >> 16) | (c & 0xff00) | ((c & 0xff) << 16);
+
+
+ pvideo = fb_32bpp_get_xy_loc(x, y0);
+
+ for (yloop = yoff; yloop < height; yloop++) {
+ fntd = bp->buffer + (yloop * bp->pitch);
+ for (xloop = 0; xloop < width ; xloop++) {
+ if ((xloop % 8) == 0) {
+ row = *fntd++;
+ }
+
+ if ((row & 0x80) != 0) {
+ *(pvideo + xloop) = fgcol;
+ }
+ row = row << 1;
+ }
+
+ pvideo += (framebuffer->linelen >> 2);
+ }
+
+
+ return true;
+}
+
+static bool fb_32bpp_text(int x, int y, const struct css_style *style,
+ const char *text, size_t length, colour bg, colour c)
+{
+ uint32_t ucs4;
+ size_t nxtchr = 0;
+ FT_UInt glyph_index;
+ FT_Face face = fb_get_face(style);
+ FT_Error error;
+
+ while (nxtchr < length) {
+ ucs4 = utf8_to_ucs4(text + nxtchr, length - nxtchr);
+ nxtchr = utf8_next(text, length, nxtchr);
+ glyph_index = FT_Get_Char_Index(face, ucs4);
+
+ error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
+ if (error)
+ continue;
+
+ error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO );
+ if (error)
+ continue;
+
+ /* now, draw to our target surface */
+ fb_32bpp_draw_ft_bitmap( &face->glyph->bitmap,
+ x + face->glyph->bitmap_left,
+ y - face->glyph->bitmap_top,
+ c);
+
+ x += face->glyph->advance.x >> 6;
+
+ }
+ return true;
+}
+#else
static bool fb_32bpp_text(int x, int y, const struct css_style *style,
const char *text, size_t length, colour bg, colour c)
{
@@ -259,17 +366,18 @@
free(buffer);
return true;
}
+#endif
static bool fb_32bpp_disc(int x, int y, int radius, colour c, bool filled)
{
- printf("disc\n");
+ LOG(("disc unimplemented"));
return true;
}
static bool fb_32bpp_arc(int x, int y, int radius, int angle1, int angle2,
colour c)
{
- printf("arc\n");
+ LOG(("arc unimplemented"));
return true;
}
@@ -365,14 +473,14 @@
static bool fb_32bpp_flush(void)
{
- printf("flush\n");
+ LOG(("flush unimplemnted"));
return true;
}
static bool fb_32bpp_path(const float *p, unsigned int n, colour fill, float width,
colour c, const float transform[6])
{
- printf("path\n");
+ LOG(("path unimplemented"));
return true;
}
Modified: trunk/netsurf/framebuffer/fb_8bpp_plotters.c
URL: http://source.netsurf-browser.org/trunk/netsurf/framebuffer/fb_8bpp_plott...
==============================================================================
--- trunk/netsurf/framebuffer/fb_8bpp_plotters.c (original)
+++ trunk/netsurf/framebuffer/fb_8bpp_plotters.c Fri Feb 20 03:51:21 2009
@@ -127,6 +127,15 @@
return true;
}
+#ifdef FB_USE_FREETYPE
+
+static bool fb_8bpp_text(int x, int y, const struct css_style *style,
+ const char *text, size_t length, colour bg, colour c)
+{
+ return false;
+
+}
+#else
static bool fb_8bpp_text(int x, int y, const struct css_style *style,
const char *text, size_t length, colour bg, colour c)
{
@@ -206,7 +215,7 @@
free(buffer);
return true;
}
-
+#endif
static bool fb_8bpp_disc(int x, int y, int radius, colour c, bool filled)
{
Removed: trunk/netsurf/framebuffer/fb_font.c
URL: http://source.netsurf-browser.org/trunk/netsurf/framebuffer/fb_font.c?rev...
==============================================================================
--- trunk/netsurf/framebuffer/fb_font.c (original)
+++ trunk/netsurf/framebuffer/fb_font.c (removed)
@@ -1,136 +1,0 @@
-/*
- * Copyright 2005 James Bursa <bursa(a)users.sourceforge.net>
- * 2008 Vincent Sanders <vince(a)simtec.co.uk>
- *
- * This file is part of NetSurf, http://www.netsurf-browser.org/
- *
- * NetSurf is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * NetSurf is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <inttypes.h>
-
-#include <assert.h>
-#include "css/css.h"
-#include "render/font.h"
-#include "desktop/options.h"
-#include "utils/utf8.h"
-
-#include "framebuffer/fb_gui.h"
-#include "framebuffer/fb_font.h"
-
-const struct fb_font_desc*
-fb_get_font(const struct css_style *style)
-{
- return &font_vga_8x16;
-}
-
-utf8_convert_ret utf8_to_font_encoding(const struct fb_font_desc* font,
- const char *string,
- size_t len,
- char **result)
-{
- return utf8_to_enc(string, font->encoding, len, result);
-
-}
-
-utf8_convert_ret utf8_to_local_encoding(const char *string,
- size_t len,
- char **result)
-{
- return utf8_to_enc(string, "CP437", len, result);
-
-}
-
-static bool nsfont_width(const struct css_style *style,
- const char *string, size_t length,
- int *width)
-{
- const struct fb_font_desc* fb_font = fb_get_font(style);
- *width = fb_font->width * utf8_bounded_length(string, length);
- return true;
-}
-
-/**
- * Find the position in a string where an x coordinate falls.
- *
- * \param style css_style for this text, with style->font_size.size ==
- * CSS_FONT_SIZE_LENGTH
- * \param string UTF-8 string to measure
- * \param length length of string
- * \param x x coordinate to search for
- * \param char_offset updated to offset in string of actual_x, [0..length]
- * \param actual_x updated to x coordinate of character closest to x
- * \return true on success, false on error and error reported
- */
-
-static bool nsfont_position_in_string(const struct css_style *style,
- const char *string, size_t length,
- int x, size_t *char_offset, int *actual_x)
-{
- const struct fb_font_desc* fb_font = fb_get_font(style);
- *char_offset = x / fb_font->width;
- if (*char_offset > length)
- *char_offset = length;
- *actual_x = *char_offset * fb_font->width;
- return true;
-}
-
-
-/**
- * Find where to split a string to make it fit a width.
- *
- * \param style css_style for this text, with style->font_size.size ==
- * CSS_FONT_SIZE_LENGTH
- * \param string UTF-8 string to measure
- * \param length length of string
- * \param x width available
- * \param char_offset updated to offset in string of actual_x, [0..length]
- * \param actual_x updated to x coordinate of character closest to x
- * \return true on success, false on error and error reported
- *
- * On exit, [char_offset == 0 ||
- * string[char_offset] == ' ' ||
- * char_offset == length]
- */
-
-static bool nsfont_split(const struct css_style *style,
- const char *string, size_t length,
- int x, size_t *char_offset, int *actual_x)
-{
-
- const struct fb_font_desc* fb_font = fb_get_font(style);
- *char_offset = x / fb_font->width;
- if (*char_offset > length) {
- *char_offset = length;
- } else {
- while (*char_offset > 0) {
- if (string[*char_offset] == ' ')
- break;
- (*char_offset)--;
- }
- }
- *actual_x = *char_offset * fb_font->width;
- return true;
-}
-
-const struct font_functions nsfont = {
- nsfont_width,
- nsfont_position_in_string,
- nsfont_split
-};
-
-/*
- * Local Variables:
- * c-basic-offset:8
- * End:
- */
Modified: trunk/netsurf/framebuffer/fb_font.h
URL: http://source.netsurf-browser.org/trunk/netsurf/framebuffer/fb_font.h?rev...
==============================================================================
--- trunk/netsurf/framebuffer/fb_font.h (original)
+++ trunk/netsurf/framebuffer/fb_font.h Fri Feb 20 03:51:21 2009
@@ -19,6 +19,20 @@
#ifndef NETSURF_FB_FONT_H
#define NETSURF_FB_FONT_H
+bool fb_font_init(void);
+bool fb_font_finalise(void);
+
+#ifdef FB_USE_FREETYPE
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+FT_Face fb_get_face(const struct css_style *style);
+
+#else
+
+#include "utils/utf8.h"
+
struct fb_font_desc {
const char *name;
int width, height;
@@ -34,6 +48,7 @@
const char *string,
size_t len,
char **result);
+#endif
#endif /* NETSURF_FB_FONT_H */
Copied: trunk/netsurf/framebuffer/fb_font_freetype.c (from r6569, trunk/netsurf/framebuffer/fb_font.c)
URL: http://source.netsurf-browser.org/trunk/netsurf/framebuffer/fb_font_freet...
==============================================================================
--- trunk/netsurf/framebuffer/fb_font.c (original)
+++ trunk/netsurf/framebuffer/fb_font_freetype.c Fri Feb 20 03:51:21 2009
@@ -18,45 +18,128 @@
*/
#include <inttypes.h>
-
#include <assert.h>
+
#include "css/css.h"
#include "render/font.h"
#include "desktop/options.h"
#include "utils/utf8.h"
+#include "utils/log.h"
#include "framebuffer/fb_gui.h"
#include "framebuffer/fb_font.h"
-const struct fb_font_desc*
-fb_get_font(const struct css_style *style)
-{
- return &font_vga_8x16;
-}
-
-utf8_convert_ret utf8_to_font_encoding(const struct fb_font_desc* font,
- const char *string,
- size_t len,
- char **result)
-{
- return utf8_to_enc(string, font->encoding, len, result);
-
-}
+static FT_Library library;
+static FT_Face face_sans_serif;
+
utf8_convert_ret utf8_to_local_encoding(const char *string,
size_t len,
char **result)
{
- return utf8_to_enc(string, "CP437", len, result);
-
-}
-
+ return utf8_to_enc(string, "UTF-8", len, result);
+}
+
+
+/* initialise font handling */
+bool fb_font_init(void)
+{
+ FT_Error error;
+
+ error = FT_Init_FreeType( &library );
+ if (error) {
+ LOG(("Freetype could not initialised (code %d)\n", error));
+ return false;
+ }
+
+ error = FT_New_Face(library,
+ "/usr/share/fonts/truetype/freefont/FreeSans.ttf",
+ 0,
+ &face_sans_serif );
+ if (error) {
+ LOG(("Could not find default font (code %d)\n", error));
+ FT_Done_FreeType(library);
+ return false;
+ }
+
+ error = FT_Set_Pixel_Sizes(face_sans_serif, 0, 14 );
+ if (error) {
+ LOG(("Could not set pixel size (code %d)\n", error));
+ return false;
+ }
+
+
+ return true;
+}
+
+bool fb_font_finalise(void)
+{
+ FT_Done_FreeType(library);
+ return true;
+}
+
+
+
+FT_Face
+fb_get_face(const struct css_style *style)
+{
+ FT_Face face;
+ face = face_sans_serif;
+ FT_Error error;
+ int size;
+
+ if (style->font_size.value.length.unit == CSS_UNIT_PX) {
+ size = style->font_size.value.length.value;
+
+ error = FT_Set_Pixel_Sizes(face_sans_serif, 0, size );
+ if (error) {
+ LOG(("Could not set pixel size (code %d)\n", error));
+ }
+ } else {
+ size = css_len2pt(&style->font_size.value.length, style);
+ error = FT_Set_Char_Size( face, 0, size*64, 72, 72 );
+ if (error) {
+ LOG(("Could not set pixel size (code %d)\n", error));
+ }
+ }
+
+
+ return face;
+}
+
+/**
+ * Measure the width of a string.
+ *
+ * \param style css_style for this text, with style->font_size.size ==
+ * CSS_FONT_SIZE_LENGTH
+ * \param string UTF-8 string to measure
+ * \param length length of string
+ * \param width updated to width of string[0..length)
+ * \return true on success, false on error and error reported
+ */
static bool nsfont_width(const struct css_style *style,
const char *string, size_t length,
int *width)
{
- const struct fb_font_desc* fb_font = fb_get_font(style);
- *width = fb_font->width * utf8_bounded_length(string, length);
+ uint32_t ucs4;
+ size_t nxtchr = 0;
+ FT_UInt glyph_index;
+ FT_Face face = fb_get_face(style);
+ FT_Error error;
+
+ *width = 0;
+ while (nxtchr < length) {
+ ucs4 = utf8_to_ucs4(string + nxtchr, length - nxtchr);
+ nxtchr = utf8_next(string, length, nxtchr);
+ glyph_index = FT_Get_Char_Index(face, ucs4);
+
+ error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
+ if (error)
+ continue;
+
+ *width += face->glyph->advance.x >> 6;
+ }
+
return true;
}
@@ -77,11 +160,29 @@
const char *string, size_t length,
int x, size_t *char_offset, int *actual_x)
{
- const struct fb_font_desc* fb_font = fb_get_font(style);
- *char_offset = x / fb_font->width;
- if (*char_offset > length)
- *char_offset = length;
- *actual_x = *char_offset * fb_font->width;
+ uint32_t ucs4;
+ size_t nxtchr = 0;
+ FT_UInt glyph_index;
+ FT_Face face = fb_get_face(style);
+ FT_Error error;
+
+ *actual_x = 0;
+ while (nxtchr < length) {
+ ucs4 = utf8_to_ucs4(string + nxtchr, length - nxtchr);
+ glyph_index = FT_Get_Char_Index(face, ucs4);
+
+ error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
+ if (error)
+ continue;
+
+ *actual_x += face->glyph->advance.x >> 6;
+ if (*actual_x > x)
+ break;
+
+ nxtchr = utf8_next(string, length, nxtchr);
+ }
+
+ *char_offset = nxtchr;
return true;
}
@@ -107,19 +208,42 @@
const char *string, size_t length,
int x, size_t *char_offset, int *actual_x)
{
-
- const struct fb_font_desc* fb_font = fb_get_font(style);
- *char_offset = x / fb_font->width;
- if (*char_offset > length) {
- *char_offset = length;
+ uint32_t ucs4;
+ size_t nxtchr = 0;
+ FT_UInt glyph_index;
+ FT_Face face = fb_get_face(style);
+ FT_Error error;
+ int last_space_x = -1;
+ int last_space_idx = -1;
+
+ *actual_x = 0;
+ while (nxtchr < length) {
+ ucs4 = utf8_to_ucs4(string + nxtchr, length - nxtchr);
+
+ if (ucs4 == 0x20) {
+ last_space_x = *actual_x;
+ last_space_idx = nxtchr;
+ }
+
+ glyph_index = FT_Get_Char_Index(face, ucs4);
+
+ error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
+ if (error)
+ continue;
+
+ *actual_x += face->glyph->advance.x >> 6;
+ if (*actual_x > x)
+ break;
+
+ nxtchr = utf8_next(string, length, nxtchr);
+ }
+
+ if (last_space_x == -1) {
+ *char_offset = nxtchr;
} else {
- while (*char_offset > 0) {
- if (string[*char_offset] == ' ')
- break;
- (*char_offset)--;
- }
- }
- *actual_x = *char_offset * fb_font->width;
+ *actual_x = last_space_x;
+ *char_offset = last_space_idx;
+ }
return true;
}
Propchange: trunk/netsurf/framebuffer/fb_font_freetype.c
------------------------------------------------------------------------------
svn:mergeinfo =
Added: trunk/netsurf/framebuffer/fb_font_internal.c
URL: http://source.netsurf-browser.org/trunk/netsurf/framebuffer/fb_font_inter...
==============================================================================
--- trunk/netsurf/framebuffer/fb_font_internal.c (added)
+++ trunk/netsurf/framebuffer/fb_font_internal.c Fri Feb 20 03:51:21 2009
@@ -1,0 +1,141 @@
+/*
+ * Copyright 2005 James Bursa <bursa(a)users.sourceforge.net>
+ * 2008 Vincent Sanders <vince(a)simtec.co.uk>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <inttypes.h>
+
+#include <assert.h>
+#include "css/css.h"
+#include "render/font.h"
+#include "desktop/options.h"
+#include "utils/utf8.h"
+
+#include "framebuffer/fb_gui.h"
+#include "framebuffer/fb_font.h"
+
+bool fb_font_init(void)
+{
+ return true;
+}
+
+const struct fb_font_desc*
+fb_get_font(const struct css_style *style)
+{
+ return &font_vga_8x16;
+}
+
+utf8_convert_ret utf8_to_font_encoding(const struct fb_font_desc* font,
+ const char *string,
+ size_t len,
+ char **result)
+{
+ return utf8_to_enc(string, font->encoding, len, result);
+
+}
+
+utf8_convert_ret utf8_to_local_encoding(const char *string,
+ size_t len,
+ char **result)
+{
+ return utf8_to_enc(string, "CP437", len, result);
+
+}
+
+static bool nsfont_width(const struct css_style *style,
+ const char *string, size_t length,
+ int *width)
+{
+ const struct fb_font_desc* fb_font = fb_get_font(style);
+ *width = fb_font->width * utf8_bounded_length(string, length);
+ return true;
+}
+
+/**
+ * Find the position in a string where an x coordinate falls.
+ *
+ * \param style css_style for this text, with style->font_size.size ==
+ * CSS_FONT_SIZE_LENGTH
+ * \param string UTF-8 string to measure
+ * \param length length of string
+ * \param x x coordinate to search for
+ * \param char_offset updated to offset in string of actual_x, [0..length]
+ * \param actual_x updated to x coordinate of character closest to x
+ * \return true on success, false on error and error reported
+ */
+
+static bool nsfont_position_in_string(const struct css_style *style,
+ const char *string, size_t length,
+ int x, size_t *char_offset, int *actual_x)
+{
+ const struct fb_font_desc* fb_font = fb_get_font(style);
+ *char_offset = x / fb_font->width;
+ if (*char_offset > length)
+ *char_offset = length;
+ *actual_x = *char_offset * fb_font->width;
+ return true;
+}
+
+
+/**
+ * Find where to split a string to make it fit a width.
+ *
+ * \param style css_style for this text, with style->font_size.size ==
+ * CSS_FONT_SIZE_LENGTH
+ * \param string UTF-8 string to measure
+ * \param length length of string
+ * \param x width available
+ * \param char_offset updated to offset in string of actual_x, [0..length]
+ * \param actual_x updated to x coordinate of character closest to x
+ * \return true on success, false on error and error reported
+ *
+ * On exit, [char_offset == 0 ||
+ * string[char_offset] == ' ' ||
+ * char_offset == length]
+ */
+
+static bool nsfont_split(const struct css_style *style,
+ const char *string, size_t length,
+ int x, size_t *char_offset, int *actual_x)
+{
+
+ const struct fb_font_desc* fb_font = fb_get_font(style);
+ *char_offset = x / fb_font->width;
+ if (*char_offset > length) {
+ *char_offset = length;
+ } else {
+ while (*char_offset > 0) {
+ if (string[*char_offset] == ' ')
+ break;
+ (*char_offset)--;
+ }
+ }
+ *actual_x = *char_offset * fb_font->width;
+ return true;
+}
+
+const struct font_functions nsfont = {
+ nsfont_width,
+ nsfont_position_in_string,
+ nsfont_split
+};
+
+/*
+ * Local Variables:
+ * c-basic-offset:8
+ * End:
+ */
Added: trunk/netsurf/framebuffer/fb_font_internal.h
URL: http://source.netsurf-browser.org/trunk/netsurf/framebuffer/fb_font_inter...
==============================================================================
--- trunk/netsurf/framebuffer/fb_font_internal.h (added)
+++ trunk/netsurf/framebuffer/fb_font_internal.h Fri Feb 20 03:51:21 2009
@@ -1,0 +1,39 @@
+/*
+ * Copyright 2008 Vincent Sanders <vince(a)simtec.co.uk>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NETSURF_FB_FONT_H
+#define NETSURF_FB_FONT_H
+
+struct fb_font_desc {
+ const char *name;
+ int width, height;
+ const char *encoding;
+ const uint32_t *data;
+};
+
+extern const struct fb_font_desc font_vga_8x16;
+
+extern const struct fb_font_desc* fb_get_font(const struct css_style *style);
+
+extern utf8_convert_ret utf8_to_font_encoding(const struct fb_font_desc* font,
+ const char *string,
+ size_t len,
+ char **result);
+
+#endif /* NETSURF_FB_FONT_H */
+
Modified: trunk/netsurf/framebuffer/fb_frontend_linuxfb.c
URL: http://source.netsurf-browser.org/trunk/netsurf/framebuffer/fb_frontend_l...
==============================================================================
--- trunk/netsurf/framebuffer/fb_frontend_linuxfb.c (original)
+++ trunk/netsurf/framebuffer/fb_frontend_linuxfb.c Fri Feb 20 03:51:21 2009
@@ -49,6 +49,7 @@
#include "framebuffer/fb_cursor.h"
#include "framebuffer/fb_frontend.h"
#include "framebuffer/fb_options.h"
+#include "framebuffer/fb_rootwindow.h"
#include "utils/log.h"
#include "utils/messages.h"
@@ -647,15 +648,11 @@
} else if (event.type == EV_REL) {
switch (event.code) {
case 0:
- fb_cursor_move(framebuffer,
- event.value,
- 0);
+ fb_rootwindow_move(framebuffer, g, event.value, 0, true);
break;
case 1:
- fb_cursor_move(framebuffer,
- 0,
- event.value);
+ fb_rootwindow_move(framebuffer, g, 0, event.value, true);
break;
case 8:
Modified: trunk/netsurf/framebuffer/fb_gui.c
URL: http://source.netsurf-browser.org/trunk/netsurf/framebuffer/fb_gui.c?rev=...
==============================================================================
--- trunk/netsurf/framebuffer/fb_gui.c (original)
+++ trunk/netsurf/framebuffer/fb_gui.c Fri Feb 20 03:51:21 2009
@@ -44,6 +44,7 @@
#include "framebuffer/fb_findfile.h"
#include "framebuffer/fb_rootwindow.h"
#include "framebuffer/fb_image_data.h"
+#include "framebuffer/fb_font.h"
#include "content/urldb.h"
#include "desktop/history_core.h"
@@ -225,6 +226,9 @@
}
framebuffer->cursor = fb_cursor_init(framebuffer, &pointer_image);
+
+ fb_font_init();
+
}
void gui_init2(int argc, char** argv)
@@ -542,7 +546,7 @@
bool gui_window_frame_resize_start(struct gui_window *g)
{
- printf("resize frame\n");
+ LOG(("resize frame\n"));
return true;
}
@@ -552,7 +556,7 @@
void gui_window_set_scale(struct gui_window *g, float scale)
{
- printf("set scale\n");
+ LOG(("set scale\n"));
}
struct gui_download_window *gui_download_window_create(const char *url,
Modified: trunk/netsurf/framebuffer/fb_rootwindow.c
URL: http://source.netsurf-browser.org/trunk/netsurf/framebuffer/fb_rootwindow...
==============================================================================
--- trunk/netsurf/framebuffer/fb_rootwindow.c (original)
+++ trunk/netsurf/framebuffer/fb_rootwindow.c Fri Feb 20 03:51:21 2009
@@ -79,6 +79,8 @@
char* text;
};
+static struct css_style root_style;
+
static struct fb_widget *widget_list;
/* widget for status */
@@ -141,7 +143,7 @@
if (widget->text != NULL) {
plot.text(fb_plot_ctx.x0 + 2,
fb_plot_ctx.y0 + 15,
- NULL,
+ &root_style,
widget->text,
strlen(widget->text),
widget->bg,
@@ -383,6 +385,10 @@
/* no widget yet has input */
inputfocus_widget = NULL;
+ /* setup root css style (for text etc.) */
+ root_style.font_size.value.length.unit = CSS_UNIT_PX;
+ root_style.font_size.value.length.value = 14;
+
/* underlying root window, cannot take input and lowest in stack */
rootwindow = calloc(1, sizeof(struct gui_window));
rootwindow->x = 0;
14 years, 7 months