Integrated aat.m into the build.

This commit is contained in:
Pietro Gagliardi 2017-02-15 23:10:23 -05:00
parent 1eb2ffaf82
commit 3e941d008e
5 changed files with 92 additions and 58 deletions

View File

@ -55,7 +55,7 @@ void specToOpenType(uiAttributeSpec *spec, specToOpenTypeEnumFunc f, void *data)
case uiAttributeNumberSpacingProportional: case uiAttributeNumberSpacingProportional:
(*f)("pnum", 1, data); (*f)("pnum", 1, data);
break; break;
case uiAttributeNumberSpacingTitling: case uiAttributeNumberSpacingTabular:
(*f)("tnum", 1, data); (*f)("tnum", 1, data);
break; break;
} }
@ -152,7 +152,7 @@ void specToOpenType(uiAttributeSpec *spec, specToOpenTypeEnumFunc f, void *data)
case uiAttributeRubyKanaForms: case uiAttributeRubyKanaForms:
boolspec(spec, "ruby", data); boolspec(spec, "ruby", data);
return; return;
case uiAttributeCJKRomanToitalics: case uiAttributeCJKRomansToItalics:
boolspec(spec, "ital", data); boolspec(spec, "ital", data);
return; return;
case uiAttributeCaseSensitiveForms: case uiAttributeCaseSensitiveForms:

View File

