diff options
Diffstat (limited to 'pango')
-rw-r--r-- | pango/fonts.c | 1 | ||||
-rw-r--r-- | pango/pango-attributes.c | 67 | ||||
-rw-r--r-- | pango/pango-attributes.h | 13 | ||||
-rw-r--r-- | pango/pango-context.c | 8 | ||||
-rw-r--r-- | pango/pango-layout.c | 129 |
5 files changed, 203 insertions, 15 deletions
diff --git a/pango/fonts.c b/pango/fonts.c index aedecad7..9700c134 100644 --- a/pango/fonts.c +++ b/pango/fonts.c @@ -22,6 +22,7 @@ #include <stdlib.h> #include <ctype.h> #include <math.h> +#include <string.h> #include "pango.h" diff --git a/pango/pango-attributes.c b/pango/pango-attributes.c index 23cfd8b1..beebcec3 100644 --- a/pango/pango-attributes.c +++ b/pango/pango-attributes.c @@ -548,6 +548,73 @@ pango_attr_rise_new (int rise) return pango_attr_int_new (&klass, (int)rise); } +static PangoAttribute * +pango_attr_shape_copy (const PangoAttribute *attr) +{ + const PangoAttrShape *shape_attr = (PangoAttrShape *)attr; + + return pango_attr_shape_new (&shape_attr->ink_rect, &shape_attr->logical_rect); +} + +static void +pango_attr_shape_destroy (PangoAttribute *attr) +{ + g_free (attr); +} + +static gboolean +pango_attr_shape_compare (const PangoAttribute *attr1, + const PangoAttribute *attr2) +{ + const PangoAttrShape *shape_attr1 = (const PangoAttrShape *)attr1; + const PangoAttrShape *shape_attr2 = (const PangoAttrShape *)attr2; + + return (shape_attr1->logical_rect.x == shape_attr2->logical_rect.x && + shape_attr1->logical_rect.y == shape_attr2->logical_rect.y && + shape_attr1->logical_rect.width == shape_attr2->logical_rect.width && + shape_attr1->logical_rect.height == shape_attr2->logical_rect.height && + shape_attr1->ink_rect.x == shape_attr2->ink_rect.x && + shape_attr1->ink_rect.y == shape_attr2->ink_rect.y && + shape_attr1->ink_rect.width == shape_attr2->ink_rect.width && + shape_attr1->ink_rect.height == shape_attr2->ink_rect.height); +} + +/** + * pango_attr_shape_new: + * @ink_rect: ink rectangle to assign to each character + * @logical_rect: logical rectangle assign to each character + * + * Create a new shape attribute. A shape is used to impose a + * particular ink and logical rect on the result of shaping a + * particular glyph. This might be used, for instance, for + * embedding a picture or a widget inside a PangoLayout. + * + * Return value: the newly created attribute + **/ +PangoAttribute * +pango_attr_shape_new (const PangoRectangle *ink_rect, + const PangoRectangle *logical_rect) +{ + static const PangoAttrClass klass = { + PANGO_ATTR_SHAPE, + pango_attr_shape_copy, + pango_attr_shape_destroy, + pango_attr_shape_compare + }; + + PangoAttrShape *result; + + g_return_val_if_fail (ink_rect != NULL, NULL); + g_return_val_if_fail (logical_rect != NULL, NULL); + + result = g_new (PangoAttrShape, 1); + result->attr.klass = &klass; + result->ink_rect = *ink_rect; + result->logical_rect = *logical_rect; + + return (PangoAttribute *)result; +} + /** * pango_attr_list_new: * diff --git a/pango/pango-attributes.h b/pango/pango-attributes.h index 3670163e..abd901f5 100644 --- a/pango/pango-attributes.h +++ b/pango/pango-attributes.h @@ -35,6 +35,7 @@ typedef struct _PangoAttrString PangoAttrString; typedef struct _PangoAttrInt PangoAttrInt; typedef struct _PangoAttrColor PangoAttrColor; typedef struct _PangoAttrFontDesc PangoAttrFontDesc; +typedef struct _PangoAttrShape PangoAttrShape; typedef struct _PangoAttrList PangoAttrList; typedef struct _PangoAttrIterator PangoAttrIterator; @@ -52,7 +53,8 @@ typedef enum { PANGO_ATTR_BACKGROUND, /* PangoAttrColor */ PANGO_ATTR_UNDERLINE, /* PangoAttrInt */ PANGO_ATTR_STRIKETHROUGH, /* PangoAttrInt */ - PANGO_ATTR_RISE /* PangoAttrInt */ + PANGO_ATTR_RISE, /* PangoAttrInt */ + PANGO_ATTR_SHAPE /* PangoAttrShape */ } PangoAttrType; typedef enum { @@ -97,6 +99,13 @@ struct _PangoAttrColor guint16 blue; }; +struct _PangoAttrShape +{ + PangoAttribute attr; + PangoRectangle ink_rect; + PangoRectangle logical_rect; +}; + struct _PangoAttrFontDesc { PangoAttribute attr; @@ -127,6 +136,8 @@ PangoAttribute *pango_attr_font_desc_new (const PangoFontDescription *desc); PangoAttribute *pango_attr_underline_new (PangoUnderline underline); PangoAttribute *pango_attr_strikethrough_new (gboolean strikethrough); PangoAttribute *pango_attr_rise_new (int rise); +PangoAttribute *pango_attr_shape_new (const PangoRectangle *ink_rect, + const PangoRectangle *logical_rect); PangoAttrList * pango_attr_list_new (void); void pango_attr_list_ref (PangoAttrList *list); diff --git a/pango/pango-context.c b/pango/pango-context.c index cf6d3b42..b1e612fa 100644 --- a/pango/pango-context.c +++ b/pango/pango-context.c @@ -603,14 +603,14 @@ pango_itemize (PangoContext *context, if (extra_attr_lists[i] && i != 0 && extra_attr_lists[i] == extra_attr_lists[i-1]) { GSList *tmp_list = extra_attr_lists[i]; - item->extra_attrs = NULL; + GSList *new_list = NULL; while (tmp_list) { - item->extra_attrs = g_slist_prepend (item->extra_attrs, - pango_attribute_copy (tmp_list->data)); + new_list = g_slist_prepend (new_list, + pango_attribute_copy (tmp_list->data)); tmp_list = tmp_list->next; } - item->extra_attrs = g_slist_reverse (item->extra_attrs); + item->extra_attrs = g_slist_reverse (new_list); } else item->extra_attrs = extra_attr_lists[i]; diff --git a/pango/pango-layout.c b/pango/pango-layout.c index eb3adad1..a1d266df 100644 --- a/pango/pango-layout.c +++ b/pango/pango-layout.c @@ -77,7 +77,10 @@ static int *pango_layout_line_get_vis2log_map (PangoLayoutLine *line, gboolean strong); static void pango_layout_get_item_properties (PangoItem *item, - PangoUnderline *uline); + PangoUnderline *uline, + PangoRectangle *ink_rect, + PangoRectangle *logical_rect, + gboolean *shape_set); static void pango_layout_init (PangoLayout *layout); static void pango_layout_class_init (PangoLayoutClass *klass); @@ -1554,6 +1557,78 @@ pango_layout_clear_lines (PangoLayout *layout) } } + +/************************************************ + * Some functions for handling PANGO_ATTR_SHAPE * + ************************************************/ + +static void +imposed_shape (gint n_chars, + PangoRectangle *shape_ink, + PangoRectangle *shape_logical, + PangoGlyphString *glyphs) +{ + int i; + + pango_glyph_string_set_size (glyphs, n_chars); + + for (i=0; i < n_chars; i++) + { + glyphs->glyphs[i].glyph = 0; + glyphs->glyphs[i].geometry.x_offset = 0; + glyphs->glyphs[i].geometry.y_offset = 0; + glyphs->glyphs[i].geometry.width = shape_logical->width; + glyphs->glyphs[i].attr.is_cluster_start = 1; + + glyphs->log_clusters[i] = i; + } +} + +static void +imposed_extents (gint n_chars, + PangoRectangle *shape_ink, + PangoRectangle *shape_logical, + PangoRectangle *ink_rect, + PangoRectangle *logical_rect) +{ + if (n_chars > 0) + { + if (ink_rect) + { + ink_rect->x = MIN (shape_ink->x, shape_ink->x + shape_logical->width * (n_chars - 1)); + ink_rect->width = MAX (shape_ink->width, shape_ink->width + shape_logical->width * (n_chars - 1)); + ink_rect->y = shape_ink->y; + ink_rect->height = shape_ink->height; + } + if (logical_rect) + { + logical_rect->x = MIN (shape_logical->x, shape_logical->x + shape_logical->width * (n_chars - 1)); + logical_rect->width = MAX (shape_logical->width, shape_logical->width + shape_logical->width * (n_chars - 1)); + logical_rect->y = shape_logical->y; + logical_rect->height = shape_logical->height; + } + } + else + { + if (ink_rect) + { + ink_rect->x = 0; + ink_rect->y = 0; + ink_rect->width = 0; + ink_rect->height = 0; + } + + if (logical_rect) + { + logical_rect->x = 0; + logical_rect->y = 0; + logical_rect->width = 0; + logical_rect->height = 0; + } + } +} + + /***************** * Line Breaking * *****************/ @@ -1681,11 +1756,18 @@ process_item (PangoLayoutLine *line, int *remaining_width) { PangoGlyphString *glyphs = pango_glyph_string_new (); + PangoRectangle shape_ink; + PangoRectangle shape_logical; + gboolean shape_set; int width; int length; int i; - if (text[item->offset] == '\t') + pango_layout_get_item_properties (item, NULL, &shape_ink, &shape_logical, &shape_set); + + if (shape_set) + imposed_shape (item->num_chars, &shape_ink, &shape_logical, glyphs); + else if (text[item->offset] == '\t') shape_tab (line, glyphs); else pango_shape (text + item->offset, item->length, &item->analysis, glyphs); @@ -1737,8 +1819,11 @@ process_item (PangoLayoutLine *line, item->offset += length; item->length -= length; item->num_chars -= num_chars; - - pango_shape (text + new_item->offset, new_item->length, &new_item->analysis, glyphs); + + if (shape_set) + imposed_shape (item->num_chars, &shape_ink, &shape_logical, glyphs); + else + pango_shape (text + new_item->offset, new_item->length, &new_item->analysis, glyphs); *remaining_width -= width; insert_run (line, new_item, glyphs); @@ -2460,11 +2545,19 @@ pango_layout_line_get_extents (PangoLayoutLine *line, PangoRectangle run_ink; PangoRectangle run_logical; + PangoRectangle shape_ink; + PangoRectangle shape_logical; + gboolean shape_set; - pango_layout_get_item_properties (run->item, &uline); - pango_glyph_string_extents (run->glyphs, run->item->analysis.font, - (ink_rect || uline != PANGO_UNDERLINE_NONE) ? &run_ink : NULL, - &run_logical); + pango_layout_get_item_properties (run->item, &uline, &shape_ink, &shape_logical, &shape_set); + + if (shape_set) + imposed_extents (run->item->num_chars, &shape_ink, &shape_logical, + (ink_rect || uline != PANGO_UNDERLINE_NONE) ? &run_ink : NULL, &run_logical); + else + pango_glyph_string_extents (run->glyphs, run->item->analysis.font, + (ink_rect || uline != PANGO_UNDERLINE_NONE) ? &run_ink : NULL, + &run_logical); switch (uline) { @@ -2668,15 +2761,21 @@ pango_layout_line_postprocess (PangoLayoutLine *line) pango_layout_line_reorder (line); } -/* This utility function is duplicated here and in pango-layout.c; should it be +/* This utility function is duplicated here and in pangox.c; should it be * public? Trouble is - what is the appropriate set of properties? */ static void pango_layout_get_item_properties (PangoItem *item, - PangoUnderline *uline) + PangoUnderline *uline, + PangoRectangle *ink_rect, + PangoRectangle *logical_rect, + gboolean *shape_set) { GSList *tmp_list = item->extra_attrs; + if (shape_set) + *shape_set = FALSE; + while (tmp_list) { PangoAttribute *attr = tmp_list->data; @@ -2686,6 +2785,16 @@ pango_layout_get_item_properties (PangoItem *item, case PANGO_ATTR_UNDERLINE: if (uline) *uline = ((PangoAttrInt *)attr)->value; + break; + + case PANGO_ATTR_SHAPE: + if (shape_set) + *shape_set = TRUE; + if (logical_rect) + *logical_rect = ((PangoAttrShape *)attr)->logical_rect; + if (ink_rect) + *ink_rect = ((PangoAttrShape *)attr)->ink_rect; + break; default: break; |