Fixed grapheme stuff on GTK+.

This commit is contained in:
Pietro Gagliardi 2016-05-25 15:07:32 -04:00
parent ac652f0690
commit 5272e749c0
4 changed files with 31 additions and 38 deletions

View File

@ -22,6 +22,9 @@ This README is being written.<br>
*Note that today's entry may be updated later today.*
* **25 May 2016**
* uiDrawTextLayout attributes are now specified in units of *graphemes* on all platforms. This means characters as seen from a user's perspective, not Unicode codepoints or UTF-8 bytes. So a long string of combining marker codepoints after one codepoint would still count as one grapheme.
* **24 May 2016**
* As promised, `uiCombobox` is now split into `uiCombobox` for non-editable comboboxes and `uiEditableCombobox` for editable comboboxes. Mind the function changes as well :)
* There is a new function `uiMainStep()`, which runs one iteration of the main loop. It takes a single boolean argument, indicating whether to wait for an event to occur or not. It returns true if an event was processed (or if no event is available if you don't want to wait) and false if the event loop was told to stop (for instance, `uiQuit()` was called).

View File

@ -173,7 +173,7 @@ void uiDrawTextFontGetMetrics(uiDrawTextFont *font, uiDrawTextFontMetrics *metri
// note: PangoCairoLayouts are tied to a given cairo_t, so we can't store one in this device-independent structure
struct uiDrawTextLayout {
char *s;
PangoGlyphString *glyphString;
ptrdiff_t *graphemes;
PangoFont *defaultFont;
double width;
PangoAttrList *attrs;
@ -187,7 +187,7 @@ uiDrawTextLayout *uiDrawNewTextLayout(const char *text, uiDrawTextFont *defaultF
layout = uiNew(uiDrawTextLayout);
layout->s = g_strdup(text);
context = mkGenericPangoCairoContext();
layout->glyphString = graphemes(layout->s, context);
layout->graphemes = graphemes(layout->s, context);
g_object_unref(context);
layout->defaultFont = defaultFont->f;
g_object_ref(layout->defaultFont); // retain a copy
@ -200,7 +200,7 @@ void uiDrawFreeTextLayout(uiDrawTextLayout *layout)
{
pango_attr_list_unref(layout->attrs);
g_object_unref(layout->defaultFont);
pango_glyph_string_free(layout->glyphString);
uiFree(layout->graphemes);
g_free(layout->s);
uiFree(layout);
}
@ -267,8 +267,8 @@ void uiDrawText(uiDrawContext *c, double x, double y, uiDrawTextLayout *layout)
static void addAttr(uiDrawTextLayout *layout, PangoAttribute *attr, intmax_t startChar, intmax_t endChar)
{
attr->start_index = layout->glyphString->log_clusters[startChar];
attr->end_index = layout->glyphString->log_clusters[endChar];
attr->start_index = layout->graphemes[startChar];
attr->end_index = layout->graphemes[endChar];
pango_attr_list_insert(layout->attrs, attr);
// pango_attr_list_insert() takes attr; we don't free it
}

View File

@ -1,41 +1,31 @@
// 25 may 2016
#include "uipriv_unix.H"
// TODO this breaks for non-BMP characters?
struct gparam {
const char *text;
PangoGlyphString *glyphString;
};
static void runItem(gpointer it, gpointer data)
ptrdiff_t *graphemes(const char *text, PangoContext *context)
{
PangoItem *item = (PangoItem *) it;
struct gparam *gparam = (struct gparam *) data;
pango_shape(gparam->text + item->offset,
item->length,
&(item->analysis),
gparam->glyphString);
pango_item_free(item);
}
PangoGlyphString *graphemes(const char *text, PangoContext *context)
{
size_t len;
GList *list;
struct gparam gparam;
size_t len, lenchars;
PangoLogAttr *logattrs;
ptrdiff_t *out;
ptrdiff_t *op;
size_t i;
len = strlen(text);
list = pango_itemize(context,
text, 0, len,
NULL, NULL);
lenchars = g_utf8_strlen(text, -1);
logattrs = (PangoLogAttr *) uiAlloc((lenchars + 1) * sizeof (PangoLogAttr), "PangoLogAttr[]");
pango_get_log_attrs(text, len,
-1, NULL,
logattrs, lenchars + 1);
gparam.text = text;
gparam.glyphString = pango_glyph_string_new();
// should be more than enough
out = (ptrdiff_t *) uiAlloc((lenchars + 2) * sizeof (ptrdiff_t), "ptrdiff_t[]");
op = out;
for (i = 0; i < lenchars; i++)
if (logattrs[i].is_cursor_position != 0)
// TODO optimize this
*op++ = g_utf8_offset_to_pointer(text, i) - text;
// and do the last one
*op++ = len;
g_list_foreach(list, runItem, &gparam);
g_list_free(list);
return gparam.glyphString;
uiFree(logattrs);
return out;
}

View File

@ -49,4 +49,4 @@ extern uiDrawTextFont *mkTextFont(PangoFont *f, gboolean add);
extern PangoFont *pangoDescToPangoFont(PangoFontDescription *pdesc);
// graphemes.c
extern PangoGlyphString *graphemes(const char *text, PangoContext *context);
extern ptrdiff_t *graphemes(const char *text, PangoContext *context);