summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Bursa <james@netsurf-browser.org>2005-02-20 00:14:40 +0000
committerJames Bursa <james@netsurf-browser.org>2005-02-20 00:14:40 +0000
commitafb3ee60c93f3d6ea31839bc379f284a40c09e5f (patch)
treeb3f3f99fce225cab7e525f8d1b08b8e8b91f685e
parent0a3d61162504861df4f14b624e5b2efc9b2b34fc (diff)
downloadlibrufl-afb3ee60c93f3d6ea31839bc379f284a40c09e5f.tar.gz
librufl-afb3ee60c93f3d6ea31839bc379f284a40c09e5f.tar.bz2
[project @ 2005-02-20 00:14:40 by bursa]
Implement rufl_paint_transformed(). Fix repeated character bug with long strings. svn path=/import/rufl/; revision=2448
-rw-r--r--rufl.h27
-rw-r--r--rufl_paint.c106
2 files changed, 95 insertions, 38 deletions
diff --git a/rufl.h b/rufl.h
index f253e98..7016dd6 100644
--- a/rufl.h
+++ b/rufl.h
@@ -5,6 +5,9 @@
* Copyright 2005 James Bursa <james@semichrome.net>
*/
+#ifndef RUFL_H
+#define RUFL_H
+
#include <stdbool.h>
#include <stdlib.h>
#include "oslib/os.h"
@@ -28,10 +31,10 @@ typedef enum {
typedef enum {
- rufl_REGULAR,
- rufl_SLANTED,
- rufl_BOLD,
- rufl_BOLD_SLANTED,
+ rufl_REGULAR = 0,
+ rufl_SLANTED = 1,
+ rufl_BOLD = 2,
+ rufl_BOLD_SLANTED = 3,
} rufl_style;
@@ -64,6 +67,19 @@ rufl_code rufl_paint(const char *font_family, rufl_style font_style,
/**
+ * Render Unicode text with a transformation matrix.
+ *
+ * Only transformations which keep the x-axis direction unchanged are
+ * supported.
+ */
+
+rufl_code rufl_paint_transformed(const char *font_family, rufl_style font_style,
+ unsigned int font_size,
+ const char *string, size_t length,
+ int x, int y, os_trfm *trfm);
+
+
+/**
* Measure the width of Unicode text.
*/
@@ -96,3 +112,6 @@ void rufl_dump_state(void);
*/
void rufl_quit(void);
+
+
+#endif
diff --git a/rufl_paint.c b/rufl_paint.c
index c4280ed..de20ca0 100644
--- a/rufl_paint.c
+++ b/rufl_paint.c
@@ -14,28 +14,29 @@
typedef enum { rufl_PAINT, rufl_WIDTH, rufl_X_TO_OFFSET } rufl_action;
+#define rufl_PROCESS_CHUNK 200
static rufl_code rufl_process(rufl_action action,
const char *font_family, rufl_style font_style,
unsigned int font_size,
const char *string0, size_t length,
- int x, int y, int *width,
+ int x, int y, os_trfm *trfm, int *width,
int click_x, size_t *char_offset, int *actual_x);
static int rufl_family_list_cmp(const void *keyval, const void *datum);
static rufl_code rufl_process_span(rufl_action action,
unsigned short *s, unsigned int n,
unsigned int font, unsigned int font_size, int *x, int y,
- int click_x, size_t *offset);
+ os_trfm *trfm, int click_x, size_t *offset);
static rufl_code rufl_process_span_old(rufl_action action,
unsigned short *s, unsigned int n,
unsigned int font, unsigned int font_size, int *x, int y,
- int click_x, size_t *offset);
+ os_trfm *trfm, int click_x, size_t *offset);
static int rufl_unicode_map_search_cmp(const void *keyval, const void *datum);
static rufl_code rufl_process_not_available(rufl_action action,
unsigned short *s, unsigned int n,
unsigned int font_size, int *x, int y,
- int click_x, size_t *offset);
+ os_trfm *trfm, int click_x, size_t *offset);
static rufl_code rufl_place_in_cache(unsigned int font, unsigned int font_size,
font_f f);
@@ -51,7 +52,25 @@ rufl_code rufl_paint(const char *font_family, rufl_style font_style,
{
return rufl_process(rufl_PAINT,
font_family, font_style, font_size, string,
- length, x, y, 0, 0, 0, 0);
+ length, x, y, 0, 0, 0, 0, 0);
+}
+
+
+/**
+ * Render Unicode text with a transformation matrix.
+ *
+ * Only transformations which keep the x-axis direction unchanged are
+ * supported.
+ */
+
+rufl_code rufl_paint_transformed(const char *font_family, rufl_style font_style,
+ unsigned int font_size,
+ const char *string, size_t length,
+ int x, int y, os_trfm *trfm)
+{
+ return rufl_process(rufl_PAINT,
+ font_family, font_style, font_size, string,
+ length, x, y, trfm, 0, 0, 0, 0);
}
@@ -66,12 +85,13 @@ rufl_code rufl_width(const char *font_family, rufl_style font_style,
{
return rufl_process(rufl_WIDTH,
font_family, font_style, font_size, string,
- length, 0, 0, width, 0, 0, 0);
+ length, 0, 0, 0, width, 0, 0, 0);
}
/**
- * Find where in a string a x coordinate falls.
+ * Find the nearest character boundary in a string to where an x coordinate
+ * falls.
*/
rufl_code rufl_x_to_offset(const char *font_family, rufl_style font_style,
@@ -82,7 +102,7 @@ rufl_code rufl_x_to_offset(const char *font_family, rufl_style font_style,
{
return rufl_process(rufl_X_TO_OFFSET,
font_family, font_style, font_size, string,
- length, 0, 0, 0, click_x, char_offset, actual_x);
+ length, 0, 0, 0, 0, click_x, char_offset, actual_x);
}
@@ -94,17 +114,17 @@ rufl_code rufl_process(rufl_action action,
const char *font_family, rufl_style font_style,
unsigned int font_size,
const char *string0, size_t length,
- int x, int y, int *width,
+ int x, int y, os_trfm *trfm, int *width,
int click_x, size_t *char_offset, int *actual_x)
{
- unsigned short s[80];
+ unsigned short s[rufl_PROCESS_CHUNK];
unsigned int font;
unsigned int font0, font1;
unsigned int n;
unsigned int u;
size_t offset;
size_t offset_u;
- size_t offset_map[80];
+ size_t offset_map[rufl_PROCESS_CHUNK];
char **family;
const char *string = string0;
struct rufl_character_set *charset;
@@ -151,7 +171,7 @@ rufl_code rufl_process(rufl_action action,
n = 1;
font0 = font1;
/* invariant: s[0..n) is in font font0 */
- while (0 < length && n < 70 && font1 == font0) {
+ while (0 < length && n < rufl_PROCESS_CHUNK && font1 == font0) {
offset_u = string - string0;
rufl_utf8_read(string, length, u);
s[n] = u;
@@ -163,6 +183,8 @@ rufl_code rufl_process(rufl_action action,
if (font1 == font0)
n++;
}
+ if (n == rufl_PROCESS_CHUNK)
+ n--;
s[n] = 0;
offset_map[n] = offset_u;
if (length == 0 && font1 == font0)
@@ -170,13 +192,16 @@ rufl_code rufl_process(rufl_action action,
if (font0 == NOT_AVAILABLE)
code = rufl_process_not_available(action, s, n,
- font_size, &x, y, click_x, &offset);
+ font_size, &x, y, trfm, click_x,
+ &offset);
else if (rufl_old_font_manager)
code = rufl_process_span_old(action, s, n, font0,
- font_size, &x, y, click_x, &offset);
+ font_size, &x, y, trfm, click_x,
+ &offset);
else
code = rufl_process_span(action, s, n, font0,
- font_size, &x, y, click_x, &offset);
+ font_size, &x, y, trfm, click_x,
+ &offset);
if (action == rufl_X_TO_OFFSET && (offset < n || click_x < x))
break;
@@ -211,7 +236,7 @@ int rufl_family_list_cmp(const void *keyval, const void *datum)
rufl_code rufl_process_span(rufl_action action,
unsigned short *s, unsigned int n,
unsigned int font, unsigned int font_size, int *x, int y,
- int click_x, size_t *offset)
+ os_trfm *trfm, int click_x, size_t *offset)
{
char font_name[80];
unsigned short *split_point;
@@ -247,9 +272,11 @@ rufl_code rufl_process_span(rufl_action action,
if (action == rufl_PAINT) {
/* paint span */
rufl_fm_error = xfont_paint(f, (const char *) s,
- font_OS_UNITS | font_GIVEN_LENGTH |
+ font_OS_UNITS |
+ (trfm ? font_GIVEN_TRFM : 0) |
+ font_GIVEN_LENGTH |
font_GIVEN_FONT | font_KERN | font_GIVEN16_BIT,
- *x, y, 0, 0, n * 2);
+ *x, y, 0, trfm, n * 2);
if (rufl_fm_error) {
xfont_lose_font(f);
return rufl_FONT_MANAGER_ERROR;
@@ -259,17 +286,20 @@ rufl_code rufl_process_span(rufl_action action,
/* increment x by width of span */
if (action == rufl_X_TO_OFFSET) {
rufl_fm_error = xfont_scan_string(f, (const char *) s,
+ (trfm ? font_GIVEN_TRFM : 0) |
font_GIVEN_LENGTH | font_GIVEN_FONT |
font_KERN | font_GIVEN16_BIT |
font_RETURN_CARET_POS,
- (click_x - *x) * 400, 0x7fffffff, 0, 0, n * 2,
+ (click_x - *x) * 400, 0x7fffffff, 0, trfm,
+ n * 2,
(char **) &split_point, &x_out, &y_out, 0);
*offset = split_point - s;
} else {
rufl_fm_error = xfont_scan_string(f, (const char *) s,
+ (trfm ? font_GIVEN_TRFM : 0) |
font_GIVEN_LENGTH | font_GIVEN_FONT |
font_KERN | font_GIVEN16_BIT,
- 0x7fffffff, 0x7fffffff, 0, 0, n * 2,
+ 0x7fffffff, 0x7fffffff, 0, trfm, n * 2,
0, &x_out, &y_out, 0);
}
if (rufl_fm_error) {
@@ -290,9 +320,9 @@ rufl_code rufl_process_span(rufl_action action,
rufl_code rufl_process_span_old(rufl_action action,
unsigned short *s, unsigned int n,
unsigned int font, unsigned int font_size, int *x, int y,
- int click_x, size_t *offset)
+ os_trfm *trfm, int click_x, size_t *offset)
{
- char s2[80];
+ char s2[rufl_PROCESS_CHUNK];
char *split_point;
const char *font_name = rufl_font_list[font].identifier;
int x_out, y_out;
@@ -336,8 +366,9 @@ rufl_code rufl_process_span_old(rufl_action action,
if (action == rufl_PAINT) {
/* paint span */
rufl_fm_error = xfont_paint(f, s2, font_OS_UNITS |
+ (trfm ? font_GIVEN_TRFM : 0) |
font_GIVEN_LENGTH | font_GIVEN_FONT | font_KERN,
- *x, y, 0, 0, n);
+ *x, y, 0, trfm, n);
if (rufl_fm_error) {
xfont_lose_font(f);
return rufl_FONT_MANAGER_ERROR;
@@ -347,15 +378,17 @@ rufl_code rufl_process_span_old(rufl_action action,
/* increment x by width of span */
if (action == rufl_X_TO_OFFSET) {
rufl_fm_error = xfont_scan_string(f, s2,
+ (trfm ? font_GIVEN_TRFM : 0) |
font_GIVEN_LENGTH | font_GIVEN_FONT |
font_KERN | font_RETURN_CARET_POS,
- (click_x - *x) * 400, 0x7fffffff, 0, 0, n,
+ (click_x - *x) * 400, 0x7fffffff, 0, trfm, n,
&split_point, &x_out, &y_out, 0);
*offset = split_point - s2;
} else {
rufl_fm_error = xfont_scan_string(f, s2,
+ (trfm ? font_GIVEN_TRFM : 0) |
font_GIVEN_LENGTH | font_GIVEN_FONT | font_KERN,
- 0x7fffffff, 0x7fffffff, 0, 0, n,
+ 0x7fffffff, 0x7fffffff, 0, trfm, n,
0, &x_out, &y_out, 0);
}
if (rufl_fm_error) {
@@ -387,22 +420,24 @@ int rufl_unicode_map_search_cmp(const void *keyval, const void *datum)
rufl_code rufl_process_not_available(rufl_action action,
unsigned short *s, unsigned int n,
unsigned int font_size, int *x, int y,
- int click_x, size_t *offset)
+ os_trfm *trfm, int click_x, size_t *offset)
{
char missing[] = "0000";
+ int dx = 7 * font_size *
+ (trfm ? trfm->entries[0][0] / 0x10000 : 1) / 64;
unsigned int i;
font_f f;
rufl_code code;
if (action == rufl_WIDTH) {
- *x += 7 * font_size / 64;
+ *x += n * dx;
return rufl_OK;
} else if (action == rufl_X_TO_OFFSET) {
- if (click_x - *x < (int) (n * 7 * font_size / 64))
- *offset = (click_x - *x) / (7 * font_size / 64);
+ if (click_x - *x < (int) (n * dx))
+ *offset = (click_x - *x) / dx;
else
*offset = n;
- *x += *offset * (7 * font_size / 64);
+ *x += *offset * dx;
return rufl_OK;
}
@@ -437,20 +472,23 @@ rufl_code rufl_process_not_available(rufl_action action,
/* first two characters in top row */
rufl_fm_error = xfont_paint(f, missing, font_OS_UNITS |
+ (trfm ? font_GIVEN_TRFM : 0) |
font_GIVEN_LENGTH | font_GIVEN_FONT | font_KERN,
- *x, y + 5 * font_size / 64,
- 0, 0, 2);
+ *x, y + (trfm ? trfm->entries[1][1] / 0x10000 :
+ 1) * 5 * font_size / 64,
+ 0, trfm, 2);
if (rufl_fm_error)
return rufl_FONT_MANAGER_ERROR;
/* last two characters underneath */
rufl_fm_error = xfont_paint(f, missing + 2, font_OS_UNITS |
+ (trfm ? font_GIVEN_TRFM : 0) |
font_GIVEN_LENGTH | font_GIVEN_FONT | font_KERN,
- *x, y, 0, 0, 2);
+ *x, y, 0, trfm, 2);
if (rufl_fm_error)
return rufl_FONT_MANAGER_ERROR;
- *x += 7 * font_size / 64;
+ *x += dx;
}
return rufl_OK;