From eecd008a160d1a83502d61793811f6392be6aa49 Mon Sep 17 00:00:00 2001 From: James Bursa Date: Wed, 21 Jan 2004 23:57:19 +0000 Subject: [project @ 2004-01-21 23:57:19 by bursa] Clean up and comment. svn path=/import/netsurf/; revision=493 --- riscos/font.c | 231 +++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 158 insertions(+), 73 deletions(-) (limited to 'riscos') diff --git a/riscos/font.c b/riscos/font.c index a33653ec9..5fb02e3b4 100644 --- a/riscos/font.c +++ b/riscos/font.c @@ -6,6 +6,12 @@ * Copyright 2003 Phil Mellor */ +/** \file + * Font handling (RISC OS implementation). + * + * The Font Manager is used to handle and render fonts. + */ + #include #include #include "oslib/font.h" @@ -25,8 +31,10 @@ struct font_set { struct font_data *font[FONT_FAMILIES * 4]; }; -/** +/** Table of font names. + * * font id = font family * 4 + bold * 2 + slanted + * * font family: 0 = sans-serif, 1 = serif, ... */ @@ -38,63 +46,13 @@ const char * const font_table[FONT_FAMILIES * 4] = { "Homerton.Bold.Oblique\\ELatin1", }; -static void font_close(struct font_data *data); /** - * functions + * Create an empty font_set. + * + * \return an opaque struct font_set. */ -unsigned long font_width(struct font_data *font, const char * text, unsigned int length) -{ - int width; - os_error * error; - - assert(font != 0 && text != 0); - - if (length == 0) - return 0; - - error = xfont_scan_string((font_f)(font->handle), text, - font_GIVEN_FONT | font_KERN | font_GIVEN_LENGTH, - 0x7fffffff, 0x7fffffff, - 0, - 0, (int)length, - 0, &width, 0, 0); - if (error != 0) { - fprintf(stderr, "%s\n", error->errmess); - die("font_width: font_scan_string failed"); - } - - return width / 800; -} - -void font_position_in_string(const char* text, struct font_data* font, - unsigned int length, unsigned long x, int* char_offset, int* pixel_offset) -{ - font_scan_block block; - char* split_point; - int x_out, y_out, length_out; - - assert(font != 0 && text != 0); - - block.space.x = block.space.y = 0; - block.letter.x = block.letter.y = 0; - block.split_char = -1; - - xfont_scan_string((font_f)(font->handle), text, - font_GIVEN_BLOCK | font_GIVEN_FONT | font_KERN | font_RETURN_CARET_POS | font_GIVEN_LENGTH, - ro_x_units(x) * 400, - 0x7fffffff, - &block, 0, (int)length, - &split_point, &x_out, &y_out, &length_out); - - *char_offset = (int)(split_point - text); - *pixel_offset = browser_x_units(x_out / 400); - - return; -} - - struct font_set *font_new_set() { struct font_set *set = xcalloc(1, sizeof(*set)); @@ -107,13 +65,26 @@ struct font_set *font_new_set() } +/** + * Open a font for use based on a css_style. + * + * \param set a font_set, as returned by font_new_set() + * \param style a css_style which describes the font + * \return a struct font_data, with a RISC OS font handle in handle + * + * The set is updated to include the font, if it was not present. + */ + struct font_data *font_open(struct font_set *set, struct css_style *style) { struct font_data *data; unsigned int size = 16 * 11; unsigned int f = 0; + font_f handle; + os_error *error; - assert(set != 0); + assert(set); + assert(style); if (style->font_size.size == CSS_FONT_SIZE_LENGTH) size = style->font_size.value.length.value * 16; @@ -145,19 +116,14 @@ struct font_data *font_open(struct font_set *set, struct css_style *style) data = xcalloc(1, sizeof(*data)); - { - font_f handle; - os_error *error; - - LOG(("font_find_font '%s' %i", font_table[f], size)); - error = xfont_find_font(font_table[f], (int)size, (int)size, - 0, 0, &handle, 0, 0); - if (error != 0) { - fprintf(stderr, "%s\n", error->errmess); - die("font_find_font failed"); - } - data->handle = handle; + error = xfont_find_font(font_table[f], (int)size, (int)size, + 0, 0, &handle, 0, 0); + if (error) { + fprintf(stderr, "%i: %s\n", error->errnum, error->errmess); + die("font_find_font failed"); } + + data->handle = handle; data->size = size; data->space_width = font_width(data, " ", 1); @@ -168,6 +134,12 @@ struct font_data *font_open(struct font_set *set, struct css_style *style) } +/** + * Frees all the fonts in a font_set. + * + * \param set a font_set as returned by font_new_set() + */ + void font_free_set(struct font_set *set) { unsigned int i; @@ -178,7 +150,8 @@ void font_free_set(struct font_set *set) for (i = 0; i < FONT_FAMILIES * 4; i++) { for (data = set->font[i]; data != 0; data = next) { next = data->next; - font_close(data); + font_lose_font((font_f)(data->handle)); + free(data); } } @@ -186,14 +159,99 @@ void font_free_set(struct font_set *set) } -void font_close(struct font_data *data) +/** + * Find the width of some text in a font. + * + * \param font a font_data, as returned by font_open() + * \param text string to measure + * \param length length of text + * \return width of text in pixels + */ + +unsigned long font_width(struct font_data *font, const char * text, unsigned int length) +{ + int width; + os_error * error; + + assert(font != 0 && text != 0); + + if (length == 0) + return 0; + + error = xfont_scan_string((font_f)(font->handle), text, + font_GIVEN_FONT | font_KERN | font_GIVEN_LENGTH, + 0x7fffffff, 0x7fffffff, + 0, + 0, (int)length, + 0, &width, 0, 0); + if (error != 0) { + fprintf(stderr, "%s\n", error->errmess); + die("font_width: font_scan_string failed"); + } + + return width / 800; +} + + +/** + * Find where in a string a x coordinate falls. + * + * For example, used to find where to position the caret in response to mouse + * click. + * + * \param text a string + * \param font a font_data, as returned by font_open() + * \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 + */ + +void font_position_in_string(const char *text, struct font_data *font, + unsigned int length, unsigned long x, + int *char_offset, int *pixel_offset) { - font_lose_font((font_f)(data->handle)); + font_scan_block block; + char *split_point; + int x_out, y_out, length_out; + os_error *error; + + assert(font != 0 && text != 0); - free(data); + block.space.x = block.space.y = 0; + block.letter.x = block.letter.y = 0; + block.split_char = -1; + + 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, 0, (int)length, + &split_point, &x_out, &y_out, &length_out); + if (error) { + fprintf(stderr, "%s\n", error->errmess); + die("font_width: font_scan_string failed"); + } + + *char_offset = (int)(split_point - text); + *pixel_offset = x_out / 2 / 400; } +/** + * Find where to split a string to fit in a width. + * + * For example, used when wrapping paragraphs. + * + * \param data a font_data, as returned by font_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 + */ + char * font_split(struct font_data *data, const char * text, unsigned int length, unsigned int width, unsigned int *used_width) { @@ -206,7 +264,7 @@ char * font_split(struct font_data *data, const char * text, unsigned int length error = xfont_scan_string((font_f)(data->handle), text, font_GIVEN_BLOCK | font_GIVEN_FONT | font_KERN | font_GIVEN_LENGTH, - ro_x_units(width) * 400, 0x7fffffff, + width * 2 * 400, 0x7fffffff, &block, 0, (int)length, @@ -217,8 +275,35 @@ char * font_split(struct font_data *data, const char * text, unsigned int length die("font_split: font_scan_string failed"); } - *used_width = browser_x_units((int)(*used_width / 400)); + *used_width = *used_width / 2 / 400; return split; } + +#ifdef TEST + +int main(void) +{ + unsigned int i; + struct font_set *set; + struct css_style style; + + style.font_size.size = CSS_FONT_SIZE_LENGTH; + style.font_weight = CSS_FONT_WEIGHT_BOLD; + style.font_style = CSS_FONT_STYLE_ITALIC; + + set = font_new_set(); + + for (i = 10; i != 100; i += 10) { + style.font_size.value.length.value = i; + font_open(set, &style); + } + + font_free_set(set); + + return 0; +} + +#endif + -- cgit v1.2.3