Migrated opentype.c and graphemes.c back.
This commit is contained in:
parent
008be9b6d8
commit
1cce6dc704
|
@ -1,208 +0,0 @@
|
||||||
// 11 may 2017
|
|
||||||
#include "uipriv_unix.h"
|
|
||||||
|
|
||||||
// TODO switch from GINT_TO_POINTER() and so to a fake GUINT_TO_POINTER()?
|
|
||||||
|
|
||||||
struct uiOpenTypeFeatures {
|
|
||||||
GHashTable *tags;
|
|
||||||
};
|
|
||||||
|
|
||||||
uiOpenTypeFeatures *uiNewOpenTypeFeatures(void)
|
|
||||||
{
|
|
||||||
uiOpenTypeFeatures *otf;
|
|
||||||
|
|
||||||
otf = uiNew(uiOpenTypeFeatures);
|
|
||||||
otf->tags = g_hash_table_new(g_direct_hash, g_direct_equal);
|
|
||||||
return otf;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiFreeOpenTypeFeatures(uiOpenTypeFeatures *otf)
|
|
||||||
{
|
|
||||||
g_hash_table_destroy(otf->tags);
|
|
||||||
uiFree(otf);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cloneTags(gpointer key, gpointer value, gpointer data)
|
|
||||||
{
|
|
||||||
// TODO is there a G_HASH_TABLE()?
|
|
||||||
g_hash_table_replace((GHashTable *) data, key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
uiOpenTypeFeatures *uiOpenTypeFeaturesClone(const uiOpenTypeFeatures *otf)
|
|
||||||
{
|
|
||||||
uiOpenTypeFeatures *out;
|
|
||||||
|
|
||||||
// TODO switch the windows one to use this
|
|
||||||
out = uiNewOpenTypeFeatures();
|
|
||||||
g_hash_table_foreach(otf->tags, cloneTags, out->tags);
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gpointer mkTag(char a, char b, char c, char d)
|
|
||||||
{
|
|
||||||
uint32_t tag;
|
|
||||||
|
|
||||||
tag = (((uint32_t) a) & 0xFF) << 24;
|
|
||||||
tag |= (((uint32_t) b) & 0xFF) << 16;
|
|
||||||
tag |= (((uint32_t) c) & 0xFF) << 8;
|
|
||||||
tag |= ((uint32_t) d) & 0xFF;
|
|
||||||
return GINT_TO_POINTER(tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiOpenTypeFeaturesAdd(uiOpenTypeFeatures *otf, char a, char b, char c, char d, uint32_t value)
|
|
||||||
{
|
|
||||||
g_hash_table_replace(otf->tags, mkTag(a, b, c, d), GINT_TO_POINTER(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiOpenTypeFeaturesRemove(uiOpenTypeFeatures *otf, char a, char b, char c, char d)
|
|
||||||
{
|
|
||||||
// will just return FALSE if the tag is not in otf->tags (half-documented as such), so we can use it safely
|
|
||||||
g_hash_table_remove(otf->tags, mkTag(a, b, c, d));
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO will the const wreck stuff up?
|
|
||||||
int uiOpenTypeFeaturesGet(const uiOpenTypeFeatures *otf, char a, char b, char c, char d, uint32_t *value)
|
|
||||||
{
|
|
||||||
gboolean found;
|
|
||||||
gpointer gv;
|
|
||||||
|
|
||||||
found = g_hash_table_lookup_extended(otf->tags,
|
|
||||||
mkTag(a, b, c, d),
|
|
||||||
NULL, &gv);
|
|
||||||
if (!found)
|
|
||||||
return 0;
|
|
||||||
*value = GPOINTER_TO_INT(gv);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct otfForEach {
|
|
||||||
const uiOpenTypeFeatures *otf;
|
|
||||||
uiOpenTypeFeaturesForEachFunc f;
|
|
||||||
void *data;
|
|
||||||
uiForEach ret;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void foreach(gpointer key, gpointer value, gpointer data)
|
|
||||||
{
|
|
||||||
struct otfForEach *ofe = (struct otfForEach *) data;
|
|
||||||
uint32_t tag;
|
|
||||||
uint8_t a, b, c, d;
|
|
||||||
|
|
||||||
// we can't stop early, so just ignore the rest if we have to
|
|
||||||
if (ofe->ret == uiForEachStop)
|
|
||||||
return;
|
|
||||||
tag = GPOINTER_TO_INT(key);
|
|
||||||
a = (uint8_t) ((tag >> 24) & 0xFF);
|
|
||||||
b = (uint8_t) ((tag >> 16) & 0xFF);
|
|
||||||
c = (uint8_t) ((tag >> 8) & 0xFF);
|
|
||||||
d = (uint8_t) (tag & 0xFF);
|
|
||||||
ofe->ret = (*(ofe->f))(ofe->otf, (char) a, (char) b, (char) c, (char) d, GPOINTER_TO_INT(value), ofe->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiOpenTypeFeaturesForEach(const uiOpenTypeFeatures *otf, uiOpenTypeFeaturesForEachFunc f, void *data)
|
|
||||||
{
|
|
||||||
struct otfForEach ofe;
|
|
||||||
|
|
||||||
memset(&ofe, 0, sizeof (struct otfForEach));
|
|
||||||
ofe.otf = otf;
|
|
||||||
ofe.f = f;
|
|
||||||
ofe.data = data;
|
|
||||||
g_hash_table_foreach(otf->tags, foreach, &ofe);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gint tagcmp(gconstpointer a, gconstpointer b)
|
|
||||||
{
|
|
||||||
return GPOINTER_TO_INT(a) - GPOINTER_TO_INT(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GList *copySortedKeys(GHashTable *tags)
|
|
||||||
{
|
|
||||||
GList *k, *copy;
|
|
||||||
|
|
||||||
k = g_hash_table_get_keys(tags);
|
|
||||||
copy = g_list_copy(k);
|
|
||||||
copy = g_list_sort(copy, tagcmp);
|
|
||||||
// TODO do we free k? the docs contradict themselves
|
|
||||||
// TODO I already forgot, does g_list_sort() copy, or just change the head?
|
|
||||||
return copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
int uiOpenTypeFeaturesEqual(const uiOpenTypeFeatures *a, const uiOpenTypeFeatures *b)
|
|
||||||
{
|
|
||||||
GList *ak, *bk;
|
|
||||||
GList *ai, *bi;
|
|
||||||
guint na, nb;
|
|
||||||
guint i;
|
|
||||||
int equal = 0;
|
|
||||||
|
|
||||||
if (a == NULL && b == NULL)
|
|
||||||
return 1;
|
|
||||||
if (a == NULL || b == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
ak = copySortedKeys(a->tags);
|
|
||||||
bk = copySortedKeys(b->tags);
|
|
||||||
|
|
||||||
na = g_list_length(ak);
|
|
||||||
nb = g_list_length(bk);
|
|
||||||
if (na != nb) {
|
|
||||||
equal = 0;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO use GPOINTER_TO_INT() in these?
|
|
||||||
ai = ak;
|
|
||||||
bi = bk;
|
|
||||||
for (i = 0; i < na; i++) {
|
|
||||||
gpointer av, bv;
|
|
||||||
|
|
||||||
// compare keys
|
|
||||||
// this is why we needed to sort earlier
|
|
||||||
if (ai->data != bi->data) {
|
|
||||||
equal = 0;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
// and compare values
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
ai = ai->next;
|
|
||||||
bi = bi->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
// all good
|
|
||||||
equal = 1;
|
|
||||||
|
|
||||||
out:
|
|
||||||
g_list_free(bk);
|
|
||||||
g_list_free(ak);
|
|
||||||
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 uiForEach toCSS(const uiOpenTypeFeatures *otf, char a, char b, char c, char d, uint32_t value, void *data)
|
|
||||||
{
|
|
||||||
// TODO is there a G_STRING()?
|
|
||||||
GString *s = (GString *) data;
|
|
||||||
|
|
||||||
// the last trailing comma is removed after foreach is done
|
|
||||||
g_string_append_printf(s, "\"%c%c%c%c\" %" PRIu32 ", ",
|
|
||||||
a, b, c, d, value);
|
|
||||||
return uiForEachContinue;
|
|
||||||
}
|
|
||||||
|
|
||||||
gchar *otfToPangoCSSString(const uiOpenTypeFeatures *otf)
|
|
||||||
{
|
|
||||||
GString *s;
|
|
||||||
|
|
||||||
s = g_string_new("");
|
|
||||||
uiOpenTypeFeaturesForEach(otf, toCSS, s);
|
|
||||||
if (s->len != 0)
|
|
||||||
// and remove the last comma
|
|
||||||
g_string_truncate(s, s->len - 2);
|
|
||||||
return g_string_free(s, FALSE);
|
|
||||||
}
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
// 11 march 2018
|
||||||
|
|
||||||
|
// opentype.c
|
||||||
|
extern GString *uiprivOpenTypeFeaturesToPangoCSSFeaturesString(const uiOpenTypeFeatures *otf);
|
|
@ -1,12 +1,13 @@
|
||||||
// 25 may 2016
|
// 25 may 2016
|
||||||
#include "uipriv_unix.h"
|
#include "uipriv_unix.h"
|
||||||
|
#include "attrstr.h"
|
||||||
|
|
||||||
int graphemesTakesUTF16(void)
|
int uiprivGraphemesTakesUTF16(void)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct graphemes *graphemes(void *s, size_t len)
|
struct graphemes *uiprivNewGraphemes(void *s, size_t len)
|
||||||
{
|
{
|
||||||
struct graphemes *g;
|
struct graphemes *g;
|
||||||
char *text = (char *) s;
|
char *text = (char *) s;
|
|
@ -0,0 +1,26 @@
|
||||||
|
// 11 may 2017
|
||||||
|
#include "uipriv_unix.h"
|
||||||
|
#include "attrstr.h"
|
||||||
|
|
||||||
|
// see https://developer.mozilla.org/en/docs/Web/CSS/font-feature-settings
|
||||||
|
static uiForEach toCSS(const uiOpenTypeFeatures *otf, char a, char b, char c, char d, uint32_t value, void *data)
|
||||||
|
{
|
||||||
|
GString *s = (GString *) data;
|
||||||
|
|
||||||
|
// the last trailing comma is removed after foreach is done
|
||||||
|
g_string_append_printf(s, "\"%c%c%c%c\" %" PRIu32 ", ",
|
||||||
|
a, b, c, d, value);
|
||||||
|
return uiForEachContinue;
|
||||||
|
}
|
||||||
|
|
||||||
|
GString *uiprivOpenTypeFeaturesToPangoCSSFeaturesString(const uiOpenTypeFeatures *otf)
|
||||||
|
{
|
||||||
|
GString *s;
|
||||||
|
|
||||||
|
s = g_string_new("");
|
||||||
|
uiOpenTypeFeaturesForEach(otf, toCSS, s);
|
||||||
|
if (s->len != 0)
|
||||||
|
// and remove the last comma
|
||||||
|
g_string_truncate(s, s->len - 2);
|
||||||
|
return s;
|
||||||
|
}
|
Loading…
Reference in New Issue