summaryrefslogtreecommitdiff
path: root/riscos
diff options
context:
space:
mode:
Diffstat (limited to 'riscos')
-rw-r--r--riscos/font.c227
-rw-r--r--riscos/font.h35
-rw-r--r--riscos/gui.c16
3 files changed, 213 insertions, 65 deletions
diff --git a/riscos/font.c b/riscos/font.c
index 05faf50cf..3ee42e8ce 100644
--- a/riscos/font.c
+++ b/riscos/font.c
@@ -1,45 +1,61 @@
/**
- * $Id: font.c,v 1.2 2002/09/11 14:24:02 monkeyson Exp $
+ * $Id: font.c,v 1.3 2002/09/26 21:38:33 bursa Exp $
*/
+#include <assert.h>
#include <stdio.h>
+#include "utf-8.h"
#include "netsurf/render/css.h"
-#include "netsurf/render/font.h"
+#include "netsurf/riscos/font.h"
#include "netsurf/render/utils.h"
#include "netsurf/desktop/gui.h"
#include "oslib/font.h"
/**
- * functions
+ * RISC OS fonts are 8-bit, so Unicode is displayed by combining many
+ * font manager fonts. Each font manager font must have 128 characters of
+ * Unicode in order, starting at character 128.
*/
-/** it is rather inefficient calling this all the time **/
-font_f riscos_font_css_to_handle(struct css_style* style)
-{
- int width = 12 * 16;
- int height = 12 * 16;
- char font_name[255];
+/**
+ * font id = font family * 4 + bold * 2 + slanted
+ * font family: 0 = sans-serif, 1 = serif, ...
+ */
- if (style->font_size.size == CSS_FONT_SIZE_LENGTH)
- width = height = style->font_size.value.length.value * 16;
+const char * const font_table[FONT_FAMILIES * 4][FONT_CHUNKS] = {
+ /* sans-serif */
+ { "Homerton.Medium\\EU0000",
+ "Homerton.Medium\\EU0080",
+ "Homerton.Medium\\EU0100" },
+ { "Homerton.Medium.Oblique\\EU0000",
+ "Homerton.Medium.Oblique\\EU0080",
+ "Homerton.Medium.Oblique\\EU0100" },
+ { "Homerton.Bold\\EU0000",
+ "Homerton.Bold\\EU0080",
+ "Homerton.Bold\\EU0100" },
+ { "Homerton.Bold.Oblique\\EU0000",
+ "Homerton.Bold.Oblique\\EU0080",
+ "Homerton.Bold.Oblique\\EU0100" },
+};
- strcpy(font_name, "Homerton.");
- if (style->font_weight == CSS_FONT_WEIGHT_BOLD)
- strcat(font_name, "Bold");
- else
- strcat(font_name, "Medium");
+/* 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 * 4];
+};
- if (style->font_style == CSS_FONT_STYLE_ITALIC || style->font_style == CSS_FONT_STYLE_OBLIQUE)
- strcat(font_name, ".Oblique");
+void font_close(struct font_data *data);
- return font_find_font(font_name, width, height, 0, 0, 0, 0);
-}
+/**
+ * functions
+ */
-unsigned long font_width(struct css_style * style, const char * text, unsigned int length)
+unsigned long font_width(struct font_data *font, const char * text, unsigned int length)
{
font_scan_block block;
os_error * error;
- font_f font;
+ char *text2;
+
+ assert(font != 0 && text != 0);
if (length == 0)
return 0;
@@ -48,20 +64,21 @@ unsigned long font_width(struct css_style * style, const char * text, unsigned i
block.letter.x = block.letter.y = 0;
block.split_char = -1;
- font = riscos_font_css_to_handle(style);
-
- error = xfont_scan_string(font, (char*) text,
- font_GIVEN_BLOCK | font_GIVEN_LENGTH | font_GIVEN_FONT | font_KERN | font_RETURN_BBOX,
+ text2 = font_utf8_to_string(font, text, length);
+ error = xfont_scan_string(font->handle[0], text2,
+ font_GIVEN_BLOCK | font_GIVEN_FONT | font_KERN | font_RETURN_BBOX,
0x7fffffff, 0x7fffffff,
&block,
- 0, length,
+ 0, 0,
0, 0, 0, 0);
if (error != 0) {
fprintf(stderr, "%s\n", error->errmess);
die("font_scan_string failed");
}
-// fprintf(stderr, "Stated length %d, strlen %d\n", (int)length, strlen(text));
+/* fprintf(stderr, "font_width: '%.*s' => '%s' => %i %i %i %i\n", length, text, text2, */
+/* block.bbox.x0, block.bbox.y0, block.bbox.x1, block.bbox.y1); */
+ free(text2);
if (length < 0x7fffffff)
{
@@ -82,33 +99,31 @@ unsigned long font_width(struct css_style * style, const char * text, unsigned i
// fprintf(stderr, "No space\n");*/
}
- font_lose_font(font);
-
return block.bbox.x1 / 800;
}
-void font_position_in_string(const char* text, struct css_style* style, int length, int x, int* char_offset, int* pixel_offset)
+void font_position_in_string(const char* text, struct font_data* font,
+ int length, int x, int* char_offset, int* pixel_offset)
{
- font_f font;
font_scan_block block;
char* split_point;
int x_out, y_out, length_out;
+ char *text2;
+
+ assert(font != 0 && text != 0);
block.space.x = block.space.y = 0;
block.letter.x = block.letter.y = 0;
block.split_char = -1;
- font = riscos_font_css_to_handle(style);
-
- xfont_scan_string(font, (char*) text,
- font_GIVEN_BLOCK | font_GIVEN_LENGTH |
- font_GIVEN_FONT | font_KERN | font_RETURN_CARET_POS,
+ text2 = font_utf8_to_string(font, text, length);
+ xfont_scan_string(font, text2,
+ font_GIVEN_BLOCK | font_GIVEN_FONT | font_KERN | font_RETURN_CARET_POS,
ro_x_units(x) * 400,
0x7fffffff,
- &block, 0, length,
+ &block, 0, 0,
&split_point, &x_out, &y_out, &length_out);
-
- font_lose_font(font);
+ free(text2);
*char_offset = (int)(split_point - text);
*pixel_offset = browser_x_units(x_out / 400);
@@ -116,3 +131,135 @@ void font_position_in_string(const char* text, struct css_style* style, int leng
return;
}
+
+struct font_set *font_new_set()
+{
+ struct font_set *set = xcalloc(1, sizeof(*set));
+ unsigned int i;
+
+ for (i = 0; i < FONT_FAMILIES * 4; i++)
+ set->font[i] = 0;
+
+ return set;
+}
+
+
+struct font_data *font_open(struct font_set *set, struct css_style *style)
+{
+ struct font_data *data;
+ unsigned int i;
+ unsigned int size = 16 * 11;
+ unsigned int f = 0;
+
+ assert(set != 0);
+
+ if (style->font_size.size == CSS_FONT_SIZE_LENGTH)
+ size = style->font_size.value.length.value * 16;
+
+ 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;
+ }
+
+ for (data = set->font[f]; data != 0; data = data->next)
+ if (data->size == size)
+ return data;
+
+ data = xcalloc(1, sizeof(*data));
+
+ for (i = 0; i < FONT_CHUNKS; i++) {
+ font_f handle = font_find_font(font_table[f][i], size, size, 0, 0, 0, 0);
+ data->handle[i] = handle;
+ }
+ data->size = size;
+
+ data->next = set->font[f];
+ set->font[f] = data;
+
+ return data;
+}
+
+
+void font_free_set(struct font_set *set)
+{
+ unsigned int i;
+ struct font_data *data, *next;
+
+ assert(set != 0);
+
+ for (i = 0; i < FONT_FAMILIES * 4; i++) {
+ for (data = set->font[i]; data != 0; data = next) {
+ next = data->next;
+ font_close(data);
+ }
+ }
+
+ free(set);
+}
+
+
+void font_close(struct font_data *data)
+{
+ unsigned int i;
+
+ for (i = 0; i < FONT_CHUNKS; i++)
+ font_lose_font(data->handle[i]);
+
+ free(data);
+}
+
+#define BUFFER_CHUNK 100
+
+char *font_utf8_to_string(struct font_data *font, const char *s, unsigned int length)
+{
+ unsigned long buffer_len = BUFFER_CHUNK;
+ char *d = xcalloc(buffer_len, sizeof(char));
+ unsigned int chunk0 = 0, chunk1;
+ unsigned int u, chars, i = 0, j = 0;
+
+ assert(font != 0 && s != 0);
+
+/* fprintf(stderr, "font_utf8_to_string: '%s'", s); */
+
+ while (j < length && s[j] != 0) {
+ u = sgetu8(s + j, &chars);
+ j += chars;
+ if (buffer_len < i + 5) {
+ buffer_len += BUFFER_CHUNK;
+ d = xrealloc(d, buffer_len * sizeof(char));
+ }
+ chunk1 = u / 0x80;
+ if (FONT_CHUNKS <= chunk1 || (u < 0x20 || (0x80 <= u && u <= 0x9f))) {
+ d[i++] = '?';
+ } else {
+ if (chunk0 != chunk1) {
+ d[i++] = font_COMMAND_FONT;
+ d[i++] = font->handle[chunk1];
+ chunk0 = chunk1;
+ }
+ d[i++] = 0x80 + (u % 0x80);
+ }
+ }
+ d[i] = 0;
+
+/* fprintf(stderr, " => '%s'\n", d); */
+
+ return d;
+}
+
diff --git a/riscos/font.h b/riscos/font.h
index ee3e4c2b2..24b5d0f5d 100644
--- a/riscos/font.h
+++ b/riscos/font.h
@@ -1,5 +1,5 @@
/**
- * $Id: font.h,v 1.1 2002/09/11 14:24:02 monkeyson Exp $
+ * $Id: font.h,v 1.2 2002/09/26 21:38:33 bursa Exp $
*/
#ifndef _NETSURF_RISCOS_FONT_H_
@@ -12,28 +12,31 @@
#include "netsurf/render/css.h"
#include "oslib/font.h"
-struct font_set;
typedef unsigned int font_id;
-struct font_split {
- unsigned long width;
- unsigned long height;
- const char * end;
+
+#define FONT_FAMILIES 1
+#define FONT_CHUNKS 3
+#define FONT_BOLD 2
+#define FONT_SLANTED 1
+
+struct font_set;
+struct font_data {
+ font_f handle[FONT_CHUNKS];
+ unsigned int size;
+ struct font_data *next;
};
/**
* interface
*/
-struct font_set * font_set_create(void);
-font_id font_add(struct font_set * font_set, const char * name, unsigned int weight,
- unsigned int size);
-void font_set_free(struct font_set * font_set);
-struct font_split font_split(struct font_set * font_set, font_id id, const char * text,
- unsigned long width, int force);
-unsigned long font_width(struct css_style * style, const char * text, unsigned int length);
-
-font_f riscos_font_css_to_handle(struct css_style* style);
+unsigned long font_width(struct font_data *font, const char * text, unsigned int length);
+void font_position_in_string(const char* text, struct font_data *font,
+ int length, int x, int* char_offset, int* pixel_offset);
-void font_position_in_string(const char* text, struct css_style* style, int length, int x, int* char_offset, int* pixel_offset);
+struct font_set *font_new_set();
+struct font_data *font_open(struct font_set *set, struct css_style *style);
+void font_free_set(struct font_set *set);
+char *font_utf8_to_string(struct font_data *data, const char *s, unsigned int length);
#endif
diff --git a/riscos/gui.c b/riscos/gui.c
index 15d38b540..b66a3b4a8 100644
--- a/riscos/gui.c
+++ b/riscos/gui.c
@@ -1,5 +1,5 @@
/**
- * $Id: gui.c,v 1.1 2002/09/11 14:24:02 monkeyson Exp $
+ * $Id: gui.c,v 1.2 2002/09/26 21:38:33 bursa Exp $
*/
#include "netsurf/riscos/font.h"
@@ -264,7 +264,7 @@ void ro_gui_window_redraw_box(gui_window* g, struct box * box, signed long x, si
struct box * c;
const char * const noname = "";
const char * name = noname;
- font_f font;
+ char *text;
switch (box->type)
{
@@ -299,8 +299,6 @@ void ro_gui_window_redraw_box(gui_window* g, struct box * box, signed long x, si
if (box->type == BOX_INLINE)
{
- font = riscos_font_css_to_handle(box->style);
-
if (g->data.browser.bw->current_content->data.html.text_selection.selected == 1)
{
struct box_position* start;
@@ -359,13 +357,13 @@ if (g->data.browser.bw->current_content->data.html.text_selection.selected == 1)
}
}
- font_paint(font, (char*) box->text,
- font_OS_UNITS | font_GIVEN_LENGTH | font_GIVEN_FONT | font_KERN,
+ text = font_utf8_to_string(box->font, box->text, box->length);
+ font_paint(box->font->handle[0], text,
+ font_OS_UNITS | font_GIVEN_FONT | font_KERN,
x + box->x * 2, y - box->y * 2 - box->height * 2,
NULL, NULL,
- box->length);
-
- font_lose_font(font);
+ 0);
+ free(text);
}
}