Did most of the work for grapheme cluster boundary based text layout characters on GTK+.
This commit is contained in:
parent
a8aa842172
commit
ac652f0690
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue