libui/darwin/aat.m

389 lines
12 KiB
Objective-C

// 14 february 2017
#import "uipriv_darwin.h"
static void boolspec(uiAttributeSpec *spec, uint16_t type, uint16_t ifTrue, uint16_t ifFalse, specToAATEnumFunc f, void *data)
{
if (spec->Value != 0) {
(*f)(type, ifTrue, data);
return;
}
(*f)(type, ifFalse, data);
}
int specToAAT(uiAttributeSpec *spec, specToAATEnumFunc f, void *data)
{
switch (spec->Type) {
case uiAttributeStandardLigatures:
boolspec(spec, kLigaturesType,
kCommonLigaturesOnSelector,
kCommonLigaturesOffSelector,
f, data);
return 1;
case uiAttributeRequiredLigatures:
boolspec(spec, kLigaturesType,
kRequiredLigaturesOnSelector,
kRequiredLigaturesOffSelector,
f, data);
return 1;
case uiAttributeDiscretionaryLigatures:
boolspec(spec, kLigaturesType,
kRareLigaturesOnSelector,
kRareLigaturesOffSelector,
f, data);
return 1;
case uiAttributeContextualLigatures:
boolspec(spec, kLigaturesType,
kContextualLigaturesOnSelector,
kContextualLigaturesOffSelector,
f, data);
return 1;
case uiAttributeHistoricalLigatures:
boolspec(spec, kLigaturesType,
kHistoricalLigaturesOnSelector,
kHistoricalLigaturesOffSelector,
f, data);
return 1;
case uiAttributeUnicase:
// TODO is this correct, or should we provide an else case?
if (spec->Value != 0)
// this is undocumented; it comes from Core Text's internal AAT-to-OpenType conversion table
(*f)(kLetterCaseType, 14, data);
return 1;
// TODO make an array?
case uiAttributeNumberSpacings:
switch (spec->Value) {
case uiAttributeNumberSpacingProportional:
(*f)(kNumberSpacingType, kProportionalNumbersSelector, data);
break;
case uiAttributeNumberSpacingTabular:
(*f)(kNumberSpacingType, kMonospacedNumbersSelector, data);
break;
}
return 1;
// TODO make an array?
case uiAttributeSuperscripts:
switch (spec->Value) {
case uiAttributeSuperscriptNone:
(*f)(kVerticalPositionType, kNormalPositionSelector, data);
break;
case uiAttributeSuperscriptSuperscript:
(*f)(kVerticalPositionType, kSuperiorsSelector, data);
break;
case uiAttributeSuperscriptSubscript:
(*f)(kVerticalPositionType, kInferiorsSelector, data);
break;
case uiAttributeSuperscriptOrdinal:
(*f)(kVerticalPositionType, kOrdinalsSelector, data);
break;
case uiAttributeSuperscriptScientificInferior:
(*f)(kVerticalPositionType, kScientificInferiorsSelector, data);
break;
}
return 1;
// TODO make an array?
case uiAttributeFractionForms:
switch (spec->Value) {
case uiAttributeFractionFormNone:
(*f)(kFractionsType, kNoFractionsSelector, data);
break;
case uiAttributeFractionFormVertical:
(*f)(kFractionsType, kVerticalFractionsSelector, data);
break;
case uiAttributeFractionFormDiagonal:
(*f)(kFractionsType, kDiagonalFractionsSelector, data);
break;
}
return 1;
case uiAttributeSlashedZero:
boolspec(spec, kTypographicExtrasType,
kSlashedZeroOnSelector,
kSlashedZeroOffSelector,
f, data);
return 1;
case uiAttributeMathematicalGreek:
boolspec(spec, kMathematicalExtrasType,
kMathematicalGreekOnSelector,
kMathematicalGreekOffSelector,
f, data);
return 1;
case uiAttributeOrnamentalForms:
(*f)(kOrnamentSetsType, (uint16_t) (spec->Value), data);
return 1;
case uiAttributeSpecificCharacterForm:
(*f)(kCharacterAlternativesType, (uint16_t) (spec->Value), data);
return 1;
case uiAttributeTitlingCapitalForms:
// TODO is this correct, or should we provide an else case?
if (spec->Value != 0)
(*f)(kStyleOptionsType, kTitlingCapsSelector, data);
return 1;
// TODO make an array?
case uiAttributeHanCharacterForms:
switch (spec->Value) {
case uiAttributeHanCharacterFormTraditional:
(*f)(kCharacterShapeType, kTraditionalCharactersSelector, data);
break;
case uiAttributeHanCharacterFormSimplified:
(*f)(kCharacterShapeType, kSimplifiedCharactersSelector, data);
break;
case uiAttributeHanCharacterFormJIS1978:
(*f)(kCharacterShapeType, kJIS1978CharactersSelector, data);
break;
case uiAttributeHanCharacterFormJIS1983:
(*f)(kCharacterShapeType, kJIS1983CharactersSelector, data);
break;
case uiAttributeHanCharacterFormJIS1990:
(*f)(kCharacterShapeType, kJIS1990CharactersSelector, data);
break;
case uiAttributeHanCharacterFormExpert:
(*f)(kCharacterShapeType, kExpertCharactersSelector, data);
break;
case uiAttributeHanCharacterFormJIS2004:
(*f)(kCharacterShapeType, kJIS2004CharactersSelector, data);
break;
case uiAttributeHanCharacterFormHojo:
(*f)(kCharacterShapeType, kHojoCharactersSelector, data);
break;
case uiAttributeHanCharacterFormNLC:
(*f)(kCharacterShapeType, kNLCCharactersSelector, data);
break;
case uiAttributeHanCharacterFormTraditionalNames:
(*f)(kCharacterShapeType, kTraditionalNamesCharactersSelector, data);
break;
}
return 1;
case uiAttributeLowercaseNumbers:
// TODO is this correct, or should we provide an else case?
if (spec->Value != 0)
(*f)(kNumberCaseType, kLowerCaseNumbersSelector, data);
return 1;
case uiAttributeHanjaToHangul:
// TODO is this correct, or should we provide an else case?
if (spec->Value != 0)
(*f)(kTransliterationType, kHanjaToHangulSelector, data);
return 1;
case uiAttributeGlyphAnnotations:
(*f)(kAnnotationType, (uint16_t) (spec->Value), data);
return 1;
case uiAttributeRubyKanaForms:
// include this for completeness
boolspec(spec, kRubyKanaType,
kRubyKanaSelector,
kNoRubyKanaSelector,
f, data);
// this is the current one
boolspec(spec, kRubyKanaType,
kRubyKanaOnSelector,
kRubyKanaOffSelector,
f, data);
return 1;
case uiAttributeCJKRomansToItalics:
// include this for completeness
boolspec(spec, kItalicCJKRomanType,
kCJKItalicRomanSelector,
kNoCJKItalicRomanSelector,
f, data);
// this is the current one
boolspec(spec, kItalicCJKRomanType,
kCJKItalicRomanOnSelector,
kCJKItalicRomanOffSelector,
f, data);
return 1;
case uiAttributeCaseSensitiveForms:
boolspec(spec, kCaseSensitiveLayoutType,
kCaseSensitiveLayoutOnSelector,
kCaseSensitiveLayoutOffSelector,
f, data);
return 1;
case uiAttributeCapitalSpacing:
boolspec(spec, kCaseSensitiveLayoutType,
kCaseSensitiveSpacingOnSelector,
kCaseSensitiveSpacingOffSelector,
f, data);
return 1;
case uiAttributeAlternateHorizontalKana:
boolspec(spec, kAlternateKanaType,
kAlternateHorizKanaOnSelector,
kAlternateHorizKanaOffSelector,
f, data);
return 1;
case uiAttributeAlternateVerticalKana:
boolspec(spec, kAlternateKanaType,
kAlternateVertKanaOnSelector,
kAlternateVertKanaOffSelector,
f, data);
return 1;
case uiAttributeStylisticAlternative1:
boolspec(spec, kStylisticAlternativesType,
kStylisticAltOneOnSelector,
kStylisticAltOneOffSelector,
f, data);
return 1;
case uiAttributeStylisticAlternative2:
boolspec(spec, kStylisticAlternativesType,
kStylisticAltTwoOnSelector,
kStylisticAltTwoOffSelector,
f, data);
return 1;
case uiAttributeStylisticAlternative3:
boolspec(spec, kStylisticAlternativesType,
kStylisticAltThreeOnSelector,
kStylisticAltThreeOffSelector,
f, data);
return 1;
case uiAttributeStylisticAlternative4:
boolspec(spec, kStylisticAlternativesType,
kStylisticAltFourOnSelector,
kStylisticAltFourOffSelector,
f, data);
return 1;
case uiAttributeStylisticAlternative5:
boolspec(spec, kStylisticAlternativesType,
kStylisticAltFiveOnSelector,
kStylisticAltFiveOffSelector,
f, data);
return 1;
case uiAttributeStylisticAlternative6:
boolspec(spec, kStylisticAlternativesType,
kStylisticAltSixOnSelector,
kStylisticAltSixOffSelector,
f, data);
return 1;
case uiAttributeStylisticAlternative7:
boolspec(spec, kStylisticAlternativesType,
kStylisticAltSevenOnSelector,
kStylisticAltSevenOffSelector,
f, data);
return 1;
case uiAttributeStylisticAlternative8:
boolspec(spec, kStylisticAlternativesType,
kStylisticAltEightOnSelector,
kStylisticAltEightOffSelector,
f, data);
return 1;
case uiAttributeStylisticAlternative9:
boolspec(spec, kStylisticAlternativesType,
kStylisticAltNineOnSelector,
kStylisticAltNineOffSelector,
f, data);
return 1;
case uiAttributeStylisticAlternative10:
boolspec(spec, kStylisticAlternativesType,
kStylisticAltTenOnSelector,
kStylisticAltTenOffSelector,
f, data);
return 1;
case uiAttributeStylisticAlternative11:
boolspec(spec, kStylisticAlternativesType,
kStylisticAltElevenOnSelector,
kStylisticAltElevenOffSelector,
f, data);
return 1;
case uiAttributeStylisticAlternative12:
boolspec(spec, kStylisticAlternativesType,
kStylisticAltTwelveOnSelector,
kStylisticAltTwelveOffSelector,
f, data);
return 1;
case uiAttributeStylisticAlternative13:
boolspec(spec, kStylisticAlternativesType,
kStylisticAltThirteenOnSelector,
kStylisticAltThirteenOffSelector,
f, data);
return 1;
case uiAttributeStylisticAlternative14:
boolspec(spec, kStylisticAlternativesType,
kStylisticAltFourteenOnSelector,
kStylisticAltFourteenOffSelector,
f, data);
return 1;
case uiAttributeStylisticAlternative15:
boolspec(spec, kStylisticAlternativesType,
kStylisticAltFifteenOnSelector,
kStylisticAltFifteenOffSelector,
f, data);
return 1;
case uiAttributeStylisticAlternative16:
boolspec(spec, kStylisticAlternativesType,
kStylisticAltSixteenOnSelector,
kStylisticAltSixteenOffSelector,
f, data);
return 1;
case uiAttributeStylisticAlternative17:
boolspec(spec, kStylisticAlternativesType,
kStylisticAltSeventeenOnSelector,
kStylisticAltSeventeenOffSelector,
f, data);
return 1;
case uiAttributeStylisticAlternative18:
boolspec(spec, kStylisticAlternativesType,
kStylisticAltEighteenOnSelector,
kStylisticAltEighteenOffSelector,
f, data);
return 1;
case uiAttributeStylisticAlternative19:
boolspec(spec, kStylisticAlternativesType,
kStylisticAltNineteenOnSelector,
kStylisticAltNineteenOffSelector,
f, data);
return 1;
case uiAttributeStylisticAlternative20:
boolspec(spec, kStylisticAlternativesType,
kStylisticAltTwentyOnSelector,
kStylisticAltTwentyOffSelector,
f, data);
return 1;
case uiAttributeContextualAlternates:
boolspec(spec, kContextualAlternatesType,
kContextualAlternatesOnSelector,
kContextualAlternatesOffSelector,
f, data);
return 1;
case uiAttributeSwashes:
boolspec(spec, kContextualAlternatesType,
kSwashAlternatesOnSelector,
kSwashAlternatesOffSelector,
f, data);
return 1;
case uiAttributeContextualSwashes:
boolspec(spec, kContextualAlternatesType,
kContextualSwashAlternatesOnSelector,
kContextualSwashAlternatesOffSelector,
f, data);
return 1;
// TODO use arrays?
case uiAttributeLowercaseCapForms:
switch (spec->Value) {
case uiAttributeCapFormNormal:
(*f)(kLowerCaseType, kDefaultLowerCaseSelector, data);
break;
case uiAttributeCapFormSmallCaps:
// include this for compatibility (some fonts that come with OS X still use this!)
// TODO make it boolean?
(*f)(kLetterCaseType, kSmallCapsSelector, data);
// this is the current one
(*f)(kLowerCaseType, kLowerCaseSmallCapsSelector, data);
break;
case uiAttributeCapFormPetiteCaps:
(*f)(kLowerCaseType, kLowerCasePetiteCapsSelector, data);
break;
}
return 1;
// TODO use arrays?
case uiAttributeUppercaseCapForms:
switch (spec->Value) {
case uiAttributeCapFormNormal:
(*f)(kUpperCaseType, kDefaultUpperCaseSelector, data);
break;
case uiAttributeCapFormSmallCaps:
(*f)(kUpperCaseType, kUpperCaseSmallCapsSelector, data);
break;
case uiAttributeCapFormPetiteCaps:
(*f)(kUpperCaseType, kUpperCasePetiteCapsSelector, data);
break;
}
return 1;
}
return 0;
}