summaryrefslogtreecommitdiff
path: root/pango
diff options
context:
space:
mode:
authorBehdad Esfahbod <behdad@gnome.org>2006-02-01 02:35:18 +0000
committerBehdad Esfahbod <behdad@src.gnome.org>2006-02-01 02:35:18 +0000
commitf969714ca865b81f7859acda4ffa578c873fdba6 (patch)
tree4a4e9f36a67686c0f73c684b07269c4fb5ed013c /pango
parentce4f52f71600a4480c17d51e43c889eba17cf70c (diff)
downloadpango-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.am3
-rw-r--r--pango/pangocairo-font.c100
-rw-r--r--pango/pangocairo-private.h5
-rw-r--r--pango/pangocairo-render.c51
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: