And implemented the new features stuff on the GTK+ side.

This commit is contained in:
Pietro Gagliardi 2017-05-17 23:37:16 -04:00
parent ff4ab7110c
commit 39cec570d9
3 changed files with 27 additions and 53 deletions

View File

@ -10,7 +10,7 @@ struct foreachParams {
const char *s;
PangoAttrList *attrs;
// keys are pointers to size_t maintained by g_new0()/g_free()
// values are GStrings
// values are strings
GHashTable *features;
// TODO use pango's built-in background attribute?
GPtrArray *backgroundClosures;
@ -38,24 +38,22 @@ static void freeFeatureString(gpointer s)
#define isCodepointStart(b) (((uint8_t) (b)) <= 0x7F || ((uint8_t) (b)) >= 0xC0)
static void ensureFeaturesInRange(struct foreachParams *p, size_t start, size_t end)
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;
new = (GString *) g_hash_table_lookup(p->features, &i);
if (new != NULL)
continue;
new = g_string_new("");
key = g_new0(size_t, 1);
*key = i;
g_hash_table_replace(p->features, key, new);
g_hash_table_replace(p->features, key, g_strdup(new->str));
}
g_string_free(new, TRUE);
}
struct closureParams {
@ -104,30 +102,6 @@ static GClosure *mkBackgroundClosure(size_t start, size_t end, double r, double
return closure;
}
struct otParam {
struct foreachParams *p;
size_t start;
size_t end;
};
// see https://developer.mozilla.org/en/docs/Web/CSS/font-feature-settings
static void doOpenType(const char *featureTag, uint32_t param, void *data)
{
struct otParam *p = (struct otParam *) data;
size_t i;
GString *s;
ensureFeaturesInRange(p->p, p->start, p->end);
for (i = p->start; i < p->end; i++) {
// don't use redundant entries; see below
if (!isCodepointStart(p->p->s[i]))
continue;
s = (GString *) g_hash_table_lookup(p->p->features, &i);
g_string_append_printf(s, "\"%s\" %" PRIu32 ", ",
featureTag, param);
}
}
static void addattr(struct foreachParams *p, size_t start, size_t end, PangoAttribute *attr)
{
if (attr == NULL) // in case of a future attribute
@ -142,7 +116,6 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t
struct foreachParams *p = (struct foreachParams *) data;
GClosure *closure;
PangoUnderline underline;
struct otParam op;
switch (spec->Type) {
case uiAttributeFamily:
@ -225,14 +198,13 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t
break;
}
break;
default:
// handle typographic features
op.p = p;
op.start = start;
op.end = end;
// TODO check if unhandled and complain
specToOpenType(spec, doOpenType, &op);
case uiAttributeFeatures:
// TODO ensure the parentheses around spec->Value are provided on Windows
setFeaturesInRange(p, start, end, (uiOpenTypeFeatures *) (spec->Value));
break;
default:
// TODO complain
;
}
return 0;
}
@ -241,18 +213,16 @@ static gboolean applyFeatures(gpointer key, gpointer value, gpointer data)
{
struct foreachParams *p = (struct foreachParams *) data;
size_t *pos = (size_t *) key;
GString *s = (GString *) value;
char *s = (char *) value;
size_t n;
// remove the trailing comma/space
g_string_truncate(s, s->len - 2);
// 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->str));
FUTURE_pango_attr_font_features_new(s));
return TRUE; // always delete; we're emptying the map
}
@ -275,7 +245,7 @@ PangoAttrList *attrstrToPangoAttrList(uiDrawTextLayoutParams *p, GPtrArray **bac
fep.attrs = pango_attr_list_new();
fep.features = g_hash_table_new_full(
featurePosHash, featurePosEqual,
g_free, freeFeatureString);
g_free, g_free);
fep.backgroundClosures = g_ptr_array_new_with_free_func(unrefClosure);
uiAttributedStringForEachAttribute(p->String, processAttribute, &fep);
applyAndFreeFeatureAttributes(&fep);

View File

@ -1,7 +1,7 @@
// 11 may 2017
#include "uipriv_windows.hpp"
#include "uipriv_unix.h"
// TODO switch from GINT_FROM_POINTER() and so to a fake GUINT_FROM_POINTER()?
// TODO switch from GINT_TO_POINTER() and so to a fake GUINT_TO_POINTER()?
struct uiOpenTypeFeatures {
GHashTable *tags;
@ -106,9 +106,9 @@ void uiOpenTypeFeaturesForEach(uiOpenTypeFeatures *otf, uiOpenTypeFeaturesForEac
g_hash_table_foreach(otf->tags, foreach, &ofe);
}
static gint tagcmp(gpointer a, gpointer b)
static gint tagcmp(gconstpointer a, gconstpointer b)
{
return GINT_FROM_POINTER(a) - GINT_FROM_POINTER(b);
return GPOINTER_TO_INT(a) - GPOINTER_TO_INT(b);
}
static GList *copySortedKeys(GHashTable *tags)
@ -130,8 +130,8 @@ int uiOpenTypeFeaturesEqual(uiOpenTypeFeatures *a, uiOpenTypeFeatures *b)
guint i;
int equal = 0;
ak = copySortedKeys(a);
bk = copySortedKeys(b);
ak = copySortedKeys(a->tags);
bk = copySortedKeys(b->tags);
na = g_list_length(ak);
nb = g_list_length(bk);
@ -140,7 +140,7 @@ int uiOpenTypeFeaturesEqual(uiOpenTypeFeatures *a, uiOpenTypeFeatures *b)
goto out;
}
// TODO use GINT_FROM_POINTER() in these?
// TODO use GPOINTER_TO_INT() in these?
ai = ak;
bi = bk;
for (i = 0; i < na; i++) {
@ -153,8 +153,8 @@ int uiOpenTypeFeaturesEqual(uiOpenTypeFeatures *a, uiOpenTypeFeatures *b)
goto out;
}
// and compare values
av = g_hash_table_lookup(a, ai->data);
bv = g_hash_table_lookup(b, bi->data);
av = g_hash_table_lookup(a->tags, ai->data);
bv = g_hash_table_lookup(b->tags, bi->data);
if (av != bv) {
equal = 0;
goto out;
@ -172,6 +172,7 @@ out:
return equal;
}
// see https://developer.mozilla.org/en/docs/Web/CSS/font-feature-settings
// TODO make this a g_hash_table_foreach() function (which requires duplicating code)?
static int toCSS(char a, char b, char c, char d, uint32_t value, void *data)
{

View File

@ -71,3 +71,6 @@ extern void invokeBackgroundClosure(GClosure *closure, uiDrawContext *c, uiDrawT
#define cairoToPango(cairo) (pango_units_from_double(cairo))
extern const PangoStyle pangoItalics[];
extern const PangoStretch pangoStretches[];
// opentype.c
extern GString *otfToPangoCSSString(uiOpenTypeFeatures *otf);