Exemple #1
0
void iupgtkFontUpdatePangoLayout(Ihandle* ih, PangoLayout* layout)
{
  IgtkFont* gtkfont;
  PangoAttrList *attrs;

  if (!layout)
    return;

  gtkfont = gtkFontGet(ih);
  if (!gtkfont)
    return;

  attrs = pango_layout_get_attributes(layout);
  if (!attrs) 
  {
    attrs = pango_attr_list_new();
    pango_attr_list_insert(attrs, pango_attribute_copy(gtkfont->strikethrough));
    pango_attr_list_insert(attrs, pango_attribute_copy(gtkfont->underline));
    pango_layout_set_attributes(layout, attrs);
  }
  else
  {
    pango_attr_list_change(attrs, pango_attribute_copy(gtkfont->strikethrough));
    pango_attr_list_change(attrs, pango_attribute_copy(gtkfont->underline));
  }
}
static void
match_label_color (GstyleColorWidget *self,
                   GstyleColor       *color)
{
  PangoLayout *layout;
  PangoAttrList *attr_list;
  PangoAttribute *attr;
  GdkRGBA rgba;
  GdkRGBA dst_rgba;

  g_assert (GSTYLE_IS_COLOR_WIDGET (self));
  g_assert (GSTYLE_IS_COLOR (color));

  layout = gtk_label_get_layout (self->label);
  attr_list = pango_layout_get_attributes (layout);
  if (attr_list == NULL)
    {
      attr_list = pango_attr_list_new ();
      gtk_label_set_attributes (self->label, attr_list);
      pango_attr_list_unref (attr_list);
    }

  gstyle_color_fill_rgba (color, &rgba);
  gstyle_utils_get_contrasted_rgba (rgba, &dst_rgba);
  attr = pango_attr_foreground_new (dst_rgba.red * 0xffff, dst_rgba.green * 0xffff, dst_rgba.blue * 0xffff);
  pango_attr_list_change (attr_list, attr);
  attr = pango_attr_background_new (rgba.red * 0xffff, rgba.green * 0xffff, rgba.blue * 0xffff);
  pango_attr_list_change (attr_list, attr);
}
Exemple #3
0
static void
test_file (const gchar *filename, GString *string)
{
  gchar *contents;
  gchar *markup;
  gsize  length;
  GError *error = NULL;
  PangoLayout *layout;
  gchar *p;
  gint width = 0;
  gint ellipsize_at = 0;
  PangoEllipsizeMode ellipsize = PANGO_ELLIPSIZE_NONE;
  PangoWrapMode wrap = PANGO_WRAP_WORD;
  PangoFontDescription *desc;

  if (!g_file_get_contents (filename, &contents, &length, &error))
    {
      fprintf (stderr, "%s\n", error->message);
      g_error_free (error);
      return;
    }

  p = strchr (contents, '\n');
  g_assert (p);
  markup = p + 1;
  *p = '\0';

  parse_params (contents, &width, &ellipsize_at, &ellipsize, &wrap);

  layout = pango_layout_new (context);

  desc = pango_font_description_from_string ("Cantarell 11");
  pango_layout_set_font_description (layout, desc);
  pango_font_description_free (desc); 

  pango_layout_set_markup (layout, markup, length);
  g_free (contents);

  if (width != 0)
    pango_layout_set_width (layout, width * PANGO_SCALE);
  pango_layout_set_ellipsize (layout, ellipsize);
  pango_layout_set_wrap (layout, wrap);

  g_string_append (string, pango_layout_get_text (layout));
  g_string_append (string, "\n---\n\n");
  g_string_append_printf (string, "wrapped: %d\n", pango_layout_is_wrapped (layout));
  g_string_append_printf (string, "ellipsized: %d\n", pango_layout_is_ellipsized (layout));
  g_string_append_printf (string, "lines: %d\n", pango_layout_get_line_count (layout));
  if (width != 0)
    g_string_append_printf (string, "width: %d\n", pango_layout_get_width (layout));
  g_string_append (string, "\n---\n\n");
   dump_attrs (pango_layout_get_attributes (layout), string);
  g_string_append (string, "\n---\n\n");
  dump_lines (layout, string);
  g_string_append (string, "\n---\n\n");
  dump_runs (layout, string);

  g_object_unref (layout);
}
static PangoAttrList*
gdip_get_layout_attributes (PangoLayout *layout)
{
	PangoAttrList *list = pango_layout_get_attributes (layout);
	if (!list)
		list = pango_attr_list_new ();
	else
		pango_attr_list_ref (list);
	return list;
}
Exemple #5
0
void
go_pango_translate_layout (PangoLayout *layout)
{
	PangoAttrList *attrs, *n_attrs;

	g_return_if_fail (layout != NULL);

	attrs = pango_layout_get_attributes (layout);
	n_attrs = go_pango_translate_attributes (attrs);
	if (attrs != n_attrs) {
		pango_layout_set_attributes (layout, n_attrs);
		pango_attr_list_unref (n_attrs);
	}

}
Exemple #6
0
static void
set_fade (AboutRenderer *r, AboutState *state, double f)
{
	GtkStyleContext *ctxt = gtk_widget_get_style_context (state->anim_area);
	PangoAttrList *attrlist = pango_layout_get_attributes (r->layout);
	GdkRGBA col, bg, fg;
	PangoAttribute *attr;

	gtk_style_context_get_color (ctxt, GTK_STATE_FLAG_NORMAL, &fg);
	gtk_style_context_get_background_color (ctxt, GTK_STATE_FLAG_NORMAL, &bg);
	col = blend_colors (&bg, &fg, f);
	attr = pango_attr_foreground_new
		(col.red * 65535., col.green * 65535., col.blue * 65535.);
	pango_attr_list_change (attrlist, attr);
	pango_layout_set_attributes (r->layout, attrlist);
}
Exemple #7
0
static void _mt_draw_string(MT_WINDOW *win, MT_STRING *str, int x_offset, int y_offset, MT_COLOR *color)
{
   MT_GTK_STRING *s = str;
   PangoLayout *layout = s->layout;
   int state_type = s->state_type;

   if (!color && s->color) color = s->color;
   if (color && !pango_layout_get_text(layout)) color = NULL;

   if (color) {
      PangoAttrList *attrlist;
      PangoAttribute *attr;

      layout = pango_layout_copy(layout);

      attrlist = pango_layout_get_attributes(layout);
      if (attrlist) {
         pango_attr_list_ref(attrlist);
      }
      else {
         attrlist = pango_attr_list_new();
      }

      if (color) {
         attr = pango_attr_foreground_new(color->r << 8, color->g << 8, color->b << 8);
         attr->start_index = 0;
         attr->end_index = strlen(pango_layout_get_text(layout));
         pango_attr_list_insert_before(attrlist, attr);
      }
      
      pango_layout_set_attributes(layout, attrlist);
      pango_attr_list_unref(attrlist);

      state_type = GTK_STATE_NORMAL;
   }

   s->parent_class->draw_layout(s->style, (GdkWindow *)win, state_type, s->use_text,
                                s->area, s->widget, s->detail, s->x + x_offset, s->y + y_offset, layout);

   if (color) {
      g_object_unref(layout);
   }
}
Exemple #8
0
static void gtkFontUpdate(IgtkFont* gtkfont)
{
  PangoAttrList *attrs;

  pango_layout_set_font_description(gtkfont->layout, gtkfont->fontdesc);

  attrs = pango_layout_get_attributes(gtkfont->layout);
  if (!attrs) 
  {
    attrs = pango_attr_list_new();
    pango_attr_list_insert(attrs, pango_attribute_copy(gtkfont->strikethrough));
    pango_attr_list_insert(attrs, pango_attribute_copy(gtkfont->underline));
    pango_layout_set_attributes(gtkfont->layout, attrs);
  }
  else
  {
    pango_attr_list_change(attrs, pango_attribute_copy(gtkfont->strikethrough));
    pango_attr_list_change(attrs, pango_attribute_copy(gtkfont->underline));
  }
}
Exemple #9
0
/**
 * gail_misc_layout_get_run_attributes:
 * @attrib_set: The #AtkAttributeSet to add the attribute to
 * @layout: The PangoLayout from which the attributes will be obtained
 * @text: The text 
 * @offset: The offset at which the attributes are required
 * @start_offset: The start offset of the current run
 * @end_offset: The end offset of the current run
 *
 * Adds the attributes for the run starting at offset to the specified
 * attribute set.
 *
 * Returns: A pointer to the #AtkAttributeSet.
 **/
