summaryrefslogtreecommitdiff
path: root/pango
diff options
context:
space:
mode:
Diffstat (limited to 'pango')
-rw-r--r--pango/fonts.c1
-rw-r--r--pango/pango-attributes.c67
-rw-r--r--pango/pango-attributes.h13
-rw-r--r--pango/pango-context.c8
-rw-r--r--pango/pango-layout.c129
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;