Esempio n. 1
0
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
}
Esempio n. 2
0
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;
    }
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
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));
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
/* 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;
}
Esempio n. 7
0
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;
    }
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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
}
Esempio n. 10
0
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;
    }
}
Esempio n. 11
0
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);
}