--- deliantra/Deliantra-Client/Client.xs 2006/06/18 19:13:19 1.120 +++ deliantra/Deliantra-Client/Client.xs 2006/06/23 20:28:19 1.121 @@ -44,6 +44,8 @@ #include "glext.h" +#define OBJ_STR "\xef\xbf\xbc" /* U+FFFC, objetc replacement character */ + #define FOW_DARKNESS 32 #define MAP_EXTEND_X 32 @@ -73,6 +75,24 @@ typedef PangoFontDescription *CFClient__Font; +static int +shape_attr_p (PangoLayoutRun *run) +{ + GSList *attrs = run->item->analysis.extra_attrs; + + while (attrs) + { + PangoAttribute *attr = attrs->data; + + if (attr->klass->type == PANGO_ATTR_SHAPE) + return 1; + + attrs = attrs->next; + } + + return 0; +} + typedef struct cf_layout { PangoLayout *pl; // either derived from a cairo or ft2 context int rgba; // wether we use rgba (cairo) or grayscale (ft2) @@ -812,6 +832,84 @@ pango_layout_set_markup (self->pl, text, textlen); } +void +set_shapes (CFClient::Layout self, ...) + CODE: +{ + PangoAttrList *attrs = 0; + const char *text = pango_layout_get_text (self->pl); + const char *pos = text; + int arg = 2; + + while (arg < items && (pos = strstr (pos, OBJ_STR))) + { + PangoRectangle rect; + PangoAttribute *attr; + + int w = SvIV (ST (arg - 1)); + int h = SvIV (ST (arg)); + + arg += 2; + + rect.x = 0; + rect.y = -h * PANGO_SCALE; + rect.width = w * PANGO_SCALE; + rect.height = h * PANGO_SCALE; + + if (!attrs) + attrs = pango_layout_get_attributes (self->pl); + + attr = pango_attr_shape_new (&rect, &rect); + attr->start_index = pos - text; + attr->end_index = attr->start_index + sizeof (OBJ_STR) - 1; + pango_attr_list_insert (attrs, attr); + + pos += sizeof (OBJ_STR) - 1; + } + + if (attrs) + pango_layout_set_attributes (self->pl, attrs); +} + +void +get_shapes (CFClient::Layout self) + PPCODE: +{ + PangoLayoutIter *iter = pango_layout_get_iter (self->pl); + + do + { + PangoLayoutRun *run = pango_layout_iter_get_run (iter); + + if (run && shape_attr_p (run)) + { + PangoRectangle extents; + pango_layout_iter_get_run_extents (iter, 0, &extents); + + PUSHs (sv_2mortal (newSViv (PANGO_PIXELS (extents.x)))); + PUSHs (sv_2mortal (newSViv (PANGO_PIXELS (extents.y)))); + } + } + while (pango_layout_iter_next_run (iter)); + + pango_layout_iter_free (iter); +} + +int +has_wrapped (CFClient::Layout self) + CODE: +{ + int lines = 1; + const char *text = pango_layout_get_text (self->pl); + + while (*text) + lines += *text++ == '\n'; + + RETVAL = lines < pango_layout_get_line_count (self->pl); +} + OUTPUT: + RETVAL + SV * get_text (CFClient::Layout self) CODE: