diff options
author | James Bursa <james@netsurf-browser.org> | 2005-02-20 00:14:40 +0000 |
---|---|---|
committer | James Bursa <james@netsurf-browser.org> | 2005-02-20 00:14:40 +0000 |
commit | afb3ee60c93f3d6ea31839bc379f284a40c09e5f (patch) | |
tree | b3f3f99fce225cab7e525f8d1b08b8e8b91f685e /rufl_paint.c | |
parent | 0a3d61162504861df4f14b624e5b2efc9b2b34fc (diff) | |
download | librufl-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
Diffstat (limited to 'rufl_paint.c')
-rw-r--r-- | rufl_paint.c | 106 |
1 files changed, 72 insertions, 34 deletions
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; |