static void handle_line_state_change (PangoRenderer *renderer, PangoRenderPart part) { LineState *state = renderer->priv->line_state; if (!state) return; if (part == PANGO_RENDER_PART_UNDERLINE && state->underline != PANGO_UNDERLINE_NONE) { PangoRectangle *rect = &state->underline_rect; rect->width = state->logical_rect_end - rect->x; draw_underline (renderer, state); state->underline = renderer->underline; rect->x = state->logical_rect_end; rect->width = 0; } if (part == PANGO_RENDER_PART_STRIKETHROUGH && state->strikethrough) { PangoRectangle *rect = &state->strikethrough_rect; rect->width = state->logical_rect_end - rect->x; draw_strikethrough (renderer, state); state->strikethrough = renderer->strikethrough; rect->x = state->logical_rect_end; rect->width = 0; } }
static void add_underline (PangoRenderer *renderer, LineState *state, PangoFontMetrics *metrics, int base_x, int base_y, PangoRectangle *ink_rect, PangoRectangle *logical_rect) { PangoRectangle *current_rect = &state->underline_rect; PangoRectangle new_rect; int underline_thickness = pango_font_metrics_get_underline_thickness (metrics); int underline_position = pango_font_metrics_get_underline_position (metrics); new_rect.x = base_x + logical_rect->x; new_rect.width = logical_rect->width; new_rect.height = underline_thickness; new_rect.y = base_y; switch (renderer->underline) { case PANGO_UNDERLINE_NONE: g_assert_not_reached (); break; case PANGO_UNDERLINE_SINGLE: case PANGO_UNDERLINE_DOUBLE: case PANGO_UNDERLINE_ERROR: new_rect.y -= underline_position; break; case PANGO_UNDERLINE_LOW: new_rect.y += ink_rect->y + ink_rect->height + underline_thickness; break; } if (renderer->underline == state->underline && new_rect.y == current_rect->y && new_rect.height == current_rect->height) { current_rect->width = new_rect.x + new_rect.width - current_rect->x; } else { draw_underline (renderer, state); *current_rect = new_rect; state->underline = renderer->underline; } }
static void print_pango_layout_line (GnomePrintContext *gpc, PangoLayoutLine *line) { GSList *tmp_list = line->runs; PangoRectangle overall_rect; PangoRectangle logical_rect; PangoRectangle ink_rect; gint x_off = 0; gnome_print_gsave (gpc); current_point_to_origin (gpc); pango_layout_line_get_extents (line, NULL, &overall_rect); while (tmp_list) { ItemProperties properties; PangoLayoutRun *run = tmp_list->data; tmp_list = tmp_list->next; get_item_properties (run->item, &properties); if (properties.shape_logical_rect) { x_off += properties.shape_logical_rect->width; continue; } gnome_print_gsave (gpc); translate (gpc, x_off, properties.rise); gnome_print_moveto (gpc, 0, 0); if (properties.uline == PANGO_UNDERLINE_NONE && !properties.strikethrough) pango_glyph_string_extents (run->glyphs, run->item->analysis.font, NULL, &logical_rect); else pango_glyph_string_extents (run->glyphs, run->item->analysis.font, &ink_rect, &logical_rect); if (properties.bg_color) { gnome_print_gsave (gpc); gnome_print_setrgbcolor (gpc, (gdouble) properties.bg_color->red / 0xFFFF, (gdouble) properties.bg_color->green / 0xFFFF, (gdouble) properties.bg_color->blue / 0xFFFF); rect_filled (gpc, logical_rect.x, - overall_rect.y - overall_rect.height, logical_rect.width, overall_rect.height); gnome_print_grestore (gpc); } if (properties.fg_color) { gnome_print_setrgbcolor (gpc, (gdouble) properties.fg_color->red / 0xFFFF, (gdouble) properties.fg_color->green / 0xFFFF, (gdouble) properties.fg_color->blue / 0xFFFF); } gnome_print_pango_glyph_string (gpc, run->item->analysis.font, run->glyphs); if (properties.uline != PANGO_UNDERLINE_NONE || properties.strikethrough) { PangoFontMetrics *metrics = pango_font_get_metrics (run->item->analysis.font, run->item->analysis.language); if (properties.uline != PANGO_UNDERLINE_NONE) draw_underline (gpc, metrics, properties.uline, ink_rect.x, ink_rect.width, ink_rect.y + ink_rect.height); if (properties.strikethrough) draw_strikethrough (gpc, metrics, ink_rect.x, ink_rect.width); pango_font_metrics_unref (metrics); } gnome_print_grestore (gpc); x_off += logical_rect.width; } gnome_print_grestore (gpc); }