Converted darwin/aat.m to the new OpenType system. We can't use the code as-is just yet, though.
This commit is contained in:
parent
72f5b680f2
commit
1a2dd1f16b
583
darwin/aat.m
583
darwin/aat.m
|
@ -1,388 +1,397 @@
|
|||
// 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)
|
||||
struct openTypeAATParams {
|
||||
void (*doAAT)(uint16_t type, uint16_t selector, void *data);
|
||||
void *data;
|
||||
};
|
||||
|
||||
#define pcall(p, type, selector) ((*(p->doAAT))(type, selector, p->data))
|
||||
|
||||
static void boolspec(uint32_t value, uint16_t type, uint16_t ifTrue, uint16_t ifFalse, struct openTypeAATParams *p)
|
||||
{
|
||||
if (spec->Value != 0) {
|
||||
(*f)(type, ifTrue, data);
|
||||
// TODO are values other than 1 accepted for true by OpenType itself? (same for the rest of the file)
|
||||
if (value != 0) {
|
||||
pcall(p, type, ifTrue);
|
||||
return;
|
||||
}
|
||||
(*f)(type, ifFalse, data);
|
||||
pcall(p, type, ifFalse);
|
||||
}
|
||||
|
||||
int specToAAT(uiAttributeSpec *spec, specToAATEnumFunc f, void *data)
|
||||
void openTypeToAAT(char a, char b, char c, char d, uint32_t value, void *data)
|
||||
{
|
||||
switch (spec->Type) {
|
||||
case uiAttributeStandardLigatures:
|
||||
boolspec(spec, kLigaturesType,
|
||||
struct openTypeAATParams *p = (struct openTypeAATParams *) data;
|
||||
|
||||
switch (mkTag(a, b, c, d)) {
|
||||
case mkTag('l', 'i', 'g', 'a'):
|
||||
boolspec(value, kLigaturesType,
|
||||
kCommonLigaturesOnSelector,
|
||||
kCommonLigaturesOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeRequiredLigatures:
|
||||
boolspec(spec, kLigaturesType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('r', 'l', 'i', 'g'):
|
||||
boolspec(value, kLigaturesType,
|
||||
kRequiredLigaturesOnSelector,
|
||||
kRequiredLigaturesOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeDiscretionaryLigatures:
|
||||
boolspec(spec, kLigaturesType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('d', 'l', 'i', 'g'):
|
||||
boolspec(value, kLigaturesType,
|
||||
kRareLigaturesOnSelector,
|
||||
kRareLigaturesOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeContextualLigatures:
|
||||
boolspec(spec, kLigaturesType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('c', 'l', 'i', 'g'):
|
||||
boolspec(value, kLigaturesType,
|
||||
kContextualLigaturesOnSelector,
|
||||
kContextualLigaturesOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeHistoricalLigatures:
|
||||
boolspec(spec, kLigaturesType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('h', 'l', 'i', 'g'):
|
||||
// This technically isn't what is meant by "historical ligatures", but Core Text's internal AAT-to-OpenType mapping says to include it, so we include it too
|
||||
case mkTag('h', 'i', 's', 't'):
|
||||
boolspec(value, kLigaturesType,
|
||||
kHistoricalLigaturesOnSelector,
|
||||
kHistoricalLigaturesOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeUnicase:
|
||||
p);
|
||||
break;
|
||||
case mkTag('u', 'n', 'i', 'c'):
|
||||
// TODO is this correct, or should we provide an else case?
|
||||
if (spec->Value != 0)
|
||||
if (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,
|
||||
pcall(p, kLetterCaseType, 14);
|
||||
break;
|
||||
|
||||
// TODO will the following handle all cases properly, or are elses going to be needed?
|
||||
case mkTag('p', 'n', 'u', 'm'):
|
||||
if (value != 0)
|
||||
pcall(p, kNumberSpacingType, kProportionalNumbersSelector);
|
||||
break;
|
||||
case mkTag('t', 'n', 'u', 'm'):
|
||||
if (value != 0)
|
||||
pcall(p, kNumberSpacingType, kMonospacedNumbersSelector);
|
||||
break;
|
||||
|
||||
// TODO will the following handle all cases properly, or are elses going to be needed?
|
||||
case mkTag('s', 'u', 'p', 's'):
|
||||
if (value != 0)
|
||||
pcall(p, kVerticalPositionType, kSuperiorsSelector);
|
||||
break;
|
||||
case mkTag('s', 'u', 'b', 's'):
|
||||
if (value != 0)
|
||||
pcall(p, kVerticalPositionType, kInferiorsSelector);
|
||||
break;
|
||||
case mkTag('o', 'r', 'd', 'n'):
|
||||
if (value != 0)
|
||||
pcall(p, kVerticalPositionType, kOrdinalsSelector);
|
||||
break;
|
||||
case mkTag('s', 'i', 'n', 'f'):
|
||||
if (value != 0)
|
||||
pcall(p, kVerticalPositionType, kScientificInferiorsSelector);
|
||||
break;
|
||||
|
||||
// TODO will the following handle all cases properly, or are elses going to be needed?
|
||||
case mkTag('a', 'f', 'r', 'c'):
|
||||
if (value != 0)
|
||||
pcall(p, kFractionsType, kVerticalFractionsSelector);
|
||||
break;
|
||||
case mkTag('f', 'r', 'a', 'c'):
|
||||
if (value != 0)
|
||||
pcall(p, kFractionsType, kDiagonalFractionsSelector);
|
||||
break;
|
||||
|
||||
case mkTag('z', 'e', 'r', 'o'):
|
||||
boolspec(value, kTypographicExtrasType,
|
||||
kSlashedZeroOnSelector,
|
||||
kSlashedZeroOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeMathematicalGreek:
|
||||
boolspec(spec, kMathematicalExtrasType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('m', 'g', 'r', 'k'):
|
||||
boolspec(value, 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:
|
||||
p);
|
||||
break;
|
||||
case mkTag('o', 'r', 'n', 'm'):
|
||||
pcall(p, kOrnamentSetsType, (uint16_t) value);
|
||||
break;
|
||||
case mkTag('a', 'a', 'l', 't'):
|
||||
pcall(p, kCharacterAlternativesType, (uint16_t) value);
|
||||
break;
|
||||
case mkTag('t', 'i', 't', 'l'):
|
||||
// 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:
|
||||
pcall(p, kStyleOptionsType, kTitlingCapsSelector);
|
||||
break;
|
||||
|
||||
// TODO will the following handle all cases properly, or are elses going to be needed?
|
||||
case mkTag('t', 'r', 'a', 'd'):
|
||||
if (value != 0)
|
||||
pcall(p, kCharacterShapeType, kTraditionalCharactersSelector);
|
||||
break;
|
||||
case mkTag('s', 'm', 'p', 'l'):
|
||||
if (value != 0)
|
||||
pcall(p, kCharacterShapeType, kSimplifiedCharactersSelector);
|
||||
break;
|
||||
case mkTag('j', 'p', '7', '8'):
|
||||
if (value != 0)
|
||||
pcall(p, kCharacterShapeType, kJIS1978CharactersSelector);
|
||||
break;
|
||||
case mkTag('j', 'p', '8', '3'):
|
||||
if (value != 0)
|
||||
pcall(p, kCharacterShapeType, kJIS1983CharactersSelector);
|
||||
break;
|
||||
case mkTag('j', 'p', '9', '0'):
|
||||
if (value != 0)
|
||||
pcall(p, kCharacterShapeType, kJIS1990CharactersSelector);
|
||||
break;
|
||||
case mkTag('e', 'x', 'p', 't'):
|
||||
if (value != 0)
|
||||
pcall(p, kCharacterShapeType, kExpertCharactersSelector);
|
||||
break;
|
||||
case mkTag('j', 'p', '0', '4'):
|
||||
if (value != 0)
|
||||
pcall(p, kCharacterShapeType, kJIS2004CharactersSelector);
|
||||
break;
|
||||
case mkTag('h', 'o', 'j', 'o'):
|
||||
if (value != 0)
|
||||
pcall(p, kCharacterShapeType, kHojoCharactersSelector);
|
||||
break;
|
||||
case mkTag('n', 'l', 'c', 'k'):
|
||||
if (value != 0)
|
||||
pcall(p, kCharacterShapeType, kNLCCharactersSelector);
|
||||
break;
|
||||
case mkTag('t', 'n', 'a', 'm'):
|
||||
if (value != 0)
|
||||
pcall(p, kCharacterShapeType, kTraditionalNamesCharactersSelector);
|
||||
break;
|
||||
|
||||
case mkTag('o', 'n', 'u', 'm'):
|
||||
// Core Text's internal AAT-to-OpenType mapping says to include this, so we include it too
|
||||
// TODO is it always set?
|
||||
case mkTag('l', 'n', 'u', 'm'):
|
||||
// TODO is this correct, or should we provide an else case?
|
||||
if (spec->Value != 0)
|
||||
(*f)(kNumberCaseType, kLowerCaseNumbersSelector, data);
|
||||
return 1;
|
||||
case uiAttributeHanjaToHangul:
|
||||
if (value != 0)
|
||||
pcall(p, kNumberCaseType, kLowerCaseNumbersSelector);
|
||||
break;
|
||||
case mkTag('h', 'n', 'g', 'l'):
|
||||
// TODO is this correct, or should we provide an else case?
|
||||
if (spec->Value != 0)
|
||||
(*f)(kTransliterationType, kHanjaToHangulSelector, data);
|
||||
return 1;
|
||||
case uiAttributeAnnotatedGlyphForms:
|
||||
(*f)(kAnnotationType, (uint16_t) (spec->Value), data);
|
||||
return 1;
|
||||
case uiAttributeRubyKanaForms:
|
||||
if (value != 0)
|
||||
pcall(p, kTransliterationType, kHanjaToHangulSelector);
|
||||
break;
|
||||
case mkTag('n', 'a', 'l', 't'):
|
||||
pcall(p, kAnnotationType, (uint16_t) value);
|
||||
break;
|
||||
case mkTag('r', 'u', 'b', 'y'):
|
||||
// include this for completeness
|
||||
boolspec(spec, kRubyKanaType,
|
||||
boolspec(value, kRubyKanaType,
|
||||
kRubyKanaSelector,
|
||||
kNoRubyKanaSelector,
|
||||
f, data);
|
||||
p);
|
||||
// this is the current one
|
||||
boolspec(spec, kRubyKanaType,
|
||||
boolspec(value, kRubyKanaType,
|
||||
kRubyKanaOnSelector,
|
||||
kRubyKanaOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeCJKRomansToItalics:
|
||||
p);
|
||||
break;
|
||||
case mkTag('i', 't', 'a', 'l'):
|
||||
// include this for completeness
|
||||
boolspec(spec, kItalicCJKRomanType,
|
||||
boolspec(value, kItalicCJKRomanType,
|
||||
kCJKItalicRomanSelector,
|
||||
kNoCJKItalicRomanSelector,
|
||||
f, data);
|
||||
p);
|
||||
// this is the current one
|
||||
boolspec(spec, kItalicCJKRomanType,
|
||||
boolspec(value, kItalicCJKRomanType,
|
||||
kCJKItalicRomanOnSelector,
|
||||
kCJKItalicRomanOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeCaseSensitiveForms:
|
||||
boolspec(spec, kCaseSensitiveLayoutType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('c', 'a', 's', 'e'):
|
||||
boolspec(value, kCaseSensitiveLayoutType,
|
||||
kCaseSensitiveLayoutOnSelector,
|
||||
kCaseSensitiveLayoutOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeCapitalSpacing:
|
||||
boolspec(spec, kCaseSensitiveLayoutType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('c', 'p', 's', 'p'):
|
||||
boolspec(value, kCaseSensitiveLayoutType,
|
||||
kCaseSensitiveSpacingOnSelector,
|
||||
kCaseSensitiveSpacingOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeAlternateHorizontalKana:
|
||||
boolspec(spec, kAlternateKanaType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('h', 'k', 'n', 'a'):
|
||||
boolspec(value, kAlternateKanaType,
|
||||
kAlternateHorizKanaOnSelector,
|
||||
kAlternateHorizKanaOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeAlternateVerticalKana:
|
||||
boolspec(spec, kAlternateKanaType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('v', 'k', 'n', 'a'):
|
||||
boolspec(value, kAlternateKanaType,
|
||||
kAlternateVertKanaOnSelector,
|
||||
kAlternateVertKanaOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeStylisticAlternate1:
|
||||
boolspec(spec, kStylisticAlternativesType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('s', 's', '0', '1'):
|
||||
boolspec(value, kStylisticAlternativesType,
|
||||
kStylisticAltOneOnSelector,
|
||||
kStylisticAltOneOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeStylisticAlternate2:
|
||||
boolspec(spec, kStylisticAlternativesType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('s', 's', '0', '2'):
|
||||
boolspec(value, kStylisticAlternativesType,
|
||||
kStylisticAltTwoOnSelector,
|
||||
kStylisticAltTwoOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeStylisticAlternate3:
|
||||
boolspec(spec, kStylisticAlternativesType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('s', 's', '0', '3'):
|
||||
boolspec(value, kStylisticAlternativesType,
|
||||
kStylisticAltThreeOnSelector,
|
||||
kStylisticAltThreeOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeStylisticAlternate4:
|
||||
boolspec(spec, kStylisticAlternativesType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('s', 's', '0', '4'):
|
||||
boolspec(value, kStylisticAlternativesType,
|
||||
kStylisticAltFourOnSelector,
|
||||
kStylisticAltFourOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeStylisticAlternate5:
|
||||
boolspec(spec, kStylisticAlternativesType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('s', 's', '0', '5'):
|
||||
boolspec(value, kStylisticAlternativesType,
|
||||
kStylisticAltFiveOnSelector,
|
||||
kStylisticAltFiveOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeStylisticAlternate6:
|
||||
boolspec(spec, kStylisticAlternativesType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('s', 's', '0', '6'):
|
||||
boolspec(value, kStylisticAlternativesType,
|
||||
kStylisticAltSixOnSelector,
|
||||
kStylisticAltSixOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeStylisticAlternate7:
|
||||
boolspec(spec, kStylisticAlternativesType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('s', 's', '0', '7'):
|
||||
boolspec(value, kStylisticAlternativesType,
|
||||
kStylisticAltSevenOnSelector,
|
||||
kStylisticAltSevenOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeStylisticAlternate8:
|
||||
boolspec(spec, kStylisticAlternativesType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('s', 's', '0', '8'):
|
||||
boolspec(value, kStylisticAlternativesType,
|
||||
kStylisticAltEightOnSelector,
|
||||
kStylisticAltEightOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeStylisticAlternate9:
|
||||
boolspec(spec, kStylisticAlternativesType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('s', 's', '0', '9'):
|
||||
boolspec(value, kStylisticAlternativesType,
|
||||
kStylisticAltNineOnSelector,
|
||||
kStylisticAltNineOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeStylisticAlternate10:
|
||||
boolspec(spec, kStylisticAlternativesType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('s', 's', '1', '0'):
|
||||
boolspec(value, kStylisticAlternativesType,
|
||||
kStylisticAltTenOnSelector,
|
||||
kStylisticAltTenOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeStylisticAlternate11:
|
||||
boolspec(spec, kStylisticAlternativesType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('s', 's', '1', '1'):
|
||||
boolspec(value, kStylisticAlternativesType,
|
||||
kStylisticAltElevenOnSelector,
|
||||
kStylisticAltElevenOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeStylisticAlternate12:
|
||||
boolspec(spec, kStylisticAlternativesType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('s', 's', '1', '2'):
|
||||
boolspec(value, kStylisticAlternativesType,
|
||||
kStylisticAltTwelveOnSelector,
|
||||
kStylisticAltTwelveOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeStylisticAlternate13:
|
||||
boolspec(spec, kStylisticAlternativesType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('s', 's', '1', '3'):
|
||||
boolspec(value, kStylisticAlternativesType,
|
||||
kStylisticAltThirteenOnSelector,
|
||||
kStylisticAltThirteenOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeStylisticAlternate14:
|
||||
boolspec(spec, kStylisticAlternativesType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('s', 's', '1', '4'):
|
||||
boolspec(value, kStylisticAlternativesType,
|
||||
kStylisticAltFourteenOnSelector,
|
||||
kStylisticAltFourteenOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeStylisticAlternate15:
|
||||
boolspec(spec, kStylisticAlternativesType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('s', 's', '1', '5'):
|
||||
boolspec(value, kStylisticAlternativesType,
|
||||
kStylisticAltFifteenOnSelector,
|
||||
kStylisticAltFifteenOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeStylisticAlternate16:
|
||||
boolspec(spec, kStylisticAlternativesType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('s', 's', '1', '6'):
|
||||
boolspec(value, kStylisticAlternativesType,
|
||||
kStylisticAltSixteenOnSelector,
|
||||
kStylisticAltSixteenOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeStylisticAlternate17:
|
||||
boolspec(spec, kStylisticAlternativesType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('s', 's', '1', '7'):
|
||||
boolspec(value, kStylisticAlternativesType,
|
||||
kStylisticAltSeventeenOnSelector,
|
||||
kStylisticAltSeventeenOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeStylisticAlternate18:
|
||||
boolspec(spec, kStylisticAlternativesType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('s', 's', '1', '8'):
|
||||
boolspec(value, kStylisticAlternativesType,
|
||||
kStylisticAltEighteenOnSelector,
|
||||
kStylisticAltEighteenOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeStylisticAlternate19:
|
||||
boolspec(spec, kStylisticAlternativesType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('s', 's', '1', '9'):
|
||||
boolspec(value, kStylisticAlternativesType,
|
||||
kStylisticAltNineteenOnSelector,
|
||||
kStylisticAltNineteenOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeStylisticAlternate20:
|
||||
boolspec(spec, kStylisticAlternativesType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('s', 's', '2', '0'):
|
||||
boolspec(value, kStylisticAlternativesType,
|
||||
kStylisticAltTwentyOnSelector,
|
||||
kStylisticAltTwentyOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeContextualAlternates:
|
||||
boolspec(spec, kContextualAlternatesType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('c', 'a', 'l', 't'):
|
||||
boolspec(value, kContextualAlternatesType,
|
||||
kContextualAlternatesOnSelector,
|
||||
kContextualAlternatesOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeSwashes:
|
||||
boolspec(spec, kContextualAlternatesType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('s', 'w', 's', 'h'):
|
||||
boolspec(value, kContextualAlternatesType,
|
||||
kSwashAlternatesOnSelector,
|
||||
kSwashAlternatesOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
case uiAttributeContextualSwashes:
|
||||
boolspec(spec, kContextualAlternatesType,
|
||||
p);
|
||||
break;
|
||||
case mkTag('c', 's', 'w', 'h'):
|
||||
boolspec(value, kContextualAlternatesType,
|
||||
kContextualSwashAlternatesOnSelector,
|
||||
kContextualSwashAlternatesOffSelector,
|
||||
f, data);
|
||||
return 1;
|
||||
// TODO use arrays?
|
||||
case uiAttributeLowercaseCapForms:
|
||||
switch (spec->Value) {
|
||||
case uiAttributeCapFormNormal:
|
||||
(*f)(kLowerCaseType, kDefaultLowerCaseSelector, data);
|
||||
break;
|
||||
case uiAttributeCapFormSmallCaps:
|
||||
p);
|
||||
break;
|
||||
|
||||
// TODO will the following handle all cases properly, or are elses going to be needed?
|
||||
case mkTag('s', 'm', 'c', 'p'):
|
||||
if (value != 0) {
|
||||
// include this for compatibility (some fonts that come with OS X still use this!)
|
||||
// TODO make it boolean?
|
||||
(*f)(kLetterCaseType, kSmallCapsSelector, data);
|
||||
pcall(p, kLetterCaseType, kSmallCapsSelector);
|
||||
// this is the current one
|
||||
(*f)(kLowerCaseType, kLowerCaseSmallCapsSelector, data);
|
||||
break;
|
||||
case uiAttributeCapFormPetiteCaps:
|
||||
(*f)(kLowerCaseType, kLowerCasePetiteCapsSelector, data);
|
||||
break;
|
||||
pcall(p, kLowerCaseType, kLowerCaseSmallCapsSelector);
|
||||
}
|
||||
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;
|
||||
break;
|
||||
case mkTag('p', 'c', 'a', 'p'):
|
||||
if (value != 0)
|
||||
pcall(p, kLowerCaseType, kLowerCasePetiteCapsSelector);
|
||||
break;
|
||||
|
||||
// TODO will the following handle all cases properly, or are elses going to be needed?
|
||||
case mkTag('c', '2', 's', 'c'):
|
||||
if (value != 0)
|
||||
pcall(p, kUpperCaseType, kUpperCaseSmallCapsSelector);
|
||||
break;
|
||||
case mkTag('c', '2', 'p', 'c'):
|
||||
if (value != 0)
|
||||
pcall(p, kUpperCaseType, kUpperCasePetiteCapsSelector);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue