Fixed grapheme stuff on GTK+.
This commit is contained in:
parent
ac652f0690
commit
5272e749c0
|
@ -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).
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue