From 2e982190094a3a2416c218d1482a49fa160ee9a3 Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Tue, 30 May 2017 19:07:01 -0400 Subject: [PATCH] And fixed the whole OpenType features nonsense on GTK+, since we now group all OpenType features together. We're now much closer to pushing this back into master! --- unix/attrstr.c | 81 +++++++--------------------------------------- unix/opentype.c | 4 +-- unix/uipriv_unix.h | 2 +- 3 files changed, 14 insertions(+), 73 deletions(-) diff --git a/unix/attrstr.c b/unix/attrstr.c index 21fe108c..ad620aed 100644 --- a/unix/attrstr.c +++ b/unix/attrstr.c @@ -3,57 +3,25 @@ // TODO pango alpha attributes turn 0 into 65535 :| -// we need to collect all the OpenType features and background blocks and add them all at once -// TODO this is the wrong approach; it causes Pango to end runs early, meaning attributes like the ligature attributes never get applied properly +// we need to collect all the background blocks and add them all at once // TODO rename this struct to something that isn't exclusively foreach-ing? struct foreachParams { const char *s; PangoAttrList *attrs; - // keys are pointers to size_t maintained by g_new0()/g_free() - // values are strings - GHashTable *features; // TODO use pango's built-in background attribute? GPtrArray *backgroundClosures; }; -static gboolean featurePosEqual(gconstpointer a, gconstpointer b) +// TODO merge this into the main function below +static PangoAttribute *mkFeaturesAttribute(const uiOpenTypeFeatures *otf) { - size_t *sa = (size_t *) a; - size_t *sb = (size_t *) b; + char *s; + PangoAttribute *attr; - return *sa == *sb; -} - -static guint featurePosHash(gconstpointer n) -{ - size_t *sn = (size_t *) n; - - return (guint) (*sn); -} - -static void freeFeatureString(gpointer s) -{ - g_string_free((GString *) s, TRUE); -} - -#define isCodepointStart(b) (((uint8_t) (b)) <= 0x7F || ((uint8_t) (b)) >= 0xC0) - -static void setFeaturesInRange(struct foreachParams *p, size_t start, size_t end, uiOpenTypeFeatures *otf) -{ - size_t i; - size_t *key; - GString *new; - - new = otfToPangoCSSString(otf); - for (i = start; i < end; i++) { - // don't create redundant entries; see below - if (!isCodepointStart(p->s[i])) - continue; - key = g_new0(size_t, 1); - *key = i; - g_hash_table_replace(p->features, key, g_strdup(new->str)); - } - g_string_free(new, TRUE); + s = otfToPangoCSSString(otf); + attr = FUTURE_pango_attr_font_features_new(s); + g_free(s); + return attr; } struct closureParams { @@ -199,8 +167,8 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t } break; case uiAttributeFeatures: - // TODO ensure the parentheses around spec->Value are provided on Windows (TODO still relevant?) - setFeaturesInRange(p, start, end, spec->Features); + // TODO handle NULLs properly on all platforms + addattr(p, start, end, mkFeaturesAttribute(spec->Features)); break; default: // TODO complain @@ -209,29 +177,6 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t return 0; } -static gboolean applyFeatures(gpointer key, gpointer value, gpointer data) -{ - struct foreachParams *p = (struct foreachParams *) data; - size_t *pos = (size_t *) key; - char *s = (char *) value; - size_t n; - - // make sure we cover an entire code point - // otherwise Pango will break apart multi-byte characters, spitting out U+FFFD characters at the invalid points - n = 1; - while (!isCodepointStart(p->s[*pos + n])) - n++; - addattr(p, *pos, *pos + n, - FUTURE_pango_attr_font_features_new(s)); - return TRUE; // always delete; we're emptying the map -} - -static void applyAndFreeFeatureAttributes(struct foreachParams *p) -{ - g_hash_table_foreach_remove(p->features, applyFeatures, p); - g_hash_table_destroy(p->features); -} - static void unrefClosure(gpointer data) { g_closure_unref((GClosure *) data); @@ -243,12 +188,8 @@ PangoAttrList *attrstrToPangoAttrList(uiDrawTextLayoutParams *p, GPtrArray **bac fep.s = uiAttributedStringString(p->String); fep.attrs = pango_attr_list_new(); - fep.features = g_hash_table_new_full( - featurePosHash, featurePosEqual, - g_free, g_free); fep.backgroundClosures = g_ptr_array_new_with_free_func(unrefClosure); uiAttributedStringForEachAttribute(p->String, processAttribute, &fep); - applyAndFreeFeatureAttributes(&fep); *backgroundClosures = fep.backgroundClosures; return fep.attrs; } diff --git a/unix/opentype.c b/unix/opentype.c index f9d14e09..608a0815 100644 --- a/unix/opentype.c +++ b/unix/opentype.c @@ -187,7 +187,7 @@ static int toCSS(char a, char b, char c, char d, uint32_t value, void *data) return 0; } -GString *otfToPangoCSSString(uiOpenTypeFeatures *otf) +gchar *otfToPangoCSSString(const uiOpenTypeFeatures *otf) { GString *s; @@ -196,5 +196,5 @@ GString *otfToPangoCSSString(uiOpenTypeFeatures *otf) if (s->len != 0) // and remove the last comma g_string_truncate(s, s->len - 2); - return s; + return g_string_free(s, FALSE); } diff --git a/unix/uipriv_unix.h b/unix/uipriv_unix.h index c80e8cc6..46a2426f 100644 --- a/unix/uipriv_unix.h +++ b/unix/uipriv_unix.h @@ -73,4 +73,4 @@ extern const PangoStyle pangoItalics[]; extern const PangoStretch pangoStretches[]; // opentype.c -extern GString *otfToPangoCSSString(uiOpenTypeFeatures *otf); +extern gchar *otfToPangoCSSString(const uiOpenTypeFeatures *otf);