From 1a52a32e5d5ccf78639c268cc660d8d8b0d98092 Mon Sep 17 00:00:00 2001 From: James Bursa Date: Sun, 20 Feb 2005 13:18:21 +0000 Subject: [PATCH] [project @ 2005-02-20 13:18:21 by bursa] Font rewrite, part 2. svn path=/import/netsurf/; revision=1518 --- render/box.c | 18 -------- render/box.h | 3 -- render/font.h | 60 ++++++++++++------------- render/html.c | 4 -- render/html.h | 2 - render/html_redraw.c | 10 +++-- render/layout.c | 102 +++++++++++++++++++++++++------------------ 7 files changed, 94 insertions(+), 105 deletions(-) diff --git a/render/box.c b/render/box.c index f93c3c99b..3062db501 100644 --- a/render/box.c +++ b/render/box.c @@ -289,7 +289,6 @@ struct box * box_create(struct css_style * style, box->float_children = NULL; box->next_float = NULL; box->col = NULL; - box->font = NULL; box->gadget = NULL; box->usemap = NULL; box->id = id1; @@ -347,14 +346,8 @@ bool xml_to_box(xmlNode *n, struct content *c) c->data.html.style = css_duplicate_style(&css_base_style); if (!c->data.html.style) return false; - c->data.html.style->font_size.value.length.value = option_font_size * 0.1; - c->data.html.fonts = nsfont_new_set(); - if (!c->data.html.fonts) { - css_free_style(c->data.html.style); - return false; - } c->data.html.object_count = 0; c->data.html.object = 0; @@ -563,7 +556,6 @@ bool convert_xml_to_box(xmlNode *n, struct content *content, box->length = strlen(box->text); } } - box->font = nsfont_open(content->data.html.fonts, box->style); box_add_child(*inline_container, box); if (box->text[0] == ' ') { @@ -619,8 +611,6 @@ bool convert_xml_to_box(xmlNode *n, struct content *content, goto no_memory; } box->length = strlen(box->text); - box->font = nsfont_open(content->data.html.fonts, - box->style); box_add_child(*inline_container, box); current[len] = old; current += len; @@ -1105,7 +1095,6 @@ struct box_result box_image(xmlNode *n, struct box_status *status, if (!box->text) return (struct box_result) {0, false, true}; box->length = strlen(box->text); - box->font = nsfont_open(status->content->data.html.fonts, style); } /* imagemap associated with this image */ @@ -1248,8 +1237,6 @@ struct box_result box_textarea(xmlNode *n, struct box_status *status, inline_box->style_clone = 1; inline_box->text = s; inline_box->length = len; - inline_box->font = nsfont_open(status->content->data.html.fonts, - style); box_add_child(inline_container, inline_box); current += len; @@ -1372,7 +1359,6 @@ struct box_result box_select(xmlNode *n, struct box_status *status, goto no_memory; inline_box->length = strlen(inline_box->text); - inline_box->font = nsfont_open(status->content->data.html.fonts, style); if (status->current_form) form_add_control(status->current_form, gadget); @@ -1458,7 +1444,6 @@ struct box_result box_input(xmlNode *n, struct box_status *status, if (!gadget) goto no_memory; gadget->box = box; - box->font = nsfont_open(status->content->data.html.fonts, style); } else if (type && strcasecmp(type, "hidden") == 0) { /* no box for hidden inputs */ @@ -1524,7 +1509,6 @@ struct box_result box_input(xmlNode *n, struct box_status *status, if (!inline_box->text) goto no_memory; inline_box->length = strlen(inline_box->text); - inline_box->font = nsfont_open(status->content->data.html.fonts, style); box_add_child(inline_container, inline_box); box_add_child(box, inline_container); @@ -1552,7 +1536,6 @@ struct box_result box_input(xmlNode *n, struct box_status *status, if (!inline_box->text) goto no_memory; inline_box->length = strlen(inline_box->text); - inline_box->font = nsfont_open(status->content->data.html.fonts, style); box_add_child(inline_container, inline_box); box_add_child(box, inline_container); @@ -1679,7 +1662,6 @@ struct box *box_input_text(xmlNode *n, struct box_status *status, return 0; inline_box->length = strlen(inline_box->text); } - inline_box->font = nsfont_open(status->content->data.html.fonts, style); box_add_child(inline_container, inline_box); box_add_child(box, inline_container); diff --git a/render/box.h b/render/box.h index 048c566dd..2bcc519f8 100644 --- a/render/box.h +++ b/render/box.h @@ -82,7 +82,6 @@ struct box; struct column; struct css_style; -struct font_data; /** Type of a struct box. */ @@ -197,8 +196,6 @@ struct box { struct column *col; /**< Array of table column data for TABLE only. */ - struct font_data *font; /**< Font, or 0 if no text. */ - /** Form control data, or 0 if not a form control. */ struct form_control* gadget; diff --git a/render/font.h b/render/font.h index 4a983098a..68563e069 100644 --- a/render/font.h +++ b/render/font.h @@ -3,52 +3,50 @@ * Licensed under the GNU General Public License, * http://www.opensource.org/licenses/gpl-license * Copyright 2003 Phil Mellor - * Copyright 2003 James Bursa + * Copyright 2005 James Bursa * Copyright 2004 John Tytgat */ +/** \file + * Font handling (interface). + * + * These functions provide font related services. They all work on UTF-8 strings + * with lengths given. + * + * Note that an interface to painting is not defined here. Painting is + * redirected through platform-dependent plotters anyway, so there is no gain in + * abstracting it here. + */ + #ifndef _NETSURF_RENDER_FONT_H_ #define _NETSURF_RENDER_FONT_H_ +#include #include -#include "netsurf/css/css.h" -typedef enum { - FONTTYPE_UFONT, - FONTTYPE_STANDARD_UTF8ENC, - FONTTYPE_STANDARD_LATIN1 -} fonttype_e; -struct font_data { - int id; - int handle; - fonttype_e ftype; - unsigned int size; - unsigned int space_width; - struct font_data *next; -}; +struct css_style; -struct font_set *nsfont_new_set(void); -struct font_data *nsfont_open(struct font_set *set, struct css_style *style); -void nsfont_free_set(struct font_set *set); -unsigned long nsfont_width(struct font_data *font, const char *text, - size_t length); -bool nsfont_position_in_string(struct font_data *font, const char *text, - size_t length, unsigned long x, int *char_offset, - int *pixel_offset); -char *nsfont_split(struct font_data *font, const char *text, - size_t length, - unsigned int width, unsigned int *used_width); -bool nsfont_paint(struct font_data *font, const char *str, - size_t length, int xpos, int ypos, void *trfm); -void nsfont_txtenum(struct font_data *font, const char *text, + +bool nsfont_width(const struct css_style *style, + const char *string, size_t length, + int *width); +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); +bool nsfont_split(const struct css_style *style, + const char *string, size_t length, + int x, size_t *char_offset, int *actual_x); + + + + +void nsfont_txtenum(void *font, const char *text, size_t length, unsigned int *width, const char **rofontname, const char **rotext, size_t *rolength, size_t *consumed); -void nsfont_fill_nametable(bool force_rescan); -void nsfont_reopen_set(struct font_set *fonts); #endif diff --git a/render/html.c b/render/html.c index 35b2c5c87..fdc0edbe0 100644 --- a/render/html.c +++ b/render/html.c @@ -71,7 +71,6 @@ bool html_create(struct content *c, const char *params[]) html->stylesheet_count = 0; html->stylesheet_content = 0; html->style = 0; - html->fonts = 0; html->object_count = 0; html->object = 0; html->imagemaps = 0; @@ -1043,9 +1042,6 @@ void html_destroy(struct content *c) if (c->data.html.style) css_free_style(c->data.html.style); - if (c->data.html.fonts) - nsfont_free_set(c->data.html.fonts); - /* Free objects */ for (i = 0; i != c->data.html.object_count; i++) { LOG(("object %i %p", i, c->data.html.object[i].content)); diff --git a/render/html.h b/render/html.h index a5b9a0fe6..e57f08b07 100644 --- a/render/html.h +++ b/render/html.h @@ -71,8 +71,6 @@ struct content_html_data { struct content **stylesheet_content; struct css_style *style; /**< Base style. */ - struct font_set *fonts; /**< Set of fonts. */ - /** Number of entries in object. */ unsigned int object_count; /** Objects. Each may be 0. */ diff --git a/render/html_redraw.c b/render/html_redraw.c index 20e9080aa..60c705cfa 100644 --- a/render/html_redraw.c +++ b/render/html_redraw.c @@ -292,7 +292,7 @@ bool html_redraw_box(struct box *box, current_background_color)) return false; - } else if (box->text && box->font) { + } else if (box->text) { /* antialias colour for under/overline */ colour = html_redraw_aa(current_background_color, /*print_text_black ? 0 :*/ box->style->color); @@ -328,7 +328,7 @@ bool html_redraw_box(struct box *box, } if (!plot.text(x, y + (int) (box->height * 0.75 * scale), - box->font, box->text, box->length, + box->style, box->text, box->length, current_background_color, /*print_text_black ? 0 :*/ box->style->color)) return false; @@ -641,13 +641,15 @@ bool html_redraw_file(int x, int y, int width, int height, text = messages_get("Form_Drop"); length = strlen(text); - text_width = nsfont_width(box->font, text, length) * scale; + if (!nsfont_width(box->style, text, length, &text_width)) + return false; + text_width *= scale; if (width < text_width + 8) x = x + width - text_width - 4; else x = x + 4; - return plot.text(x, y + height * 0.75, box->font, text, length, + return plot.text(x, y + height * 0.75, box->style, text, length, background_colour, /*print_text_black ? 0 :*/ box->style->color); } diff --git a/render/layout.c b/render/layout.c index 5b5a1453c..d2999f374 100644 --- a/render/layout.c +++ b/render/layout.c @@ -722,6 +722,7 @@ bool layout_line(struct box *first, int width, int *y, int x0 = 0; int x1 = width; int x, h, x_previous; + int space_width; struct box *left; struct box *right; struct box *b; @@ -781,11 +782,16 @@ bool layout_line(struct box *first, int width, int *y, if (b->text) { if (b->width == UNKNOWN_WIDTH) - b->width = nsfont_width(b->font, - b->text, - b->length); - x += b->width + b->space ? - b->font->space_width : 0; + /** \todo handle errors */ + nsfont_width(b->style, b->text, + b->length, &b->width); + x += b->width; + if (b->space) { + /** \todo optimize out */ + nsfont_width(b->style, " ", 1, + &space_width); + x += space_width; + } } else b->width = 0; @@ -898,9 +904,13 @@ bool layout_line(struct box *first, int width, int *y, space_before = space_after; if (b->object) space_after = 0; - else if (b->text) - space_after = b->space ? b->font->space_width : 0; - else + else if (b->text) { + space_after = 0; + if (b->space) + /** \todo handle errors, optimize */ + nsfont_width(b->style, " ", 1, + &space_after); + } else space_after = 0; split_box = b; move_y = true; @@ -961,7 +971,7 @@ bool layout_line(struct box *first, int width, int *y, if (x1 - x0 < x && split_box) { /* the last box went over the end */ unsigned int i; - unsigned int space = 0; + size_t space = 0; int w; struct box * c2; @@ -981,7 +991,9 @@ bool layout_line(struct box *first, int width, int *y, if (space == 0) w = split_box->width; else - w = nsfont_width(split_box->font, split_box->text, space); + /** \todo handle errors */ + nsfont_width(split_box->style, split_box->text, + space, &w); LOG(("splitting: split_box %p, space %u, w %i, left %p, " "right %p, inline_count %u", @@ -1031,39 +1043,39 @@ bool layout_line(struct box *first, int width, int *y, } else { /* fit as many words as possible */ assert(space != 0); - space = nsfont_split(split_box->font, - split_box->text, - split_box->length, - x1 - x0 - x - space_before, &w) - - split_box->text; + /** \todo handle errors */ + nsfont_split(split_box->style, + split_box->text, split_box->length, + x1 - x0 - x - space_before, &space, &w); LOG(("'%.*s' %i %u %i", (int) split_box->length, split_box->text, x1 - x0, space, w)); /* assert(space == split_box->length || split_box->text[space] = ' '); */ if (space == 0) space = 1; - /* \todo use box pool */ - c2 = pool_alloc(box_pool, sizeof *c2); - if (!c2) - return false; - memcpy(c2, split_box, sizeof *c2); - c2->text = strndup(split_box->text + space + 1, - split_box->length - (space + 1)); - if (!c2->text) - return false; - c2->length = split_box->length - (space + 1); - c2->width = UNKNOWN_WIDTH; - c2->clone = 1; - split_box->length = space; - split_box->width = w; - split_box->space = 1; - c2->next = split_box->next; - split_box->next = c2; - c2->prev = split_box; - if (c2->next) - c2->next->prev = c2; - else - c2->parent->last = c2; - b = c2; + if (space != split_box->length) { + c2 = pool_alloc(box_pool, sizeof *c2); + if (!c2) + return false; + memcpy(c2, split_box, sizeof *c2); + c2->text = strndup(split_box->text + space + 1, + split_box->length - (space + 1)); + if (!c2->text) + return false; + c2->length = split_box->length - (space + 1); + c2->width = UNKNOWN_WIDTH; + c2->clone = 1; + split_box->length = space; + split_box->width = w; + split_box->space = 1; + c2->next = split_box->next; + split_box->next = c2; + c2->prev = split_box; + if (c2->next) + c2->next->prev = c2; + else + c2->parent->last = c2; + b = c2; + } x += space_before + w; /* fprintf(stderr, "layout_line: overflow, fit\n"); */ } @@ -1822,18 +1834,22 @@ void calculate_inline_widths(struct box *box, int *min, int *line_max) int width; /* max = all one line */ - box->width = nsfont_width(box->font, box->text, box->length); + /** \todo handle errors */ + nsfont_width(box->style, box->text, box->length, &box->width); *line_max += box->width; - if (box->next && box->space) - *line_max += box->font->space_width; + if (box->next && box->space) { + nsfont_width(box->style, " ", 1, &width); + *line_max += width; + } /* min = widest word */ i = 0; do { for (j = i; j != box->length && box->text[j] != ' '; j++) ; - width = nsfont_width(box->font, box->text + i, j - i); - if (*min < width) *min = width; + nsfont_width(box->style, box->text + i, j - i, &width); + if (*min < width) + *min = width; i = j + 1; } while (j != box->length); }