@ -1,6 +1,7 @@
# 3 june 2016 # 3 june 2016
list(APPEND _LIBUI_SOURCES list(APPEND _LIBUI_SOURCES
darwin/aat.m
darwin/alloc.m darwin/alloc.m
darwin/area.m darwin/area.m
darwin/areaevents.m darwin/areaevents.m

View File

@ -1,8 +1,6 @@
// 14 february 2017 // 14 february 2017
#import "uipriv_darwin.h" #import "uipriv_darwin.h"
typedef void (*specToAATEnumFunc)(uint16_t type, uint16_t selector, void *data);
static void boolspec(uiAttributeSpec *spec, uint16_t type, uint16_t ifTrue, uint16_t ifFalse, specToAATEnumFunc f, void *data) static void boolspec(uiAttributeSpec *spec, uint16_t type, uint16_t ifTrue, uint16_t ifFalse, specToAATEnumFunc f, void *data)
{ {
if (spec->Value != 0) { if (spec->Value != 0) {
@ -12,7 +10,7 @@ static void boolspec(uiAttributeSpec *spec, uint16_t type, uint16_t ifTrue, uint
(*f)(type, ifFalse, data); (*f)(type, ifFalse, data);
} }
void specToAAT(uiAttributeSpec *spec, specToAATEnumFunc f, void *data) int specToAAT(uiAttributeSpec *spec, specToAATEnumFunc f, void *data)
{ {
switch (spec->Type) { switch (spec->Type) {
case uiAttributeStandardLigatures: case uiAttributeStandardLigatures:
@ -20,48 +18,48 @@ void specToAAT(uiAttributeSpec *spec, specToAATEnumFunc f, void *data)
kCommonLigaturesOnSelector, kCommonLigaturesOnSelector,
kCommonLigaturesOffSelector, kCommonLigaturesOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeRequiredLigatures: case uiAttributeRequiredLigatures:
boolspec(spec, kLigaturesType, boolspec(spec, kLigaturesType,
kRequiredLigaturesOnSelector, kRequiredLigaturesOnSelector,
kRequiredLigaturesOffSelector, kRequiredLigaturesOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeDiscretionaryLigatures: case uiAttributeDiscretionaryLigatures:
boolspec(spec, kLigaturesType, boolspec(spec, kLigaturesType,
kRareLigaturesOnSelector, kRareLigaturesOnSelector,
kRareLigaturesOffSelector, kRareLigaturesOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeContextualLigatures: case uiAttributeContextualLigatures:
boolspec(spec, kLigaturesType, boolspec(spec, kLigaturesType,
kContextualLigaturesOnSelector, kContextualLigaturesOnSelector,
kContextualLigaturesOffSelector, kContextualLigaturesOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeHistoricalLigatures: case uiAttributeHistoricalLigatures:
boolspec(spec, kLigaturesType, boolspec(spec, kLigaturesType,
kHistoricalLigaturesOnSelector, kHistoricalLigaturesOnSelector,
kHistoricalLigaturesOffSelector, kHistoricalLigaturesOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeUnicase: case uiAttributeUnicase:
// TODO is this correct, or should we provide an else case? // TODO is this correct, or should we provide an else case?
if (spec->Value != 0) if (spec->Value != 0)
// this is undocumented; it comes from Core Text's internal AAT-to-OpenType conversion table // this is undocumented; it comes from Core Text's internal AAT-to-OpenType conversion table
(*f)(kLetterCaseType, 14, data); (*f)(kLetterCaseType, 14, data);
return; return 1;
// TODO make an array? // TODO make an array?
case uiAttributeNumberSpacings: case uiAttributeNumberSpacings:
switch (spec->Value) { switch (spec->Value) {
case uiAttributeNumberSpacingProportional: case uiAttributeNumberSpacingProportional:
(*f)(kNumberSpacingType, kProportionalNumbersSelector, data); (*f)(kNumberSpacingType, kProportionalNumbersSelector, data);
break; break;
case uiAttributeNumberSpacingTitling: case uiAttributeNumberSpacingTabular:
(*f)(kNumberSpacingType, kMonospacedNumbersSelector, data); (*f)(kNumberSpacingType, kMonospacedNumbersSelector, data);
break; break;
} }
return; return 1;
// TODO make an array? // TODO make an array?
case uiAttributeSuperscripts: case uiAttributeSuperscripts:
switch (spec->Value) { switch (spec->Value) {
@ -81,7 +79,7 @@ void specToAAT(uiAttributeSpec *spec, specToAATEnumFunc f, void *data)
(*f)(kVerticalPositionType, kScientificInferiorsSelector, data); (*f)(kVerticalPositionType, kScientificInferiorsSelector, data);
break; break;
} }
return; return 1;
// TODO make an array? // TODO make an array?
case uiAttributeFractionForms: case uiAttributeFractionForms:
switch (spec->Value) { switch (spec->Value) {
@ -95,30 +93,30 @@ void specToAAT(uiAttributeSpec *spec, specToAATEnumFunc f, void *data)
(*f)(kFractionsType, kDiagonalFractionsSelector, data); (*f)(kFractionsType, kDiagonalFractionsSelector, data);
break; break;
} }
return; return 1;
case uiAttributeSlashedZero: case uiAttributeSlashedZero:
boolspec(spec, kTypographicExtrasType, boolspec(spec, kTypographicExtrasType,
kSlashedZeroOnSelector, kSlashedZeroOnSelector,
kSlashedZeroOffSelector, kSlashedZeroOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeMathematicalGreek: case uiAttributeMathematicalGreek:
boolspec(spec, kMathematicalExtrasType, boolspec(spec, kMathematicalExtrasType,
kMathematicalGreekOnSelector, kMathematicalGreekOnSelector,
kMathematicalGreekOffSelector, kMathematicalGreekOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeOrnamentalForms: case uiAttributeOrnamentalForms:
(*f)(kOrnamentSetsType, (uint16_t) (spec->Value), data); (*f)(kOrnamentSetsType, (uint16_t) (spec->Value), data);
return; return 1;
case uiAttributeSpecificCharacterForm: case uiAttributeSpecificCharacterForm:
(*f)(kCharacterAlternativesType, (uint16_t) (spec->Value), data); (*f)(kCharacterAlternativesType, (uint16_t) (spec->Value), data);
return; return 1;
case uiAttributeTitlingCapitalForms: case uiAttributeTitlingCapitalForms:
// TODO is this correct, or should we provide an else case? // TODO is this correct, or should we provide an else case?
if (spec->Value != 0) if (spec->Value != 0)
(*f)(kStyleOptionsType, kTitlingCapsSelector, data); (*f)(kStyleOptionsType, kTitlingCapsSelector, data);
return; return 1;
// TODO make an array? // TODO make an array?
case uiAttributeHanCharacterForms: case uiAttributeHanCharacterForms:
switch (spec->Value) { switch (spec->Value) {
@ -153,20 +151,20 @@ void specToAAT(uiAttributeSpec *spec, specToAATEnumFunc f, void *data)
(*f)(kCharacterShapeType, kTraditionalNamesCharactersSelector, data); (*f)(kCharacterShapeType, kTraditionalNamesCharactersSelector, data);
break; break;
} }
return; return 1;
case uiAttributeLowercaseNumbers: case uiAttributeLowercaseNumbers:
// TODO is this correct, or should we provide an else case? // TODO is this correct, or should we provide an else case?
if (spec->Value != 0) if (spec->Value != 0)
(*f)(kNumberCaseType, kLowerCaseNumbersSelector, data); (*f)(kNumberCaseType, kLowerCaseNumbersSelector, data);
return; return 1;
case uiAttributeHanjaToHangul: case uiAttributeHanjaToHangul:
// TODO is this correct, or should we provide an else case? // TODO is this correct, or should we provide an else case?
if (spec->Value != 0) if (spec->Value != 0)
(*f)(kTransliterationType, kHanjaToHangulSelector, data); (*f)(kTransliterationType, kHanjaToHangulSelector, data);
return; return 1;
case uiAttributeGlyphAnnotations: case uiAttributeGlyphAnnotations:
(*f)(kAnnotationType, (uint16_t) (spec->Value), data); (*f)(kAnnotationType, (uint16_t) (spec->Value), data);
return; return 1;
case uiAttributeRubyKanaForms: case uiAttributeRubyKanaForms:
// include this for completeness // include this for completeness
boolspec(spec, kRubyKanaType, boolspec(spec, kRubyKanaType,
@ -178,8 +176,8 @@ void specToAAT(uiAttributeSpec *spec, specToAATEnumFunc f, void *data)
kRubyKanaOnSelector, kRubyKanaOnSelector,
kRubyKanaOffSelector, kRubyKanaOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeCJKRomanToitalics: case uiAttributeCJKRomansToItalics:
// include this for completeness // include this for completeness
boolspec(spec, kItalicCJKRomanType, boolspec(spec, kItalicCJKRomanType,
kCJKItalicRomanSelector, kCJKItalicRomanSelector,
@ -190,173 +188,173 @@ void specToAAT(uiAttributeSpec *spec, specToAATEnumFunc f, void *data)
kCJKItalicRomanOnSelector, kCJKItalicRomanOnSelector,
kCJKItalicRomanOffSelector, kCJKItalicRomanOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeCaseSensitiveForms: case uiAttributeCaseSensitiveForms:
boolspec(spec, kCaseSensitiveLayoutType, boolspec(spec, kCaseSensitiveLayoutType,
kCaseSensitiveLayoutOnSelector, kCaseSensitiveLayoutOnSelector,
kCaseSensitiveLayoutOffSelector, kCaseSensitiveLayoutOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeCapitalSpacing: case uiAttributeCapitalSpacing:
boolspec(spec, kCaseSensitiveLayoutType, boolspec(spec, kCaseSensitiveLayoutType,
kCaseSensitiveSpacingOnSelector, kCaseSensitiveSpacingOnSelector,
kCaseSensitiveSpacingOffSelector, kCaseSensitiveSpacingOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeAlternateHorizontalKana: case uiAttributeAlternateHorizontalKana:
boolspec(spec, kAlternateKanaType, boolspec(spec, kAlternateKanaType,
kAlternateHorizKanaOnSelector, kAlternateHorizKanaOnSelector,
kAlternateHorizKanaOffSelector, kAlternateHorizKanaOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeAlternateVerticalKana: case uiAttributeAlternateVerticalKana:
boolspec(spec, kAlternateKanaType, boolspec(spec, kAlternateKanaType,
kAlternateVertKanaOnSelector, kAlternateVertKanaOnSelector,
kAlternateVertKanaOffSelector, kAlternateVertKanaOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeStylisticAlternative1: case uiAttributeStylisticAlternative1:
boolspec(spec, kStylisticAlternativesType, boolspec(spec, kStylisticAlternativesType,
kStylisticAltOneOnSelector, kStylisticAltOneOnSelector,
kStylisticAltOneOffSelector, kStylisticAltOneOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeStylisticAlternative2: case uiAttributeStylisticAlternative2:
boolspec(spec, kStylisticAlternativesType, boolspec(spec, kStylisticAlternativesType,
kStylisticAltTwoOnSelector, kStylisticAltTwoOnSelector,
kStylisticAltTwoOffSelector, kStylisticAltTwoOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeStylisticAlternative3: case uiAttributeStylisticAlternative3:
boolspec(spec, kStylisticAlternativesType, boolspec(spec, kStylisticAlternativesType,
kStylisticAltThreeOnSelector, kStylisticAltThreeOnSelector,
kStylisticAltThreeOffSelector, kStylisticAltThreeOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeStylisticAlternative4: case uiAttributeStylisticAlternative4:
boolspec(spec, kStylisticAlternativesType, boolspec(spec, kStylisticAlternativesType,
kStylisticAltFourOnSelector, kStylisticAltFourOnSelector,
kStylisticAltFourOffSelector, kStylisticAltFourOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeStylisticAlternative5: case uiAttributeStylisticAlternative5:
boolspec(spec, kStylisticAlternativesType, boolspec(spec, kStylisticAlternativesType,
kStylisticAltFiveOnSelector, kStylisticAltFiveOnSelector,
kStylisticAltFiveOffSelector, kStylisticAltFiveOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeStylisticAlternative6: case uiAttributeStylisticAlternative6:
boolspec(spec, kStylisticAlternativesType, boolspec(spec, kStylisticAlternativesType,
kStylisticAltSixOnSelector, kStylisticAltSixOnSelector,
kStylisticAltSixOffSelector, kStylisticAltSixOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeStylisticAlternative7: case uiAttributeStylisticAlternative7:
boolspec(spec, kStylisticAlternativesType, boolspec(spec, kStylisticAlternativesType,
kStylisticAltSevenOnSelector, kStylisticAltSevenOnSelector,
kStylisticAltSevenOffSelector, kStylisticAltSevenOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeStylisticAlternative8: case uiAttributeStylisticAlternative8:
boolspec(spec, kStylisticAlternativesType, boolspec(spec, kStylisticAlternativesType,
kStylisticAltEightOnSelector, kStylisticAltEightOnSelector,
kStylisticAltEightOffSelector, kStylisticAltEightOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeStylisticAlternative9: case uiAttributeStylisticAlternative9:
boolspec(spec, kStylisticAlternativesType, boolspec(spec, kStylisticAlternativesType,
kStylisticAltNineOnSelector, kStylisticAltNineOnSelector,
kStylisticAltNineOffSelector, kStylisticAltNineOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeStylisticAlternative10: case uiAttributeStylisticAlternative10:
boolspec(spec, kStylisticAlternativesType, boolspec(spec, kStylisticAlternativesType,
kStylisticAltTenOnSelector, kStylisticAltTenOnSelector,
kStylisticAltTenOffSelector, kStylisticAltTenOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeStylisticAlternative11: case uiAttributeStylisticAlternative11:
boolspec(spec, kStylisticAlternativesType, boolspec(spec, kStylisticAlternativesType,
kStylisticAltElevenOnSelector, kStylisticAltElevenOnSelector,
kStylisticAltElevenOffSelector, kStylisticAltElevenOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeStylisticAlternative12: case uiAttributeStylisticAlternative12:
boolspec(spec, kStylisticAlternativesType, boolspec(spec, kStylisticAlternativesType,
kStylisticAltTwelveOnSelector, kStylisticAltTwelveOnSelector,
kStylisticAltTwelveOffSelector, kStylisticAltTwelveOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeStylisticAlternative13: case uiAttributeStylisticAlternative13:
boolspec(spec, kStylisticAlternativesType, boolspec(spec, kStylisticAlternativesType,
kStylisticAltThirteenOnSelector, kStylisticAltThirteenOnSelector,
kStylisticAltThirteenOffSelector, kStylisticAltThirteenOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeStylisticAlternative14: case uiAttributeStylisticAlternative14:
boolspec(spec, kStylisticAlternativesType, boolspec(spec, kStylisticAlternativesType,
kStylisticAltFourteenOnSelector, kStylisticAltFourteenOnSelector,
kStylisticAltFourteenOffSelector, kStylisticAltFourteenOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeStylisticAlternative15: case uiAttributeStylisticAlternative15:
boolspec(spec, kStylisticAlternativesType, boolspec(spec, kStylisticAlternativesType,
kStylisticAltFifteenOnSelector, kStylisticAltFifteenOnSelector,
kStylisticAltFifteenOffSelector, kStylisticAltFifteenOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeStylisticAlternative16: case uiAttributeStylisticAlternative16:
boolspec(spec, kStylisticAlternativesType, boolspec(spec, kStylisticAlternativesType,
kStylisticAltSixteenOnSelector, kStylisticAltSixteenOnSelector,
kStylisticAltSixteenOffSelector, kStylisticAltSixteenOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeStylisticAlternative17: case uiAttributeStylisticAlternative17:
boolspec(spec, kStylisticAlternativesType, boolspec(spec, kStylisticAlternativesType,
kStylisticAltSeventeenOnSelector, kStylisticAltSeventeenOnSelector,
kStylisticAltSeventeenOffSelector, kStylisticAltSeventeenOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeStylisticAlternative18: case uiAttributeStylisticAlternative18:
boolspec(spec, kStylisticAlternativesType, boolspec(spec, kStylisticAlternativesType,
kStylisticAltEighteenOnSelector, kStylisticAltEighteenOnSelector,
kStylisticAltEighteenOffSelector, kStylisticAltEighteenOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeStylisticAlternative19: case uiAttributeStylisticAlternative19:
boolspec(spec, kStylisticAlternativesType, boolspec(spec, kStylisticAlternativesType,
kStylisticAltNineteenOnSelector, kStylisticAltNineteenOnSelector,
kStylisticAltNineteenOffSelector, kStylisticAltNineteenOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeStylisticAlternative20: case uiAttributeStylisticAlternative20:
boolspec(spec, kStylisticAlternativesType, boolspec(spec, kStylisticAlternativesType,
kStylisticAltTwentyOnSelector, kStylisticAltTwentyOnSelector,
kStylisticAltTwentyOffSelector, kStylisticAltTwentyOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeContextualAlternates: case uiAttributeContextualAlternates:
boolspec(spec, kContextualAlternatesType, boolspec(spec, kContextualAlternatesType,
kContextualAlternatesOnSelector, kContextualAlternatesOnSelector,
kContextualAlternatesOffSelector, kContextualAlternatesOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeSwashes: case uiAttributeSwashes:
boolspec(spec, kContextualAlternatesType, boolspec(spec, kContextualAlternatesType,
kSwashAlternatesOnSelector, kSwashAlternatesOnSelector,
kSwashAlternatesOffSelector, kSwashAlternatesOffSelector,
f, data); f, data);
return; return 1;
case uiAttributeContextualSwashes: case uiAttributeContextualSwashes:
boolspec(spec, kContextualAlternatesType, boolspec(spec, kContextualAlternatesType,
kContextualSwashAlternatesOnSelector, kContextualSwashAlternatesOnSelector,
kContextualSwashAlternatesOffSelector, kContextualSwashAlternatesOffSelector,
f, data); f, data);
return; return 1;
// TODO use arrays? // TODO use arrays?
case uiAttributeLowercaseCapForms: case uiAttributeLowercaseCapForms:
switch (spec->Value) { switch (spec->Value) {
case uiAttributeCapFormNone: case uiAttributeCapFormNormal:
(*f)(kLowerCaseType, kDefaultLowerCaseSelector, data); (*f)(kLowerCaseType, kDefaultLowerCaseSelector, data);
break; break;
case uiAttributeCapFormSmallCaps: case uiAttributeCapFormSmallCaps:
@ -370,11 +368,11 @@ void specToAAT(uiAttributeSpec *spec, specToAATEnumFunc f, void *data)
(*f)(kLowerCaseType, kLowerCasePetiteCapsSelector, data); (*f)(kLowerCaseType, kLowerCasePetiteCapsSelector, data);
break; break;
} }
return; return 1;
// TODO use arrays? // TODO use arrays?
case uiAttributeUppercaseCapForms: case uiAttributeUppercaseCapForms:
switch (spec->Value) { switch (spec->Value) {
case uiAttributeCapFormNone: case uiAttributeCapFormNormal:
(*f)(kUpperCaseType, kDefaultUpperCaseSelector, data); (*f)(kUpperCaseType, kDefaultUpperCaseSelector, data);
break; break;
case uiAttributeCapFormSmallCaps: case uiAttributeCapFormSmallCaps:
@ -384,6 +382,7 @@ void specToAAT(uiAttributeSpec *spec, specToAATEnumFunc f, void *data)
(*f)(kUpperCaseType, kUpperCasePetiteCapsSelector, data); (*f)(kUpperCaseType, kUpperCasePetiteCapsSelector, data);
break; break;
} }
return; return 1;
} }
return 0;
} }

View File

@ -139,6 +139,27 @@ static CGColorRef mkcolor(uiAttributeSpec *spec)
return color; return color;
} }
struct aatParam {
struct foreachParams *p;
size_t start;
size_t end;
};
static void doAAT(uint16_t type, uint16_t selector, void *data)
{
struct aatParam *p = (struct aatParam *) data;
ensureFontInRange(p->p, p->start, p->end);
adjustFontInRange(p->p, p->start, p->end, ^(struct fontParams *fp) {
fp->featureTypes[fp->nFeatures] = type;
fp->featureSelectors[fp->nFeatures] = selector;
fp->nFeatures++;
if (fp->nFeatures == maxFeatures) {
// TODO
}
});
}
static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t start, size_t end, void *data) static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t start, size_t end, void *data)
{ {
struct foreachParams *p = (struct foreachParams *) data; struct foreachParams *p = (struct foreachParams *) data;
@ -148,6 +169,7 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t
backgroundBlock block; backgroundBlock block;
int32_t us; int32_t us;
CFNumberRef num; CFNumberRef num;
struct aatParam ap;
ostart = start; ostart = start;
oend = end; oend = end;
@ -251,6 +273,14 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t
}); });
break; break;
// TODO // TODO
default:
// handle typographic features
ap.p = p;
ap.start = start;
ap.end = end;
// TODO check if unhandled and complain
specToAAT(spec, doAAT, &ap);
break;
} }
return 0; return 0;
} }

View File

@ -150,3 +150,7 @@ extern void initUnderlineColors(void);
extern void uninitUnderlineColors(void); extern void uninitUnderlineColors(void);
typedef void (^backgroundBlock)(uiDrawContext *c, uiDrawTextLayout *layout, double x, double y); typedef void (^backgroundBlock)(uiDrawContext *c, uiDrawTextLayout *layout, double x, double y);
extern CFAttributedStringRef attrstrToCoreFoundation(uiDrawTextLayoutParams *p, NSArray **backgroundBlocks); extern CFAttributedStringRef attrstrToCoreFoundation(uiDrawTextLayoutParams *p, NSArray **backgroundBlocks);
// aat.m
typedef void (*specToAATEnumFunc)(uint16_t type, uint16_t selector, void *data);
extern int specToAAT(uiAttributeSpec *spec, specToAATEnumFunc f, void *data);