diff options
author | Behdad Esfahbod <behdad@gnome.org> | 2007-12-10 08:31:33 +0000 |
---|---|---|
committer | Behdad Esfahbod <behdad@src.gnome.org> | 2007-12-10 08:31:33 +0000 |
commit | f4fad0c741636d017aefd76d58e271466696cc6f (patch) | |
tree | 2e77cb9df99173cd841609f5ccdb4a40136dcd21 /pango/pangoxft-render.c | |
parent | ed7f7ab40893d20bab5a221cc95cfcba965cd93e (diff) | |
download | pango-f4fad0c741636d017aefd76d58e271466696cc6f.tar.gz |
Bug 478914 – Use something invalid instead of '?' when validating input
2007-12-10 Behdad Esfahbod <behdad@gnome.org>
Bug 478914 – Use something invalid instead of '?' when validating
input text
* pango/pango-layout.c (pango_layout_set_text): Set invalid input
bytes to -1, which gives a unichar value of -1, and eventually a
glyph value of -1, aka PANGO_GLYPH_INVALID_INPUT.
* pango/fonts.c (pango_font_get_glyph_extents),
(pango_font_get_metrics), (pango_font_get_font_map):
* pango/modules.c (build_map):
* pango/pango-context.c (get_script), (get_shaper_and_font),
(string_from_script), (itemize_state_process_run):
* pango/pango-coverage.c (pango_coverage_get):
* pango/pango-impl-utils.h:
* pango/pango-utils.c:
* pango/pangocairo-font.c (pango_cairo_font_get_scaled_font),
(_pango_cairo_font_private_get_hex_box_info),
(_pango_cairo_font_private_get_glyph_extents_missing):
* pango/pangocairo-private.h:
* pango/pangocairo-render.c (_pango_cairo_renderer_draw_frame),
(_pango_cairo_renderer_draw_box_glyph),
(_pango_cairo_renderer_draw_unknown_glyph):
* pango/pangofc-fontmap.c (pango_fc_font_map_get_patterns):
* pango/pangoft2-private.h:
* pango/pangoft2-render.c (pango_ft2_font_render_box_glyph),
(pango_ft2_font_render_glyph), (pango_ft2_renderer_draw_glyph):
* pango/pangoft2.c (pango_ft2_font_get_face),
(pango_ft2_font_get_glyph_extents):
* pango/pangox.c (pango_x_find_subfont), (pango_x_render):
* pango/pangoxft-font.c (_pango_xft_font_get_mini_font),
(get_glyph_extents_missing), (pango_xft_font_get_font):
* pango/pangoxft-private.h:
* pango/pangoxft-render.c (get_total_matrix), (draw_box),
(_pango_xft_renderer_draw_box_glyph),
(_pango_xft_renderer_draw_unknown_glyph),
(pango_xft_renderer_draw_glyphs):
* pango/shape.c (pango_shape):
Render PANGO_GLYPH_INVALID_INPUT to a single-width box with a cross
inside. Also cleanup spewed warnings and warn at the source, where
we fail to find a shaper, instead of at every location that we see
a NULL font.
* pango/pango-font.h:
* docs/pango-sections.txt:
* docs/tmpl/glyphs.sgml:
New public macro:
PANGO_GLYPH_INVALID_INPUT
svn path=/trunk/; revision=2519
Diffstat (limited to 'pango/pangoxft-render.c')
-rw-r--r-- | pango/pangoxft-render.c | 111 |
1 files changed, 90 insertions, 21 deletions
diff --git a/pango/pangoxft-render.c b/pango/pangoxft-render.c index efaae64e..5505ba5c 100644 --- a/pango/pangoxft-render.c +++ b/pango/pangoxft-render.c @@ -290,12 +290,31 @@ box_in_bounds (PangoRenderer *renderer, } static void +get_total_matrix (PangoMatrix *total, + const PangoMatrix *global, + double x, + double y, + double width, + double height) +{ + PangoMatrix local = PANGO_MATRIX_INIT; + gdouble angle = atan2 (height, width); + + pango_matrix_translate (&local, x, y); + pango_matrix_rotate (&local, -angle * (180. / G_PI)); + + *total = *global; + pango_matrix_concat (total, &local); +} + +static void draw_box (PangoRenderer *renderer, gint line_width, gint x, gint y, gint width, - gint height) + gint height, + gboolean invalid) { pango_renderer_draw_rectangle (renderer, PANGO_RENDER_PART_FOREGROUND, x, y, width, line_width); @@ -305,13 +324,49 @@ draw_box (PangoRenderer *renderer, x + width - line_width, y + line_width, line_width, height - line_width * 2); pango_renderer_draw_rectangle (renderer, PANGO_RENDER_PART_FOREGROUND, x, y + height - line_width, width, line_width); + + if (invalid) + { + int length; + double in_width, in_height; + PangoMatrix orig_matrix = PANGO_MATRIX_INIT, new_matrix; + const PangoMatrix *porig_matrix; + + in_width = pango_units_to_double (width - 2 * line_width); + in_height = pango_units_to_double (height - 2 * line_width); + length = PANGO_SCALE * sqrt (in_width*in_width + in_height*in_height); + + porig_matrix = pango_renderer_get_matrix (renderer); + if (porig_matrix) + { + orig_matrix = *porig_matrix; + porig_matrix = &orig_matrix; + } + + get_total_matrix (&new_matrix, &orig_matrix, + pango_units_to_double (x + line_width), pango_units_to_double (y + line_width), + in_width, in_height); + pango_renderer_set_matrix (renderer, &new_matrix); + pango_renderer_draw_rectangle (renderer, PANGO_RENDER_PART_FOREGROUND, + 0, -line_width / 2, length, line_width); + + get_total_matrix (&new_matrix, &orig_matrix, + pango_units_to_double (x + line_width), pango_units_to_double (y + height - line_width), + in_width, -in_height); + pango_renderer_set_matrix (renderer, &new_matrix); + pango_renderer_draw_rectangle (renderer, PANGO_RENDER_PART_FOREGROUND, + 0, -line_width / 2, length, line_width); + + pango_renderer_set_matrix (renderer, porig_matrix); + } } static void _pango_xft_renderer_draw_box_glyph (PangoRenderer *renderer, PangoGlyphInfo *gi, int glyph_x, - int glyph_y) + int glyph_y, + gboolean invalid) { int x = glyph_x + PANGO_SCALE; int y = glyph_y - PANGO_SCALE * (PANGO_UNKNOWN_GLYPH_HEIGHT - 1); @@ -319,7 +374,7 @@ _pango_xft_renderer_draw_box_glyph (PangoRenderer *renderer, int height = PANGO_SCALE * (PANGO_UNKNOWN_GLYPH_HEIGHT - 2); if (box_in_bounds (renderer, x, y, width, height)) - draw_box (renderer, PANGO_SCALE, x, y, width, height); + draw_box (renderer, PANGO_SCALE, x, y, width, height, invalid); } static void @@ -335,17 +390,33 @@ _pango_xft_renderer_draw_unknown_glyph (PangoRenderer *renderer, int xs[4]; int row, col; int cols; - PangoGlyph glyph; + gunichar ch; + gboolean invalid_input; + + PangoFont *mini_font; + XftFont *mini_xft_font; - PangoFont *mini_font = _pango_xft_font_get_mini_font (xfont); - XftFont *mini_xft_font = pango_xft_font_get_font (mini_font); + ch = gi->glyph & ~PANGO_GLYPH_UNKNOWN_FLAG; + if (G_UNLIKELY (gi->glyph == PANGO_GLYPH_INVALID_INPUT || ch > 0x10FFFF)) + { + invalid_input = TRUE; + cols = 1; + } + else + { + invalid_input = FALSE; + cols = ch > 0xffff ? 3 : 2; + g_snprintf (buf, sizeof(buf), (ch > 0xffff) ? "%06X" : "%04X", ch); + } + + mini_font = _pango_xft_font_get_mini_font (xfont); + mini_xft_font = pango_xft_font_get_font (mini_font); if (!mini_xft_font) { - _pango_xft_renderer_draw_box_glyph (renderer, gi, glyph_x, glyph_y); + _pango_xft_renderer_draw_box_glyph (renderer, gi, glyph_x, glyph_y, invalid_input); return; } - glyph = gi->glyph & ~PANGO_GLYPH_UNKNOWN_FLAG; ys[0] = glyph_y - PANGO_SCALE * xft_font->ascent + PANGO_SCALE * (((xft_font->ascent + xft_font->descent) - (xfont->mini_height * 2 + xfont->mini_pad * 5 + PANGO_SCALE / 2) / PANGO_SCALE) / 2); ys[1] = ys[0] + 2 * xfont->mini_pad + xfont->mini_height; @@ -356,17 +427,6 @@ _pango_xft_renderer_draw_unknown_glyph (PangoRenderer *renderer, xs[2] = xs[1] + xfont->mini_width + xfont->mini_pad; xs[3] = xs[2] + xfont->mini_width + xfont->mini_pad; - if (glyph > 0xffff) - { - cols = 3; - g_snprintf (buf, sizeof(buf), "%06X", glyph); - } - else - { - cols = 2; - g_snprintf (buf, sizeof(buf), "%04X", glyph); - } - if (box_in_bounds (renderer, xs[0], ys[0], xfont->mini_width * cols + xfont->mini_pad * (2 * cols + 1), @@ -376,7 +436,11 @@ _pango_xft_renderer_draw_unknown_glyph (PangoRenderer *renderer, draw_box (renderer, xfont->mini_pad, xs[0], ys[0], xfont->mini_width * cols + xfont->mini_pad * (2 * cols + 1), - xfont->mini_height * 2 + xfont->mini_pad * 5); + xfont->mini_height * 2 + xfont->mini_pad * 5, + invalid_input); + + if (invalid_input) + return; for (row = 0; row < 2; row++) for (col = 0; col < cols; col++) @@ -414,7 +478,12 @@ pango_xft_renderer_draw_glyphs (PangoRenderer *renderer, int glyph_x = x + x_off + gi->geometry.x_offset; int glyph_y = y + gi->geometry.y_offset; - _pango_xft_renderer_draw_box_glyph (renderer, gi, glyph_x, glyph_y); + _pango_xft_renderer_draw_unknown_glyph (renderer, + xfont, + xft_font, + gi, + glyph_x, + glyph_y); } x_off += gi->geometry.width; |