diff options
Diffstat (limited to 'pango')
-rw-r--r-- | pango/fonts.c | 22 | ||||
-rw-r--r-- | pango/modules.c | 8 | ||||
-rw-r--r-- | pango/pango-engine.c | 29 | ||||
-rw-r--r-- | pango/pango-engine.h | 4 | ||||
-rw-r--r-- | pango/pango-layout.c | 18 | ||||
-rw-r--r-- | pango/pango-renderer.c | 2 | ||||
-rw-r--r-- | pango/pango-types.h | 2 | ||||
-rw-r--r-- | pango/pangocairo-atsuifont.c | 57 | ||||
-rw-r--r-- | pango/pangocairo-fcfont.c | 6 | ||||
-rw-r--r-- | pango/pangocairo-font.c | 17 | ||||
-rw-r--r-- | pango/pangocairo-private.h | 8 | ||||
-rw-r--r-- | pango/pangocairo-render.c | 81 | ||||
-rw-r--r-- | pango/pangocairo-win32font.c | 4 | ||||
-rw-r--r-- | pango/pangofc-decoder.c | 4 | ||||
-rw-r--r-- | pango/pangofc-font.c | 10 | ||||
-rw-r--r-- | pango/pangoft2-private.h | 8 | ||||
-rw-r--r-- | pango/pangoft2-render.c | 114 | ||||
-rw-r--r-- | pango/pangoft2.c | 86 | ||||
-rw-r--r-- | pango/pangowin32.c | 41 | ||||
-rw-r--r-- | pango/pangox.c | 162 | ||||
-rw-r--r-- | pango/pangoxft-font.c | 29 | ||||
-rw-r--r-- | pango/pangoxft-render.c | 187 | ||||
-rw-r--r-- | pango/shape.c | 36 |
23 files changed, 563 insertions, 372 deletions
diff --git a/pango/fonts.c b/pango/fonts.c index e030d6b5..79d237e9 100644 --- a/pango/fonts.c +++ b/pango/fonts.c @@ -1166,25 +1166,25 @@ pango_font_get_glyph_extents (PangoFont *font, PangoRectangle *ink_rect, PangoRectangle *logical_rect) { - if (G_UNLIKELY (font == NULL)) + if (G_UNLIKELY (!PANGO_IS_FONT (font))) { if (!_pango_warning_history.get_glyph_extents) { _pango_warning_history.get_glyph_extents = TRUE; - g_critical ("pango_font_get_glyph_extents called with font == NULL, expect ugly output"); + g_critical ("pango_font_get_glyph_extents called with bad font, expect ugly output"); } if (ink_rect) { - ink_rect->x = 0; - ink_rect->y = 0; - ink_rect->height = PANGO_UNKNOWN_GLYPH_HEIGHT * PANGO_SCALE; - ink_rect->width = PANGO_UNKNOWN_GLYPH_WIDTH * PANGO_SCALE; + ink_rect->x = PANGO_SCALE; + ink_rect->y = - (PANGO_UNKNOWN_GLYPH_HEIGHT - 1) * PANGO_SCALE; + ink_rect->height = (PANGO_UNKNOWN_GLYPH_HEIGHT - 2) * PANGO_SCALE; + ink_rect->width = (PANGO_UNKNOWN_GLYPH_WIDTH - 2) * PANGO_SCALE; } if (logical_rect) { - logical_rect->x = 0; - logical_rect->y = 0; + logical_rect->x = logical_rect->y = 0; + logical_rect->y = - PANGO_UNKNOWN_GLYPH_HEIGHT * PANGO_SCALE; logical_rect->height = PANGO_UNKNOWN_GLYPH_HEIGHT * PANGO_SCALE; logical_rect->width = PANGO_UNKNOWN_GLYPH_WIDTH * PANGO_SCALE; } @@ -1279,7 +1279,8 @@ pango_font_metrics_new (void) PangoFontMetrics * pango_font_metrics_ref (PangoFontMetrics *metrics) { - g_return_val_if_fail (metrics != NULL, NULL); + if (!metrics) + return NULL; metrics->ref_count++; @@ -1297,7 +1298,8 @@ pango_font_metrics_ref (PangoFontMetrics *metrics) void pango_font_metrics_unref (PangoFontMetrics *metrics) { - g_return_if_fail (metrics != NULL); + if (!metrics) + return; g_return_if_fail (metrics->ref_count > 0 ); metrics->ref_count--; diff --git a/pango/modules.c b/pango/modules.c index f7d8e42b..df928690 100644 --- a/pango/modules.c +++ b/pango/modules.c @@ -600,11 +600,11 @@ build_map (PangoMapInfo *info) gchar *filename = g_build_filename (pango_get_sysconf_subdirectory (), "pango.modules", NULL); - g_warning ("No builtin or dynamically loaded modules\n" - "were found. Pango will not work correctly. This probably means\n" - "there was an error in the creation of:\n" + g_warning ("No builtin or dynamically\n" + "loaded modules were found. Pango will not work correctly.\n" + "This probably means there was an error in the creation of:\n" " '%s'\n" - "You may be able to recreate this file by running pango-querymodules.", + "You should create this file by running pango-querymodules.", filename); g_free (filename); diff --git a/pango/pango-engine.c b/pango/pango-engine.c index 4179119f..ed7df7d2 100644 --- a/pango/pango-engine.c +++ b/pango/pango-engine.c @@ -68,12 +68,6 @@ _pango_engine_shape_shape (PangoEngineShape *engine, { glyphs->num_glyphs = 0; - g_return_if_fail (PANGO_IS_ENGINE_SHAPE (engine)); - g_return_if_fail (PANGO_IS_FONT (font)); - g_return_if_fail (text != NULL); - g_return_if_fail (analysis != NULL); - g_return_if_fail (glyphs != NULL); - PANGO_ENGINE_SHAPE_GET_CLASS (engine)->script_shape (engine, font, text, length, @@ -112,27 +106,26 @@ fallback_engine_shape (PangoEngineShape *engine, int i; const char *p; - g_return_if_fail (font != NULL); - g_return_if_fail (text != NULL); - g_return_if_fail (length >= 0); - g_return_if_fail (analysis != NULL); + n_chars = text ? g_utf8_strlen (text, length) : 0; - n_chars = g_utf8_strlen (text, length); pango_glyph_string_set_size (glyphs, n_chars); p = text; - i = 0; - while (i < n_chars) + for (i = 0; i < n_chars; i++) { - glyphs->glyphs[i].glyph = 0; + PangoRectangle logical_rect; + PangoGlyph glyph = g_utf8_get_char (p) | PANGO_GLYPH_UNKNOWN_FLAG; + + pango_font_get_glyph_extents (analysis->font, glyph, NULL, &logical_rect); + + glyphs->glyphs[i].glyph = glyph; glyphs->glyphs[i].geometry.x_offset = 0; glyphs->glyphs[i].geometry.y_offset = 0; - glyphs->glyphs[i].geometry.width = 0; - - glyphs->log_clusters[i] = p - text; + glyphs->glyphs[i].geometry.width = logical_rect.width; - ++i; + glyphs->log_clusters[i] = p - text; + p = g_utf8_next_char (p); } } diff --git a/pango/pango-engine.h b/pango/pango-engine.h index daf15a3d..591eadff 100644 --- a/pango/pango-engine.h +++ b/pango/pango-engine.h @@ -162,8 +162,8 @@ struct _PangoEngineShape * using the @log_clusters array. Each input character must occur in one * of the output logical clusters; * if no rendering is desired for a character, this may involve - * inserting glyphs with the #PangoGlyph ID 0, which is guaranteed never - * to render. + * inserting glyphs with the #PangoGlyph ID #PANGO_GLYPH_EMPTY, which + * is guaranteed never to render. * @covers: Returns the characters that this engine can cover * with a given font for a given language. If not overridden, the default * implementation simply returns the coverage information for the diff --git a/pango/pango-layout.c b/pango/pango-layout.c index dd92b944..8e006284 100644 --- a/pango/pango-layout.c +++ b/pango/pango-layout.c @@ -2339,7 +2339,7 @@ imposed_shape (const char *text, for (i=0, p = text; i < n_chars; i++, p = g_utf8_next_char (p)) { - glyphs->glyphs[i].glyph = 0; + glyphs->glyphs[i].glyph = PANGO_GLYPH_EMPTY; glyphs->glyphs[i].geometry.x_offset = 0; glyphs->glyphs[i].geometry.y_offset = 0; glyphs->glyphs[i].geometry.width = shape_logical->width; @@ -2612,7 +2612,7 @@ shape_tab (PangoLayoutLine *line, pango_glyph_string_set_size (glyphs, 1); - glyphs->glyphs[0].glyph = 0; + glyphs->glyphs[0].glyph = PANGO_GLYPH_EMPTY; glyphs->glyphs[0].geometry.x_offset = 0; glyphs->glyphs[0].geometry.y_offset = 0; glyphs->glyphs[0].attr.is_cluster_start = 1; @@ -3844,11 +3844,19 @@ pango_layout_line_get_empty_extents (PangoLayoutLine *line, metrics = pango_font_get_metrics (font, pango_context_get_language (layout->context)); - logical_rect->y = - pango_font_metrics_get_ascent (metrics); - logical_rect->height = - logical_rect->y + pango_font_metrics_get_descent (metrics); + if (metrics) + { + logical_rect->y = - pango_font_metrics_get_ascent (metrics); + logical_rect->height = - logical_rect->y + pango_font_metrics_get_descent (metrics); + pango_font_metrics_unref (metrics); + } + else + { + logical_rect->y = 0; + logical_rect->height = 0; + } g_object_unref (font); - pango_font_metrics_unref (metrics); } else { diff --git a/pango/pango-renderer.c b/pango/pango-renderer.c index cb7095b2..67bef8cf 100644 --- a/pango/pango-renderer.c +++ b/pango/pango-renderer.c @@ -965,7 +965,7 @@ pango_renderer_draw_glyph (PangoRenderer *renderer, g_return_if_fail (PANGO_IS_RENDERER (renderer)); g_return_if_fail (renderer->active_count > 0); - if (glyph == 0) /* glyph 0 never renders */ + if (glyph == PANGO_GLYPH_EMPTY) /* glyph PANGO_GLYPH_EMPTY never renders */ return; PANGO_RENDERER_GET_CLASS (renderer)->draw_glyph (renderer, font, glyph, x, y); diff --git a/pango/pango-types.h b/pango/pango-types.h index 2026102c..c93daf4d 100644 --- a/pango/pango-types.h +++ b/pango/pango-types.h @@ -46,7 +46,7 @@ typedef struct _PangoLanguage PangoLanguage; typedef guint32 PangoGlyph; #define PANGO_GLYPH_UNKNOWN_FLAG ((PangoGlyph)0x10000000) -#define PANGO_GLYPH_NULL ((PangoGlyph)0xFFFFFFFF) +#define PANGO_GLYPH_EMPTY ((PangoGlyph)0xFFFFFFFF) /* A rectangle. Used to store logical and physical extents of glyphs, * runs, strings, etc. diff --git a/pango/pangocairo-atsuifont.c b/pango/pangocairo-atsuifont.c index e4d0d183..fbb74683 100644 --- a/pango/pangocairo-atsuifont.c +++ b/pango/pangocairo-atsuifont.c @@ -67,7 +67,7 @@ pango_cairo_atsui_font_get_atsu_font_id (PangoCairoATSUIFont *cafont) return cafont->font_id; } -static void +static gboolean pango_cairo_atsui_font_install (PangoCairoFont *font, cairo_t *cr) { @@ -78,6 +78,8 @@ pango_cairo_atsui_font_install (PangoCairoFont *font, cairo_set_font_matrix (cr, &cafont->font_matrix); cairo_set_font_options (cr, cafont->options); + + return TRUE; } static cairo_font_face_t * @@ -142,36 +144,53 @@ pango_cairo_atsui_font_get_glyph_extents (PangoFont *font, PangoRectangle *logical_rect) { cairo_scaled_font_t *scaled_font; + cairo_font_extents_t font_extents; cairo_text_extents_t extents; cairo_glyph_t cairo_glyph; scaled_font = pango_cairo_atsui_font_get_scaled_font (PANGO_CAIRO_FONT (font)); + if (logical_rect) + cairo_scaled_font_extents (scaled_font, &font_extents); + cairo_glyph.index = glyph; cairo_glyph.x = 0; cairo_glyph.y = 0; - cairo_scaled_font_glyph_extents (scaled_font, - &cairo_glyph, 1, &extents); - - if (ink_rect) + if (glyph != PANGO_GLYPH_EMPTY) { - ink_rect->x = extents.x_bearing * PANGO_SCALE; - ink_rect->y = extents.y_bearing * PANGO_SCALE; - ink_rect->width = extents.width * PANGO_SCALE; - ink_rect->height = extents.height * PANGO_SCALE; + cairo_scaled_font_glyph_extents (scaled_font, + &cairo_glyph, 1, &extents); + + if (ink_rect) + { + ink_rect->x = extents.x_bearing * PANGO_SCALE; + ink_rect->y = extents.y_bearing * PANGO_SCALE; + ink_rect->width = extents.width * PANGO_SCALE; + ink_rect->height = extents.height * PANGO_SCALE; + } + + if (logical_rect) + { + logical_rect->x = 0; + logical_rect->y = - font_extents.ascent * PANGO_SCALE; + logical_rect->width = extents.x_advance * PANGO_SCALE; + logical_rect->height = (font_extents.ascent + font_extents.descent) * PANGO_SCALE; + } } - - if (logical_rect) + else { - cairo_font_extents_t font_extents; - - cairo_scaled_font_extents (scaled_font, &font_extents); - - logical_rect->x = 0; - logical_rect->y = - font_extents.ascent * PANGO_SCALE; - logical_rect->width = extents.x_advance * PANGO_SCALE; - logical_rect->height = (font_extents.ascent + font_extents.descent) * PANGO_SCALE; + if (ink_rect) + { + ink_rect->x = ink_rect->y = ink_rect->width = ink_rect->height = 0; + } + if (logical_rect) + { + logical_rect->x = 0; + logical_rect->y = - font_extents.ascent * PANGO_SCALE; + logical_rect->width = 0; + logical_rect->height = (font_extents.ascent + font_extents.descent) * PANGO_SCALE; + } } } diff --git a/pango/pangocairo-fcfont.c b/pango/pangocairo-fcfont.c index 49326088..e4ff8a31 100644 --- a/pango/pangocairo-fcfont.c +++ b/pango/pangocairo-fcfont.c @@ -173,7 +173,7 @@ pango_cairo_fc_font_get_scaled_font (PangoCairoFont *font) * Method implementations * ********************************/ -static void +static gboolean pango_cairo_fc_font_install (PangoCairoFont *font, cairo_t *cr) { @@ -183,6 +183,8 @@ pango_cairo_fc_font_install (PangoCairoFont *font, pango_cairo_fc_font_get_font_face (font)); cairo_set_font_matrix (cr, &cffont->font_matrix); cairo_set_font_options (cr, cffont->options); + + return TRUE; } static void @@ -438,7 +440,7 @@ pango_cairo_fc_font_get_glyph_extents (PangoFont *font, if (cffont->glyph_extents_cache == NULL) pango_cairo_fc_font_glyph_extents_cache_init (cffont); - if (glyph == PANGO_GLYPH_NULL) + if (glyph == PANGO_GLYPH_EMPTY) { if (ink_rect) *ink_rect = cffont->font_extents; diff --git a/pango/pangocairo-font.c b/pango/pangocairo-font.c index 7bb0206a..99e2d930 100644 --- a/pango/pangocairo-font.c +++ b/pango/pangocairo-font.c @@ -69,7 +69,7 @@ pango_cairo_font_get_type (void) * Makes @font the current font for rendering in the specified * Cairo context. **/ -void +gboolean _pango_cairo_font_install (PangoCairoFont *font, cairo_t *cr) { @@ -78,13 +78,13 @@ _pango_cairo_font_install (PangoCairoFont *font, if (!_pango_cairo_warning_history.font_install) { _pango_cairo_warning_history.font_install = TRUE; - g_critical ("_pango_cairo_font_install called with font == NULL, expect ugly output"); + g_critical ("_pango_cairo_font_install called with bad font, expect ugly output"); cairo_set_font_face (cr, NULL); } - return; + return FALSE; } - (* PANGO_CAIRO_FONT_GET_IFACE (font)->install) (font, cr); + return (* PANGO_CAIRO_FONT_GET_IFACE (font)->install) (font, cr); } cairo_font_face_t * @@ -161,7 +161,7 @@ _pango_cairo_font_get_hex_box_info (PangoCairoFont *cfont) } /* we hint to the nearest device units */ -#define HINT(value, scale, scale_inv) (ceil ((value) * scale) * scale_inv) +#define HINT(value, scale, scale_inv) (ceil ((value-1e-5) * 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) @@ -233,7 +233,7 @@ _pango_cairo_font_get_hex_box_info (PangoCairoFont *cfont) hbi->digit_width = HINT_X (width); hbi->digit_height = HINT_Y (height); - pad = MIN (hbi->digit_width / 10, hbi->digit_height / 12); + pad = (font_extents.ascent + font_extents.descent) / 43; hbi->pad_x = HINT_X (pad); hbi->pad_y = HINT_Y (pad); hbi->line_width = MIN (hbi->pad_x, hbi->pad_y); @@ -257,6 +257,11 @@ _pango_cairo_get_glyph_extents_missing (PangoCairoFont *cfont, gint rows, cols; hbi = _pango_cairo_font_get_hex_box_info (cfont); + if (!hbi) + { + pango_font_get_glyph_extents (NULL, glyph, ink_rect, logical_rect); + return; + } rows = hbi->rows; cols = ((glyph & ~PANGO_GLYPH_UNKNOWN_FLAG) > 0xffff ? 6 : 4) / rows; diff --git a/pango/pangocairo-private.h b/pango/pangocairo-private.h index 3858786f..104bac29 100644 --- a/pango/pangocairo-private.h +++ b/pango/pangocairo-private.h @@ -56,8 +56,8 @@ struct _PangoCairoFontIface { GTypeInterface g_iface; - void (*install) (PangoCairoFont *font, - cairo_t *cr); + gboolean (*install) (PangoCairoFont *font, + cairo_t *cr); cairo_font_face_t *(*get_font_face) (PangoCairoFont *font); @@ -66,8 +66,8 @@ struct _PangoCairoFontIface GType pango_cairo_font_get_type (void); -void _pango_cairo_font_install (PangoCairoFont *font, - cairo_t *cr); +gboolean _pango_cairo_font_install (PangoCairoFont *font, + cairo_t *cr); cairo_font_face_t *_pango_cairo_font_get_font_face (PangoCairoFont *font); cairo_scaled_font_t *_pango_cairo_font_get_scaled_font (PangoCairoFont *font); diff --git a/pango/pangocairo-render.c b/pango/pangocairo-render.c index 5a902ad8..08a58def 100644 --- a/pango/pangocairo-render.c +++ b/pango/pangocairo-render.c @@ -59,6 +59,33 @@ set_color (PangoCairoRenderer *crenderer, } static void +_pango_cairo_renderer_draw_box_glyph (PangoCairoRenderer *crenderer, + PangoGlyphInfo *gi, + double cx, + double cy) +{ + double temp_x, temp_y; + + cairo_save (crenderer->cr); + cairo_get_current_point (crenderer->cr, &temp_x, &temp_y); + + cairo_rectangle (crenderer->cr, + cx + 1.5, + cy + 1.5 - PANGO_UNKNOWN_GLYPH_HEIGHT, + (double)gi->geometry.width / PANGO_SCALE - 3.0, + PANGO_UNKNOWN_GLYPH_HEIGHT - 3.0); + + if (!crenderer->do_path) + { + cairo_set_line_width (crenderer->cr, 1.0); + cairo_stroke (crenderer->cr); + } + + cairo_move_to (crenderer->cr, temp_x, temp_y); + cairo_restore (crenderer->cr); +} + +static void _pango_cairo_renderer_draw_unknown_glyph (PangoCairoRenderer *crenderer, PangoFont *font, PangoGlyphInfo *gi, @@ -78,20 +105,10 @@ _pango_cairo_renderer_draw_unknown_glyph (PangoCairoRenderer *crenderer, cairo_get_current_point (crenderer->cr, &temp_x, &temp_y); hbi = _pango_cairo_font_get_hex_box_info ((PangoCairoFont *)font); - if (!hbi) - { - cairo_rectangle (crenderer->cr, - cx + 1.5, - cy - 1.5, - (double)gi->geometry.width / PANGO_SCALE - 3.0, - PANGO_UNKNOWN_GLYPH_HEIGHT - 3.0); - - if (!crenderer->do_path) - { - cairo_set_line_width (crenderer->cr, 1.0); - cairo_stroke (crenderer->cr); - } + if (!hbi || !_pango_cairo_font_install (PANGO_CAIRO_FONT (hbi->font), crenderer->cr)) + { + _pango_cairo_renderer_draw_box_glyph (crenderer, gi, cx, cy); goto done; } @@ -103,9 +120,9 @@ _pango_cairo_renderer_draw_unknown_glyph (PangoCairoRenderer *crenderer, cairo_rectangle (crenderer->cr, cx + hbi->pad_x * 1.5, - cy + hbi->box_descent - hbi->pad_y * 0.5, + cy + hbi->box_descent - hbi->box_height + hbi->pad_y * 0.5, (double)gi->geometry.width / PANGO_SCALE - 3 * hbi->pad_x, - -(hbi->box_height - hbi->pad_y)); + (hbi->box_height - hbi->pad_y)); if (!crenderer->do_path) { @@ -113,8 +130,6 @@ _pango_cairo_renderer_draw_unknown_glyph (PangoCairoRenderer *crenderer, cairo_stroke (crenderer->cr); } - _pango_cairo_font_install (PANGO_CAIRO_FONT (hbi->font), crenderer->cr); - x0 = cx + hbi->pad_x * 3.0; y0 = cy + hbi->box_descent - hbi->pad_y * 2; @@ -165,6 +180,27 @@ pango_cairo_renderer_draw_glyphs (PangoRenderer *renderer, set_color (crenderer, PANGO_RENDER_PART_FOREGROUND); } + if (!_pango_cairo_font_install (PANGO_CAIRO_FONT (font), crenderer->cr)) + { + for (i = 0; i < glyphs->num_glyphs; i++) + { + PangoGlyphInfo *gi = &glyphs->glyphs[i]; + + if (gi->glyph != PANGO_GLYPH_EMPTY) + { + double cx = crenderer->x_offset + + (double)(x + x_position + gi->geometry.x_offset) / PANGO_SCALE; + double cy = crenderer->y_offset + + (double)(y + gi->geometry.y_offset) / PANGO_SCALE; + + _pango_cairo_renderer_draw_unknown_glyph (crenderer, font, gi, cx, cy); + } + x_position += gi->geometry.width; + } + + goto done; + } + if (glyphs->num_glyphs > MAX_STACK) cairo_glyphs = g_new (cairo_glyph_t, glyphs->num_glyphs); else @@ -175,10 +211,12 @@ pango_cairo_renderer_draw_glyphs (PangoRenderer *renderer, { PangoGlyphInfo *gi = &glyphs->glyphs[i]; - if (gi->glyph != PANGO_GLYPH_NULL) + if (gi->glyph != PANGO_GLYPH_EMPTY) { - double cx = crenderer->x_offset + (double)(x + x_position + gi->geometry.x_offset) / PANGO_SCALE; - double cy = crenderer->y_offset + (double)(y + gi->geometry.y_offset) / PANGO_SCALE; + double cx = crenderer->x_offset + + (double)(x + x_position + gi->geometry.x_offset) / PANGO_SCALE; + double cy = crenderer->y_offset + + (double)(y + gi->geometry.y_offset) / PANGO_SCALE; if (gi->glyph & PANGO_GLYPH_UNKNOWN_FLAG) _pango_cairo_renderer_draw_unknown_glyph (crenderer, font, gi, cx, cy); @@ -193,8 +231,6 @@ pango_cairo_renderer_draw_glyphs (PangoRenderer *renderer, x_position += gi->geometry.width; } - _pango_cairo_font_install (PANGO_CAIRO_FONT (font), crenderer->cr); - if (crenderer->do_path) cairo_glyph_path (crenderer->cr, cairo_glyphs, count); else @@ -203,6 +239,7 @@ pango_cairo_renderer_draw_glyphs (PangoRenderer *renderer, if (glyphs->num_glyphs > MAX_STACK) g_free (cairo_glyphs); +done: if (!crenderer->do_path) cairo_restore (crenderer->cr); diff --git a/pango/pangocairo-win32font.c b/pango/pangocairo-win32font.c index d6a563be..80661c3c 100644 --- a/pango/pangocairo-win32font.c +++ b/pango/pangocairo-win32font.c @@ -138,7 +138,7 @@ pango_cairo_win32_font_get_scaled_font (PangoCairoFont *font) * Method implementations * ********************************/ -static void +static gboolean pango_cairo_win32_font_install (PangoCairoFont *font, cairo_t *cr) { @@ -210,7 +210,7 @@ compute_glyph_extents (PangoFont *font, logical_rect->width = 0; logical_rect->height = (font_extents.ascent + font_extents.descent) * PANGO_SCALE; - if (glyph) + if (glyph != PANGO_GLYPH_EMPTY) { cairo_glyph.index = glyph; cairo_glyph.x = 0; diff --git a/pango/pangofc-decoder.c b/pango/pangofc-decoder.c index a2989528..1f985265 100644 --- a/pango/pangofc-decoder.c +++ b/pango/pangofc-decoder.c @@ -70,7 +70,7 @@ pango_fc_decoder_get_charset (PangoFcDecoder *decoder, * glyph is most convenient for it. (Usually whatever glyph is directly * in the fonts character map table.) * - * Return value: the glyph index, or %PANGO_GLYPH_NULL if the glyph isn't + * Return value: the glyph index, or 0 if the glyph isn't * covered by the font. * * Since: 1.6 @@ -80,7 +80,7 @@ pango_fc_decoder_get_glyph (PangoFcDecoder *decoder, PangoFcFont *fcfont, guint32 wc) { - g_return_val_if_fail (PANGO_IS_FC_DECODER (decoder), PANGO_GLYPH_NULL); + g_return_val_if_fail (PANGO_IS_FC_DECODER (decoder), 0); return PANGO_FC_DECODER_GET_CLASS (decoder)->get_glyph (decoder, fcfont, wc); } diff --git a/pango/pangofc-font.c b/pango/pangofc-font.c index 8dafbcb0..a14dd43a 100644 --- a/pango/pangofc-font.c +++ b/pango/pangofc-font.c @@ -435,7 +435,7 @@ pango_fc_font_create_metrics_for_context (PangoFcFont *fcfont, g_object_unref (layout); return metrics; -} +} /* This function is cut-and-pasted into pangocairo-fcfont.c - it might be * better to add a virtual fcfont->create_context (font). @@ -469,7 +469,7 @@ pango_fc_font_get_metrics (PangoFont *font, return pango_font_metrics_new (); info = g_slice_new0 (PangoFcMetricsInfo); - + fcfont->metrics_by_lang = g_slist_prepend (fcfont->metrics_by_lang, info); @@ -518,7 +518,7 @@ pango_fc_font_real_get_glyph (PangoFcFont *font, index = FcFreeTypeCharIndex (face, wc); if (index > (FT_UInt)face->num_glyphs) - index = PANGO_GLYPH_NULL; + index = 0; PANGO_FC_FONT_UNLOCK_FACE (font); @@ -600,7 +600,7 @@ pango_fc_font_has_char (PangoFcFont *font, * for @font. If you only want to determine * whether the font has the glyph, use pango_fc_font_has_char(). * - * Return value: the glyph index, or %PANGO_GLYPH_NULL, if the Unicode + * Return value: the glyph index, or 0, if the Unicode * character doesn't exist in the font. * * Since: 1.4 @@ -817,7 +817,7 @@ pango_fc_font_get_raw_extents (PangoFcFont *fcfont, face = PANGO_FC_FONT_LOCK_FACE (fcfont); - if (!glyph) + if (glyph == PANGO_GLYPH_EMPTY) gm = NULL; else gm = get_per_char (face, load_flags, glyph); diff --git a/pango/pangoft2-private.h b/pango/pangoft2-private.h index ac5c85a8..02c2cfc9 100644 --- a/pango/pangoft2-private.h +++ b/pango/pangoft2-private.h @@ -112,4 +112,12 @@ GType pango_ft2_renderer_get_type (void); PangoRenderer *_pango_ft2_font_map_get_renderer (PangoFT2FontMap *ft2fontmap); +typedef struct _PangoFT2WarningHistory PangoFT2WarningHistory; + +struct _PangoFT2WarningHistory { + guint get_face : 1; +}; + +extern PangoFT2WarningHistory _pango_ft2_warning_history; + #endif /* __PANGOFT2_PRIVATE_H__ */ diff --git a/pango/pangoft2-render.c b/pango/pangoft2-render.c index 5aa1872e..2a814861 100644 --- a/pango/pangoft2-render.c +++ b/pango/pangoft2-render.c @@ -100,20 +100,97 @@ pango_ft2_free_rendered_glyph (PangoFT2RenderedGlyph *rendered) } static PangoFT2RenderedGlyph * +pango_ft2_font_render_box_glyph (int width, + int height, + int top) +{ + PangoFT2RenderedGlyph *box; + int i, j, offset1, offset2, line_width; + + line_width = MAX ((height + 43) / 44, 1); + if (width < 1 || height < 1) + line_width = 0; + + box = g_slice_new (PangoFT2RenderedGlyph); + + box->bitmap_left = 0; + box->bitmap_top = top; + + box->bitmap.pixel_mode = ft_pixel_mode_grays; + + box->bitmap.width = width; + box->bitmap.rows = height; + box->bitmap.pitch = height; + + box->bitmap.buffer = g_malloc0 (box->bitmap.rows * box->bitmap.pitch); + + /* draw the box */ + for (j = 0; j < line_width; j++) + { + offset1 = box->bitmap.pitch * (MIN (1 + j, height - 1)); + offset2 = box->bitmap.pitch * (MAX (box->bitmap.rows - 2 - j, 0)); + for (i = 1; + i < box->bitmap.width - 1; + i++) + { + box->bitmap.buffer[offset1 + i] = 0xff; + box->bitmap.buffer[offset2 + i] = 0xff; + } + } + for (j = 0; j < line_width; j++) + { + offset1 = MIN (1 + j, width - 1); + offset2 = MAX (box->bitmap.width - 2 - j, 0); + for (i = box->bitmap.pitch; + i < (box->bitmap.rows - 1) * box->bitmap.pitch; + i += box->bitmap.pitch) + { + box->bitmap.buffer[offset1 + i] = 0xff; + box->bitmap.buffer[offset2 + i] = 0xff; + } + } + + return box; +} + +static PangoFT2RenderedGlyph * pango_ft2_font_render_glyph (PangoFont *font, int glyph_index) { - PangoFT2RenderedGlyph *rendered; FT_Face face; - rendered = g_slice_new (PangoFT2RenderedGlyph); + if (glyph_index & PANGO_GLYPH_UNKNOWN_FLAG) + { + static PangoFT2RenderedGlyph *box; + PangoFontMetrics *metrics; + + if (!font) + goto generic_box; + + metrics = pango_font_get_metrics (font, NULL); + if (!metrics) + goto generic_box; + + /* this box gets cached, so don't bother with static'ing it. + */ + + box = pango_ft2_font_render_box_glyph (PANGO_PIXELS (metrics->approximate_char_width), + PANGO_PIXELS (metrics->ascent + metrics->descent), + PANGO_PIXELS (metrics->ascent)); + pango_font_metrics_unref (metrics); + + return box; + } face = pango_ft2_font_get_face (font); if (face) { + PangoFT2RenderedGlyph *rendered; PangoFT2Font *ft2font = (PangoFT2Font *) font; + rendered = g_slice_new (PangoFT2RenderedGlyph); + /* Draw glyph */ FT_Load_Glyph (face, glyph_index, ft2font->load_flags); FT_Render_Glyph (face->glyph, @@ -125,11 +202,23 @@ pango_ft2_font_render_glyph (PangoFont *font, face->glyph->bitmap.rows * face->glyph->bitmap.pitch); rendered->bitmap_left = face->glyph->bitmap_left; rendered->bitmap_top = face->glyph->bitmap_top; + + return rendered; } else - g_warning ("couldn't get face for PangoFT2Face, expect ugly output"); + { + static PangoFT2RenderedGlyph *box = NULL; + + generic_box: + if (!box) + { + box = pango_ft2_font_render_box_glyph (PANGO_UNKNOWN_GLYPH_WIDTH, + PANGO_UNKNOWN_GLYPH_HEIGHT, + PANGO_UNKNOWN_GLYPH_HEIGHT); + } - return rendered; + return box; + } } static void @@ -151,9 +240,18 @@ pango_ft2_renderer_draw_glyph (PangoRenderer *renderer, int ix, iy; if (glyph & PANGO_GLYPH_UNKNOWN_FLAG) - glyph = PANGO_GLYPH_NULL; - if (glyph == PANGO_GLYPH_NULL) - return; + { + FT_Face face = pango_ft2_font_get_face (font); + if (face && FT_IS_SFNT (face)) + glyph = pango_ft2_get_unknown_glyph (font); + else + { + /* Since we only draw an empty box for FT2 renderer, + * unify the rendered bitmaps in the cache. + */ + glyph = PANGO_GLYPH_UNKNOWN_FLAG; + } + } rendered_glyph = _pango_ft2_font_get_cache_glyph_data (font, glyph); add_glyph_to_cache = FALSE; @@ -588,8 +686,8 @@ pango_ft2_render_transformed (FT_Bitmap *bitmap, PangoRenderer *renderer; g_return_if_fail (bitmap != NULL); - g_return_if_fail (PANGO_FT2_IS_FONT (font)); g_return_if_fail (glyphs != NULL); + g_return_if_fail (PANGO_FT2_IS_FONT (font)); fontmap = PANGO_FC_FONT (font)->fontmap; renderer = _pango_ft2_font_map_get_renderer (PANGO_FT2_FONT_MAP (fontmap)); diff --git a/pango/pangoft2.c b/pango/pangoft2.c index 459fa0ab..c20afdf5 100644 --- a/pango/pangoft2.c +++ b/pango/pangoft2.c @@ -33,6 +33,8 @@ #include "pangofc-fontmap.h" #include "pangofc-private.h" +PangoFT2WarningHistory _pango_ft2_warning_history = { FALSE }; + /* for compatibility with older freetype versions */ #ifndef FT_LOAD_TARGET_MONO #define FT_LOAD_TARGET_MONO FT_LOAD_MONOCHROME @@ -58,8 +60,6 @@ static void pango_ft2_font_get_glyph_extents (PangoFont * static FT_Face pango_ft2_font_real_lock_face (PangoFcFont *font); static void pango_ft2_font_real_unlock_face (PangoFcFont *font); -static PangoGlyph pango_ft2_font_real_get_unknown_glyph (PangoFcFont *font, - gunichar wc); PangoFT2Font * _pango_ft2_font_new (PangoFT2FontMap *ft2fontmap, @@ -173,6 +173,16 @@ pango_ft2_font_get_face (PangoFont *font) FcBool antialias, hinting, autohint; int id; + if (G_UNLIKELY (!PANGO_FT2_IS_FONT (font))) + { + if (!_pango_ft2_warning_history.get_face) + { + _pango_ft2_warning_history.get_face = TRUE; + g_critical ("pango_ft2_font_get_face called with bad font, expect ugly output"); + } + return NULL; + } + pattern = fcfont->font_pattern; if (!ft2font->face) @@ -259,7 +269,6 @@ pango_ft2_font_class_init (PangoFT2FontClass *class) fc_font_class->lock_face = pango_ft2_font_real_lock_face; fc_font_class->unlock_face = pango_ft2_font_real_unlock_face; - fc_font_class->get_unknown_glyph = pango_ft2_font_real_get_unknown_glyph; } static PangoFT2GlyphInfo * @@ -296,25 +305,52 @@ pango_ft2_font_get_glyph_extents (PangoFont *font, { PangoFT2GlyphInfo *info; - if (glyph & PANGO_GLYPH_UNKNOWN_FLAG) - glyph = PANGO_GLYPH_NULL; - if (glyph == PANGO_GLYPH_NULL) + if (glyph == PANGO_GLYPH_EMPTY) { if (ink_rect) - { - ink_rect->x = 0; - ink_rect->y = 0; - ink_rect->height = PANGO_UNKNOWN_GLYPH_HEIGHT * PANGO_SCALE; - ink_rect->width = PANGO_UNKNOWN_GLYPH_WIDTH * PANGO_SCALE; - } + ink_rect->x = ink_rect->y = ink_rect->height = ink_rect->width = 0; if (logical_rect) + logical_rect->x = logical_rect->y = logical_rect->height = logical_rect->width = 0; + return; + } + + if (glyph & PANGO_GLYPH_UNKNOWN_FLAG) + { + FT_Face face = pango_ft2_font_get_face (font); + if (face && FT_IS_SFNT (face)) + glyph = pango_ft2_get_unknown_glyph (font); + else { - logical_rect->x = 0; - logical_rect->y = 0; - logical_rect->height = PANGO_UNKNOWN_GLYPH_HEIGHT * PANGO_SCALE; - logical_rect->width = PANGO_UNKNOWN_GLYPH_WIDTH * PANGO_SCALE; + PangoFontMetrics *metrics = pango_font_get_metrics (font, NULL); + + if (metrics) + { + if (ink_rect) + { + ink_rect->x = PANGO_SCALE; + ink_rect->y = - (metrics->ascent - PANGO_SCALE); + ink_rect->height = metrics->ascent + metrics->descent - 2 * PANGO_SCALE; + ink_rect->width = metrics->approximate_char_width - 2 * PANGO_SCALE; + } + if (logical_rect) + { + logical_rect->x = 0; + logical_rect->y = -metrics->ascent; + logical_rect->height = metrics->ascent + metrics->descent; + logical_rect->width = metrics->approximate_char_width; + } + + pango_font_metrics_unref (metrics); + } + else + { + if (ink_rect) + ink_rect->x = ink_rect->y = ink_rect->height = ink_rect->width = 0; + if (logical_rect) + logical_rect->x = logical_rect->y = logical_rect->height = logical_rect->width = 0; + } + return; } - return; } info = pango_ft2_font_get_glyph_info (font, glyph, TRUE); @@ -381,13 +417,6 @@ pango_ft2_font_real_unlock_face (PangoFcFont *font) { } -static PangoGlyph -pango_ft2_font_real_get_unknown_glyph (PangoFcFont *font, - gunichar wc) -{ - return 0; -} - static gboolean pango_ft2_free_glyph_info_callback (gpointer key, gpointer value, @@ -505,7 +534,8 @@ _pango_ft2_font_get_cache_glyph_data (PangoFont *font, { PangoFT2GlyphInfo *info; - g_return_val_if_fail (PANGO_FT2_IS_FONT (font), NULL); + if (!PANGO_FT2_IS_FONT (font)) + return NULL; info = pango_ft2_font_get_glyph_info (font, glyph_index, FALSE); @@ -522,7 +552,8 @@ _pango_ft2_font_set_cache_glyph_data (PangoFont *font, { PangoFT2GlyphInfo *info; - g_return_if_fail (PANGO_FT2_IS_FONT (font)); + if (!PANGO_FT2_IS_FONT (font)) + return; info = pango_ft2_font_get_glyph_info (font, glyph_index, TRUE); @@ -535,7 +566,8 @@ void _pango_ft2_font_set_glyph_cache_destroy (PangoFont *font, GDestroyNotify destroy_notify) { - g_return_if_fail (PANGO_FT2_IS_FONT (font)); + if (!PANGO_FT2_IS_FONT (font)) + return; PANGO_FT2_FONT (font)->glyph_cache_destroy = destroy_notify; } diff --git a/pango/pangowin32.c b/pango/pangowin32.c index 77970285..e3af31c7 100644 --- a/pango/pangowin32.c +++ b/pango/pangowin32.c @@ -311,11 +311,12 @@ pango_win32_render (HDC hdc, * point zero (just spacing). */ while (i < glyphs->num_glyphs && - (glyphs->glyphs[i].glyph == PANGO_GLYPH_NULL || cur_y_offset == glyphs->glyphs[i].geometry.y_offset)) + (glyphs->glyphs[i].glyph == PANGO_GLYPH_EMPTY || + cur_y_offset == glyphs->glyphs[i].geometry.y_offset)) { - if (glyphs->glyphs[i].glyph == PANGO_GLYPH_NULL) + if (glyphs->glyphs[i].glyph == PANGO_GLYPH_EMPTY) { - /* PANGO_GLYPH_NULL glyphs should not be rendered, but their + /* PANGO_GLYPH_EMPTY glyphs should not be rendered, but their * indicated width (set up by PangoLayout) should be taken * into account. */ @@ -460,6 +461,15 @@ pango_win32_font_get_glyph_extents (PangoFont *font, MAT2 m = {{0,1}, {0,0}, {0,0}, {0,1}}; PangoWin32GlyphInfo *info; + if (glyph == PANGO_GLYPH_EMPTY) + { + if (ink_rect) + ink_rect->x = ink_rect->width = ink_rect->y = ink_rect->height = 0; + if (logical_rect) + logical_rect->x = logical_rect->width = logical_rect->y = logical_rect->height = 0; + return; + } + if (glyph & PANGO_GLYPH_UNKNOWN_FLAG) glyph_index = glyph = 0; @@ -467,17 +477,7 @@ pango_win32_font_get_glyph_extents (PangoFont *font, if (!info) { - info = g_new (PangoWin32GlyphInfo, 1); - - info->ink_rect.x = 0; - info->ink_rect.width = 0; - info->ink_rect.y = 0; - info->ink_rect.height = 0; - - info->logical_rect.x = 0; - info->logical_rect.width = 0; - info->logical_rect.y = 0; - info->logical_rect.height = 0; + info = g_new0 (PangoWin32GlyphInfo, 1); memset (&gm, 0, sizeof (gm)); @@ -1365,7 +1365,8 @@ font_get_cmap (PangoFont *font) * @font: a #PangoFont. * @wc: a Unicode character. * - * Obtains the index of the glyph for @wc in @font. + * Obtains the index of the glyph for @wc in @font, or 0, if not + * covered. * * Return value: the glyph index for @wc. **/ @@ -1381,7 +1382,7 @@ pango_win32_font_get_glyph_index (PangoFont *font, cmap = font_get_cmap (font); if (cmap == NULL) - return PANGO_GLYPH_NULL; + return 0; if (win32font->win32face->cmap_format == 4) { @@ -1394,10 +1395,10 @@ pango_win32_font_get_glyph_index (PangoFont *font, guint16 ch = wc; if (wc > 0xFFFF) - return PANGO_GLYPH_NULL; + return 0; if (!find_segment (cmap4, ch, &segment)) - return PANGO_GLYPH_NULL; + return 0; id_range_offset = get_id_range_offset (cmap4); id_delta = get_id_delta (cmap4); @@ -1413,7 +1414,7 @@ pango_win32_font_get_glyph_index (PangoFont *font, if (id) glyph = (id_delta[segment] + id) %65536; else - glyph = PANGO_GLYPH_NULL; + glyph = 0; } } else if (win32font->win32face->cmap_format == 12) @@ -1421,7 +1422,7 @@ pango_win32_font_get_glyph_index (PangoFont *font, struct format_12_cmap *cmap12 = cmap; guint32 i; - glyph = PANGO_GLYPH_NULL; + glyph = 0; for (i = 0; i < cmap12->count; i++) { if (cmap12->groups[i*3+0] <= wc && wc <= cmap12->groups[i*3+1]) diff --git a/pango/pangox.c b/pango/pangox.c index fe85cd98..06694713 100644 --- a/pango/pangox.c +++ b/pango/pangox.c @@ -399,21 +399,58 @@ pango_x_render (Display *display, * the ink rect here would be a noticeable speed hit. * This is close enough. */ - if (!(glyph != PANGO_GLYPH_NULL && + if (!(glyph != PANGO_GLYPH_EMPTY && glyph_x >= -16384 && glyph_x <= 32767 && glyph_y >= -16384 && glyph_y <= 32767)) goto next_glyph; - if (glyph & PANGO_GLYPH_UNKNOWN_FLAG) - { - PangoFontMetrics *metrics = pango_font_get_metrics (font, - pango_language_from_string ("en")); + if ((glyph & PANGO_GLYPH_UNKNOWN_FLAG) == 0) + { + guint16 index = PANGO_X_GLYPH_INDEX (glyph); + guint16 subfont_index = PANGO_X_GLYPH_SUBFONT (glyph); + PangoXSubfontInfo *subfont; + + subfont = pango_x_find_subfont (font, subfont_index); + if (subfont) + { + fs = pango_x_get_font_struct (font, subfont); + if (!fs) + continue; + + if (fs->fid != old_fid) + { + FLUSH; + XSetFont (display, gc, fs->fid); + old_fid = fs->fid; + } + + if (charcount == G_N_ELEMENTS (xcharbuffer) || + (charcount > 0 && (glyph_y != glyph_y0 || + glyph_x != expected_x))) + FLUSH; + + if (charcount == 0) + { + glyph_x0 = glyph_x; + glyph_y0 = glyph_y; + } + xcharbuffer[charcount].byte1 = index / 256; + xcharbuffer[charcount].byte2 = index % 256; + + expected_x = glyph_x + XTextWidth16 (fs, &xcharbuffer[charcount], 1); + + charcount++; + } else + goto unknown_glyph; + } else { + PangoFontMetrics *metrics; int x1, y1, x2, y2; /* rectangle the character should go inside. */ int baseline; int stroke_thick; - gunichar wc; - + + unknown_glyph: + metrics = pango_font_get_metrics (font, pango_language_from_string ("en")); FLUSH; x1 = glyph_x; @@ -423,7 +460,10 @@ pango_x_render (Display *display, baseline = glyph_y; stroke_thick = MAX ((int) (0.5 + 0.075 * (y2 - y1)), 1); - wc = glyph & (~PANGO_GLYPH_UNKNOWN_FLAG); + if (glyph & PANGO_GLYPH_UNKNOWN_FLAG) + wc = glyph & (~PANGO_GLYPH_UNKNOWN_FLAG); + else + wc = 0; switch (wc) { @@ -518,44 +558,6 @@ pango_x_render (Display *display, pango_font_metrics_unref (metrics); } - else - { - guint16 index = PANGO_X_GLYPH_INDEX (glyph); - guint16 subfont_index = PANGO_X_GLYPH_SUBFONT (glyph); - PangoXSubfontInfo *subfont; - - subfont = pango_x_find_subfont (font, subfont_index); - if (subfont) - { - fs = pango_x_get_font_struct (font, subfont); - if (!fs) - continue; - - if (fs->fid != old_fid) - { - FLUSH; - XSetFont (display, gc, fs->fid); - old_fid = fs->fid; - } - - if (charcount == G_N_ELEMENTS (xcharbuffer) || - (charcount > 0 && (glyph_y != glyph_y0 || - glyph_x != expected_x))) - FLUSH; - - if (charcount == 0) - { - glyph_x0 = glyph_x; - glyph_y0 = glyph_y; - } - xcharbuffer[charcount].byte1 = index / 256; - xcharbuffer[charcount].byte2 = index % 256; - - expected_x = glyph_x + XTextWidth16 (fs, &xcharbuffer[charcount], 1); - - charcount++; - } - } next_glyph: x_off += glyphs->glyphs[i].geometry.width; @@ -574,7 +576,32 @@ pango_x_font_get_glyph_extents (PangoFont *font, XCharStruct *cs; PangoXSubfontInfo *subfont; - if (glyph != PANGO_GLYPH_NULL && glyph & PANGO_GLYPH_UNKNOWN_FLAG) + if (glyph == PANGO_GLYPH_EMPTY) + { + if (ink_rect) + ink_rect->x = ink_rect->width = ink_rect->y = ink_rect->height = 0; + if (logical_rect) + logical_rect->x = logical_rect->width = logical_rect->y = logical_rect->height = 0; + return; + } + if ((glyph & PANGO_GLYPH_UNKNOWN_FLAG) == 0 && pango_x_find_glyph (font, glyph, &subfont, &cs)) + { + if (ink_rect) + { + ink_rect->x = PANGO_SCALE * cs->lbearing; + ink_rect->width = PANGO_SCALE * (cs->rbearing - cs->lbearing); + ink_rect->y = PANGO_SCALE * -cs->ascent; + ink_rect->height = PANGO_SCALE * (cs->ascent + cs->descent); + } + if (logical_rect) + { + logical_rect->x = 0; + logical_rect->width = PANGO_SCALE * cs->width; + logical_rect->y = - PANGO_SCALE * subfont->font_struct->ascent; + logical_rect->height = PANGO_SCALE * (subfont->font_struct->ascent + subfont->font_struct->descent); + } + } + else { PangoFontMetrics *metrics = pango_font_get_metrics (font, pango_language_from_string ("en")); @@ -582,7 +609,10 @@ pango_x_font_get_glyph_extents (PangoFont *font, gdouble width_factor; int w; - wc = glyph & (~PANGO_GLYPH_UNKNOWN_FLAG); + if (glyph & PANGO_GLYPH_UNKNOWN_FLAG) + wc = glyph & (~PANGO_GLYPH_UNKNOWN_FLAG); + else + wc = 0; switch (wc) { @@ -623,40 +653,6 @@ pango_x_font_get_glyph_extents (PangoFont *font, } } - else if (glyph != PANGO_GLYPH_NULL && pango_x_find_glyph (font, glyph, &subfont, &cs)) - { - if (ink_rect) - { - ink_rect->x = PANGO_SCALE * cs->lbearing; - ink_rect->width = PANGO_SCALE * (cs->rbearing - cs->lbearing); - ink_rect->y = PANGO_SCALE * -cs->ascent; - ink_rect->height = PANGO_SCALE * (cs->ascent + cs->descent); - } - if (logical_rect) - { - logical_rect->x = 0; - logical_rect->width = PANGO_SCALE * cs->width; - logical_rect->y = - PANGO_SCALE * subfont->font_struct->ascent; - logical_rect->height = PANGO_SCALE * (subfont->font_struct->ascent + subfont->font_struct->descent); - } - } - else - { - if (ink_rect) - { - ink_rect->x = 0; - ink_rect->width = 0; - ink_rect->y = 0; - ink_rect->height = 0; - } - if (logical_rect) - { - logical_rect->x = 0; - logical_rect->width = 0; - logical_rect->y = 0; - logical_rect->height = 0; - } - } } static gboolean @@ -701,7 +697,7 @@ itemize_string_foreach (PangoFont *font, PangoGlyphString *glyph_str = pango_glyph_string_new (); PangoEngineShape *shaper, *last_shaper; int last_level; - long n_chars, i; + int i; guint8 *embedding_levels; PangoDirection base_dir = PANGO_DIRECTION_LTR; gboolean finished = FALSE; diff --git a/pango/pangoxft-font.c b/pango/pangoxft-font.c index f67d7b5b..2e96c1f4 100644 --- a/pango/pangoxft-font.c +++ b/pango/pangoxft-font.c @@ -172,7 +172,7 @@ _pango_xft_font_get_mini_font (PangoXftFont *xfont) xfont->mini_width = PANGO_SCALE * width; xfont->mini_height = PANGO_SCALE * height; - xfont->mini_pad = PANGO_SCALE * MAX (height / 10, 1); + xfont->mini_pad = PANGO_SCALE * MAX ((int)(2.2 * height + 27) / 28, 1); } return xfont->mini_font; @@ -325,27 +325,16 @@ pango_xft_font_get_glyph_extents (PangoFont *font, if (!fcfont->fontmap) /* Display closed */ goto fallback; - if (glyph == PANGO_GLYPH_NULL) + if (glyph == PANGO_GLYPH_EMPTY) { fallback: - if (ink_rect) - { - ink_rect->x = 0; - ink_rect->width = 0; - ink_rect->y = 0; - ink_rect->height = 0; - } + ink_rect->x = ink_rect->width = ink_rect->y = ink_rect->height = 0; if (logical_rect) - { - logical_rect->x = 0; - logical_rect->width = 0; - logical_rect->y = 0; - logical_rect->height = 0; - } + logical_rect->x = logical_rect->width = logical_rect->y = logical_rect->height = 0; return; } - else if (glyph & PANGO_GLYPH_UNKNOWN_FLAG) + if (glyph & PANGO_GLYPH_UNKNOWN_FLAG) { get_glyph_extents_missing (xfont, glyph, ink_rect, logical_rect); } @@ -449,7 +438,7 @@ pango_xft_font_real_get_glyph (PangoFcFont *font, gunichar wc) { XftFont *xft_font = xft_font_get_font ((PangoFont *)font); - + return XftCharIndex (NULL, xft_font, wc); } @@ -484,7 +473,7 @@ pango_xft_font_get_font (PangoFont *font) if (!_pango_xft_warning_history.get_font) { _pango_xft_warning_history.get_font = TRUE; - g_critical ("pango_xft_font_get_font called with font == NULL, expect ugly output"); + g_critical ("pango_xft_font_get_font called with bad font, expect ugly output"); } return NULL; } @@ -587,7 +576,7 @@ pango_xft_font_unlock_face (PangoFont *font) * * Use pango_fc_font_get_glyph() instead. * - * Return value: the glyph index, or %PANGO_GLYPH_NULL, if the Unicode + * Return value: the glyph index, or 0, if the Unicode * character does not exist in the font. * * Since: 1.2 @@ -596,7 +585,7 @@ guint pango_xft_font_get_glyph (PangoFont *font, gunichar wc) { - g_return_val_if_fail (PANGO_XFT_IS_FONT (font), PANGO_GLYPH_NULL); + g_return_val_if_fail (PANGO_XFT_IS_FONT (font), 0); return pango_fc_font_get_glyph (PANGO_FC_FONT (font), wc); } diff --git a/pango/pangoxft-render.c b/pango/pangoxft-render.c index 7d85008b..3c5e5bed 100644 --- a/pango/pangoxft-render.c +++ b/pango/pangoxft-render.c @@ -68,11 +68,6 @@ static void pango_xft_renderer_draw_glyphs (PangoRenderer *renderer, PangoGlyphString *glyphs, int x, int y); -static void pango_xft_renderer_draw_glyph (PangoRenderer *renderer, - PangoFont *font, - PangoGlyph glyph, - double x, - double y); static void pango_xft_renderer_draw_trapezoid (PangoRenderer *renderer, PangoRenderPart part, double y1, @@ -109,7 +104,6 @@ pango_xft_renderer_class_init (PangoXftRendererClass *klass) klass->composite_trapezoids = pango_xft_renderer_real_composite_trapezoids; renderer_class->draw_glyphs = pango_xft_renderer_draw_glyphs; - renderer_class->draw_glyph = pango_xft_renderer_draw_glyph; renderer_class->draw_trapezoid = pango_xft_renderer_draw_trapezoid; renderer_class->part_changed = pango_xft_renderer_part_changed; renderer_class->end = pango_xft_renderer_end; @@ -314,6 +308,88 @@ draw_box (PangoRenderer *renderer, } static void +_pango_xft_renderer_draw_box_glyph (PangoRenderer *renderer, + PangoGlyphInfo *gi, + int glyph_x, + int glyph_y) +{ + int x = glyph_x + PANGO_SCALE; + int y = glyph_y - PANGO_SCALE * (PANGO_UNKNOWN_GLYPH_HEIGHT - 1); + int width = gi->geometry.width - PANGO_SCALE * 2; + 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); +} + +static void +_pango_xft_renderer_draw_unknown_glyph (PangoRenderer *renderer, + PangoXftFont *xfont, + XftFont *xft_font, + PangoGlyphInfo *gi, + int glyph_x, + int glyph_y) +{ + char buf[7]; + int ys[3]; + int xs[4]; + int row, col; + int cols; + PangoGlyph glyph; + + PangoFont *mini_font = _pango_xft_font_get_mini_font (xfont); + XftFont *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); + 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; + ys[2] = ys[1] + xfont->mini_height + xfont->mini_pad; + + xs[0] = glyph_x; + xs[1] = xs[0] + 2 * xfont->mini_pad; + 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), + xfont->mini_height * 2 + xfont->mini_pad * 5)) + { + 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); + + for (row = 0; row < 2; row++) + for (col = 0; col < cols; col++) + { + draw_glyph (renderer, mini_font, + XftCharIndex (NULL, mini_xft_font, + buf[row * cols + col] & 0xff), + xs[col+1], + ys[row+1]); + } + } +} + +static void pango_xft_renderer_draw_glyphs (PangoRenderer *renderer, PangoFont *font, PangoGlyphString *glyphs, @@ -330,22 +406,17 @@ pango_xft_renderer_draw_glyphs (PangoRenderer *renderer, { for (i=0; i<glyphs->num_glyphs; i++) { - PangoGlyph glyph = glyphs->glyphs[i].glyph; - int glyph_x = x + x_off + glyphs->glyphs[i].geometry.x_offset; - int glyph_y = y + glyphs->glyphs[i].geometry.y_offset; + PangoGlyphInfo *gi = &glyphs->glyphs[i]; - if (glyph != PANGO_GLYPH_NULL && glyph & PANGO_GLYPH_UNKNOWN_FLAG) + if (gi->glyph != PANGO_GLYPH_EMPTY) { - int x = glyph_x + PANGO_SCALE; - int y = glyph_y + PANGO_SCALE; - int width = PANGO_SCALE * (PANGO_UNKNOWN_GLYPH_WIDTH - 2); - int height = PANGO_SCALE * (PANGO_UNKNOWN_GLYPH_HEIGHT - 2); + int glyph_x = x + x_off + gi->geometry.x_offset; + int glyph_y = y + gi->geometry.y_offset; - if (box_in_bounds (renderer, x, y, width, height)) - draw_box (renderer, PANGO_SCALE, x, y, width, height); + _pango_xft_renderer_draw_box_glyph (renderer, gi, glyph_x, glyph_y); } - x_off += glyphs->glyphs[i].geometry.width; + x_off += gi->geometry.width; } return; } @@ -355,87 +426,33 @@ pango_xft_renderer_draw_glyphs (PangoRenderer *renderer, for (i=0; i<glyphs->num_glyphs; i++) { - PangoGlyph glyph = glyphs->glyphs[i].glyph; - int glyph_x = x + x_off + glyphs->glyphs[i].geometry.x_offset; - int glyph_y = y + glyphs->glyphs[i].geometry.y_offset; + PangoGlyphInfo *gi = &glyphs->glyphs[i]; - if (glyph != PANGO_GLYPH_NULL) + if (gi->glyph != PANGO_GLYPH_EMPTY) { - if (glyph & PANGO_GLYPH_UNKNOWN_FLAG) + int glyph_x = x + x_off + gi->geometry.x_offset; + int glyph_y = y + gi->geometry.y_offset; + + if (gi->glyph & PANGO_GLYPH_UNKNOWN_FLAG) { - char buf[7]; - int ys[3]; - int xs[4]; - int row, col; - int cols; - - PangoFont *mini_font = _pango_xft_font_get_mini_font (xfont); - XftFont *mini_xft_font = pango_xft_font_get_font (mini_font); - - 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; - ys[2] = ys[1] + xfont->mini_height + xfont->mini_pad; - - xs[0] = glyph_x; - xs[1] = xs[0] + 2 * xfont->mini_pad; - 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), - xfont->mini_height * 2 + xfont->mini_pad * 5)) - { - 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); - - for (row = 0; row < 2; row++) - for (col = 0; col < cols; col++) - { - draw_glyph (renderer, mini_font, - XftCharIndex (NULL, mini_xft_font, - buf[row * cols + col] & 0xff), - xs[col+1], - ys[row+1]); - } - } + _pango_xft_renderer_draw_unknown_glyph (renderer, + xfont, + xft_font, + gi, + glyph_x, + glyph_y); } else { - draw_glyph (renderer, font, glyph, glyph_x, glyph_y); + draw_glyph (renderer, font, gi->glyph, glyph_x, glyph_y); } } - x_off += glyphs->glyphs[i].geometry.width; + x_off += gi->geometry.width; } } static void -pango_xft_renderer_draw_glyph (PangoRenderer *renderer, - PangoFont *font, - PangoGlyph glyph, - double x, - double y) -{ - g_critical ("pango_xft_renderer_draw_glyph(): should not be called"); -} - -static void flush_trapezoids (PangoXftRenderer *xftrenderer) { if (!xftrenderer->priv->trapezoids || diff --git a/pango/shape.c b/pango/shape.c index 50a083a3..29c28998 100644 --- a/pango/shape.c +++ b/pango/shape.c @@ -46,7 +46,7 @@ pango_shape (const gchar *text, int i; int last_cluster = -1; - if (G_LIKELY (analysis->shape_engine && analysis->font)) + if (G_LIKELY (PANGO_IS_ENGINE_SHAPE (analysis->shape_engine) && PANGO_IS_FONT (analysis->font))) { _pango_engine_shape_shape (analysis->shape_engine, analysis->font, text, length, analysis, glyphs); @@ -84,15 +84,17 @@ pango_shape (const gchar *text, } else { - if (!analysis->shape_engine && !_pango_warning_history.shape_shape_engine) + if (!PANGO_IS_ENGINE_SHAPE (analysis->shape_engine) && + !_pango_warning_history.shape_shape_engine) { _pango_warning_history.shape_font = TRUE; - g_critical ("pango_shape called with analysis->shape_engine == NULL, expect ugly output"); + g_critical ("pango_shape called with bad shape_engine, expect ugly output"); } - if (!analysis->font && !_pango_warning_history.shape_font) + if (!PANGO_IS_FONT (analysis->font) && + !_pango_warning_history.shape_font) { _pango_warning_history.shape_font = TRUE; - g_critical ("pango_shape called with analysis->font == NULL, expect ugly output"); + g_critical ("pango_shape called with bad font, expect ugly output"); } glyphs->num_glyphs = 0; @@ -100,28 +102,10 @@ pango_shape (const gchar *text, if (!glyphs->num_glyphs) { - /* If failed to get glyphs, put unknown glyphs for all characters - */ - const char *p = text; - pango_glyph_string_set_size (glyphs, g_utf8_strlen (text, length)); + PangoEngineShape *fallback_engine = _pango_get_fallback_shaper (); - for (i = 0; i < glyphs->num_glyphs; i++) - { - PangoRectangle logical_rect; - PangoGlyph glyph = g_utf8_get_char (p) | PANGO_GLYPH_UNKNOWN_FLAG; - - pango_font_get_glyph_extents (analysis->font, glyph, NULL, &logical_rect); - - glyphs->glyphs[i].glyph = glyph; - - glyphs->glyphs[i].geometry.x_offset = 0; - glyphs->glyphs[i].geometry.y_offset = 0; - glyphs->glyphs[i].geometry.width = logical_rect.width; - - glyphs->log_clusters[i] = i; - - p = g_utf8_next_char (p); - } + _pango_engine_shape_shape (fallback_engine, analysis->font, + text, length, analysis, glyphs); } /* Set glyphs[i].attr.is_cluster_start based on log_clusters[] |