summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--riscos/dialog.c11
-rw-r--r--riscos/font.c1374
-rw-r--r--riscos/gui.c17
-rw-r--r--riscos/gui.h4
-rw-r--r--riscos/plotters.c20
-rw-r--r--riscos/print.c4
-rw-r--r--riscos/save_draw.c6
-rw-r--r--riscos/thumbnail.c9
-rw-r--r--riscos/ufont.c1273
-rw-r--r--riscos/ufont.h70
10 files changed, 224 insertions, 2564 deletions
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 <bursa@users.sourceforge.net>
- * Copyright 2003 Phil Mellor <monkeyson@users.sourceforge.net>
- * Copyright 2004 John Tytgat <John.Tytgat@aaug.net>
- * Copyright 2004 John M Bell <jmb202@ecs.soton.ac.uk>
+ * Copyright 2005 James Bursa <bursa@users.sourceforge.net>
*/
/** \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 <assert.h>
-#include <stdio.h>
-#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 <string.h>
#include <swis.h>
+#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 <bursa@users.sourceforge.net>
- * Copyright 2004 John Tytgat <John.Tytgat@aaug.net>
- */
-
-/** \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 <assert.h>
-#include <limits.h>
-#include <wchar.h>
-
-#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 <result + 2> onwards
- are set using the RISC OS font with handle <result + 1> */
- 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, <result> 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 <fontNameP> 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 <virFHP> 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 <bursa@users.sourceforge.net>
- * Copyright 2004 John Tytgat <John.Tytgat@aaug.net>
- */
-
-#ifndef UFONT_HEADER_INCLUDED
-#define UFONT_HEADER_INCLUDED
-
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#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