[project @ 2004-01-21 23:57:19 by bursa]

Clean up and comment.

svn path=/import/netsurf/; revision=493
This commit is contained in:
James Bursa 2004-01-21 23:57:19 +00:00
parent 6b367e0795
commit eecd008a16

View File

@ -6,6 +6,12 @@
* Copyright 2003 Phil Mellor <monkeyson@users.sourceforge.net>
*/
/** \file
* Font handling (RISC OS implementation).
*
* The Font Manager is used to handle and render fonts.
*/
#include <assert.h>
#include <stdio.h>
#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)
{
font_lose_font((font_f)(data->handle));
/**
* 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
*/
free(data);
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_scan_block block;
char *split_point;
int x_out, y_out, length_out;
os_error *error;
assert(font != 0 && text != 0);
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