diff options
author | Behdad Esfahbod <behdad@gnome.org> | 2006-02-01 02:35:18 +0000 |
---|---|---|
committer | Behdad Esfahbod <behdad@src.gnome.org> | 2006-02-01 02:35:18 +0000 |
commit | f969714ca865b81f7859acda4ffa578c873fdba6 (patch) | |
tree | 4a4e9f36a67686c0f73c684b07269c4fb5ed013c /pango | |
parent | ce4f52f71600a4480c17d51e43c889eba17cf70c (diff) | |
download | pango-f969714ca865b81f7859acda4ffa578c873fdba6.tar.gz |
pango/pangocairo-private.h, pango/pangocairo-font.c, Hint hexbox. Also
2006-01-31 Behdad Esfahbod <behdad@gnome.org>
* pango/pangocairo-private.h, pango/pangocairo-font.c,
* pango/pangocairo-render.c: Hint hexbox. Also draw a singl-row
hexbox for very small sizes.
Diffstat (limited to 'pango')
-rw-r--r-- | pango/Makefile.am | 3 | ||||
-rw-r--r-- | pango/pangocairo-font.c | 100 | ||||
-rw-r--r-- | pango/pangocairo-private.h | 5 | ||||
-rw-r--r-- | pango/pangocairo-render.c | 51 |
4 files changed, 107 insertions, 52 deletions
diff --git a/pango/Makefile.am b/pango/Makefile.am index 1e98d731..050d878a 100644 --- a/pango/Makefile.am +++ b/pango/Makefile.am @@ -252,7 +252,8 @@ libpangocairo_1_0_la_LDFLAGS = $(LIBRARY_LIBTOOL_OPTIONS) libpangocairo_1_0_la_LIBADD = \ libpango-$(PANGO_API_VERSION).la \ $(GLIB_LIBS) \ - $(CAIRO_LIBS) + $(CAIRO_LIBS) \ + $(libm) libpangocairo_1_0_la_DEPENDENCIES = \ libpango-$(PANGO_API_VERSION).la libpangocairo_1_0_la_SOURCES = \ diff --git a/pango/pangocairo-font.c b/pango/pangocairo-font.c index ee98020f..a99676ac 100644 --- a/pango/pangocairo-font.c +++ b/pango/pangocairo-font.c @@ -21,6 +21,8 @@ #include <config.h> +#include <math.h> + #include "pango-impl-utils.h" #include "pangocairo.h" #include "pangocairo-private.h" @@ -118,7 +120,13 @@ _pango_cairo_get_hex_box_info (PangoCairoFont *cfont) PangoFont *mini_font; PangoCairoFont *mini_cfont; PangoCairoHexBoxInfo *hbi; + + /* for metrics hinting */ + double scale_x, scale_x_inv, scale_y, scale_y_inv; + int i; + int rows; + double pad; double width = 0; double height = 0; cairo_font_extents_t font_extents; @@ -131,24 +139,57 @@ _pango_cairo_get_hex_box_info (PangoCairoFont *cfont) if (hbi) return hbi; + scaled_font = _pango_cairo_font_get_scaled_font (cfont); - mini_desc = pango_font_description_new (); - desc = pango_font_describe ((PangoFont *)cfont); - - pango_font_description_set_family_static (mini_desc, "mono-space"); + /* prepare for some hinting */ + { + cairo_matrix_t ctm; + double x, y; + cairo_scaled_font_get_ctm (scaled_font, &ctm); + + x = 1.; y = 0.; + cairo_matrix_transform_distance (&ctm, &x, &y); + scale_x = sqrt (x*x + y*y); + scale_x_inv = 1 / scale_x; + + x = 0.; y = 1.; + cairo_matrix_transform_distance (&ctm, &x, &y); + scale_y = sqrt (x*x + y*y); + scale_y_inv = 1 / scale_y; + } - /* set size on mini_desc */ +/* we hint to the nearest device units */ +#define HINT(value, scale, scale_inv) (ceil ((value) * scale) * scale_inv) +#define HINT_X(value) HINT ((value), scale_x, scale_x_inv) +#define HINT_Y(value) HINT ((value), scale_y, scale_y_inv) + + /* create mini_font description */ { - int new_size; - new_size = pango_font_description_get_size (desc) / 2.4 + .9; + double size, mini_size; + + desc = pango_font_describe ((PangoFont *)cfont); + size = pango_font_description_get_size (desc) / (1.*PANGO_SCALE); + + mini_desc = pango_font_description_new (); + pango_font_description_set_family_static (mini_desc, "mono-space"); + + /* TODO: The stuff here should give a shit to whether it's + * absolute size or not. */ + rows = 2; + mini_size = HINT_Y (size / 2.4); + if (mini_size < 5.0) + { + rows = 1; + mini_size = MIN (size, 5.0); + } if (pango_font_description_get_size_is_absolute (desc)) - pango_font_description_set_absolute_size (mini_desc, new_size); + pango_font_description_set_absolute_size (mini_desc, mini_size * PANGO_SCALE); else - pango_font_description_set_size (mini_desc, new_size); - } + pango_font_description_set_size (mini_desc, mini_size * PANGO_SCALE); - pango_font_description_free (desc); + pango_font_description_free (desc); + } /* load mini_font */ { @@ -161,15 +202,14 @@ _pango_cairo_get_hex_box_info (PangoCairoFont *cfont) pango_context_set_language (context, pango_language_from_string ("en")); mini_font = pango_font_map_load_font (fontmap, context, mini_desc); + pango_font_description_free (mini_desc); g_object_unref (context); g_object_unref (fontmap); } - pango_font_description_free (mini_desc); mini_cfont = (PangoCairoFont *) mini_font; - scaled_font = _pango_cairo_font_get_scaled_font (cfont); scaled_mini_font = _pango_cairo_font_get_scaled_font (mini_cfont); surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 0, 0); @@ -197,16 +237,20 @@ _pango_cairo_get_hex_box_info (PangoCairoFont *cfont) hbi = g_slice_new (PangoCairoHexBoxInfo); hbi->font = mini_font; + hbi->rows = rows; - hbi->digit_width = width; - hbi->digit_height = height; + hbi->digit_width = HINT_X (width); + hbi->digit_height = HINT_Y (height); - hbi->pad = hbi->digit_height / 8; + pad = MIN (hbi->digit_width / 10, hbi->digit_height / 12); + hbi->pad_x = HINT_X (pad); + hbi->pad_y = HINT_Y (pad); + hbi->line_width = MIN (hbi->pad_x, hbi->pad_y); + + hbi->box_height = 3 * hbi->pad_y + rows * (hbi->pad_y + hbi->digit_height); + hbi->box_descent = HINT_Y (font_extents.descent - + (font_extents.ascent + font_extents.descent - hbi->box_height) / 2); - hbi->box_height = 5 * hbi->pad + 2 * hbi->digit_height; - hbi->box_descent = font_extents.descent - - (font_extents.ascent + font_extents.descent - hbi->box_height) / 2; - g_object_set_data_full (G_OBJECT (cfont), "hex_box_info", hbi, (GDestroyNotify)_pango_cairo_hex_box_info_destroy); return hbi; @@ -219,25 +263,27 @@ _pango_cairo_get_glyph_extents_missing (PangoCairoFont *cfont, PangoRectangle *logical_rect) { PangoCairoHexBoxInfo *hbi; - gint cols; + gint rows, cols; - cols = (glyph & ~PANGO_CAIRO_UNKNOWN_FLAG) > 0xffff ? 3 : 2; hbi = _pango_cairo_get_hex_box_info (cfont); + + rows = hbi->rows; + cols = ((glyph & ~PANGO_CAIRO_UNKNOWN_FLAG) > 0xffff ? 6 : 4) / rows; if (ink_rect) { - ink_rect->x = PANGO_SCALE * hbi->pad; + ink_rect->x = PANGO_SCALE * hbi->pad_x; ink_rect->y = PANGO_SCALE * (hbi->box_descent - hbi->box_height); - ink_rect->width = PANGO_SCALE * (3 * hbi->pad + cols * (hbi->digit_width + hbi->pad)); + ink_rect->width = PANGO_SCALE * (3 * hbi->pad_x + cols * (hbi->digit_width + hbi->pad_x)); ink_rect->height = PANGO_SCALE * hbi->box_height; } if (logical_rect) { logical_rect->x = 0; - logical_rect->y = PANGO_SCALE * (hbi->box_descent - (hbi->box_height + hbi->pad)); - logical_rect->width = PANGO_SCALE * (5 * hbi->pad + cols * (hbi->digit_width + hbi->pad)); - logical_rect->height = PANGO_SCALE * (hbi->box_height + 2 * hbi->pad); + logical_rect->y = PANGO_SCALE * (hbi->box_descent - (hbi->box_height + hbi->pad_y)); + logical_rect->width = PANGO_SCALE * (5 * hbi->pad_x + cols * (hbi->digit_width + hbi->pad_x)); + logical_rect->height = PANGO_SCALE * (hbi->box_height + 2 * hbi->pad_y); } } diff --git a/pango/pangocairo-private.h b/pango/pangocairo-private.h index 48d3c0f3..5f78b690 100644 --- a/pango/pangocairo-private.h +++ b/pango/pangocairo-private.h @@ -89,9 +89,12 @@ typedef struct _PangoCairoHexBoxInfo PangoCairoHexBoxInfo; struct _PangoCairoHexBoxInfo { PangoFont *font; + int rows; double digit_width; double digit_height; - double pad; + double pad_x; + double pad_y; + double line_width; double box_descent; double box_height; }; diff --git a/pango/pangocairo-render.c b/pango/pangocairo-render.c index 4abed6f8..9d539260 100644 --- a/pango/pangocairo-render.c +++ b/pango/pangocairo-render.c @@ -66,10 +66,9 @@ _pango_cairo_renderer_draw_unknown_glyph (PangoCairoRenderer *crenderer, double cy) { char buf[7]; - double ys[2]; - double xs[3]; + double x0, y0; int row, col; - int cols; + int rows, cols; char hexbox_string[2] = {0, 0}; double temp_x, temp_y; PangoCairoHexBoxInfo *hbi; @@ -79,45 +78,49 @@ _pango_cairo_renderer_draw_unknown_glyph (PangoCairoRenderer *crenderer, ch = gi->glyph & ~PANGO_CAIRO_UNKNOWN_FLAG; - cols = ch > 0xffff ? 3 : 2; - g_snprintf (buf, sizeof(buf), cols == 2 ? "%04X" : "%06X", ch); - - ys[1] = cy + hbi->box_descent - hbi->pad * 2; - ys[0] = ys[1] - hbi->digit_height - hbi->pad; - - xs[0] = cx + hbi->pad * 3.0; - xs[1] = xs[0] + hbi->digit_width + hbi->pad; - xs[2] = xs[1] + hbi->digit_width + hbi->pad; + rows = hbi->rows; + cols = (ch > 0xffff ? 6 : 4) / rows; + g_snprintf (buf, sizeof(buf), (ch > 0xffff) ? "%06X" : "%04X", ch); cairo_save (crenderer->cr); cairo_get_current_point (crenderer->cr, &temp_x, &temp_y); cairo_rectangle (crenderer->cr, - cx + hbi->pad * 1.5, - cy + hbi->box_descent - hbi->pad * 0.5, - (double)gi->geometry.width / PANGO_SCALE - 3 * hbi->pad, - -(hbi->box_height - hbi->pad)); + cx + hbi->pad_x * 1.5, + cy + hbi->box_descent - hbi->pad_y * 0.5, + (double)gi->geometry.width / PANGO_SCALE - 3 * hbi->pad_x, + -(hbi->box_height - hbi->pad_y)); if (!crenderer->do_path) { cairo_save (crenderer->cr); - cairo_set_line_width (crenderer->cr, hbi->pad); + cairo_set_line_width (crenderer->cr, hbi->line_width); cairo_stroke (crenderer->cr); cairo_restore (crenderer->cr); } _pango_cairo_font_install (PANGO_CAIRO_FONT (hbi->font), crenderer->cr); - for (row = 0; row < 2; row++) + + x0 = cx + hbi->pad_x * 3.0; + y0 = cy + hbi->box_descent - hbi->pad_y * 2; + + for (row = 0; row < rows; row++) + { + double y = y0 - (rows - 1 - row) * (hbi->digit_height + hbi->pad_y); for (col = 0; col < cols; col++) { + double x = x0 + col * (hbi->digit_width + hbi->pad_x); + + cairo_move_to (crenderer->cr, x, y); + hexbox_string[0] = buf[row * cols + col]; - cairo_move_to (crenderer->cr, xs[col], ys[row]); if (crenderer->do_path) cairo_text_path (crenderer->cr, hexbox_string); else cairo_show_text (crenderer->cr, hexbox_string); } + } cairo_move_to (crenderer->cr, temp_x, temp_y); cairo_restore (crenderer->cr); @@ -212,11 +215,13 @@ pango_cairo_renderer_draw_rectangle (PangoRenderer *renderer, crenderer->x_offset + (double)x / PANGO_SCALE, crenderer->y_offset + (double)y / PANGO_SCALE, (double)width / PANGO_SCALE, (double)height / PANGO_SCALE); + if (!crenderer->do_path) - cairo_fill (crenderer->cr); - - if (!crenderer->do_path) - cairo_restore (crenderer->cr); + { + cairo_fill (crenderer->cr); + + cairo_restore (crenderer->cr); + } } /* Draws an error underline that looks like one of: |