JNIEXPORT void JNICALL Java_org_gnome_pango_PangoLayoutLine_pango_1layout_1line_1get_1extents ( JNIEnv* env, jclass cls, jlong _self, jlong _inkRect, jlong _logicalRect ) { PangoLayoutLine* self; PangoRectangle* inkRect; PangoRectangle* logicalRect; // convert parameter self self = (PangoLayoutLine*) _self; // convert parameter inkRect inkRect = (PangoRectangle*) _inkRect; // convert parameter logicalRect logicalRect = (PangoRectangle*) _logicalRect; // call function pango_layout_line_get_extents(self, inkRect, logicalRect); // cleanup parameter self // cleanup parameter inkRect // cleanup parameter logicalRect }
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; } }
static void add_line_to_postscript(paps_private_t *paps, GString *line_str, double x_pos, double y_pos, PangoLayoutLine *line) { PangoRectangle ink_rect, logical_rect; pango_layout_line_get_extents(line, &ink_rect, &logical_rect); #if 0 // TBD - Handle RTL scripts if (paps->pango_dir == PANGO_DIRECTION_RTL) { x_pos += page_layout->column_width - logical_rect.width / (page_layout->pt_to_pixel * PANGO_SCALE); } #endif draw_contour(paps, line_str, line, x_pos, y_pos); }
static VALUE rg_extents(VALUE self) { PangoRectangle ink_rect, logical_rect; pango_layout_line_get_extents(_SELF(self), &ink_rect, &logical_rect); return rb_assoc_new(PANGORECTANGLE2RVAL(&ink_rect), PANGORECTANGLE2RVAL(&logical_rect)); }
static void begin_print (GtkPrintOperation *operation, GtkPrintContext *context, PrintData *print_data) { PangoFontDescription *desc; PangoLayoutLine *layout_line; double width, height; double page_height; GList *page_breaks; int num_lines; int line; width = gtk_print_context_get_width (context); height = gtk_print_context_get_height (context); print_data->layout = gtk_print_context_create_pango_layout (context); desc = pango_font_description_from_string (print_data->font); pango_layout_set_font_description (print_data->layout, desc); pango_font_description_free (desc); pango_layout_set_width (print_data->layout, width * PANGO_SCALE); pango_layout_set_text (print_data->layout, print_data->text, -1); num_lines = pango_layout_get_line_count (print_data->layout); page_breaks = NULL; page_height = 0; for (line = 0; line < num_lines; line++) { PangoRectangle ink_rect, logical_rect; double line_height; layout_line = pango_layout_get_line (print_data->layout, line); pango_layout_line_get_extents (layout_line, &ink_rect, &logical_rect); line_height = logical_rect.height / 1024.0; if (page_height + line_height > height) { page_breaks = g_list_prepend (page_breaks, GINT_TO_POINTER (line)); page_height = 0; } page_height += line_height; } page_breaks = g_list_reverse (page_breaks); gtk_print_operation_set_n_pages (operation, g_list_length (page_breaks) + 1); print_data->page_breaks = page_breaks; }
/* Split a list of paragraphs into a list of lines. */ gchar *paps_layout_to_postscript_strdup(paps_t *paps_, double pos_x, double pos_y, PangoLayout *layout) { paps_private_t *paps = (paps_private_t*)paps_; GString *layout_str = g_string_new(""); gchar *ret_str; int para_num_lines, line_idx; double scale = 72.0 / PANGO_SCALE / PAPS_DPI; para_num_lines = pango_layout_get_line_count(layout); for (line_idx=0; line_idx<para_num_lines; line_idx++) { PangoRectangle logical_rect, ink_rect; PangoLayoutLine *pango_line = pango_layout_get_line(layout, line_idx); pango_layout_line_get_extents(pango_line, &ink_rect, &logical_rect); add_line_to_postscript(paps, layout_str, pos_x, pos_y, pango_line); pos_y -= logical_rect.height * scale; } ret_str = layout_str->str; g_string_free(layout_str, FALSE); return ret_str; }
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; } }
void MCGContextDrawPlatformText(MCGContextRef self, const unichar_t *p_text, uindex_t p_length, MCGPoint p_location, const MCGFont &p_font) { // MW-2013-12-19: [[ Bug 11559 ]] Do nothing if no text support. if (!s_has_text_support) return; if (!MCGContextIsValid(self)) return; bool t_success; t_success = true; if (t_success) t_success = s_layout != NULL; char *t_text; t_text = nil; if (t_success) t_success = MCCStringFromUnicodeSubstring(p_text, p_length / 2, t_text); MCGAffineTransform t_transform; MCGPoint t_device_location; PangoLayoutLine *t_line; t_line = nil; if (t_success) { t_transform = MCGContextGetDeviceTransform(self); t_device_location = MCGPointApplyAffineTransform(p_location, t_transform); t_transform . tx = modff(t_device_location . x, &t_device_location . x); t_transform . ty = modff(t_device_location . y, &t_device_location . y); PangoMatrix t_ptransform; t_ptransform . xx = t_transform . a; t_ptransform . xy = t_transform . b; t_ptransform . yx = t_transform . c; t_ptransform . yy = t_transform . d; t_ptransform . x0 = t_transform . tx; t_ptransform . y0 = t_transform . ty; pango_context_set_matrix(s_pango, &t_ptransform); pango_layout_set_font_description(s_layout, (PangoFontDescription *) p_font . fid); pango_layout_set_text(s_layout, t_text, -1); MCCStringFree(t_text); extern PangoLayoutLine *(*pango_layout_get_line_readonly_ptr)(PangoLayout *, int); if (pango_layout_get_line_readonly_ptr != nil) t_line = pango_layout_get_line_readonly_ptr(s_layout, 0); else t_line = pango_layout_get_line(s_layout, 0); t_success = t_line != nil; } MCGIntRectangle t_text_bounds, t_clipped_bounds; if (t_success) { PangoRectangle t_pbounds; pango_layout_line_get_extents(t_line, NULL, &t_pbounds); MCGRectangle t_float_text_bounds; t_float_text_bounds . origin . x = t_pbounds . x / PANGO_SCALE; t_float_text_bounds . origin . y = t_pbounds . y / PANGO_SCALE; t_float_text_bounds . size . width = t_pbounds . width / PANGO_SCALE; t_float_text_bounds . size . height = t_pbounds . height / PANGO_SCALE; MCGRectangle t_device_clip; t_device_clip = MCGContextGetDeviceClipBounds(self); t_device_clip . origin . x -= t_device_location . x; t_device_clip . origin . y -= t_device_location . y; MCGRectangle t_float_clipped_bounds; t_float_clipped_bounds = MCGRectangleIntersection(t_float_text_bounds, t_device_clip); t_text_bounds = MCGRectangleIntegerBounds(t_float_text_bounds); t_clipped_bounds = MCGRectangleIntegerBounds(t_float_clipped_bounds); if (t_clipped_bounds . width == 0 || t_clipped_bounds . height == 0) return; } void *t_data; t_data = nil; if (t_success) t_success = MCMemoryNew(t_clipped_bounds . width * t_clipped_bounds . height, t_data); if (t_success) { FT_Bitmap t_ftbitmap; t_ftbitmap . rows = t_clipped_bounds . height; t_ftbitmap . width = t_clipped_bounds . width; t_ftbitmap . pitch = t_clipped_bounds . width; t_ftbitmap . buffer = (unsigned char*) t_data; t_ftbitmap . num_grays = 256; t_ftbitmap . pixel_mode = FT_PIXEL_MODE_GRAY; t_ftbitmap . palette_mode = 0; t_ftbitmap . palette = nil; pango_ft2_render_layout_line(&t_ftbitmap, t_line, -(t_clipped_bounds . x - t_text_bounds . x), -(t_clipped_bounds . y - t_text_bounds . y) - t_text_bounds . y); SkPaint t_paint; t_paint . setStyle(SkPaint::kFill_Style); t_paint . setAntiAlias(self -> state -> should_antialias); t_paint . setColor(MCGColorToSkColor(self -> state -> fill_color)); SkXfermode *t_blend_mode; t_blend_mode = MCGBlendModeToSkXfermode(self -> state -> blend_mode); t_paint . setXfermode(t_blend_mode); if (t_blend_mode != NULL) t_blend_mode -> unref(); SkBitmap t_bitmap; t_bitmap . setConfig(SkBitmap::kA8_Config, t_clipped_bounds . width, t_clipped_bounds . height); t_bitmap . setIsOpaque(false); t_bitmap . setPixels(t_data); self -> layer -> canvas -> drawSprite(t_bitmap, t_clipped_bounds . x + t_device_location . x, t_clipped_bounds . y + t_device_location . y, &t_paint); } MCMemoryDelete(t_data); self -> is_valid = t_success; }
void wxWindowX11::GetTextExtent(const wxString& string, int *x, int *y, int *descent, int *externalLeading, const wxFont *theFont) const { wxFont fontToUse = m_font; if (theFont) fontToUse = *theFont; wxCHECK_RET( fontToUse.Ok(), wxT("invalid font") ); if (string.IsEmpty()) { if (x) (*x) = 0; if (y) (*y) = 0; return; } #if wxUSE_UNICODE PangoLayout *layout = pango_layout_new( wxTheApp->GetPangoContext() ); PangoFontDescription *desc = fontToUse.GetNativeFontInfo()->description; pango_layout_set_font_description(layout, desc); const wxCharBuffer data = wxConvUTF8.cWC2MB( string ); pango_layout_set_text(layout, (const char*) data, strlen( (const char*) data )); PangoLayoutLine *line = (PangoLayoutLine *)pango_layout_get_lines(layout)->data; PangoRectangle rect; pango_layout_line_get_extents(line, NULL, &rect); if (x) (*x) = (wxCoord) (rect.width / PANGO_SCALE); if (y) (*y) = (wxCoord) (rect.height / PANGO_SCALE); if (descent) { // Do something about metrics here (*descent) = 0; } if (externalLeading) (*externalLeading) = 0; // ?? g_object_unref( G_OBJECT( layout ) ); #else WXFontStructPtr pFontStruct = fontToUse.GetFontStruct(1.0, wxGlobalDisplay()); int direction, ascent, descent2; XCharStruct overall; int slen = string.Len(); XTextExtents((XFontStruct*) pFontStruct, (char*) string.c_str(), slen, &direction, &ascent, &descent2, &overall); if ( x ) *x = (overall.width); if ( y ) *y = (ascent + descent2); if (descent) *descent = descent2; if (externalLeading) *externalLeading = 0; #endif }
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); }