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); }
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; }
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); } }
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); }
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); } }
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)); } }
/** * 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; }
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; }
static VALUE rg_attributes(VALUE self) { return BOXED2RVAL(pango_layout_get_attributes(_SELF(self)), PANGO_TYPE_ATTR_LIST); }
PangoAttrList *textbox_get_pango_attributes ( textbox *tb ) { return pango_layout_get_attributes ( tb->layout ); }
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); } }
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); }