AtkAttributeSet* 
gail_misc_layout_get_run_attributes (AtkAttributeSet *attrib_set,
                                     PangoLayout     *layout,
                                     const gchar     *text,
                                     gint            offset,
                                     gint            *start_offset,
                                     gint            *end_offset)
{
  PangoAttrIterator *iter;
  PangoAttrList *attr;  
  PangoAttrString *pango_string;
  PangoAttrInt *pango_int;
  PangoAttrColor *pango_color;
  PangoAttrLanguage *pango_lang;
  PangoAttrFloat *pango_float;
  gint index, start_index, end_index;
  gboolean is_next = TRUE;
  gchar *value = NULL;
  glong len;

  len = g_utf8_strlen (text, -1);
  /* Grab the attributes of the PangoLayout, if any */
  if ((attr = pango_layout_get_attributes (layout)) == NULL)
    {
      *start_offset = 0;
      *end_offset = len;
      return attrib_set;
    }
  iter = pango_attr_list_get_iterator (attr);
  /* Get invariant range offsets */
  /* If offset out of range, set offset in range */
  if (offset > len)
    offset = len;
  else if (offset < 0)
    offset = 0;

  index = g_utf8_offset_to_pointer (text, offset) - text;
  pango_attr_iterator_range (iter, &start_index, &end_index);
  while (is_next)
    {
      if (index >= start_index && index < end_index)
        {
          *start_offset = g_utf8_pointer_to_offset (text, 
                                                    text + start_index);  
          if (end_index == G_MAXINT)
          /* Last iterator */
            end_index = len;
      
          *end_offset = g_utf8_pointer_to_offset (text, 
                                                  text + end_index);  
          break;
        }  
      is_next = pango_attr_iterator_next (iter);
      pango_attr_iterator_range (iter, &start_index, &end_index);
    }
  /* Get attributes */
  if ((pango_string = (PangoAttrString*) pango_attr_iterator_get (iter, 
                                   PANGO_ATTR_FAMILY)) != NULL)
    {
      value = g_strdup_printf("%s", pango_string->value);
      attrib_set = gail_misc_add_attribute (attrib_set, 
                                            ATK_TEXT_ATTR_FAMILY_NAME, 
                                            value);
    } 
  if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter, 
                                   PANGO_ATTR_STYLE)) != NULL)
    {
      attrib_set = gail_misc_add_attribute (attrib_set, 
                                            ATK_TEXT_ATTR_STYLE, 
      g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STYLE, pango_int->value)));
    } 
  if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter, 
                                   PANGO_ATTR_WEIGHT)) != NULL)
    {
      value = g_strdup_printf("%i", pango_int->value);
      attrib_set = gail_misc_add_attribute (attrib_set, 
                                            ATK_TEXT_ATTR_WEIGHT, 
                                            value);
    } 
  if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter, 
                                   PANGO_ATTR_VARIANT)) != NULL)
    {
      attrib_set = gail_misc_add_attribute (attrib_set, 
                                            ATK_TEXT_ATTR_VARIANT, 
       g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_VARIANT, pango_int->value)));
    } 
  if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter, 
                                   PANGO_ATTR_STRETCH)) != NULL)
    {
      attrib_set = gail_misc_add_attribute (attrib_set, 
                                            ATK_TEXT_ATTR_STRETCH, 
       g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STRETCH, pango_int->value)));
    } 
  if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter, 
                                   PANGO_ATTR_SIZE)) != NULL)
    {
      value = g_strdup_printf("%i", pango_int->value / PANGO_SCALE);
      attrib_set = gail_misc_add_attribute (attrib_set, 
                                            ATK_TEXT_ATTR_SIZE,
                                            value);
    } 
  if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter, 
                                   PANGO_ATTR_UNDERLINE)) != NULL)
    {
      attrib_set = gail_misc_add_attribute (attrib_set, 
                                            ATK_TEXT_ATTR_UNDERLINE, 
       g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_UNDERLINE, pango_int->value)));
    } 
  if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter, 
                                   PANGO_ATTR_STRIKETHROUGH)) != NULL)
    {
      attrib_set = gail_misc_add_attribute (attrib_set, 
                                            ATK_TEXT_ATTR_STRIKETHROUGH, 
       g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STRIKETHROUGH, pango_int->value)));
    } 
  if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter, 
                                   PANGO_ATTR_RISE)) != NULL)
    {
      value = g_strdup_printf("%i", pango_int->value);
      attrib_set = gail_misc_add_attribute (attrib_set, 
                                            ATK_TEXT_ATTR_RISE,
                                            value);
    } 
  if ((pango_lang = (PangoAttrLanguage*) pango_attr_iterator_get (iter, 
                                   PANGO_ATTR_LANGUAGE)) != NULL)
    {
      value = g_strdup( pango_language_to_string( pango_lang->value));
      attrib_set = gail_misc_add_attribute (attrib_set, 
                                            ATK_TEXT_ATTR_LANGUAGE, 
                                            value);
    } 
  if ((pango_float = (PangoAttrFloat*) pango_attr_iterator_get (iter, 
                                   PANGO_ATTR_SCALE)) != NULL)
    {
      value = g_strdup_printf("%g", pango_float->value);
      attrib_set = gail_misc_add_attribute (attrib_set, 
                                            ATK_TEXT_ATTR_SCALE, 
                                            value);
    } 
  if ((pango_color = (PangoAttrColor*) pango_attr_iterator_get (iter, 
                                    PANGO_ATTR_FOREGROUND)) != NULL)
    {
      value = g_strdup_printf ("%u,%u,%u", 
                               pango_color->color.red, 
                               pango_color->color.green, 
                               pango_color->color.blue);
      attrib_set = gail_misc_add_attribute (attrib_set, 
                                            ATK_TEXT_ATTR_FG_COLOR, 
                                            value);
    } 
  if ((pango_color = (PangoAttrColor*) pango_attr_iterator_get (iter, 
                                     PANGO_ATTR_BACKGROUND)) != NULL)
    {
      value = g_strdup_printf ("%u,%u,%u", 
                               pango_color->color.red, 
                               pango_color->color.green, 
                               pango_color->color.blue);
      attrib_set = gail_misc_add_attribute (attrib_set, 
                                            ATK_TEXT_ATTR_BG_COLOR, 
                                            value);
    } 
  pango_attr_iterator_destroy (iter);
  return attrib_set;
}
Exemple #10
0
static gboolean
text_item_renderer (AboutRenderer *r, AboutState *state)
{
	PangoLayout *layout = r->layout;
	int age = state->now - r->start_time;
	double rage = CLAMP (age / (double)r->duration, 0.0, 1.0);
	GtkWidget *widget = state->anim_area;
	GtkStyleContext *ctxt;
	const int fade = 500;
	int x, y, width, height;
	cairo_t *cr;
	GtkAllocation wa;
	GdkRGBA color;
	double alpha = 1;

	if (age >= r->duration)
		return FALSE;

	if (r->fade_in && age < fade)
		alpha = age / (double)fade;
	else if (r->fade_out && r->duration - age < fade)
		alpha = (r->duration - age) / (double)fade;

	ctxt = gtk_widget_get_style_context (widget);

	gtk_widget_get_allocation (widget, &wa);
	x = (int)(PANGO_SCALE * wa.width *
		  (r->start.x + rage * (r->end.x - r->start.x)));
	y = (int)(PANGO_SCALE * wa.height *
		  (r->start.y + rage * (r->end.y - r->start.y)));

	if (r->expansion.count) {
		PangoAttrList *attrlist = pango_layout_get_attributes (layout);
		const char *p, *text = pango_layout_get_text (layout);
		PangoRectangle ink, logical;

		memset (&ink, 0, sizeof (ink));
		logical = ink;

		logical.width = (int)(rage * r->expansion.rate * r->natural_width / r->expansion.count);

		p = text;
		while (*p) {
			const char *next = g_utf8_next_char (p);
			gunichar uc = g_utf8_get_char (p);
			PangoAttribute *attr;

			if (uc == UNICODE_ZERO_WIDTH_SPACE_C) {
				attr = pango_attr_shape_new (&ink, &logical);
				attr->start_index = p - text;
				attr->end_index = next - text;
				pango_attr_list_change (attrlist, attr);
			}
			p = next;
		}
		pango_layout_set_attributes (layout, attrlist);
	}

	pango_layout_get_size (layout, &width, &height);
	x -= width / 2;
	y -= height / 2;

	cr = r->cr;
	gnm_style_context_get_color (ctxt, GTK_STATE_FLAG_NORMAL, &color);
	color.alpha = alpha;
	gdk_cairo_set_source_rgba (cr, &color);
	cairo_move_to (cr, x / (double)PANGO_SCALE, y / (double)PANGO_SCALE);
	pango_cairo_show_layout (cr, layout);

	return TRUE;
}
Exemple #11
0
static VALUE
rg_attributes(VALUE self)
{
    return BOXED2RVAL(pango_layout_get_attributes(_SELF(self)), PANGO_TYPE_ATTR_LIST);
}
Exemple #12
0
PangoAttrList *textbox_get_pango_attributes ( textbox *tb )
{
    return pango_layout_get_attributes ( tb->layout );
}
Exemple #13
0
void RrFontDraw(XftDraw *d, RrTextureText *t, RrRect *area)
{
    gint x,y,w;
    XftColor c;
    gint mw;
    PangoRectangle rect;
    PangoAttrList *attrlist;
    PangoEllipsizeMode ell;

    g_assert(!t->flow || t->maxwidth > 0);

    y = area->y;
    if (!t->flow)
        /* center the text vertically
           We do this centering based on the 'baseline' since different fonts
           have different top edges. It looks bad when the whole string is
           moved when 1 character from a non-default language is included in
           the string */
        y += font_calculate_baseline(t->font, area->height);

    /* the +2 and -4 leave a small blank edge on the sides */
    x = area->x + 2;
    w = area->width;
    if (t->flow) w = MAX(w, t->maxwidth);
    w -= 4;
    /* h = area->height; */

    if (t->flow)
        ell = PANGO_ELLIPSIZE_NONE;
    else {
        switch (t->ellipsize) {
        case RR_ELLIPSIZE_NONE:
            ell = PANGO_ELLIPSIZE_NONE;
            break;
        case RR_ELLIPSIZE_START:
            ell = PANGO_ELLIPSIZE_START;
            break;
        case RR_ELLIPSIZE_MIDDLE:
            ell = PANGO_ELLIPSIZE_MIDDLE;
            break;
        case RR_ELLIPSIZE_END:
            ell = PANGO_ELLIPSIZE_END;
            break;
        default:
            g_assert_not_reached();
        }
    }

    pango_layout_set_text(t->font->layout, t->string, -1);
    pango_layout_set_width(t->font->layout, w * PANGO_SCALE);
    pango_layout_set_ellipsize(t->font->layout, ell);
    pango_layout_set_single_paragraph_mode(t->font->layout, !t->flow);

    /* * * end of setting up the layout * * */

    pango_layout_get_pixel_extents(t->font->layout, NULL, &rect);
    mw = rect.width;

    /* pango_layout_set_alignment doesn't work with
       pango_xft_render_layout_line */
    switch (t->justify) {
    case RR_JUSTIFY_LEFT:
        break;
    case RR_JUSTIFY_RIGHT:
        x += (w - mw);
        break;
    case RR_JUSTIFY_CENTER:
        x += (w - mw) / 2;
        break;
    case RR_JUSTIFY_NUM_TYPES:
        g_assert_not_reached();
    }

    if (t->shadow_offset_x || t->shadow_offset_y) {
        /* From nvidia's readme (chapter 23):

           When rendering to a 32-bit window, keep in mind that the X RENDER
           extension, used by most composite managers, expects "premultiplied
           alpha" colors. This means that if your color has components (r,g,b)
           and alpha value a, then you must render (a*r, a*g, a*b, a) into the
           target window.
        */
        c.color.red = (t->shadow_color->r | t->shadow_color->r << 8) *
            t->shadow_alpha / 255;
        c.color.green = (t->shadow_color->g | t->shadow_color->g << 8) *
            t->shadow_alpha / 255;
        c.color.blue = (t->shadow_color->b | t->shadow_color->b << 8) *
            t->shadow_alpha / 255;
        c.color.alpha = 0xffff * t->shadow_alpha / 255;
        c.pixel = t->shadow_color->pixel;

        /* see below... */
        if (!t->flow) {
            pango_xft_render_layout_line
                (d, &c,
#if PANGO_VERSION_MAJOR > 1 || \
    (PANGO_VERSION_MAJOR == 1 && PANGO_VERSION_MINOR >= 16)
                 pango_layout_get_line_readonly(t->font->layout, 0),
#else
                 pango_layout_get_line(t->font->layout, 0),
#endif
                 (x + t->shadow_offset_x) * PANGO_SCALE,
                 (y + t->shadow_offset_y) * PANGO_SCALE);
        }
        else {
            pango_xft_render_layout(d, &c, t->font->layout,
                                    (x + t->shadow_offset_x) * PANGO_SCALE,
                                    (y + t->shadow_offset_y) * PANGO_SCALE);
        }
    }

    c.color.red = t->color->r | t->color->r << 8;
    c.color.green = t->color->g | t->color->g << 8;
    c.color.blue = t->color->b | t->color->b << 8;
    c.color.alpha = 0xff | 0xff << 8; /* fully opaque text */
    c.pixel = t->color->pixel;

    if (t->shortcut) {
        const gchar *s = t->string + t->shortcut_pos;

        t->font->shortcut_underline->start_index = t->shortcut_pos;
        t->font->shortcut_underline->end_index = t->shortcut_pos +
            (g_utf8_next_char(s) - s);

        /* the attributes are owned by the layout.
           re-add the attributes to the layout after changing the
           start and end index */
        attrlist = pango_layout_get_attributes(t->font->layout);
        pango_attr_list_ref(attrlist);
        pango_layout_set_attributes(t->font->layout, attrlist);
        pango_attr_list_unref(attrlist);
    }

    /* layout_line() uses y to specify the baseline
       The line doesn't need to be freed, it's a part of the layout */
    if (!t->flow) {
        pango_xft_render_layout_line
            (d, &c,
#if PANGO_VERSION_MAJOR > 1 || \
    (PANGO_VERSION_MAJOR == 1 && PANGO_VERSION_MINOR >= 16)
             pango_layout_get_line_readonly(t->font->layout, 0),
#else
             pango_layout_get_line(t->font->layout, 0),
#endif
             x * PANGO_SCALE,
             y * PANGO_SCALE);
    }
    else {
        pango_xft_render_layout(d, &c, t->font->layout,
                                x * PANGO_SCALE,
                                y * PANGO_SCALE);
    }

    if (t->shortcut) {
        t->font->shortcut_underline->start_index = 0;
        t->font->shortcut_underline->end_index = 0;
        /* the attributes are owned by the layout.
           re-add the attributes to the layout after changing the
           start and end index */
        attrlist = pango_layout_get_attributes(t->font->layout);
        pango_attr_list_ref(attrlist);
        pango_layout_set_attributes(t->font->layout, attrlist);
        pango_attr_list_unref(attrlist);
    }
}
Exemple #14
0
static VALUE
rg_attributes(VALUE self)
{
    return PANGOATTRLIST2RVAL(pango_layout_get_attributes(_SELF(self)));
}
static void
gutter_renderer_text_draw (GtkSourceGutterRenderer      *renderer,
                           cairo_t                      *cr,
                           GdkRectangle                 *background_area,
                           GdkRectangle                 *cell_area,
                           GtkTextIter                  *start,
                           GtkTextIter                  *end,
                           GtkSourceGutterRendererState  state)
{
	GtkSourceGutterRendererText *text = GTK_SOURCE_GUTTER_RENDERER_TEXT (renderer);
	gint width;
	gint height;
	PangoAttrList *attr_list;
	gfloat xalign;
	gfloat yalign;
	GtkSourceGutterRendererAlignmentMode mode;
	GtkTextView *view;
	gint x = 0;
	gint y = 0;
	GtkStyleContext *context;

	/* Chain up to draw background */
	if (GTK_SOURCE_GUTTER_RENDERER_CLASS (gtk_source_gutter_renderer_text_parent_class)->draw != NULL)
	{
		GTK_SOURCE_GUTTER_RENDERER_CLASS (gtk_source_gutter_renderer_text_parent_class)->draw (renderer,
												       cr,
												       background_area,
												       cell_area,
												       start,
												       end,
												       state);
	}

	view = gtk_source_gutter_renderer_get_view (renderer);

	if (text->priv->is_markup)
	{
		pango_layout_set_markup (text->priv->cached_layout,
		                         text->priv->text,
		                         -1);
	}
	else
	{
		pango_layout_set_text (text->priv->cached_layout,
		                       text->priv->text,
		                       -1);
	}

	attr_list = pango_layout_get_attributes (text->priv->cached_layout);

	if (!attr_list)
	{
		pango_layout_set_attributes (text->priv->cached_layout,
		                             pango_attr_list_copy (text->priv->cached_attr_list));
	}
	else
	{
		pango_attr_list_insert (attr_list,
		                        pango_attribute_copy (text->priv->fg_attr));
	}

	pango_layout_get_pixel_size (text->priv->cached_layout, &width, &height);

	gtk_source_gutter_renderer_get_alignment (renderer,
	                                          &xalign,
	                                          &yalign);

	mode = gtk_source_gutter_renderer_get_alignment_mode (renderer);

	switch (mode)
	{
		case GTK_SOURCE_GUTTER_RENDERER_ALIGNMENT_MODE_CELL:
			x = cell_area->x + (cell_area->width - width) * xalign;
			y = cell_area->y + (cell_area->height - height) * yalign;
		break;
		case GTK_SOURCE_GUTTER_RENDERER_ALIGNMENT_MODE_FIRST:
			center_on (renderer,
			           cell_area,
			           start,
			           width,
			           height,
			           xalign,
			           yalign,
			           &x,
			           &y);
		break;
		case GTK_SOURCE_GUTTER_RENDERER_ALIGNMENT_MODE_LAST:
			center_on (renderer,
			           cell_area,
			           end,
			           width,
			           height,
			           xalign,
			           yalign,
			           &x,
			           &y);
		break;
	}

	context = gtk_widget_get_style_context (GTK_WIDGET (view));
	gtk_render_layout (context, cr, x, y, text->priv->cached_layout);
}