diff --git a/common/attrlist.c b/common/attrlist.c index e50ec141..cb0833bc 100644 --- a/common/attrlist.c +++ b/common/attrlist.c @@ -651,12 +651,14 @@ void attrlistRemoveCharacters(struct attrlist *alist, size_t start, size_t end) void attrlistForEach(struct attrlist *alist, uiAttributedString *s, uiAttributedStringForEachAttributeFunc f, void *data) { struct attr *a; + uiForEach ret; - for (a = alist->first; a != NULL; a = a->next) - // TODO document this - // TODO should this be return 0 to break? - if ((*f)(s, &(a->spec), a->start, a->end, data)) + for (a = alist->first; a != NULL; a = a->next) { + ret = (*f)(s, &(a->spec), a->start, a->end, data); + if (ret == uiForEachStop) + // TODO for all: break or return? break; + } } struct attrlist *attrlistNew(void) diff --git a/darwin/attrstr.m b/darwin/attrstr.m index 6cf412a4..63539702 100644 --- a/darwin/attrstr.m +++ b/darwin/attrstr.m @@ -209,7 +209,7 @@ static CGColorRef mkcolor(uiAttributeSpec *spec) return color; } -static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t start, size_t end, void *data) +static uiForEach processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t start, size_t end, void *data) { struct foreachParams *p = (struct foreachParams *) data; CFRange range; @@ -316,7 +316,7 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t // TODO complain ; } - return 0; + return uiForEachContinue; } static BOOL cfaIsEqual(combinedFontAttr *a, combinedFontAttr *b) diff --git a/darwin/opentype.m b/darwin/opentype.m index 56bdc755..24f35f63 100644 --- a/darwin/opentype.m +++ b/darwin/opentype.m @@ -70,15 +70,18 @@ void uiOpenTypeFeaturesForEach(const uiOpenTypeFeatures *otf, uiOpenTypeFeatures NSNumber *vn = (NSNumber *) value; uint32_t tag; uint8_t a, b, c, d; + uiForEach ret; tag = mapObjectValue(tn); a = (uint8_t) ((tag >> 24) & 0xFF); b = (uint8_t) ((tag >> 16) & 0xFF); c = (uint8_t) ((tag >> 8) & 0xFF); d = (uint8_t) (tag & 0xFF); - // TODO handle return value - (*f)((char) a, (char) b, (char) c, (char) d, + ret = (*f)((char) a, (char) b, (char) c, (char) d, mapObjectValue(vn), data); + // TODO for all: require exact match? + if (ret == uiForEachStop) + *stop = YES; }]; } @@ -90,7 +93,7 @@ int uiOpenTypeFeaturesEqual(const uiOpenTypeFeatures *a, const uiOpenTypeFeature // TODO explain all this // TODO rename outerArray and innerDict (the names made sense when this was part of fontdescAppendFeatures(), but not here) // TODO make all this use enumerateKeysAndObjects (which requires duplicating code)? -static int otfArrayForEachAAT(char a, char b, char c, char d, uint32_t value, void *data) +static uiForEach otfArrayForEachAAT(char a, char b, char c, char d, uint32_t value, void *data) { CFMutableArrayRef outerArray = (CFMutableArrayRef) data; @@ -121,12 +124,11 @@ static int otfArrayForEachAAT(char a, char b, char c, char d, uint32_t value, vo CFRelease(numSelector); CFRelease(numType); }); - // TODO - return 0; + return uiForEachContinue; } // TODO find out which fonts differ in AAT small caps and test them with this -static int otfArrayForEachOT(char a, char b, char c, char d, uint32_t value, void *data) +static uiForEach otfArrayForEachOT(char a, char b, char c, char d, uint32_t value, void *data) { CFMutableArrayRef outerArray = (CFMutableArrayRef) data; CFDictionaryRef innerDict; @@ -163,8 +165,7 @@ static int otfArrayForEachOT(char a, char b, char c, char d, uint32_t value, voi CFRelease(innerDict); CFRelease(numValue); CFRelease(strTag); - // TODO - return 0; + return uiForEachContinue; } CFArrayRef otfToFeaturesArray(const uiOpenTypeFeatures *otf) diff --git a/ui.h b/ui.h index 922d0625..72e5eaef 100644 --- a/ui.h +++ b/ui.h @@ -34,6 +34,12 @@ extern "C" { // TODO uiBool? +// uiForEach represents the return value from one of libui's various ForEach functions. +_UI_ENUM(uiForEach) { + uiForEachContinue, + uiForEachStop, +}; + typedef struct uiInitOptions uiInitOptions; struct uiInitOptions { diff --git a/ui_attrstr.h b/ui_attrstr.h index 2f41cebb..9dc72a5a 100644 --- a/ui_attrstr.h +++ b/ui_attrstr.h @@ -55,7 +55,7 @@ _UI_ENUM(uiDrawUnderlineColor) { // TODO rename? typedef struct uiOpenTypeFeatures uiOpenTypeFeatures; // TODO pass the feature set? -typedef int (*uiOpenTypeFeaturesForEachFunc)(char a, char b, char c, char d, uint32_t value, void *data); +typedef uiForEach (*uiOpenTypeFeaturesForEachFunc)(char a, char b, char c, char d, uint32_t value, void *data); // TODO detailed constructor? _UI_EXTERN uiOpenTypeFeatures *uiNewOpenTypeFeatures(void); _UI_EXTERN void uiFreeOpenTypeFeatures(uiOpenTypeFeatures *otf); @@ -83,9 +83,8 @@ struct uiAttributeSpec { const uiOpenTypeFeatures *Features; // TODO rename to OpenTypeFeatures? }; -// TODO name the foreach return values // TODO make the spec const in a way that doesn't allow fields to be modified? -typedef int (*uiAttributedStringForEachAttributeFunc)(uiAttributedString *s, uiAttributeSpec *spec, size_t start, size_t end, void *data); +typedef uiForEach (*uiAttributedStringForEachAttributeFunc)(uiAttributedString *s, uiAttributeSpec *spec, size_t start, size_t end, void *data); // @role uiAttributedString constructor // uiNewAttributedString() creates a new uiAttributedString from diff --git a/unix/attrstr.c b/unix/attrstr.c index 7f12fff8..7dc83a6e 100644 --- a/unix/attrstr.c +++ b/unix/attrstr.c @@ -65,7 +65,7 @@ static void addattr(struct foreachParams *p, size_t start, size_t end, PangoAttr pango_attr_list_insert(p->attrs, attr); } -static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t start, size_t end, void *data) +static uiForEach processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t start, size_t end, void *data) { struct foreachParams *p = (struct foreachParams *) data; GClosure *closure; @@ -164,7 +164,7 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t // TODO complain ; } - return 0; + return uiForEachContinue; } static void unrefClosure(gpointer data) diff --git a/unix/opentype.c b/unix/opentype.c index 608a0815..9b90d0ba 100644 --- a/unix/opentype.c +++ b/unix/opentype.c @@ -78,7 +78,7 @@ int uiOpenTypeFeaturesGet(uiOpenTypeFeatures *otf, char a, char b, char c, char struct otfForEach { uiOpenTypeFeaturesForEachFunc f; void *data; - // TODO store continuation status here + uiForEach ret; }; static void foreach(gpointer key, gpointer value, gpointer data) @@ -87,13 +87,15 @@ static void foreach(gpointer key, gpointer value, gpointer 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); - // TODO handle return value - (*(ofe->f))((char) a, (char) b, (char) c, (char) d, GPOINTER_TO_INT(value), ofe->data); + ofe->ret = (*(ofe->f))((char) a, (char) b, (char) c, (char) d, GPOINTER_TO_INT(value), ofe->data); } void uiOpenTypeFeaturesForEach(const uiOpenTypeFeatures *otf, uiOpenTypeFeaturesForEachFunc f, void *data) @@ -175,7 +177,7 @@ out: // 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) +static uiForEach toCSS(char a, char b, char c, char d, uint32_t value, void *data) { // TODO is there a G_STRING()? GString *s = (GString *) data; @@ -183,8 +185,7 @@ static int toCSS(char a, char b, char c, char d, uint32_t value, void *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); - // TODO use this - return 0; + return uiForEachContinue; } gchar *otfToPangoCSSString(const uiOpenTypeFeatures *otf) diff --git a/windows/attrstr.cpp b/windows/attrstr.cpp index 71f753d4..7bcd5e53 100644 --- a/windows/attrstr.cpp +++ b/windows/attrstr.cpp @@ -49,7 +49,7 @@ static backgroundFunc mkBackgroundFunc(size_t start, size_t end, double r, doubl }; } -static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t start, size_t end, void *data) +static uiForEach processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t start, size_t end, void *data) { struct foreachParams *p = (struct foreachParams *) data; DWRITE_TEXT_RANGE range; @@ -184,7 +184,7 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t // TODO complain ; } - return 0; + return uiForEachContinue; } static void applyAndFreeEffectsAttributes(struct foreachParams *p) diff --git a/windows/opentype.cpp b/windows/opentype.cpp index 0275d916..21833e2c 100644 --- a/windows/opentype.cpp +++ b/windows/opentype.cpp @@ -64,14 +64,16 @@ void uiOpenTypeFeaturesForEach(const uiOpenTypeFeatures *otf, uiOpenTypeFeatures end = otf->tags->end(); for (iter = otf->tags->begin(); iter != end; iter++) { uint8_t a, b, c, d; + uiForEach ret; a = (uint8_t) (iter->first & 0xFF); b = (uint8_t) ((iter->first >> 8) & 0xFF); c = (uint8_t) ((iter->first >> 16) & 0xFF); d = (uint8_t) ((iter->first >> 24) & 0xFF); - // TODO handle return value - (*f)((char) a, (char) b, (char) c, (char) d, + ret = (*f)((char) a, (char) b, (char) c, (char) d, iter->second, data); + if (ret == uiForEachStop) + return; } }