From 65b5ae0f8fe15d3ad659817cd72febf16cccdfe2 Mon Sep 17 00:00:00 2001 From: James Bursa Date: Sun, 20 Feb 2005 13:19:19 +0000 Subject: [project @ 2005-02-20 13:19:19 by bursa] Font rewrite, part 3. Note that Draw export and printing are broken by these changes. svn path=/import/netsurf/; revision=1519 --- riscos/dialog.c | 11 +- riscos/font.c | 1374 ++++++++-------------------------------------------- riscos/gui.c | 17 +- riscos/gui.h | 4 + riscos/plotters.c | 20 +- riscos/print.c | 4 +- riscos/save_draw.c | 6 +- riscos/thumbnail.c | 9 +- riscos/ufont.c | 1273 ------------------------------------------------ riscos/ufont.h | 70 --- 10 files changed, 224 insertions(+), 2564 deletions(-) delete mode 100644 riscos/ufont.c delete mode 100644 riscos/ufont.h diff --git a/riscos/dialog.c b/riscos/dialog.c index f10987f77..96a72a9ba 100644 --- a/riscos/dialog.c +++ b/riscos/dialog.c @@ -468,7 +468,7 @@ void ro_gui_dialog_redraw(wimp_draw *redraw) { os_error *error; osbool more; struct toolbar_display *display; - + for (display = toolbars; display; display = display->next) { if ((display->toolbar) && (display->toolbar->toolbar_handle == redraw->w)) { ro_gui_theme_redraw(display->toolbar, redraw); @@ -594,7 +594,7 @@ void ro_gui_dialog_config_prepare(void) "Homerton.Medium"); ro_gui_set_icon_selected_state(dialog_config_font, ICON_CONFIG_FONT_USE_UFONT, option_font_ufont); - + /* image pane */ ro_gui_choices_fg_plot_style = option_fg_plot_style; ro_gui_choices_bg_plot_style = option_bg_plot_style; @@ -615,7 +615,7 @@ void ro_gui_dialog_set_image_quality(int icon, unsigned int tinct_options) { messages_get(ro_gui_image_name[i])); ro_gui_set_icon_selected_state(dialog_config_image, icon + 3, (tinct_options & tinct_BILINEAR_FILTER)); - + } /** @@ -711,7 +711,7 @@ void ro_gui_dialog_config_set(void) { dialog_config_font, ICON_CONFIG_FONT_DEF)); option_font_ufont = ro_gui_get_icon_selected_state( dialog_config_font, ICON_CONFIG_FONT_USE_UFONT); - + /* image pane */ if ((option_fg_plot_style != (int)ro_gui_choices_fg_plot_style) || (option_bg_plot_style != (int)ro_gui_choices_bg_plot_style)) { @@ -808,7 +808,6 @@ void ro_gui_dialog_click_config(wimp_pointer *pointer) void ro_gui_save_options(void) { - nsfont_fill_nametable(true); /* NCOS doesnt have the fancy Universal Boot vars; so select * the path to the choices file based on the build options */ #ifndef NCOS @@ -1397,7 +1396,7 @@ void ro_gui_dialog_load_themes(void) { warn_user("WimpError", error->errmess); return; } - + parent_width = state.visible.x1 - state.visible.x0; min_extent = state.visible.y0 - state.visible.y1; nested_y = 0; diff --git a/riscos/font.c b/riscos/font.c index dd26cf0ff..3b63cf633 100644 --- a/riscos/font.c +++ b/riscos/font.c @@ -2,1267 +2,273 @@ * This file is part of NetSurf, http://netsurf.sourceforge.net/ * Licensed under the GNU General Public License, * http://www.opensource.org/licenses/gpl-license - * Copyright 2004 James Bursa - * Copyright 2003 Phil Mellor - * Copyright 2004 John Tytgat - * Copyright 2004 John M Bell + * Copyright 2005 James Bursa */ /** \file * Font handling (RISC OS implementation). * - * The Font Manager is used to handle and render fonts. + * The RUfl is used handle and render fonts. */ #include -#include -#include "oslib/font.h" -#include "oslib/os.h" +#include "rufl.h" #include "netsurf/css/css.h" -#include "netsurf/desktop/gui.h" #include "netsurf/render/font.h" #include "netsurf/riscos/gui.h" #include "netsurf/riscos/options.h" -#include "netsurf/riscos/ufont.h" #include "netsurf/utils/log.h" -#include "netsurf/utils/utils.h" -#define FONT_MAX_NAME 128 /* max length of a font name */ -#define FONT_FAMILIES 6 /* Number of families */ -#define FONT_FACES 4 /* Number of faces per family */ +static void nsfont_read_style(const struct css_style *style, + const char **font_family, unsigned int *font_size, + rufl_style *font_style); -/* Font Variants */ -#define FONT_SMALLCAPS 4 - -/* Font Styles */ -#define FONT_BOLD 2 -#define FONT_SLANTED 1 - -/* Font families */ -#define FONT_DEFAULT (0 * FONT_FACES) -#define FONT_SANS_SERIF (1 * FONT_FACES) -#define FONT_SERIF (2 * FONT_FACES) -#define FONT_MONOSPACE (3 * FONT_FACES) -#define FONT_CURSIVE (4 * FONT_FACES) -#define FONT_FANTASY (5 * FONT_FACES) - -/* a font_set is just a linked list of font_data for each face for now */ -struct font_set { - struct font_data *font[FONT_FAMILIES * FONT_FACES]; -}; - -static os_error *nsfont_open_ufont(const char *fontNameP, const char *fbFontNameP, int size, int *handleP, bool *using_fb, bool log_errors); -static os_error *nsfont_open_standard(const char *fontNameP, const char *fbFontNameP, int size, int *handleP, bool *using_fb, bool log_errors); -static char *nsfont_create_font_name(char *base, int id); - -/** Table of font names. - * - * font id = font family * 4 + bold * 2 + slanted - * - * font family: 1 = sans-serif, 2 = serif, 3 = monospace, 4 = cursive, - * 5 = fantasy. - * Font family 0 must be available as it is the replacement font when - * the other font families can not be found. - */ -static char font_table[FONT_FAMILIES * FONT_FACES][FONT_MAX_NAME] = { - /* default */ /* ---bs */ -/*0*/ "Homerton.Medium", /* 00000 */ -/*1*/ "Homerton.Medium.Oblique", /* 00001 */ -/*2*/ "Homerton.Bold", /* 00010 */ -/*3*/ "Homerton.Bold.Oblique", /* 00011 */ - /* sans-serif */ -/*4*/ "Homerton.Medium", /* 00100 */ -/*5*/ "Homerton.Medium.Oblique", /* 00101 */ -/*6*/ "Homerton.Bold", /* 00110 */ -/*7*/ "Homerton.Bold.Oblique", /* 00111 */ - /* serif */ -/*8*/ "Trinity.Medium", /* 01000 */ -/*9*/ "Trinity.Medium.Italic", /* 01001 */ -/*10*/ "Trinity.Bold", /* 01010 */ -/*11*/ "Trinity.Bold.Italic", /* 01011 */ - /* monospace */ -/*12*/ "Corpus.Medium", /* 01100 */ -/*13*/ "Corpus.Medium.Oblique", /* 01101 */ -/*14*/ "Corpus.Bold", /* 01110 */ -/*15*/ "Corpus.Bold.Oblique", /* 01111 */ - /* cursive */ -/*16*/ "Churchill.Medium", /* 10000 */ -/*17*/ "Churchill.Medium.Italic", /* 10001 */ -/*18*/ "Churchill.Bold", /* 10010 */ -/*19*/ "Churchill.Bold.Italic", /* 10011 */ - /* fantasy */ -/*20*/ "Sassoon.Primary", /* 10100 */ -/*21*/ "Sassoon.Primary.Oblique", /* 10101 */ -/*22*/ "Sassoon.Primary.Bold", /* 10110 */ -/*23*/ "Sassoon.Primary.Bold.Oblique", /* 10111 */ -}; /** - * Create an empty font_set. + * Measure the width of a string. * - * \return an opaque struct font_set, or NULL on memory exhaustion + * \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 */ -struct font_set *nsfont_new_set(void) -{ - struct font_set *set; - unsigned int i; - - LOG(("nsfont_new_set()\n")); - - if ((set = malloc(sizeof(*set))) == NULL) - return NULL; - - for (i = 0; i < FONT_FAMILIES * FONT_FACES; i++) - set->font[i] = NULL; - - return set; -} -/** - * Open a font for use based on a css_style. - * - * \param set a font_set, as returned by nsfont_new_set() - * \param style a css_style which describes the font - * \return a struct font_data, with an opaque font handle in handle - * - * The set is updated to include the font, if it was not present. - */ -struct font_data *nsfont_open(struct font_set *set, struct css_style *style) +bool nsfont_width(const struct css_style *style, + const char *string, size_t length, + int *width) { - struct font_data *data; - unsigned int size = option_font_size * 1.6; - unsigned int f = 0; - int fhandle; - os_error *error; - bool using_fb; - - assert(set != NULL); - assert(style != NULL); - - if (style->font_size.size == CSS_FONT_SIZE_LENGTH) - size = (int)(css_len2px(&style->font_size.value.length, - style) * 72.0 / 90.0 * 16.); - if (size < option_font_min_size * 1.6) - size = option_font_min_size * 1.6; - if (1600 < size) - size = 1600; - - switch (style->font_family) { - case CSS_FONT_FAMILY_SANS_SERIF: - f += FONT_SANS_SERIF; - break; - case CSS_FONT_FAMILY_SERIF: - f += FONT_SERIF; - break; - case CSS_FONT_FAMILY_MONOSPACE: - f += FONT_MONOSPACE; - break; - case CSS_FONT_FAMILY_CURSIVE: - f += FONT_CURSIVE; - break; - case CSS_FONT_FAMILY_FANTASY: - f += FONT_FANTASY; - break; - default: - break; - } - /** \todo (re)implement smallcaps */ -/* switch (style->font_variant) { - case CSS_FONT_VARIANT_SMALL_CAPS: - f += FONT_SMALLCAPS; - break; - default: - break; - } -*/ - - switch (style->font_weight) { - case CSS_FONT_WEIGHT_BOLD: - case CSS_FONT_WEIGHT_600: - case CSS_FONT_WEIGHT_700: - case CSS_FONT_WEIGHT_800: - case CSS_FONT_WEIGHT_900: - f += FONT_BOLD; - break; - default: - break; - } - - switch (style->font_style) { - case CSS_FONT_STYLE_ITALIC: - case CSS_FONT_STYLE_OBLIQUE: - f += FONT_SLANTED; - break; - default: - break; + const char *font_family; + unsigned int font_size; + rufl_style font_style; + rufl_code code; + + nsfont_read_style(style, &font_family, &font_size, &font_style); + + code = rufl_width(font_family, font_style, font_size, + string, length, + width); + if (code != rufl_OK) { + if (code == rufl_FONT_MANAGER_ERROR) + LOG(("rufl_width: rufl_FONT_MANAGER_ERROR: 0x%x: %s", + rufl_fm_error->errnum, + rufl_fm_error->errmess)); + else + LOG(("rufl_width: 0x%x", code)); +/* warn_user("MiscError", "font error"); */ + return false; } - for (data = set->font[f]; data != NULL; data = data->next) - if (data->size == size) - return data; - - if ((data = malloc(sizeof(*data))) == NULL) - return NULL; - - /* Strategy : first try the UFont font code with given font name - * or the default font name if the former fails. - * If this still fails, try the use the default RISC OS font open - * in UTF-8 encoding (again first with given font name, then with - * the default font name). - * If this still fails, we repeat the previous step but now using - * the Latin 1 encoding. - */ - if (!option_font_ufont || (error = nsfont_open_ufont(font_table[f], font_table[f % 4], (int)size, &fhandle, &using_fb, true)) != NULL) { - char fontName1[FONT_MAX_NAME+10]; - char fontName2[FONT_MAX_NAME+10]; - /* Go for the UTF-8 encoding with standard FontManager */ - strcpy(fontName1, font_table[f]); - strcat(fontName1, "\\EUTF8"); - strcpy(fontName2, font_table[f % 4]); - strcat(fontName2, "\\EUTF8"); - - if ((error = nsfont_open_standard(fontName1, fontName2, (int)size, &fhandle, &using_fb, true)) != NULL) { - /* All UTF-8 font methods failed, only support Latin 1 */ - strcpy(fontName1, font_table[f]); - strcat(fontName1, "\\ELatin1"); - strcpy(fontName2, font_table[f % 4]); - strcat(fontName2, "\\ELatin1"); - - if ((error = nsfont_open_standard(fontName1, fontName2, (int)size, &fhandle, &using_fb, true)) != NULL) { - LOG(("(u)font_find_font failed : %s\n", error->errmess)); - die("(u)font_find_font failed"); - } - data->ftype = FONTTYPE_STANDARD_LATIN1; - } else - data->ftype = FONTTYPE_STANDARD_UTF8ENC; - } else - data->ftype = FONTTYPE_UFONT; - - data->id = (using_fb) ? f % 4 : f; - data->handle = fhandle; - data->size = size; - data->space_width = nsfont_width(data, " ", sizeof(" ")-1); - - data->next = set->font[f]; - set->font[f] = data; - - return data; + *width /= 2; + return true; } /** - * Open font via UFont code. + * Find the position in a string where an x coordinate falls. * - * \param fontNameP UFont font name - * \param fbFontNameP fallback UFont font name - * \param size font size - * \param handle returning UFont handle in case there isn't an error. - * \param using_fb returning whether the fallback font was used or not. - * \return error in case there was one. + * \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 os_error *nsfont_open_ufont(const char *fontNameP, const char *fbFontNameP, int size, int *handleP, bool *using_fb, bool log_errors) -{ - os_error *errorP; - *handleP = 0; *using_fb = false; - if ((errorP = xufont_find_font(fontNameP, size, size, 0, 0, (ufont_f *)handleP, NULL, NULL)) == NULL) - return NULL; - if (log_errors) - LOG(("ufont_find_font(<%s>) failed <%s> (case 1)", fontNameP, errorP->errmess)); - /* If the fallback font is the same as the first font name, return */ - if (strcmp(fontNameP, fbFontNameP) == 0) - return errorP; - *using_fb = true; - if ((errorP = xufont_find_font(fbFontNameP, size, size, 0, 0, (ufont_f *)handleP, NULL, NULL)) == NULL) - return NULL; - if (log_errors) - LOG(("ufont_find_font(<%s>) failed <%s> (case 2)", fbFontNameP, errorP->errmess)); - return errorP; -} - -/** - * Open font via standard FontManager. - * - * \param fontNameP RISC OS font name - * \param fbFontNameP fallback RISC OS font name - * \param size font size - * \param handle RISC OS handle in case there isn't an error. - * \param using_fb returning whether the fallback font was used or not. - * \return error in case there was one. - */ -static os_error *nsfont_open_standard(const char *fontNameP, const char *fbFontNameP, int size, int *handleP, bool *using_fb, bool log_errors) +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) { - os_error *errorP; - *handleP = 0; *using_fb = false; - if ((errorP = xfont_find_font(fontNameP, size, size, 0, 0, (font_f *)handleP, NULL, NULL)) == NULL) - return NULL; - if (log_errors) - LOG(("font_find_font(<%s>) failed <%s> (case 1)", fontNameP, errorP->errmess)); - /* If the fallback font is the same as the first font name, return */ - if (strcmp(fontNameP, fbFontNameP) == 0) - return errorP; - *using_fb = true; - if ((errorP = xfont_find_font(fbFontNameP, size, size, 0, 0, (font_f *)handleP, NULL, NULL)) == NULL) - return NULL; - if (log_errors) - LOG(("font_find_font(<%s>) failed <%s> (case 2)", fbFontNameP, errorP->errmess)); - return errorP; -} - - -/** - * Frees all the fonts in a font_set. - * - * \param set a font_set as returned by nsfont_new_set() - */ -void nsfont_free_set(struct font_set *set) -{ - unsigned int i; - - LOG(("nsfont_free_set()\n")); - assert(set != NULL); - - for (i = 0; i < FONT_FAMILIES * FONT_FACES; i++) { - struct font_data *data, *next; - for (data = set->font[i]; data != NULL; data = next) { - os_error *error; - next = data->next; - switch (data->ftype) { - case FONTTYPE_UFONT: - error = xufont_lose_font((ufont_f)data->handle); - break; - case FONTTYPE_STANDARD_UTF8ENC: - case FONTTYPE_STANDARD_LATIN1: - error = xfont_lose_font((font_f)data->handle); - break; - default: - assert(0); - break; - } - if (error != NULL) - LOG(("(u)font_lose_font() failed : 0x%x <%s>\n", error->errnum, error->errmess)); - free(data); - } + const char *font_family; + unsigned int font_size; + rufl_style font_style; + rufl_code code; + + nsfont_read_style(style, &font_family, &font_size, &font_style); + + code = rufl_x_to_offset(font_family, font_style, font_size, + string, length, + x * 2, char_offset, actual_x); + if (code != rufl_OK) { + if (code == rufl_FONT_MANAGER_ERROR) + LOG(("rufl_x_to_offset: rufl_FONT_MANAGER_ERROR: " + "0x%x: %s", + rufl_fm_error->errnum, + rufl_fm_error->errmess)); + else + LOG(("rufl_x_to_offset: 0x%x", code)); +/* warn_user("MiscError", "font error"); */ + return false; } - free(set); + *actual_x /= 2; + return true; } /** - * Find the width of some text in a font. + * 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 * - * \param font a font_data, as returned by nsfont_open() - * \param text string to measure - * \param length length of text - * \return width of text in pixels + * On exit, [char_offset == 0 || + * string[char_offset] == ' ' || + * char_offset == length] */ -unsigned long nsfont_width(struct font_data *font, const char *text, - size_t length) -{ - int width; - os_error *error; - - assert(font != NULL && text != NULL); - - if (length == 0) - return 0; - - switch (font->ftype) { - case FONTTYPE_UFONT: - error = xufont_scan_string((ufont_f)font->handle, - text, - font_GIVEN_FONT - | font_KERN - | font_GIVEN_LENGTH, - 0x7fffffff, 0x7fffffff, - NULL, - NULL, (int)length, - NULL, &width, NULL, NULL); - break; - case FONTTYPE_STANDARD_UTF8ENC: - error = xfont_scan_string((font_f)font->handle, - text, - font_GIVEN_FONT - | font_KERN - | font_GIVEN_LENGTH, - 0x7fffffff, 0x7fffffff, - NULL, - NULL, (int)length, - NULL, &width, NULL, NULL); - break; - case FONTTYPE_STANDARD_LATIN1: { - const char *loc_text = cnv_strn_local_enc(text, length, NULL); - if (!loc_text) - return 0; - error = xfont_scan_string((font_f)font->handle, - loc_text, - font_GIVEN_FONT - | font_KERN, - 0x7fffffff, 0x7fffffff, - NULL, - NULL, 0, - NULL, &width, NULL, NULL); - free((void *)loc_text); - break; - } - default: - assert(0); - break; +bool nsfont_split(const struct css_style *style, + const char *string, size_t length, + int x, size_t *char_offset, int *actual_x) +{ + const char *font_family; + unsigned int font_size; + rufl_style font_style; + rufl_code code; + + nsfont_read_style(style, &font_family, &font_size, &font_style); + + code = rufl_x_to_offset(font_family, font_style, font_size, + string, length, + x * 2, char_offset, actual_x); + if (code != rufl_OK) { + if (code == rufl_FONT_MANAGER_ERROR) + LOG(("rufl_x_to_offset: rufl_FONT_MANAGER_ERROR: " + "0x%x: %s", + rufl_fm_error->errnum, + rufl_fm_error->errmess)); + else + LOG(("rufl_x_to_offset: 0x%x", code)); +/* warn_user("MiscError", "font error"); */ + return false; } - if (error != NULL) { - LOG(("(u)font_scan_string failed : %s", error->errmess)); - die("nsfont_width: (u)font_scan_string failed"); + + while (*char_offset && string[*char_offset] != ' ') + (*char_offset)--; + + code = rufl_width(font_family, font_style, font_size, + string, *char_offset, + actual_x); + if (code != rufl_OK) { + if (code == rufl_FONT_MANAGER_ERROR) + LOG(("rufl_width: rufl_FONT_MANAGER_ERROR: 0x%x: %s", + rufl_fm_error->errnum, + rufl_fm_error->errmess)); + else + LOG(("rufl_width: 0x%x", code)); +/* warn_user("MiscError", "font error"); */ + return false; } - return width / 800; + *actual_x /= 2; + return true; } /** - * Find where in a string a x coordinate falls. - * - * For example, used to find where to position the caret in response to mouse - * click. + * Paint a string. * - * \param font a font_data, as returned by nsfont_open() - * \param text a string - * \param length length of text - * \param x horizontal position in pixels - * \param char_offset updated to give the offset in the string - * \param pixel_offset updated to give the coordinate of the character in pixels - * \return true on success, false on failure. + * \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 + * \param y y coordinate + * \param scale scale to apply to font size + * \param bg background colour + * \param c colour for text + * \return true on success, false on error and error reported */ -bool nsfont_position_in_string(struct font_data *font, const char *text, - size_t length, unsigned long x, - int *char_offset, int *pixel_offset) -{ - os_error *error; - font_scan_block block; - const char *split; - int x_out; - - assert(font != NULL && text != NULL); - - block.space.x = block.space.y = block.letter.x = block.letter.y = 0; - block.split_char = -1; - switch (font->ftype) { - case FONTTYPE_UFONT: - error = xufont_scan_string((ufont_f)font->handle, - text, - font_GIVEN_BLOCK - | font_GIVEN_FONT - | font_KERN - | font_RETURN_CARET_POS - | font_GIVEN_LENGTH, - x * 2 * 400, 0x7fffffff, - &block, NULL, (int)length, - (unsigned const char **)&split, - &x_out, NULL, NULL); - break; - case FONTTYPE_STANDARD_UTF8ENC: - error = xfont_scan_string((font_f)font->handle, - text, - font_GIVEN_BLOCK - | font_GIVEN_FONT - | font_KERN - | font_RETURN_CARET_POS - | font_GIVEN_LENGTH, - x * 2 * 400, 0x7fffffff, - &block, NULL, (int)length, - (char **)&split, - &x_out, NULL, NULL); - break; - case FONTTYPE_STANDARD_LATIN1: { - const ptrdiff_t *back_mapP; - const char *loc_text = cnv_strn_local_enc(text, length, &back_mapP); - if (!loc_text) - return false; - - error = xfont_scan_string((font_f)font->handle, - loc_text, - font_GIVEN_BLOCK - | font_GIVEN_FONT - | font_KERN - | font_RETURN_CARET_POS, - x * 2 * 400, 0x7fffffff, - &block, NULL, 0, - (char **)&split, - &x_out, NULL, NULL); - split = &text[back_mapP[split - loc_text]]; - free((void *)loc_text); free((void *)back_mapP); - break; - } - default: - assert(0); - break; - } - if (error != NULL) { - LOG(("(u)font_scan_string failed : %s\n", error->errmess)); -/* die("nsfont_position_in_string: (u)font_scan_string failed");*/ - return false; +bool nsfont_paint(struct css_style *style, const char *string, + size_t length, int x, int y, float scale) +{ + const char *font_family; + unsigned int font_size; + rufl_style font_style; + rufl_code code; + + nsfont_read_style(style, &font_family, &font_size, &font_style); + + code = rufl_paint(font_family, font_style, font_size * scale, + string, length, x, y); + if (code != rufl_OK) { + if (code == rufl_FONT_MANAGER_ERROR) + LOG(("rufl_width: rufl_FONT_MANAGER_ERROR: 0x%x: %s", + rufl_fm_error->errnum, + rufl_fm_error->errmess)); + else + LOG(("rufl_width: 0x%x", code)); } - - *char_offset = (int)(split - text); - *pixel_offset = x_out / 800; - return true; } /** - * Find where to split a string to fit in a width. - * - * For example, used when wrapping paragraphs. + * Convert a css_style to a font family, size and rufl_style. * - * \param font a font_data, as returned by nsfont_open() - * \param text string to split - * \param length length of text - * \param width available width - * \param used_width updated to actual width used - * \return pointer to character which does not fit + * \param style css_style for this text, with style->font_size.size == + * CSS_FONT_SIZE_LENGTH + * \param font_family updated to font family + * \param font_size updated to font size + * \param font_style updated to font style */ -char *nsfont_split(struct font_data *font, const char *text, - size_t length, unsigned int width, unsigned int *used_width) -{ - os_error *error; - font_scan_block block; - const char *split; - assert(font != NULL && text != NULL); +void nsfont_read_style(const struct css_style *style, + const char **font_family, unsigned int *font_size, + rufl_style *font_style) +{ + *font_family = "Homerton"; - block.space.x = block.space.y = block.letter.x = block.letter.y = 0; - block.split_char = ' '; + assert(style->font_size.size == CSS_FONT_SIZE_LENGTH); + *font_size = css_len2px(&style->font_size.value.length, style) * + 72.0 / 90.0 * 16.; + if (*font_size < option_font_min_size * 1.6) + *font_size = option_font_min_size * 1.6; + if (1600 < *font_size) + *font_size = 1600; - switch (font->ftype) { - case FONTTYPE_UFONT: - error = xufont_scan_string((ufont_f)font->handle, - text, - font_GIVEN_BLOCK - | font_GIVEN_FONT - | font_KERN - | font_GIVEN_LENGTH, - width * 2 * 400, 0x7fffffff, - &block, - NULL, - (int)length, - (unsigned const char **)&split, - used_width, NULL, NULL); + switch (style->font_style) { + case CSS_FONT_STYLE_ITALIC: + case CSS_FONT_STYLE_OBLIQUE: + *font_style = rufl_SLANTED; break; - case FONTTYPE_STANDARD_UTF8ENC: - error = xfont_scan_string((font_f)font->handle, - text, - font_GIVEN_BLOCK - | font_GIVEN_FONT - | font_KERN - | font_GIVEN_LENGTH, - width * 2 * 400, 0x7fffffff, - &block, - NULL, - (int)length, - (char **)&split, - used_width, NULL, NULL); + default: + *font_style = rufl_REGULAR; break; - case FONTTYPE_STANDARD_LATIN1: { - const ptrdiff_t *back_mapP; - const char *loc_text = cnv_strn_local_enc(text, length, &back_mapP); - if (!loc_text) - return NULL; + } - error = xfont_scan_string((font_f)font->handle, - loc_text, - font_GIVEN_BLOCK - | font_GIVEN_FONT - | font_KERN, - width * 2 * 400, 0x7fffffff, - &block, - NULL, - 0, - (char **)&split, - used_width, NULL, NULL); - split = &text[back_mapP[split - loc_text]]; - free((void *)loc_text); free((void *)back_mapP); + switch (style->font_weight) { + case CSS_FONT_WEIGHT_BOLD: + case CSS_FONT_WEIGHT_600: + case CSS_FONT_WEIGHT_700: + case CSS_FONT_WEIGHT_800: + case CSS_FONT_WEIGHT_900: + *font_style += rufl_BOLD; break; - } default: - assert(0); break; } - if (error != NULL) { - LOG(("(u)font_scan_string failed : %s\n", error->errmess)); - die("nsfont_split: (u)font_scan_string failed"); - } - - assert(split == &text[length] || *split == ' ' || *split == '\t'); - - *used_width = *used_width / 2 / 400; - - return (char*)split; } -bool nsfont_paint(struct font_data *data, const char *text, - size_t length, int xpos, int ypos, void *trfm) -{ - os_error *error; - unsigned int flags; - const int var_input[3] = {136, 137, -1}; /* XOrig, YOrig, Terminator */ - int var_output[3]; - bool background_blending = option_background_blending; - - flags = font_OS_UNITS | font_GIVEN_FONT | font_KERN; - if (trfm != NULL) - flags |= font_GIVEN_TRFM; - - /* font background blending (RO3.7+) */ - if (ro_gui_current_redraw_gui) - background_blending = ro_gui_current_redraw_gui->option.background_blending; - if (background_blending) { - int version; - - /* Font manager versions below 3.35 complain - * about this flag being set. - */ - error = xfont_cache_addr(&version, 0, 0); - /**\todo should we do anything else on error? */ - if (!error && version >= 335) - flags |= font_BLEND_FONT; - } - - assert(data != NULL); - assert(text != NULL); - - /* adjust by the origin - * (not if printing as the result is undefined) - */ - if (!print_active) { - xos_read_vdu_variables((const os_vdu_var_list *)&var_input, - (int *)&var_output); - xpos += var_output[0]; - ypos += var_output[1]; - } - - - switch (data->ftype) { - case FONTTYPE_UFONT: - flags |= font_GIVEN_LENGTH; - error = xufont_paint((ufont_f)data->handle, text, - flags, xpos, ypos, NULL, - trfm, length); - break; - case FONTTYPE_STANDARD_UTF8ENC: - flags |= font_GIVEN_LENGTH; - error = xfont_paint((font_f)data->handle, text, - flags, xpos, ypos, NULL, - trfm, length); - break; - case FONTTYPE_STANDARD_LATIN1: { - const char *loc_text = cnv_strn_local_enc(text, length, NULL); - if (!loc_text) - return false; - - error = xfont_paint((font_f)data->handle, loc_text, - flags, xpos, ypos, NULL, - trfm, 0); - free((void *)loc_text); - break; - } - default: - assert(0); - break; - } - if (error != NULL) { - LOG(("(u)font_paint failed : %s\n", error->errmess)); - /*die("nsfont_paint: (u)font_paint failed");*/ - return false; - } - return true; -} -/** - * Given a text line, return the number of bytes which can be set using - * one RISC OS font and the bounding box fitting that part of the text - * only. - * - * \param font a font_data, as returned by nsfont_open() - * \param text string text. Does not have to be NUL terminated. - * \param length length in bytes of the text to consider. - * \param width returned width of the text which can be set with one RISC OS font. If 0, then error happened or initial text length was 0. - * \param rofontname returned name of the RISC OS font which can be used to set the text. If NULL, then error happened or initial text length was 0. - * \param rotext returned string containing the characters in returned RISC OS font. Not necessary NUL terminated. free() after use. If NULL, then error happened or initial text length was 0. - * \param rolength length of return rotext string. If 0, then error happened or initial text length was 0. - * \param consumed number of bytes of the given text which can be set with one RISC OS font. If 0, then error happened or initial text length was 0. - */ -void nsfont_txtenum(struct font_data *font, const char *text, +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) -{ - static char *fontname[FONT_MAX_NAME]; /** \todo: not nice */ - - assert(font != NULL && text != NULL && rofontname != NULL && rotext != NULL && rolength != NULL && consumed != NULL); - - *rotext = *rofontname = NULL; - *consumed = *rolength = *width = 0; - - if (length == 0) - return; - - switch (font->ftype) { - case FONTTYPE_UFONT: - (void)xufont_txtenum((ufont_f)font->handle, - text, - font_GIVEN_FONT - | font_KERN - | font_GIVEN_LENGTH, - length, - (int *)width, - (unsigned const char **)rofontname, - (unsigned const char **)rotext, - rolength, - consumed); - *width /= 800; - break; - case FONTTYPE_STANDARD_UTF8ENC: { - int rowidth; - os_error *error; - - error = xfont_scan_string((font_f)font->handle, - text, - font_GIVEN_FONT - | font_KERN - | font_GIVEN_LENGTH, - 0x7fffffff, 0x7fffffff, - NULL, - NULL, (int)length, - NULL, &rowidth, NULL, NULL); - if (error != NULL) - return; - - strcpy(fontname, font_table[font->id]); - strcat(fontname, "\\EUTF8"); - if ((*rotext = strndup(text, length)) == NULL) - return; - *rolength = length; - *rofontname = fontname; - *consumed = length; - *width = (unsigned int)rowidth / 800; - break; - } - case FONTTYPE_STANDARD_LATIN1: { - int rowidth; - os_error *error; - - if ((*rotext = cnv_strn_local_enc(text, length, NULL)) == NULL) - return; - - error = xfont_scan_string((font_f)font->handle, - *rotext, - font_GIVEN_FONT - | font_KERN, - 0x7fffffff, 0x7fffffff, - NULL, - NULL, 0, - NULL, &rowidth, NULL, NULL); - if (error != NULL) { - free((void *)*rotext); *rotext = NULL; - return; - } - *rolength = strlen(*rotext); - strcpy(fontname, font_table[font->id]); - strcat(fontname, "\\ELatin1"); - *rofontname = fontname; - *consumed = length; - *width = (unsigned int)rowidth / 800; - break; - } - default: - assert(0); - break; - } -} - -/** - * Fill in the font_table, based on the user's options - * - * \param force_rescan Indicate whether to rescan font names - * and update options - */ -void nsfont_fill_nametable(bool force_rescan) -{ - int i; - char *name = NULL, *created = NULL; - - for (i = 0; i != FONT_FAMILIES * FONT_FACES; i++) { - /* read the relevant option string */ - switch (i) { - /* default */ - case FONT_DEFAULT: - name = option_font_default; - break; - case FONT_DEFAULT + FONT_SLANTED: - name = option_font_default_italic; - break; - case FONT_DEFAULT + FONT_BOLD: - name = option_font_default_bold; - break; - case FONT_DEFAULT + FONT_BOLD + FONT_SLANTED: - name = option_font_default_bold_italic; - break; - /* sans */ - case FONT_SANS_SERIF: - name = option_font_sans; - break; - case FONT_SANS_SERIF + FONT_SLANTED: - name = option_font_sans_italic; - break; - case FONT_SANS_SERIF + FONT_BOLD: - name = option_font_sans_bold; - break; - case FONT_SANS_SERIF + FONT_BOLD + FONT_SLANTED: - name = option_font_sans_bold_italic; - break; - /* serif */ - case FONT_SERIF: - name = option_font_serif; - break; - case FONT_SERIF + FONT_SLANTED: - name = option_font_serif_italic; - break; - case FONT_SERIF + FONT_BOLD: - name = option_font_serif_bold; - break; - case FONT_SERIF + FONT_BOLD + FONT_SLANTED: - name = option_font_serif_bold_italic; - break; - /* mono */ - case FONT_MONOSPACE: - name = option_font_mono; - break; - case FONT_MONOSPACE + FONT_SLANTED: - name = option_font_mono_italic; - break; - case FONT_MONOSPACE + FONT_BOLD: - name = option_font_mono_bold; - break; - case FONT_MONOSPACE + FONT_BOLD + FONT_SLANTED: - name = option_font_mono_bold_italic; - break; - /* cursive */ - case FONT_CURSIVE: - name = option_font_cursive; - break; - case FONT_CURSIVE + FONT_SLANTED: - name = option_font_cursive_italic; - break; - case FONT_CURSIVE + FONT_BOLD: - name = option_font_cursive_bold; - break; - case FONT_CURSIVE + FONT_BOLD + FONT_SLANTED: - name = option_font_cursive_bold_italic; - break; - /* fantasy */ - case FONT_FANTASY: - name = option_font_fantasy; - break; - case FONT_FANTASY + FONT_SLANTED: - name = option_font_fantasy_italic; - break; - case FONT_FANTASY + FONT_BOLD: - name = option_font_fantasy_bold; - break; - case FONT_FANTASY + FONT_BOLD + FONT_SLANTED: - name = option_font_fantasy_bold_italic; - break; - } - - if ((!force_rescan || (force_rescan && i == ((i / FONT_FACES) * FONT_FACES))) && name && name[0] != '\0') { - /* got a configured font name => use it */ - strncpy(font_table[i], name, FONT_MAX_NAME); - } - else { - char *dot, *next_segment; - - /* no configured name => try to create one */ - - /* get the base font for the family */ - name = strdup(font_table[(i/FONT_FACES)*FONT_FACES]); - next_segment = name; - - do { - dot = strchr(next_segment, '.'); - - /* restore '.' */ - if (next_segment != name) - *(next_segment-1) = '.'; - - if (dot) { - *dot = '\0'; - next_segment = dot+1; - } - - created = nsfont_create_font_name(name, i); - - } while(!created && dot); - - /* now fill in the table entry */ - if (created) { - strncpy(font_table[i], created, - FONT_MAX_NAME); - free(created); - } - - free(name); - - /* don't modify options if not rescanning */ - if (!force_rescan) - continue; - - /* write the relevant option string */ - switch (i) { - /* default */ - case FONT_DEFAULT: - if (option_font_default) - free(option_font_default); - option_font_default = strdup(font_table[i]); - break; - case FONT_DEFAULT + FONT_SLANTED: - if (option_font_default_italic) - free(option_font_default_italic); - option_font_default_italic = strdup(font_table[i]); - break; - case FONT_DEFAULT + FONT_BOLD: - if (option_font_default_bold) - free(option_font_default_bold); - option_font_default_bold = strdup(font_table[i]); - break; - case FONT_DEFAULT + FONT_BOLD + FONT_SLANTED: - if (option_font_default_bold_italic) - free(option_font_default_bold_italic); - option_font_default_bold_italic = strdup(font_table[i]); - break; - /* sans */ - case FONT_SANS_SERIF: - if (option_font_sans) - free(option_font_sans); - option_font_sans = strdup(font_table[i]); - break; - case FONT_SANS_SERIF + FONT_SLANTED: - if (option_font_sans_italic) - free(option_font_sans_italic); - option_font_sans_italic = strdup(font_table[i]); - break; - case FONT_SANS_SERIF + FONT_BOLD: - if (option_font_sans_bold) - free(option_font_sans_bold); - option_font_sans_bold = strdup(font_table[i]); - break; - case FONT_SANS_SERIF + FONT_BOLD + FONT_SLANTED: - if (option_font_sans_bold_italic) - free(option_font_sans_bold_italic); - option_font_sans_bold_italic = strdup(font_table[i]); - break; - /* serif */ - case FONT_SERIF: - if (option_font_serif) - free(option_font_serif); - option_font_serif = strdup(font_table[i]); - break; - case FONT_SERIF + FONT_SLANTED: - if (option_font_serif_italic) - free(option_font_serif_italic); - option_font_serif_italic = strdup(font_table[i]); - break; - case FONT_SERIF + FONT_BOLD: - if (option_font_serif_bold) - free(option_font_serif_bold); - option_font_serif_bold = strdup(font_table[i]); - break; - case FONT_SERIF + FONT_BOLD + FONT_SLANTED: - if (option_font_serif_bold_italic) - free(option_font_serif_bold_italic); - option_font_serif_bold_italic = strdup(font_table[i]); - break; - /* mono */ - case FONT_MONOSPACE: - if (option_font_mono) - free(option_font_mono); - option_font_mono = strdup(font_table[i]); - break; - case FONT_MONOSPACE + FONT_SLANTED: - if (option_font_mono_italic) - free(option_font_mono_italic); - option_font_mono_italic = strdup(font_table[i]); - break; - case FONT_MONOSPACE + FONT_BOLD: - if (option_font_mono_bold) - free(option_font_mono_bold); - option_font_mono_bold = strdup(font_table[i]); - break; - case FONT_MONOSPACE + FONT_BOLD + FONT_SLANTED: - if (option_font_mono_bold_italic) - free(option_font_mono_bold_italic); - option_font_mono_bold_italic = strdup(font_table[i]); - break; - /* cursive */ - case FONT_CURSIVE: - if (option_font_cursive) - free(option_font_cursive); - option_font_cursive = strdup(font_table[i]);; - break; - case FONT_CURSIVE + FONT_SLANTED: - if (option_font_cursive_italic) - free(option_font_cursive_italic); - option_font_cursive_italic = strdup(font_table[i]); - break; - case FONT_CURSIVE + FONT_BOLD: - if (option_font_cursive_bold) - free(option_font_cursive_bold); - option_font_cursive_bold = strdup(font_table[i]); - break; - case FONT_CURSIVE + FONT_BOLD + FONT_SLANTED: - if (option_font_cursive_bold_italic) - free(option_font_cursive_bold_italic); - option_font_cursive_bold_italic = strdup(font_table[i]); - break; - /* fantasy */ - case FONT_FANTASY: - if (option_font_fantasy) - free(option_font_fantasy); - option_font_fantasy = strdup(font_table[i]); - break; - case FONT_FANTASY + FONT_SLANTED: - if (option_font_fantasy_italic) - free(option_font_fantasy_italic); - option_font_fantasy_italic = strdup(font_table[i]); - break; - case FONT_FANTASY + FONT_BOLD: - if (option_font_fantasy_bold) - free(option_font_fantasy_bold); - option_font_fantasy_bold = strdup(font_table[i]); - break; - case FONT_FANTASY + FONT_BOLD + FONT_SLANTED: - if (option_font_fantasy_bold_italic) - free(option_font_fantasy_bold_italic); - option_font_fantasy_bold_italic = strdup(font_table[i]); - break; - } - } - } -} - -/* lookup table used by nsfont_create_font_name. - * Italic entries *must* precede bold entries - */ -static const char *style_lookup[] = { -#define ITALIC_COUNT 3 - "Italic", "Oblique", "Slant", -#define BOLD_COUNT 5 - "Bold", "Demi", "ExtraBold", "Ultra", "Heavy" -}; - -/** - * Create a valid font name, testing for presence on the system - * - * \param base The base name - * \param id The id of the font (entry into font_table) - * \return The font name, or NULL on failure - */ -char *nsfont_create_font_name(char *base, int id) -{ - char *created, tempname[FONT_MAX_NAME+10]; - int bold, italic; - os_error *error; - int fhandle; - bool using_fb, found = false; - - created = malloc(FONT_MAX_NAME); - if (!created) - return NULL; - - /* Font presence testing strategy is as-per nsfont_open */ - - /* try bold-italic first */ - if ((id & FONT_BOLD) && (id & FONT_SLANTED)) { - for (bold = 0; bold != BOLD_COUNT; bold++) { - for (italic = 0; italic != ITALIC_COUNT; italic++) { - snprintf(created, FONT_MAX_NAME, - "%s.%s.%s", base, - style_lookup[bold+ITALIC_COUNT], - style_lookup[italic]); - - /* try ufont first */ - if (option_font_ufont && (error = nsfont_open_ufont(created, created, 160, &fhandle, &using_fb, false)) == NULL) { - xufont_lose_font((ufont_f)fhandle); - found = true; - break; - } - - /* then UTF8 encoding */ - strcpy(tempname, created); - strcat(tempname, "\\EUTF8"); - if ((error = nsfont_open_standard(tempname, tempname, 160, &fhandle, &using_fb, false)) == NULL) { - xfont_lose_font((font_f)fhandle); - found = true; - break; - } - - /* then Latin1 */ - strcpy(tempname, created); - strcat(tempname, "\\ELatin1"); - if ((error = nsfont_open_standard(tempname, tempname, 160, &fhandle, &using_fb, false)) == NULL) { - xfont_lose_font((font_f)fhandle); - found = true; - break; - } - } - if (found) - break; - } - } - /* bold */ - else if (id & FONT_BOLD) { - for (bold = 0; bold != BOLD_COUNT; bold++) { - snprintf(created, FONT_MAX_NAME, "%s.%s", base, - style_lookup[bold+ITALIC_COUNT]); - - /* try ufont first */ - if (option_font_ufont && (error = nsfont_open_ufont(created, created, 160, &fhandle, &using_fb, false)) == NULL) { - xufont_lose_font((ufont_f)fhandle); - found = true; - break; - } - - /* then UTF8 encoding */ - strcpy(tempname, created); - strcat(tempname, "\\EUTF8"); - if ((error = nsfont_open_standard(tempname, tempname, 160, &fhandle, &using_fb, false)) == NULL) { - xfont_lose_font((font_f)fhandle); - found = true; - break; - } - - /* then Latin1 */ - strcpy(tempname, created); - strcat(tempname, "\\ELatin1"); - if ((error = nsfont_open_standard(tempname, tempname, 160, &fhandle, &using_fb, false)) == NULL) { - xfont_lose_font((font_f)fhandle); - found = true; - break; - } - } - } - /* italic */ - else if (id & FONT_SLANTED) { - for (italic = 0; italic != ITALIC_COUNT; italic++) { - snprintf(created, FONT_MAX_NAME, "%s.%s", base, - style_lookup[italic]); - - /* try ufont first */ - if (option_font_ufont && (error = nsfont_open_ufont(created, created, 160, &fhandle, &using_fb, false)) == NULL) { - xufont_lose_font((ufont_f)fhandle); - found = true; - break; - } - - /* then UTF8 encoding */ - strcpy(tempname, created); - strcat(tempname, "\\EUTF8"); - if ((error = nsfont_open_standard(tempname, tempname, 160, &fhandle, &using_fb, false)) == NULL) { - xfont_lose_font((font_f)fhandle); - found = true; - break; - } - - /* then Latin1 */ - strcpy(tempname, created); - strcat(tempname, "\\ELatin1"); - if ((error = nsfont_open_standard(tempname, tempname, 160, &fhandle, &using_fb, false)) == NULL) { - xfont_lose_font((font_f)fhandle); - found = true; - break; - } - } - } - - if (found) - return created; - - free(created); - return NULL; -} - - -/** - * Reopens all font handles to the current screen resolution - */ -void nsfont_reopen_set(struct font_set *fonts) { - os_error *error; - char fontName1[FONT_MAX_NAME+10]; - char fontName2[FONT_MAX_NAME+10]; - struct font_data *f; - bool using_fb; - - for (int i = 0; i < (FONT_FAMILIES * FONT_FACES); i++) { - for (f = fonts->font[i]; f; f = f->next) { - switch (f->ftype) { - case FONTTYPE_UFONT: - error = xufont_lose_font((ufont_f)f->handle); - if (error) { - LOG(("xufont_lose_font: 0x%x: %s", - error->errnum, error->errmess)); - } - error = nsfont_open_ufont(font_table[f->id], font_table[f->id % 4], - (int)f->size, &f->handle, &using_fb, true); - if (error) { - LOG(("nsfont_open_ufont: 0x%x: %s", - error->errnum, error->errmess)); - } - break; - case FONTTYPE_STANDARD_LATIN1: - error = xfont_lose_font((font_f)f->handle); - if (error) { - LOG(("xfont_lose_font: 0x%x: %s", - error->errnum, error->errmess)); - } - strcpy(fontName1, font_table[f->id]); - strcat(fontName1, "\\ELatin1"); - strcpy(fontName2, font_table[f->id % 4]); - strcat(fontName2, "\\ELatin1"); - error = nsfont_open_standard(fontName1, fontName2, (int)f->size, - &f->handle, &using_fb, true); - if (error) { - LOG(("nsfont_open_standard: 0x%x: %s", - error->errnum, error->errmess)); - } - break; - case FONTTYPE_STANDARD_UTF8ENC: - error = xfont_lose_font((font_f)f->handle); - if (error) { - LOG(("xfont_lose_font: 0x%x: %s", - error->errnum, error->errmess)); - } - strcpy(fontName1, font_table[f->id]); - strcat(fontName1, "\\EUTF8"); - strcpy(fontName2, font_table[f->id % 4]); - strcat(fontName2, "\\EUTF8"); - error = nsfont_open_standard(fontName1, fontName2, (int)f->size, - &f->handle, &using_fb, true); - if (error) { - LOG(("nsfont_open_standard: 0x%x: %s", - error->errnum, error->errmess)); - } - break; - } - f->space_width = nsfont_width(f, " ", sizeof(" ")-1); - } - } -} + size_t *consumed) { } diff --git a/riscos/gui.c b/riscos/gui.c index 0f64d0e80..d3b3f3fab 100644 --- a/riscos/gui.c +++ b/riscos/gui.c @@ -33,6 +33,7 @@ #include "oslib/wimp.h" #include "oslib/wimpspriteop.h" #include "oslib/uri.h" +#include "rufl.h" #include "netsurf/content/url_store.h" #include "netsurf/utils/config.h" #include "netsurf/desktop/gui.h" @@ -223,7 +224,7 @@ void gui_init(int argc, char** argv) option_theme = strdup("Aletheia"); /* default for no options */ ro_gui_choose_language(); - + url_store_load("Choices:WWW.NetSurf.URL"); NETSURF_DIR = getenv("NetSurf$Dir"); @@ -258,7 +259,9 @@ void gui_init(int argc, char** argv) #ifndef ncos ro_gui_check_fonts(); #endif - nsfont_fill_nametable(false); + + /** \todo handle errors */ + rufl_init(); /* Issue a *Desktop to poke AcornURI into life */ if (getenv("NetSurf$Start_URI_Handler")) @@ -560,6 +563,7 @@ void gui_quit(void) ro_gui_global_history_save(); ro_gui_hotlist_save(); ro_gui_history_quit(); + rufl_quit(); free(gui_sprites); xwimp_close_down(task_handle); free(default_stylesheet_url); @@ -572,7 +576,7 @@ void gui_quit(void) * Handles a signal */ static void gui_signal(int sig) { - ro_gui_cleanup(); + ro_gui_cleanup(); raise(sig); } @@ -1078,7 +1082,6 @@ void ro_gui_keypress(wimp_key *key) void ro_gui_user_message(wimp_event_no event, wimp_message *message) { - struct content *c; switch (message->action) { case message_HELP_REQUEST: ro_gui_interactive_help_request(message); @@ -1125,11 +1128,7 @@ void ro_gui_user_message(wimp_event_no event, wimp_message *message) break; case message_MODE_CHANGE: ro_gui_history_mode_change(); - for (c = content_list; c; c = c->next) { - if ((c->type == CONTENT_HTML) && - (c->data.html.fonts)) - nsfont_reopen_set(c->data.html.fonts); - } + rufl_invalidate_cache(); break; #ifdef WITH_URI diff --git a/riscos/gui.h b/riscos/gui.h index 43a7b9e85..4e2921056 100644 --- a/riscos/gui.h +++ b/riscos/gui.h @@ -249,6 +249,10 @@ void ro_gui_print_open(struct gui_window *g, int x, int y, bool sub_menu, bool k void ro_gui_print_click(wimp_pointer *pointer); bool ro_gui_print_keypress(wimp_key *key); +/* in font.c */ +bool nsfont_paint(struct css_style *style, const char *string, + size_t length, int x, int y, float scale); + /* in plotters.c */ extern const struct plotter_table ro_plotters; extern int ro_plot_origin_x; diff --git a/riscos/plotters.c b/riscos/plotters.c index 7fea7affc..d2f8d52a8 100644 --- a/riscos/plotters.c +++ b/riscos/plotters.c @@ -31,7 +31,7 @@ static bool ro_plot_polygon(int *p, unsigned int n, colour fill); static bool ro_plot_fill(int x0, int y0, int x1, int y1, colour c); static bool ro_plot_clip(int clip_x0, int clip_y0, int clip_x1, int clip_y1); -static bool ro_plot_text(int x, int y, struct font_data *font, +static bool ro_plot_text(int x, int y, struct css_style *style, const char *text, size_t length, colour bg, colour c); static bool ro_plot_disc(int x, int y, int radius, colour colour); static bool ro_plot_bitmap(int x, int y, int width, int height, @@ -62,11 +62,7 @@ const struct plotter_table ro_plotters = { int ro_plot_origin_x = 0; int ro_plot_origin_y = 0; - -os_trfm ro_plot_trfm = { { - { 0x10000, 0 }, - { 0, 0x10000, }, - { 0, 0 } } }; +float ro_plot_scale = 1.0; bool ro_plot_clg(colour c) @@ -300,22 +296,23 @@ bool ro_plot_clip(int clip_x0, int clip_y0, } -bool ro_plot_text(int x, int y, struct font_data *font, +bool ro_plot_text(int x, int y, struct css_style *style, const char *text, size_t length, colour bg, colour c) { os_error *error; - error = xcolourtrans_set_font_colours(font->handle, + error = xcolourtrans_set_font_colours(font_CURRENT, bg << 8, c << 8, 14, 0, 0, 0); if (error) { LOG(("xcolourtrans_set_font_colours: 0x%x: %s", error->errnum, error->errmess)); return false; } - return nsfont_paint(font, text, length, + + return nsfont_paint(style, text, length, ro_plot_origin_x + x * 2, ro_plot_origin_y - y * 2, - &ro_plot_trfm); + ro_plot_scale); } @@ -395,6 +392,5 @@ bool ro_plot_group_end(void) void ro_plot_set_scale(float scale) { - ro_plot_trfm.entries[0][0] = ro_plot_trfm.entries[1][1] = - scale * 0x10000; + ro_plot_scale = scale; } diff --git a/riscos/print.c b/riscos/print.c index d4931e9d0..dcd0c2c8b 100644 --- a/riscos/print.c +++ b/riscos/print.c @@ -750,7 +750,7 @@ bool print_find_fonts(struct box *box, struct print_font **print_fonts, int *fon int i; assert(box); - +#if 0 if (box->text && box->font && box->length > 0) { txt = box->text; txt_len = box->length; @@ -794,7 +794,7 @@ bool print_find_fonts(struct box *box, struct print_font **print_fonts, int *fon if (!print_find_fonts(a, print_fonts, font_count)) return false; } - +#endif return true; } diff --git a/riscos/save_draw.c b/riscos/save_draw.c index 51f6a0e36..e8b4dd34a 100644 --- a/riscos/save_draw.c +++ b/riscos/save_draw.c @@ -87,7 +87,7 @@ static bool draw_plot_polygon(int *p, unsigned int n, colour fill); static bool draw_plot_fill(int x0, int y0, int x1, int y1, colour c); static bool draw_plot_clip(int clip_x0, int clip_y0, int clip_x1, int clip_y1); -static bool draw_plot_text(int x, int y, struct font_data *font, +static bool draw_plot_text(int x, int y, struct css_style *style, const char *text, size_t length, colour bc, colour colour); static bool draw_plot_disc(int x, int y, int radius, colour colour); static bool draw_plot_bitmap(int x, int y, int width, int height, @@ -858,9 +858,10 @@ bool draw_plot_clip(int clip_x0, int clip_y0, int clip_x1, int clip_y1) * \param colour the text colour * \return true on success, false on error (error got reported) */ -bool draw_plot_text(int x, int y, struct font_data *font, +bool draw_plot_text(int x, int y, struct css_style *style, const char *text, size_t length, colour bc, colour colour) { +#if 0 while (length != 0) { size_t width, rolength, consumed; const char *rofontname, *rotext; @@ -912,6 +913,7 @@ bool draw_plot_text(int x, int y, struct font_data *font, text += consumed; length -= consumed; } +#endif return true; } diff --git a/riscos/thumbnail.c b/riscos/thumbnail.c index 091f43bfc..e28cdf7e5 100644 --- a/riscos/thumbnail.c +++ b/riscos/thumbnail.c @@ -15,6 +15,7 @@ #include #include +#include "rufl.h" #include "oslib/colourtrans.h" #include "oslib/osfile.h" #include "oslib/osspriteop.h" @@ -112,15 +113,11 @@ void thumbnail_create(struct content *content, osspriteop_area *area, colourtrans_set_gcol(os_COLOUR_WHITE, colourtrans_SET_BG, os_ACTION_OVERWRITE, 0); os_clg(); - if ((content->type == CONTENT_HTML) && - (content->data.html.fonts)) - nsfont_reopen_set(content->data.html.fonts); + rufl_invalidate_cache(); content_redraw(content, 0, 0, width, height, 0, 0, width, height, scale, 0xFFFFFF); thumbnail_restore_output(save_area); - if ((content->type == CONTENT_HTML) && - (content->data.html.fonts)) - nsfont_reopen_set(content->data.html.fonts); + rufl_invalidate_cache(); /* Go back from 32bpp to [n]bpp if we should. */ diff --git a/riscos/ufont.c b/riscos/ufont.c deleted file mode 100644 index 9cedcd79a..000000000 --- a/riscos/ufont.c +++ /dev/null @@ -1,1273 +0,0 @@ -/* ufont.c - * Licensed under the GNU General Public License, - * http://www.opensource.org/licenses/gpl-license - * Copyright 2000 James Bursa - * Copyright 2004 John Tytgat - */ - -/** \file - * UFont - Unicode wrapper for non-Unicode aware FontManager - * - * This code allows non-Unicode aware FontManager to be used for - * displaying Unicode encoded text lines. It needs the !UFont - * resource (accessed via UFont$Path). - */ - -#include -#include -#include - -#include "oslib/osfile.h" - -#include "ufont.h" - -// #define DEBUG_UFONT -// #define DEBUG_ACTIVATE_SANITY_CHECK -// #define DEBUG_DUMP_INTERNALS - -#ifdef DEBUG_UFONT -# define dbg_fprintf fprintf -#else -# define dbg_fprintf (1)?0:fprintf -#endif -#ifdef DEBUG_ACTIVATE_SANITY_CHECK -# define do_sanity_check sanity_check -#else -# define do_sanity_check (1)?0:sanity_check -#endif -#define MALLOC_CHUNK 256 - -typedef struct usage_chain_s usage_chain_t; -typedef struct virtual_fh_s virtual_fh_t; -/* Virtual font handle : - */ -struct virtual_fh_s - { - const char *fontNameP; /* => malloc'ed block holding RISC OS font name */ - int xsize, ysize; /* font size */ - int xres, yres; /* requested or actual resolution */ - unsigned int usage; /* the higher, the more this font handle is used for setting its glyphs */ - unsigned int refCount; /* number of times this struct is refered from ufont_f element */ - usage_chain_t *usageP; /* Ptr to element usage chain; if non NULL, we have a RISC OS font handle allocated. When refCount is 0, this is not necessary NULL. */ - }; -#define kInitialFHArraySize 20 -static virtual_fh_t *oVirtualFHArrayP; -static size_t oCurVirtualFHArrayElems; -static size_t oMaxVirtualFHArrayElems; - -/* Usage chain (one element per open RISC OS font handle) : - */ -struct usage_chain_s - { - usage_chain_t *nextP; - usage_chain_t *prevP; - - size_t chainTimer; /* When equal to oChainTimer, you can not throw this element out the chain. */ - font_f ro_fhandle; /* RISC OS font handle (garanteed non zero) */ - virtual_fh_t *virFHP; - }; - -typedef struct ufont_map_s ufont_map_t; - -struct ufont_map_s - { - byte fontnr[65536]; /* Must be 1st (comes straight from 'Data' file). Each entry is an index in the virtual_font_index array. */ - byte character[65536]; /* Must be 2nd (comes straight from 'Data' file) */ - - const char *uFontNameP; /* => malloc'ed block holding UFont name */ - unsigned int refCount; - ufont_map_t *nextP; - }; -static const ufont_map_t *oMapCollectionP; - -struct ufont_font - { - ufont_map_t *mapP; - unsigned int virtual_handles_used; /* Number of filled virtual_font_index[] elements */ - size_t virtual_font_index[256]; /* Index in the oVirtualFHArrayP */ - }; - -/* Walking the chain starting with oUsageChain->nextP and continuing via - * ->nextP until reaching oUsageChain again, results in equal or - * decreasing ->virFHP->usage values. - * Also walking the chain starting with oUsageChain->prevP and continuing - * via ->prevP until reaching oUsageChain again, results in equal or - * increasing ->virFHP->usage values. - */ -static usage_chain_t oUsageChain; -static size_t oCurUsageChainElems; -/* Maximum number of RISC OS handles open by UFont : - */ -#define kMaxUsageChainElems 80 -static size_t oChainTimer; - -static os_error *create_map(const char *fontNameP, const ufont_map_t **mapPP); -static os_error *delete_map(ufont_map_t *mapP); -static int eat_utf8(wchar_t *pwc, const byte *s, int n); -static os_error *addref_virtual_fonthandle(const char *fontNameP, int xsize, int ysize, int xres, int yres, int *xresOutP, int *yresOutP, size_t *offsetP); -static os_error *deref_virtual_fonthandle(size_t offset); -static os_error *activate_virtual_fh(virtual_fh_t *virFHP); -static os_error *remove_usage_chain_elem(usage_chain_t *usageElemP); -static void repos_usage_chain_elem(usage_chain_t *usageElemP); -static const char *get_rofontname(font_f rofhandle); -#ifdef DEBUG_DUMP_INTERNALS -static void dump_internals(void); -#endif -static int sanity_check(const char *testMsgP); - -/* UFont error messages : - */ -static os_error error_badparams = { error_BAD_PARAMETERS, "Bad parameters" }; -static os_error error_exists = { error_FONT_NOT_FOUND, "UFont Fonts/Data file not found" }; -static os_error error_memory = { error_FONT_NO_ROOM, "Insufficient memory for font" }; -static os_error error_size = { error_FONT_BAD_FONT_FILE, "Wrong size of font file" }; -static os_error error_fnt_corrupt = { 1 /** \todo */, "UFont is corrupt" }; -static os_error error_toomany_handles = { 2 /** \todo */, "Too many UFont handles are needed to fulfill current request" }; -static os_error error_noufont = { 3 /** \todo */, "Unable to find UFont font" }; -static os_error error_badrohandle = { 4 /** \todo */, "Invalid internal RISC OS font handle" }; - -/* - * UFont_FindFont - * - * => as Font_FindFont, but - * font_name does not support '\' qualifiers - * - * <= as Font_FindFont, but - * handle is 32-bit - * Results from xres_out and yres_out are questionable because we - * delay-loading the real font data. - */ -os_error * -xufont_find_font(char const *fontNameP, - int xsize, - int ysize, - int xres, - int yres, - ufont_f *font, - int *xresOutP, - int *yresOutP) -{ - ufont_f fontP; - const char *old_font; - char *fonts_file; - char file_name[256]; // \todo: fixed size, i.e. not safe. - fileswitch_object_type objType; - int size; - os_error *errorP; - -if (font == NULL) - return &error_badparams; -/* Be sure never to return garbage as result. */ -*font = NULL; - -/* Allocate memory for UFont font set */ -if ((fontP = (ufont_f)calloc(1, sizeof(struct ufont_font))) == NULL) - return &error_memory; - -if ((errorP = create_map(fontNameP, &fontP->mapP)) != NULL) - { - (void)xufont_lose_font(fontP); - return errorP; - } -if (fontP->mapP == NULL) - { - (void)xufont_lose_font(fontP); - return &error_noufont; - } - -/* Find size of Fonts file : - */ -strcpy(file_name, fontNameP); -strcat(file_name, ".Fonts"); -if ((errorP = xosfile_read_stamped_path(file_name, "UFont:", &objType, NULL, NULL, &size, NULL, NULL)) != NULL) - { - (void)xufont_lose_font(fontP); - return errorP; - } -if (objType != fileswitch_IS_FILE) - { - (void)xufont_lose_font(fontP); - return &error_exists; - } - -if ((fonts_file = (char *)malloc(size)) == NULL) - { - (void)xufont_lose_font(fontP); - return &error_memory; - } - -/* Load Fonts : - */ -if ((errorP = xosfile_load_stamped_path(file_name, fonts_file, "UFont:", NULL, NULL, NULL, NULL, NULL)) != NULL) - { - (void)xufont_lose_font(fontP); - free((void *)fonts_file); - return errorP; - } - -/* Open all fonts listed in Fonts : - */ -for (old_font = fonts_file, fontP->virtual_handles_used = 0; - old_font - fonts_file < size; - old_font += strlen(old_font) + 1, ++fontP->virtual_handles_used) - { - /* UFont can maximum have 256 real RISC OS fonts : - */ - if (fontP->virtual_handles_used < 256) - { - dbg_fprintf(stderr, "%i %s: ", fontP->virtual_handles_used, old_font); - errorP = addref_virtual_fonthandle(old_font, xsize, ysize, xres, yres, xresOutP, yresOutP, &fontP->virtual_font_index[fontP->virtual_handles_used]); - } - else - errorP = &error_fnt_corrupt; - - if (errorP != NULL) - { - (void)xufont_lose_font(fontP); - free((void *)fonts_file); - return errorP; - } - - dbg_fprintf(stderr, "%i\n", fontP->virtual_font_index[fontP->virtual_handles_used]); - } - -/* free Fonts */ -free((void *)fonts_file); fonts_file = NULL; - -*font = fontP; -if (xresOutP != NULL) - *xresOutP = 96; -if (yresOutP != NULL) - *yresOutP = 96; -return NULL; -} - - -/* - * UFont_LoseFont - * - * => font handle as returned by UFont_FindFont - * Even if there was an error returned, we tried to delete as much - * as possible. The ufont_f is definately not reusable afterwards. - */ -os_error * -xufont_lose_font(ufont_f fontP) -{ - unsigned int index; - os_error *theErrorP; - -theErrorP = (fontP->mapP != NULL) ? delete_map(fontP->mapP) : NULL; - -/* Close all fonts used : - */ -for (index = 0; index < fontP->virtual_handles_used; ++index) - { - os_error *errorP; - dbg_fprintf(stderr, "About to deref virtual font handle %d\n", fontP->virtual_font_index[index]); - if ((errorP = deref_virtual_fonthandle(fontP->virtual_font_index[index])) != NULL) - theErrorP = errorP; - } - -/* Free ufont structure : - */ -free((void *)fontP); - -return theErrorP; -} - - -/* - * UFont_Paint - * - * => font handle as returned by UFont_FindFont - * string is Unicode UTF-8 encoded - * other parameters as Font_Paint - */ -os_error * -xufont_paint(ufont_f fontP, - unsigned char const *string, - font_string_flags flags, - int xpos, - int ypos, - font_paint_block const *block, - os_trfm const *trfm, - int length) -{ - char *result; - os_error *error; - - if ((flags & font_GIVEN_LENGTH) == 0) - length = INT_MAX; - - dbg_fprintf(stderr, "xufont_paint() : size %d, consider len %d\n", strlen(string), length); - if ((error = xufont_convert(fontP, string, length, &result, NULL)) != NULL) - return error; - if (result[0] == '\0') - return NULL; - - assert(result[0] == font_COMMAND_FONT); - error = xfont_paint(result[1], &result[2], - (flags & (~font_GIVEN_LENGTH)) | font_GIVEN_FONT, - xpos, ypos, block, trfm, 0); - return error; -} - - -/* - * UFont_ScanString - * - * => font handle as returned by UFont_FindFont - * string is Unicode UTF-8 encoded - * split length is index in string, not pointer - * other parameters as Font_ScanString - * - * <= as Font_ScanString - */ -os_error * -xufont_scan_string(ufont_f fontP, - unsigned char const *string, - font_string_flags flags, - int x, - int y, - font_scan_block const *block, - os_trfm const *trfm, - int length, - unsigned char const **split_point, - int *x_out, - int *y_out, - int *length_out) -{ - char *result; - char *split_point_i; - unsigned int *table; - os_error *error; - - if ((flags & font_GIVEN_LENGTH) == 0) - length = INT_MAX; - - dbg_fprintf(stderr, "xufont_scan_string() : size %d, consider len %d\n", strlen(string), length); - if ((error = xufont_convert(fontP, string, length, &result, &table)) != NULL) - return error; - if (result[0] == '\0') - { - if (split_point != NULL) - *split_point = string; - if (x_out != NULL) - *x_out = 0; - if (y_out != NULL) - *y_out = 0; - if (length_out != NULL) - *length_out = 0; - return NULL; - } - - assert(result[0] == font_COMMAND_FONT); - error = xfont_scan_string(result[1], &result[2], - (flags & (~font_GIVEN_LENGTH)) | font_GIVEN_FONT, - x, y, block, trfm, 0, - (split_point) ? &split_point_i : NULL, - x_out, y_out, length_out); - if (error != NULL) - return error; - - if (split_point != NULL) - { - dbg_fprintf(stderr, "RISC OS scan string split at offset %d (char %d)\n", split_point_i - result, *split_point_i); - *split_point = &string[table[split_point_i - result]]; - dbg_fprintf(stderr, "UTF-8 Split offset at %d (char %d)\n", *split_point - string, **split_point); - } - - return NULL; -} - - -/** - * Given a text line, return the number of bytes which can be set using - * one RISC OS font and the bounding box fitting that part of the text - * only. - * - * \param font a ufont font handle, as returned by xufont_find_font(). - * \param string string text. Does not have to be NUL terminated. - * \param flags FontManger flags to be used internally - * \param length length in bytes of the text to consider. - * \param width returned width of the text which can be set with one RISC OS font. If 0, then error happened or initial text length was 0. - * \param rofontname returned name of the RISC OS font which can be used to set the text. If NULL, then error happened or initial text length was 0. - * \param rotext returned string containing the characters in returned RISC OS font. Not necessary NUL terminated. free() after use. If NULL, then error happened or initial text length was 0. - * \param rolength length of return rotext string. If 0, then error happened or initial text length was 0. - * \param consumed number of bytes of the given text which can be set with one RISC OS font. If 0, then error happened or initial text length was 0. - */ -os_error *xufont_txtenum(ufont_f fontP, - unsigned char const *string, - font_string_flags flags, - size_t length, - int *widthP, - unsigned char const **rofontnameP, - unsigned char const **rotextP, - size_t *rolengthP, - size_t *consumedP) -{ - char *result, *end_result; - unsigned int *table; - os_error *errorP; - - int width; - const char *rofontname; - char *rotext; - size_t rolength; - - *rotextP = *rofontnameP = NULL; - *consumedP = *rolengthP = *widthP = 0; - - if ((flags & font_GIVEN_LENGTH) == 0) - length = INT_MAX; - - if (length == 0) - return NULL; - - if ((errorP = xufont_convert(fontP, string, length, &result, &table)) != NULL) - return errorP; - if (result[0] == '\0') - return NULL; - assert(result[0] == font_COMMAND_FONT); - - /* Find how many characters starting at onwards - are set using the RISC OS font with handle */ - for (end_result = result + 2; *end_result != '\0' && *end_result != font_COMMAND_FONT; ++end_result) - ; - - rolength = end_result - result - 2; - if ((errorP = xfont_scan_string(result[1], &result[2], - flags | font_GIVEN_LENGTH | font_GIVEN_FONT, - 0x7fffffff, 0x7fffffff, - NULL, NULL, - rolength, - NULL, - &width, NULL, - NULL)) != NULL) - return errorP; - if ((rofontname = get_rofontname(result[1])) == NULL) - return &error_badrohandle; - if ((rotext = malloc(rolength)) == NULL) - return &error_memory; - memcpy(rotext, result + 2, rolength); - - *widthP = width; - *rofontnameP = rofontname; - *rotextP = rotext; - *rolengthP = rolength; - *consumedP = table[end_result - result]; - - return NULL; -} - - -/* - * UFont_Convert - * - * => initial font - * UTF-8 string to convert to RISC OS font numbers and codes. - * max length to convert (characters) or NUL char terminated. - * - * <= string converted to Font_Paint format - * table of offsets in UTF-8 string - */ -os_error * -xufont_convert(ufont_f fontP, - unsigned char const *string, - size_t length, - char **presult, /* may not be NULL ! */ - size_t **ptable /* may be NULL */) -{ - static char *resultP; - static size_t *tableP; - static size_t currentSize; - - size_t max_length; - size_t string_index, new_string_index, result_index; - virtual_fh_t *curVirFH = NULL; - -assert(presult != NULL); - -do_sanity_check("xufont_convert() : begin"); - -/* Find upfront if we're NUL char terminated or length terminated. */ -for (max_length = 0; max_length < length && string[max_length] != '\0'; ++max_length) - /* no body */; - -/* Increase timer so we can enforce a set of usage elements to remain active. - */ -++oChainTimer; - -/* Ensure memory block. - */ -if (resultP == NULL) - { - if ((resultP = (char *)malloc(MALLOC_CHUNK)) == NULL) - return &error_memory; - currentSize = MALLOC_CHUNK; - } -if (tableP == NULL && (tableP = (size_t *)malloc(MALLOC_CHUNK * sizeof(size_t))) == NULL) - return &error_memory; - -dbg_fprintf(stderr, "xufont_convert() : "); -for (string_index = 0, result_index = 0; - string_index < max_length; - string_index = new_string_index) - { - wchar_t wchar; - int result = eat_utf8(&wchar, &string[string_index], max_length - string_index); - - if (result == 0) - { - /* Too few input bytes : abort conversion */ - fprintf(stderr, "eat_utf8() : too few input bytes\n"); - break; - } - else if (result < 0) - { - /* Corrupt UTF-8 stream : skip <-result> input characters. */ - fprintf(stderr, "eat_utf8() : error %d\n", result); -fprintf(stderr, "String <%.*s> error pos %d\n", length, string, string_index); - wchar = '?'; - new_string_index = string_index - result; - } - else - { - /* Normal case : one wchar_t produced, bytes consumed. */ - if (wchar >= 0x10000) - wchar = '?'; - new_string_index = string_index + result; - } - - dbg_fprintf(stderr, "src offset 0x%x : 0x%x ", string_index, wchar); - - /* Reserve room for at least 32 more entries. - */ - if (result_index + 32 > currentSize) - { - if ((resultP = realloc(resultP, currentSize*2)) == NULL - || (tableP = realloc(tableP, currentSize*2 * sizeof(size_t))) == NULL) - return &error_memory; - - currentSize *= 2; - } - - { - const byte fontnr = fontP->mapP->fontnr[wchar]; - virtual_fh_t *virFHP; - usage_chain_t *usageP; - - assert(fontnr < fontP->virtual_handles_used); - virFHP = &oVirtualFHArrayP[fontP->virtual_font_index[fontnr]]; - - /* Check if current font is ok : - */ - if (virFHP != curVirFH) - { - os_error *errorP; - - curVirFH = virFHP; - - /* Make sure we have a RISC OS font handle associated : - */ - if ((errorP = activate_virtual_fh(virFHP)) != NULL) - return errorP; - usageP = virFHP->usageP; - assert(usageP != NULL); - assert(usageP->ro_fhandle != 0); - tableP[result_index] = tableP[result_index + 1] = string_index; - resultP[result_index++] = font_COMMAND_FONT; - resultP[result_index++] = usageP->ro_fhandle; - - dbg_fprintf(stderr, "{%i} ", resultP[result_index - 1]); - } - else - { - usageP = virFHP->usageP; - assert(usageP != NULL); - } - - ++virFHP->usage; - /* By increasing the usage counter, it might that the oUsageChain needs - * reordering. - */ - if (usageP != oUsageChain.nextP && virFHP->usage > usageP->prevP->virFHP->usage) - repos_usage_chain_elem(usageP); - - tableP[result_index] = string_index; - resultP[result_index++] = fontP->mapP->character[wchar]; - dbg_fprintf(stderr, "[0x%x] ", resultP[result_index - 1]); - } - } -resultP[result_index] = 0; -*presult = resultP; - -tableP[result_index] = string_index; -if (ptable != NULL) - *ptable = tableP; - -#ifdef DEBUG_UFONT -fprintf(stderr, "\nRISC OS font string result:\n"); - -for (result_index = 0; resultP[result_index] != 0; ++result_index) - fprintf(stderr, " Dst offset %d : 0x%x (src offset %d)\n", result_index, resultP[result_index], tableP[result_index]); -#endif - -do_sanity_check("xufont_convert() : end"); - -dbg_fprintf(stderr, "--- After convert()\n"); -//dump_internals(); - -return NULL; -} - - -/* Creates or reuses an existing ufont_map_t - */ -static os_error *create_map(const char *uFontNameP, const ufont_map_t **mapPP) -{ - ufont_map_t *curMapP; - size_t uFontNameLen = strlen(uFontNameP); - char *fileNameP; - os_error *errorP; - -/* Make sure we never return garbage results. - */ -*mapPP = NULL; - -if ((fileNameP = (char *)alloca(uFontNameLen + sizeof(".Data"))) == NULL) - return &error_memory; -memcpy(fileNameP, uFontNameP, uFontNameLen); -do { - fileswitch_object_type objType; - int size; - - memcpy(&fileNameP[uFontNameLen], ".Data", sizeof(".Data")); - if ((errorP = xosfile_read_stamped_path(fileNameP, "UFont:", &objType, NULL, NULL, &size, NULL, NULL)) != NULL) - return errorP; - - if (objType == fileswitch_NOT_FOUND) - { - /* Look for the Data file one directory level up. */ - while (uFontNameLen != 0 && fileNameP[--uFontNameLen] != '.') - /* no body */; - if (uFontNameLen == 0) - return &error_exists; - } - else if (objType == fileswitch_IS_FILE) - { - if (size != 2*65536) - return &error_size; - break; - } - else - return &error_exists; - } while (1); - -/* Try to reuse an existing map : - */ -for (curMapP = oMapCollectionP; curMapP != NULL; curMapP = curMapP->nextP) - { - size_t curUFontNameLen = strlen(curMapP->uFontNameP); - - if (uFontNameLen != curUFontNameLen) - continue; - - if (memcmp(fileNameP, curMapP->uFontNameP, curUFontNameLen) != 0) - break; - } -if (curMapP != NULL) - { - ++curMapP->refCount; - *mapPP = curMapP; - return NULL; - } - -/* We need to create & load new map into memory : - */ -if ((curMapP = (ufont_map_t *)malloc(sizeof(ufont_map_t))) == NULL) - return &error_memory; - -/* Load Data file : - */ -if ((errorP = xosfile_load_stamped_path(fileNameP, (byte *)&curMapP->fontnr[0], "UFont:", NULL, NULL, NULL, NULL, NULL)) != NULL) - { - free((void *)curMapP); - return errorP; - } -fileNameP[uFontNameLen] = '\0'; -if ((curMapP->uFontNameP = strdup(fileNameP)) == NULL) - { - free((void *)curMapP); - return &error_memory; - } -curMapP->refCount = 1; -curMapP->nextP = oMapCollectionP; -oMapCollectionP = curMapP; - -*mapPP = curMapP; -return NULL; -} - - -static os_error *delete_map(ufont_map_t *mapP) -{ -assert(mapP->refCount > 0); ---mapP->refCount; -/** \todo: we don't remove the map from the oMapCollection list. Should we ? - */ - -return NULL; -} - - -/** - * Convert next sequence of UTF-8 bytes into wchar_t - * - * \param pwc resulting wchar_t result. - * \param s ptr to UTF-8 encoded string - * \param n maximum of bytes which can be consumed via s - * \return - * x > 0: number of bytes consumed at s, valid wchar_t returned at pwc[0] - * x = 0: too few input bytes, pwc[0] is undefined - * x < 0: illegal UTF-8 stream, skip -x characters at s, pwc[0] is undefined - */ -static int eat_utf8(wchar_t *pwc, const byte *s, int n) -{ - byte c; - int i; - - if (n < 1) - return 0; /* not enough input bytes */ - else if ((c = s[0]) < 0x80) { - *pwc = c; - return 1; - } else if (c < 0xc2) - goto do_sync; - else if (c < 0xe0) { - if (n < 2) - return 0; /* not enough input bytes */ - if (!((s[1] ^ 0x80) < 0x40)) - goto do_sync; - *pwc = ((wchar_t) (c & 0x1f) << 6) | (wchar_t) (s[1] ^ 0x80); - return 2; - } else if (c < 0xf0) { - if (n < 3) - return 0; /* not enough input bytes */ - if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 && (c >= 0xe1 || s[1] >= 0xa0))) - goto do_sync; - *pwc = ((wchar_t) (c & 0x0f) << 12) | ((wchar_t) (s[1] ^ 0x80) << 6) | (wchar_t) (s[2] ^ 0x80); - return 3; - } else if (c < 0xf8) { - if (n < 4) - return 0; /* not enough input bytes */ - if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 && (s[3] ^ 0x80) < 0x40 && (c >= 0xf1 || s[1] >= 0x90))) - goto do_sync; - *pwc = ((wchar_t) (c & 0x07) << 18) | ((wchar_t) (s[1] ^ 0x80) << 12) | ((wchar_t) (s[2] ^ 0x80) << 6) | (wchar_t) (s[3] ^ 0x80); - return 4; - } else if (c < 0xfc) { - if (n < 5) - return 0; /* not enough input bytes */ - if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40 && (c >= 0xf9 || s[1] >= 0x88))) - goto do_sync; - *pwc = ((wchar_t) (c & 0x03) << 24) | ((wchar_t) (s[1] ^ 0x80) << 18) | ((wchar_t) (s[2] ^ 0x80) << 12) | ((wchar_t) (s[3] ^ 0x80) << 6) | (wchar_t) (s[4] ^ 0x80); - return 5; - } else if (c < 0xfe) { - if (n < 6) - return 0; /* not enough input bytes */ - if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40 && (s[5] ^ 0x80) < 0x40 && (c >= 0xfd || s[1] >= 0x84))) - goto do_sync; - *pwc = ((wchar_t) (c & 0x01) << 30) | ((wchar_t) (s[1] ^ 0x80) << 24) | ((wchar_t) (s[2] ^ 0x80) << 18) | ((wchar_t) (s[3] ^ 0x80) << 12) | ((wchar_t) (s[4] ^ 0x80) << 6) | (wchar_t) (s[5] ^ 0x80); - return 6; - } - -do_sync: - /* The UTF-8 sequence at s is illegal, skipping from s onwards - * until first non top character is found or %11xxxxxx is found - * (both valid UTF-8 *starts* - not necessary valid sequences). - */ - for (i = 1; i < n && !((s[i] & 0x80) == 0x00 || (s[i] & 0xC0) == 0xC0); ++i) - /* no body */; - return -i; -} - - -/** - * Adds the RISC OS font to the oVirtualFHArrayP list and - * returns the index in that array. - * oVirtualFHArrayP can be reallocated (and all virFHP ptrs in oUsageChain). - * Results in xresOutP and yresOutP are not always that meaningful because - * of the delayed-loading of the real RISC OS font data. - * xresOutP and/or yresOutP may be NULL. - */ -static os_error *addref_virtual_fonthandle(const char *fontNameP, int xsize, int ysize, int xres, int yres, int *xresOutP, int *yresOutP, size_t *offsetP) -{ - size_t curIndex; - virtual_fh_t *unusedSlotP; - - assert(offsetP != NULL); - - do_sanity_check("addref_virtual_fonthandle() : begin"); - - if (oVirtualFHArrayP == NULL) { - if ((oVirtualFHArrayP = (virtual_fh_t *)calloc(kInitialFHArraySize, sizeof(virtual_fh_t))) == NULL) - return &error_memory; - /* oCurVirtualFHArrayElems = 0; Isn't really necessary because of static */ - oMaxVirtualFHArrayElems = kInitialFHArraySize; - } - - /* Check for duplicate (and find first unused slot if any) : - */ - for (unusedSlotP = NULL, curIndex = 0; - curIndex < oCurVirtualFHArrayElems; - ++curIndex) { - virtual_fh_t *virFHP = &oVirtualFHArrayP[curIndex]; - - if (virFHP->fontNameP != NULL /* case strdup(fontNameP) failed */ - && stricmp(virFHP->fontNameP, fontNameP) == 0 - && virFHP->xsize == xsize && virFHP->ysize == ysize) { - if (xresOutP != NULL) - *xresOutP = virFHP->xres; - if (yresOutP != NULL) - *yresOutP = virFHP->yres; - ++virFHP->refCount; - *offsetP = curIndex; - do_sanity_check("addref_virtual_fonthandle() : case 1"); - return NULL; - } - - if (virFHP->refCount == 0 && unusedSlotP == NULL) - unusedSlotP = virFHP; - } - - /* Can we reuse a slot ? - * I.e. a virtual FH which refCount is zero. - */ - if (unusedSlotP != NULL) { - if (unusedSlotP->usageP != NULL) { - os_error *errorP; - - /* This slot is refered in the usage chain, we have to unlink it. - */ - if ((errorP = remove_usage_chain_elem(unusedSlotP->usageP)) != NULL) - return errorP; - } - - unusedSlotP->usage = 0; - if (unusedSlotP->fontNameP != NULL) - free((void *)unusedSlotP->fontNameP); - if ((unusedSlotP->fontNameP = strdup(fontNameP)) == NULL) - return &error_memory; - - unusedSlotP->xsize = xsize; - unusedSlotP->ysize = ysize; - unusedSlotP->xres = (xres > 1) ? xres : 96; - if (xresOutP != NULL) - *xresOutP = unusedSlotP->xres; - unusedSlotP->yres = (yres > 1) ? yres : 96; - if (yresOutP != NULL) - *yresOutP = unusedSlotP->yres; - unusedSlotP->refCount = 1; - *offsetP = unusedSlotP - oVirtualFHArrayP; - do_sanity_check("addref_virtual_fonthandle() : case 2"); - return NULL; - } - - /* Add new entry : - */ - if (oCurVirtualFHArrayElems == oMaxVirtualFHArrayElems) { - virtual_fh_t *newVirtualFHArrayP; - size_t extraOffset; - usage_chain_t *usageP; - - /* Don't use realloc() as when that fails, we don't even have the original - * memory block anymore. - */ - if ((newVirtualFHArrayP = (virtual_fh_t *)calloc(2*oMaxVirtualFHArrayElems, sizeof(virtual_fh_t))) == NULL) - return &error_memory; - memcpy(newVirtualFHArrayP, oVirtualFHArrayP, oMaxVirtualFHArrayElems * sizeof(virtual_fh_t)); - free((void *)oVirtualFHArrayP); - extraOffset = (const char *)newVirtualFHArrayP - (const char *)oVirtualFHArrayP; - oVirtualFHArrayP = newVirtualFHArrayP; - oMaxVirtualFHArrayElems *= 2; - - /* Update the virFHP pointers in the usage chain : - */ - if (oUsageChain.nextP != NULL) { - for (usageP = oUsageChain.nextP; usageP != &oUsageChain; usageP = usageP->nextP) - usageP->virFHP = (virtual_fh_t *)&((char *)usageP->virFHP)[extraOffset]; - } - } - - unusedSlotP = &oVirtualFHArrayP[oCurVirtualFHArrayElems]; - if ((unusedSlotP->fontNameP = (const char *)strdup(fontNameP)) == NULL) - return &error_memory; - unusedSlotP->xsize = xsize; - unusedSlotP->ysize = ysize; - unusedSlotP->xres = (xres > 1) ? xres : 96; - if (xresOutP != NULL) - *xresOutP = unusedSlotP->xres; - unusedSlotP->yres = (yres > 1) ? yres : 96; - if (yresOutP != NULL) - *yresOutP = unusedSlotP->yres; - unusedSlotP->refCount = 1; - *offsetP = oCurVirtualFHArrayElems++; - - do_sanity_check("addref_virtual_fonthandle() : case 3"); - return NULL; -} - - -/** - * Deref virtual_fh_t element in oVirtualFHArrayP array. - */ -static os_error *deref_virtual_fonthandle(size_t offset) -{ - assert(/* offset >= 0 && */ offset < oCurVirtualFHArrayElems); - assert(oVirtualFHArrayP[offset].refCount > 0); - - /* When the refCount reaches 0, it will be reused by preference when a - * new usageChain element is needed in addref_virtual_fonthandle(). - */ - --oVirtualFHArrayP[offset].refCount; - - do_sanity_check("deref_virtual_fonthandle()"); - return NULL; -} - - -/** - * Virtual font handle needs to have a RISC OS font handle - * associated via virFHP->usageP. For this we can throw out all other - * usage chain elements which have a chainTimer different from oChainTimer. - * However, we may not have more than kMaxUsageChainElems chain elements - * active. - * Afterwards: either an error, either virFHP->usageP points to an usage chain - * element in the oUsageChain linked list and that usage chain element has - * a valid RISC OS font handle associated. - */ -static os_error *activate_virtual_fh(virtual_fh_t *virFHP) -{ - usage_chain_t *usageP; - - dbg_fprintf(stderr, "+++ activate_virtual_fh(virFHP %p, usageP ? %p)\n", virFHP, virFHP->usageP); - do_sanity_check("activate_virtual_fh() : begin"); - - /* The easiest case : we already have a RISC OS font handle : - */ - if ((usageP = virFHP->usageP) != NULL) { - usageP->chainTimer = oChainTimer; - assert(usageP->ro_fhandle != 0); - assert(usageP->virFHP == virFHP); - do_sanity_check("activate_virtual_fh() : case 1"); - dbg_fprintf(stderr, "--- done, activate_virtual_fh(), case 1\n"); - return NULL; - } - - /* The second easiest case : we're still allowed to create an extra - * chain element : - */ - if (oCurUsageChainElems < kMaxUsageChainElems) { - os_error *errorP; - - if ((usageP = (usage_chain_t *)malloc(sizeof(usage_chain_t))) == NULL) - return &error_memory; - usageP->chainTimer = oChainTimer; - - if ((errorP = xfont_find_font(virFHP->fontNameP, - virFHP->xsize, virFHP->ysize, - virFHP->xres, virFHP->yres, - &usageP->ro_fhandle, - &virFHP->xres, &virFHP->yres)) != NULL) { - free((void *)usageP); - return errorP; - } - usageP->virFHP = virFHP; - virFHP->usageP = usageP; - ++oCurUsageChainElems; - - /* Make sure oUsageChain nextP and prevP point to at least something (is - * only executed once and should probably better be done in a global - * init routine). - */ - if (oUsageChain.nextP == NULL) - oUsageChain.nextP = oUsageChain.prevP = &oUsageChain; - } - else { - os_error *errorP; - - /* The more difficult one : we need to reuse a usage chain element. - * Take the last one because that is least used but skip the onces - * with chainTimer equal to the current oChainTimer because those - * RISC OS font handles are still used in the font string we're - * currently processing. - */ - for (usageP = oUsageChain.prevP; - usageP != &oUsageChain && usageP->chainTimer == oChainTimer; - usageP = usageP->prevP) - /* no body */; - if (usageP == &oUsageChain) { - /* Painful : all usage chain elements are in use and we already have the - * maximum of chain elements reached. - */ - return &error_toomany_handles; - } - - usageP->chainTimer = oChainTimer; - /* The virtual font handle currently in usageP->virFHP no longer has a real - * RISC OS font handle anymore. - */ - usageP->virFHP->usageP = NULL; - if ((errorP = xfont_lose_font(usageP->ro_fhandle)) != NULL) - return errorP; - if ((errorP = xfont_find_font(virFHP->fontNameP, - virFHP->xsize, virFHP->ysize, - virFHP->xres, virFHP->yres, - &usageP->ro_fhandle, - &virFHP->xres, &virFHP->yres)) != NULL) - return errorP; - usageP->virFHP = virFHP; - virFHP->usageP = usageP; - - /* Delink : - */ - usageP->prevP->nextP = usageP->nextP; - usageP->nextP->prevP = usageP->prevP; - } - - /* Link usageP in the oUsageChain based on its current virFHP->usage value : - */ - { - const unsigned int usage = virFHP->usage; - usage_chain_t *runUsageP; - - for (runUsageP = &oUsageChain; - runUsageP != oUsageChain.nextP && runUsageP->prevP->virFHP->usage <= usage; - runUsageP = runUsageP->prevP) - /* no body */; - - /* We have to link usageP between runUsageP and runUsageP->prevP - * because runUsageP->prevP has higher usage than the one we need to - * link in -or- we're at the end/start. - */ - usageP->nextP = runUsageP; - usageP->prevP = runUsageP->prevP; - runUsageP->prevP->nextP = usageP; - runUsageP->prevP = usageP; - } - do_sanity_check("activate_virtual_fh() : case 2"); - dbg_fprintf(stderr, "--- done, activate_virtual_fh(), case 2\n"); - - return NULL; -} - - -/** - * Remove the usage_chaint_t element from the usage chain - */ -static os_error *remove_usage_chain_elem(usage_chain_t *usageP) -{ - os_error *errorP; - - assert(usageP != NULL); - assert(oCurUsageChainElems > 0); - assert(usageP->ro_fhandle != 0); - assert(usageP->virFHP != NULL); - - if ((errorP = xfont_lose_font(usageP->ro_fhandle)) != NULL) - return errorP; - - usageP->virFHP->usageP = NULL; - - /* Delink it : - */ - usageP->prevP->nextP = usageP->nextP; - usageP->nextP->prevP = usageP->prevP; - - --oCurUsageChainElems; - free((void *)usageP); - - do_sanity_check("remove_usage_chain_elem() : end"); - return NULL; -} - - -/*** - * Should be called when the usage_chain_t element is no longer in the right - * place in the chain based on its virFHP->usage value. - * - * usageP is no longer in the right place in the chain because its - * ->virFHP->usage value increased. Reposition it towards prev - * direction. - */ -static void repos_usage_chain_elem(usage_chain_t *usageP) -{ - usage_chain_t *prev1P, *prev2P; - const unsigned int curUsage = usageP->virFHP->usage; - - dbg_fprintf(stderr, "+++ repos_usage_chain_elem(%p)\n", usageP); - - /* If this assert goes off, then it means that this routine shouldn't - * have been called. - */ - assert(curUsage > usageP->prevP->virFHP->usage); - - /* Delink : - */ - usageP->prevP->nextP = usageP->nextP; - usageP->nextP->prevP = usageP->prevP; - - /* Place usageElemP between prev1P and prev2P. - */ - for (prev1P = usageP->prevP, prev2P = prev1P->prevP; - prev2P != &oUsageChain && curUsage > prev2P->virFHP->usage; - prev1P = prev2P, prev2P = prev2P->prevP) { - dbg_fprintf(stderr, "> prev1P %p (%d), usageElemP %p (%d), prev2P %p (%d), dummy %p\n", prev1P, prev1P->virFHP->usage, usageP, usageP->virFHP->usage, prev2P, prev2P->virFHP->usage, &oUsageChain); - assert(prev1P->virFHP->usage <= prev2P->virFHP->usage); - } - - dbg_fprintf(stderr, "prev1P %p (%d), usageElemP %p (%d), prev2P %p (%d), dummy %p\n", prev1P, prev1P->virFHP->usage, usageP, usageP->virFHP->usage, prev2P, prev2P->virFHP->usage, &oUsageChain); - - /* Relink between prev1P and prev2P : - */ - prev1P->prevP = usageP; - usageP->prevP = prev2P; - prev2P->nextP = usageP; - usageP->nextP = prev1P; - - do_sanity_check("repos_usage_chain_elem() : end"); - dbg_fprintf(stderr, "--- done, repos_usage_chain_elem()\n"); -} - - -/** - * Retrieves the RISC OS font name of given RISC OS fonthandle. - * - * \param rofhandle RISC OS font handle - */ -static const char *get_rofontname(font_f rofhandle) -{ - usage_chain_t *usageP; - - if (oUsageChain.nextP == NULL) - return NULL; - - for (usageP = oUsageChain.nextP; usageP != &oUsageChain; usageP = usageP->nextP) - if (usageP->ro_fhandle == rofhandle) - return usageP->virFHP->fontNameP; - - return NULL; -} - - -#ifdef DEBUG_DUMP_INTERNALS -/** - * Prints to stderr the complete internal state of UFont. - */ -static void dump_internals(void) -{ - fprintf(stderr, "Dump UFont internals:\n - Virtual font handle array at %p (length %d, max length %d)\n - Usage chain elements %d\n - Chain timer is %d\n Dump usage chain (first dummy at %p):\n", oVirtualFHArrayP, oCurVirtualFHArrayElems, oMaxVirtualFHArrayElems, oCurUsageChainElems, oChainTimer, &oUsageChain); - if (oUsageChain.prevP == NULL || oUsageChain.nextP == NULL) { - fprintf(stderr, " Empty usage chain\n"); - if (oUsageChain.prevP != oUsageChain.nextP) - fprintf(stderr, " *** Corrupted empty usage chain: next %p, prev %p\n", oUsageChain.nextP, oUsageChain.prevP); - if (oCurUsageChainElems != 0) - fprintf(stderr, " *** Current usage chain length is wrong\n"); - } - else { - size_t usageCount; - const usage_chain_t *usageP; - - for (usageCount = 0, usageP = oUsageChain.nextP; usageP != &oUsageChain; ++usageCount, usageP = usageP->nextP) { - fprintf(stderr, " -%d- : cur %p, next %p, prev %p, timer %d, RISC OS font handle %d, virtual font %p (%d, %s), usage %d\n", usageCount, usageP, usageP->nextP, usageP->prevP, usageP->chainTimer, usageP->ro_fhandle, usageP->virFHP, usageP->virFHP - oVirtualFHArrayP, usageP->virFHP->fontNameP, usageP->virFHP->usage); - if (usageP->nextP->prevP != usageP) - fprintf(stderr, " *** Bad usageP->nextP->prevP != usageP\n"); - if (usageP->prevP->nextP != usageP) - fprintf(stderr, " *** Bad usageP->prevP->nextP != usageP\n"); - if (usageP->virFHP < oVirtualFHArrayP || usageP->virFHP >= &oVirtualFHArrayP[oCurVirtualFHArrayElems]) - fprintf(stderr, " *** Bad virtual font handle\n"); - } - if (usageCount != oCurUsageChainElems) - fprintf(stderr, " *** Current usage chain length is wrong\n"); - if (usageCount > kMaxUsageChainElems) - fprintf(stderr, " *** Current usage chain is too long\n"); - } - - if (oVirtualFHArrayP != NULL) { - size_t fhIndex; - - fprintf(stderr, " Dump virtual font handles:\n"); - for (fhIndex = 0; fhIndex < oCurVirtualFHArrayElems; ++fhIndex) { - const virtual_fh_t *virFHP = &oVirtualFHArrayP[fhIndex]; - - fprintf(stderr, " -%d (%p)- : <%s>, size %d,%d, res %d,%d, usage %d, ref count %d, usage chain ptr %p\n", fhIndex, virFHP, virFHP->fontNameP, virFHP->xsize, virFHP->ysize, virFHP->xres, virFHP->yres, virFHP->usage, virFHP->refCount, virFHP->usageP); - if (virFHP->usageP != NULL) { - const usage_chain_t *usageP; - - for (usageP = oUsageChain.nextP; - usageP != virFHP->usageP && usageP != &oUsageChain; - usageP = usageP->nextP) - /* no body */; - if (usageP != virFHP->usageP) - fprintf(stderr, " *** Usage chain ptr could not be found in usage chain\n"); - } - } - } -} -#endif - - -/** - * Does do a full sanity check of UFont internal datastructures. - * Will assert() when something odd if found. - */ -static int sanity_check(const char *testMsgP) -{ - dbg_fprintf(stderr, "Sanity check <%s>\n", testMsgP); - if (oUsageChain.prevP == NULL || oUsageChain.nextP == NULL) { - assert(oUsageChain.prevP == oUsageChain.nextP); - assert(oCurUsageChainElems == 0); - } - else { - size_t usageCount; - const usage_chain_t *usageP; - - /* We should see equal or decreasing usage values. - */ - for (usageCount = 0, usageP = oUsageChain.nextP; usageP != &oUsageChain; ++usageCount, usageP = usageP->nextP) { - assert(usageP->nextP->prevP == usageP); - assert(usageP->prevP->nextP == usageP); - assert(usageP->chainTimer <= oChainTimer); - assert(usageP->ro_fhandle != 0); - assert(oVirtualFHArrayP != NULL); - assert(usageP->virFHP >= oVirtualFHArrayP && usageP->virFHP < &oVirtualFHArrayP[oCurVirtualFHArrayElems]); - assert(usageP->virFHP->usageP == usageP); - assert(usageP == oUsageChain.prevP || usageP->virFHP->usage >= usageP->nextP->virFHP->usage); - } - assert(usageCount == oCurUsageChainElems); - assert(usageCount <= kMaxUsageChainElems); - } - - if (oVirtualFHArrayP != NULL) { - size_t fhIndex; - - for (fhIndex = 0; fhIndex < oCurVirtualFHArrayElems; ++fhIndex) { - const virtual_fh_t *virFHP = &oVirtualFHArrayP[fhIndex]; - - if (virFHP->usageP != NULL) { - const usage_chain_t *usageP; - - assert(virFHP->fontNameP != NULL); - assert(virFHP->xsize > 0 && virFHP->ysize > 0); - assert(virFHP->xres > 0 && virFHP->yres > 0); - for (usageP = oUsageChain.nextP; - usageP != virFHP->usageP && usageP != &oUsageChain; - usageP = usageP->nextP) - /* no body */; - assert(usageP == virFHP->usageP); - } - } - } - - return 0; -} diff --git a/riscos/ufont.h b/riscos/ufont.h deleted file mode 100644 index 620c3db89..000000000 --- a/riscos/ufont.h +++ /dev/null @@ -1,70 +0,0 @@ -/* ufont.h - * Licensed under the GNU General Public License, - * http://www.opensource.org/licenses/gpl-license - * Copyright 2000 James Bursa - * Copyright 2004 John Tytgat - */ - -#ifndef UFONT_HEADER_INCLUDED -#define UFONT_HEADER_INCLUDED - -#include -#include -#include -#include - -#include "oslib/font.h" -#include "oslib/os.h" - -typedef struct ufont_font *ufont_f; - -extern os_error *xufont_find_font(char const *font_name, - int xsize, - int ysize, - int xres, - int yres, - ufont_f *font, - int *xresOutP, - int *yresOutP); - -extern os_error *xufont_lose_font(ufont_f font); - -extern os_error *xufont_paint(ufont_f font, - unsigned char const *string, - font_string_flags flags, - int xpos, - int ypos, - font_paint_block const *block, - os_trfm const *trfm, - int length); - -extern os_error *xufont_scan_string(ufont_f font, - unsigned char const *string, - font_string_flags flags, - int x, - int y, - font_scan_block const *block, - os_trfm const *trfm, - int length, - unsigned char const **split_point, - int *x_out, - int *y_out, - int *length_out); - -extern os_error *xufont_txtenum(ufont_f font, - unsigned char const *string, - font_string_flags flags, - size_t length, - int *width, - unsigned char const **rofontname, - unsigned char const **rotext, - size_t *rolength, - size_t *consumed); - -extern os_error *xufont_convert(ufont_f font, - unsigned char const *string, - size_t length, - char **presult, - size_t **ptable); - -#endif -- cgit v1.2.3