void fo_doc_cairo_do_line_callbacks (cairo_t *cr, PangoLayoutLine *line, gint x, gint y) { GSList *run_list; PangoRectangle overall_rect; PangoRectangle logical_rect; gint x_off = 0; pango_layout_line_get_extents (line, NULL, &overall_rect); run_list = line->runs; while (run_list) { PangoLayoutRun *run = run_list->data; pango_glyph_string_extents (run->glyphs, run->item->analysis.font, NULL, &logical_rect); fo_doc_cairo_do_run_callbacks (cr, run, x + x_off, y); x_off += logical_rect.width; run_list = run_list->next; } }
int GtkPaintContext::stringWidth(const char *str, int len) const { if (myContext == 0) { return 0; } if (!g_utf8_validate(str, len, 0)) { return 0; } pango_shape(str, len, &myAnalysis, myString); PangoRectangle logicalRectangle; pango_glyph_string_extents(myString, myAnalysis.font, 0, &logicalRectangle); return (logicalRectangle.width + PANGO_SCALE / 2) / PANGO_SCALE; }
static VALUE rglyph_extents(int argc, VALUE *argv, VALUE self) { VALUE font, start_index, end_index; PangoRectangle ink_rect; PangoRectangle logical_rect; rb_scan_args(argc, argv, "12", &font, &start_index, &end_index); if (NIL_P(start_index)){ pango_glyph_string_extents(_SELF(self), PANGO_FONT(RVAL2GOBJ(font)), &ink_rect, &logical_rect); } else { pango_glyph_string_extents_range(_SELF(self), NUM2INT(start_index), NUM2INT(end_index), PANGO_FONT(RVAL2GOBJ(font)), &ink_rect, &logical_rect); } return rb_assoc_new(BOXED2RVAL(&ink_rect, PANGO_TYPE_RECTANGLE), BOXED2RVAL(&logical_rect, PANGO_TYPE_RECTANGLE)); }
static void pango_draw_line (XftDraw *draw, Window id, GC gc, XftColor *xft_color, PangoLayoutLine *line, int x, int y) { GSList *p; for (p = line->runs; p != NULL; p = p->next) { PangoLayoutRun *run = p->data; PangoFont *font = run->item->analysis.font; PangoGlyphString *glyphs = run->glyphs; PangoRectangle rect; pango_glyph_string_extents (glyphs, font, NULL, &rect); #ifdef HAVE_PANGO_XFT if (PANGO_XFT_IS_FONT (font)) pango_xft_render (draw, xft_color, font, glyphs, x, y); #else pango_x_render (dpy, id, gc, font, glyphs, x, y); #endif x += rect.width / PANGO_SCALE; } }
/*! Draw a line. @param *context [in] Context @param *surface [out] Surface to draw on it @param *line [in] Innter variable of Pango @param x [in] X location of line @param y [in] Y location of line @param height [in] Height of line @param baseline [in] Rise / sink of line (for super/subscript) */ static void drawLine( SDLPango_Context *context, SDL_Surface *surface, PangoLayoutLine *line, gint x, gint y, gint height, gint baseline) { GSList *tmp_list = line->runs; PangoColor fg_color, bg_color; PangoRectangle logical_rect; PangoRectangle ink_rect; int x_off = 0; while (tmp_list) { SDLPango_Matrix color_matrix = context->color_matrix; PangoUnderline uline = PANGO_UNDERLINE_NONE; gboolean strike, fg_set, bg_set, shape_set; gint rise, risen_y; PangoLayoutRun *run = tmp_list->data; SDL_Rect d_rect; tmp_list = tmp_list->next; getItemProperties(run->item, &uline, &strike, &rise, &fg_color, &fg_set, &bg_color, &bg_set, &shape_set, &ink_rect, &logical_rect); risen_y = y + baseline - PANGO_PIXELS (rise); if(fg_set) { color_matrix.m[0][1] = (Uint8)(fg_color.red >> 8); color_matrix.m[1][1] = (Uint8)(fg_color.green >> 8); color_matrix.m[2][1] = (Uint8)(fg_color.blue >> 8); color_matrix.m[3][1] = 255; if(color_matrix.m[3][0] == 0) { color_matrix.m[0][0] = (Uint8)(fg_color.red >> 8); color_matrix.m[1][0] = (Uint8)(fg_color.green >> 8); color_matrix.m[2][0] = (Uint8)(fg_color.blue >> 8); } } if (bg_set) { color_matrix.m[0][0] = (Uint8)(bg_color.red >> 8); color_matrix.m[1][0] = (Uint8)(bg_color.green >> 8); color_matrix.m[2][0] = (Uint8)(bg_color.blue >> 8); color_matrix.m[3][0] = 255; } if(! shape_set) { if (uline == PANGO_UNDERLINE_NONE) 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); d_rect.w = (Uint16)PANGO_PIXELS(logical_rect.width); d_rect.h = (Uint16)height; d_rect.x = (Uint16)(x + PANGO_PIXELS (x_off)); d_rect.y = (Uint16)(risen_y - baseline); if((! context->tmp_ftbitmap) || d_rect.w + d_rect.x > context->tmp_ftbitmap->width || d_rect.h + d_rect.y > context->tmp_ftbitmap->rows) { freeFTBitmap(context->tmp_ftbitmap); context->tmp_ftbitmap = createFTBitmap(d_rect.w + d_rect.x, d_rect.h + d_rect.y); } drawGlyphString(context, surface, &color_matrix, run->item->analysis.font, run->glyphs, &d_rect, baseline); } switch (uline) { case PANGO_UNDERLINE_NONE: break; case PANGO_UNDERLINE_DOUBLE: drawHLine(surface, &color_matrix, risen_y + 4, x + PANGO_PIXELS (x_off + ink_rect.x), x + PANGO_PIXELS (x_off + ink_rect.x + ink_rect.width)); /* Fall through */ case PANGO_UNDERLINE_SINGLE: drawHLine(surface, &color_matrix, risen_y + 2, x + PANGO_PIXELS (x_off + ink_rect.x), x + PANGO_PIXELS (x_off + ink_rect.x + ink_rect.width)); break; case PANGO_UNDERLINE_ERROR: { int point_x; int counter = 0; int end_x = x + PANGO_PIXELS (x_off + ink_rect.x + ink_rect.width); for (point_x = x + PANGO_PIXELS (x_off + ink_rect.x) - 1; point_x <= end_x; point_x += 2) { if (counter) drawHLine(surface, &color_matrix, risen_y + 2, point_x, MIN (point_x + 1, end_x)); else drawHLine(surface, &color_matrix, risen_y + 3, point_x, MIN (point_x + 1, end_x)); counter = (counter + 1) % 2; } } break; case PANGO_UNDERLINE_LOW: drawHLine(surface, &color_matrix, risen_y + PANGO_PIXELS (ink_rect.y + ink_rect.height), x + PANGO_PIXELS (x_off + ink_rect.x), x + PANGO_PIXELS (x_off + ink_rect.x + ink_rect.width)); break; } if (strike) drawHLine(surface, &color_matrix, risen_y + PANGO_PIXELS (logical_rect.y + logical_rect.height / 2), x + PANGO_PIXELS (x_off + logical_rect.x), x + PANGO_PIXELS (x_off + logical_rect.x + logical_rect.width)); x_off += logical_rect.width; }
void x11_draw_layout_line_with_colors( Drawable drawable, GC gc, int x, int y, PangoLayoutLine *line, wxColour &colour ) { PangoRectangle overall_rect; PangoRectangle logical_rect; PangoRectangle ink_rect; PangoContext *context; gint x_off = 0; gint rise = 0; context = pango_layout_get_context (line->layout); pango_layout_line_get_extents (line,NULL, &overall_rect); GSList *tmp_list = line->runs; while (tmp_list) { PangoUnderline uline = PANGO_UNDERLINE_NONE; PangoLayoutRun *run = (PangoLayoutRun *) tmp_list->data; PangoColor fg_color, bg_color; gboolean strike, fg_set, bg_set, shape_set; gint risen_y; tmp_list = tmp_list->next; x11_pango_get_item_properties (run->item, &uline, &strike, &rise, &fg_color, &fg_set, &bg_color, &bg_set, &shape_set, &ink_rect, &logical_rect); /* we subtract the rise because X coordinates are upside down */ risen_y = y - rise / PANGO_SCALE; if (!shape_set) { if (uline == PANGO_UNDERLINE_NONE) 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 0 XDrawRectangle( drawable, gc, TRUE, x + (x_off + logical_rect.x) / PANGO_SCALE, risen_y + overall_rect.y / PANGO_SCALE, logical_rect.width / PANGO_SCALE, overall_rect.height / PANGO_SCALE); #endif if (!shape_set) { int gx = x + x_off / PANGO_SCALE; int gy = risen_y; x11_draw_glyphs( drawable, gc, run->item->analysis.font, gx, gy, run->glyphs, colour ); } if (uline == PANGO_UNDERLINE_SINGLE) { XDrawLine( wxGlobalDisplay(), drawable, gc, x + (x_off + ink_rect.x) / PANGO_SCALE - 1, risen_y + 1, x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE, risen_y + 1); } x_off += logical_rect.width; } }
static void render_layout_line (GdkDrawable *drawable, GtkTextRenderState *render_state, PangoLayoutLine *line, GSList **shaped_pointer, int x, int y, gboolean selected, GList **widgets) { GSList *tmp_list = line->runs; PangoRectangle overall_rect; PangoRectangle logical_rect; PangoRectangle ink_rect; gint x_off = 0; GdkGC *fg_gc; pango_layout_line_get_extents (line, NULL, &overall_rect); while (tmp_list) { PangoLayoutRun *run = tmp_list->data; GtkTextAppearance *appearance; gint risen_y; gint shaped_width_pixels = 0; gboolean need_ink = FALSE; tmp_list = tmp_list->next; get_item_properties (run->item, &appearance); g_assert (appearance != NULL); risen_y = y - PANGO_PIXELS (appearance->rise); if (selected) { if (GTK_WIDGET_HAS_FOCUS (render_state->widget)) fg_gc = render_state->widget->style->text_gc[GTK_STATE_SELECTED]; else fg_gc = render_state->widget->style->text_gc [GTK_STATE_ACTIVE]; } else { gtk_text_render_state_update (render_state, appearance); fg_gc = render_state->fg_gc; } if (appearance->underline != PANGO_UNDERLINE_NONE || appearance->strikethrough) need_ink = TRUE; if (appearance->is_text) { if (need_ink) pango_glyph_string_extents (run->glyphs, run->item->analysis.font, &ink_rect, &logical_rect); else pango_glyph_string_extents (run->glyphs, run->item->analysis.font, NULL, &logical_rect); } else { if (need_ink) get_shape_extents (run, &ink_rect, &logical_rect); else get_shape_extents (run, NULL, &logical_rect); } if (appearance->draw_bg && !selected) gdk_draw_rectangle (drawable, render_state->bg_gc, TRUE, x + PANGO_PIXELS (x_off) + PANGO_PIXELS (logical_rect.x), risen_y + PANGO_PIXELS (logical_rect.y), PANGO_PIXELS (logical_rect.width), PANGO_PIXELS (logical_rect.height)); if (appearance->is_text) gdk_draw_glyphs (drawable, fg_gc, run->item->analysis.font, x + PANGO_PIXELS (x_off), risen_y, run->glyphs); else { GObject *shaped = (*shaped_pointer)->data; *shaped_pointer = (*shaped_pointer)->next; if (shaped == NULL) { /* This happens if we have an empty widget anchor. Draw * something empty-looking. */ GdkRectangle shape_rect, draw_rect; shape_rect.x = x + x_off / PANGO_SCALE; shape_rect.y = risen_y - PANGO_PIXELS (logical_rect.height); shape_rect.width = PANGO_PIXELS (logical_rect.width); shape_rect.height = PANGO_PIXELS (logical_rect.height); if (gdk_rectangle_intersect (&shape_rect, &render_state->clip_rect, &draw_rect)) { gdk_draw_rectangle (drawable, render_state->fg_gc, FALSE, shape_rect.x, shape_rect.y, shape_rect.width, shape_rect.height); gdk_draw_line (drawable, render_state->fg_gc, shape_rect.x, shape_rect.y, shape_rect.x + shape_rect.width, shape_rect.y + shape_rect.height); gdk_draw_line (drawable, render_state->fg_gc, shape_rect.x + shape_rect.width, shape_rect.y, shape_rect.x, shape_rect.y + shape_rect.height); } shaped_width_pixels = shape_rect.width; } else if (GDK_IS_PIXBUF (shaped)) { gint width, height; GdkRectangle pixbuf_rect, draw_rect; GdkPixbuf *pixbuf; pixbuf = GDK_PIXBUF (shaped); width = gdk_pixbuf_get_width (pixbuf); height = gdk_pixbuf_get_height (pixbuf); pixbuf_rect.x = x + x_off / PANGO_SCALE; pixbuf_rect.y = risen_y - height; pixbuf_rect.width = width; pixbuf_rect.height = height; if (gdk_rectangle_intersect (&pixbuf_rect, &render_state->clip_rect, &draw_rect)) { gdk_draw_pixbuf (drawable, render_state->fg_gc, pixbuf, draw_rect.x - pixbuf_rect.x, draw_rect.y - pixbuf_rect.y, draw_rect.x, draw_rect.y, draw_rect.width, draw_rect.height, GDK_RGB_DITHER_NORMAL, 0, 0); } shaped_width_pixels = width; } else if (GTK_IS_WIDGET (shaped)) { GtkWidget *widget; widget = GTK_WIDGET (shaped); shaped_width_pixels = widget->allocation.width; if (widgets) { g_object_ref (widget); *widgets = g_list_prepend (*widgets, widget); } } else g_assert_not_reached (); /* not a pixbuf or widget */ } switch (appearance->underline) { case PANGO_UNDERLINE_NONE: break; case PANGO_UNDERLINE_DOUBLE: g_assert (need_ink); gdk_draw_line (drawable, fg_gc, x + (x_off + ink_rect.x) / PANGO_SCALE - 1, risen_y + 3, x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE, risen_y + 3); /* Fall through */ case PANGO_UNDERLINE_SINGLE: g_assert (need_ink); gdk_draw_line (drawable, fg_gc, x + (x_off + ink_rect.x) / PANGO_SCALE - 1, risen_y + 1, x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE, risen_y + 1); break; case PANGO_UNDERLINE_LOW: g_assert (need_ink); gdk_draw_line (drawable, fg_gc, x + (x_off + ink_rect.x) / PANGO_SCALE - 1, risen_y + (ink_rect.y + ink_rect.height) / PANGO_SCALE + 1, x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE, risen_y + (ink_rect.y + ink_rect.height) / PANGO_SCALE + 1); break; } if (appearance->strikethrough) { gint strikethrough_y = risen_y + (0.3 * logical_rect.y) / PANGO_SCALE; g_assert (need_ink); gdk_draw_line (drawable, fg_gc, x + (x_off + ink_rect.x) / PANGO_SCALE - 1, strikethrough_y, x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE, strikethrough_y); } if (appearance->is_text) x_off += logical_rect.width; else x_off += shaped_width_pixels * PANGO_SCALE; } }
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); }