Did most of the work for grapheme cluster boundary based text layout characters on GTK+.

This commit is contained in:
Pietro Gagliardi 2016-05-25 01:52:53 -04:00
parent a8aa842172
commit ac652f0690
7 changed files with 58 additions and 22 deletions

View File

@ -19,6 +19,7 @@ CFILES += \
unix/editablecombo.c \
unix/entry.c \
unix/fontbutton.c \
unix/graphemes.c \
unix/group.c \
unix/label.c \
unix/main.c \

View File

@ -173,34 +173,22 @@ 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;
ptrdiff_t *charsToBytes;
PangoGlyphString *glyphString;
PangoFont *defaultFont;
double width;
PangoAttrList *attrs;
};
static ptrdiff_t *computeCharsToBytes(const char *s)
{
ptrdiff_t *charsToBytes;
glong i, charlen;
// we INCLUDE the null terminator as a character in the string
// g_utf8_offset_to_pointer() doesn't stop on null terminator so this should work
charlen = g_utf8_strlen(s, -1) + 1;
charsToBytes = (ptrdiff_t *) uiAlloc(charlen * sizeof (ptrdiff_t), "ptrdiff_t[]");
// TODO speed this up by not needing to scan the whole string again
for (i = 0; i < charlen; i++)
charsToBytes[i] = g_utf8_offset_to_pointer(s, i) - s;
return charsToBytes;
}
uiDrawTextLayout *uiDrawNewTextLayout(const char *text, uiDrawTextFont *defaultFont, double width)
{
uiDrawTextLayout *layout;
PangoContext *context;
layout = uiNew(uiDrawTextLayout);
layout->s = g_strdup(text);
layout->charsToBytes = computeCharsToBytes(layout->s);
context = mkGenericPangoCairoContext();
layout->glyphString = graphemes(layout->s, context);
g_object_unref(context);
layout->defaultFont = defaultFont->f;
g_object_ref(layout->defaultFont); // retain a copy
uiDrawTextLayoutSetWidth(layout, width);
@ -212,7 +200,7 @@ void uiDrawFreeTextLayout(uiDrawTextLayout *layout)
{
pango_attr_list_unref(layout->attrs);
g_object_unref(layout->defaultFont);
uiFree(layout->charsToBytes);
pango_glyph_string_free(layout->glyphString);
g_free(layout->s);
uiFree(layout);
}
@ -279,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->charsToBytes[startChar];
attr->end_index = layout->charsToBytes[endChar];
attr->start_index = layout->glyphString->log_clusters[startChar];
attr->end_index = layout->glyphString->log_clusters[endChar];
pango_attr_list_insert(layout->attrs, attr);
// pango_attr_list_insert() takes attr; we don't free it
}

41
unix/graphemes.c Normal file
View File

@ -0,0 +1,41 @@
// 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)
{
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;
len = strlen(text);
list = pango_itemize(context,
text, 0, len,
NULL, NULL);
gparam.text = text;
gparam.glyphString = pango_glyph_string_new();
g_list_foreach(list, runItem, &gparam);
g_list_free(list);
return gparam.glyphString;
}

View File

@ -7,6 +7,7 @@
#include <math.h>
#include <dlfcn.h> // see drawtext.c
#include <langinfo.h>
#include <string.h>
#include "../ui.h"
#include "../ui_unix.h"
#include "../common/uipriv.h"
@ -42,5 +43,10 @@ extern void childSetMargined(struct child *c, int margined);
// draw.c
extern uiDrawContext *newContext(cairo_t *);
extern void freeContext(uiDrawContext *);
// drawtext.c
extern uiDrawTextFont *mkTextFont(PangoFont *f, gboolean add);
extern PangoFont *pangoDescToPangoFont(PangoFontDescription *pdesc);
// graphemes.c
extern PangoGlyphString *graphemes(const char *text, PangoContext *context);

View File

@ -28,7 +28,7 @@ CXXFILES += \
windows/events.cpp \
windows/fontbutton.cpp \
windows/fontdialog.cpp \
windows/grapheme.cpp \
windows/graphemes.cpp \
windows/group.cpp \
windows/init.cpp \
windows/label.cpp \

View File

@ -140,7 +140,7 @@ extern BOOL showColorDialog(HWND parent, struct colorDialogRGBA *c);
// sizing.cpp
extern void getSizing(HWND hwnd, uiWindowsSizing *sizing, HFONT font);
// grapheme.cpp
// graphemes.cpp
extern size_t *graphemes(WCHAR *msg);