And finished integrating the new attributed string stuff on OS X.
This commit is contained in:
parent
06becce34c
commit
01df4631f6
|
@ -60,7 +60,7 @@ static void attrClearSpec(struct attr *a)
|
|||
uiFree((char *) (a->spec.Family));
|
||||
break;
|
||||
case uiAttributeFeatures:
|
||||
uiOpenTypeFeaturesFree((uiOpenTypeFeatures *) (a->spec.Features));
|
||||
uiFreeOpenTypeFeatures((uiOpenTypeFeatures *) (a->spec.Features));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
62
darwin/aat.m
62
darwin/aat.m
|
@ -16,8 +16,6 @@ static void boolspec(uint32_t value, uint16_t type, uint16_t ifTrue, uint16_t if
|
|||
// TODO double-check drawtext example to make sure all of these are used properly (I already screwed dlig up by putting clig twice instead)
|
||||
void openTypeToAAT(char a, char b, char c, char d, uint32_t value, aatBlock f)
|
||||
{
|
||||
struct openTypeAATParams *p = (struct openTypeAATParams *) data;
|
||||
|
||||
switch (mkTag(a, b, c, d)) {
|
||||
case mkTag('l', 'i', 'g', 'a'):
|
||||
boolspec(value, kLigaturesType,
|
||||
|
@ -55,45 +53,45 @@ void openTypeToAAT(char a, char b, char c, char d, uint32_t value, aatBlock f)
|
|||
// TODO is this correct, or should we provide an else case?
|
||||
if (value != 0)
|
||||
// this is undocumented; it comes from Core Text's internal AAT-to-OpenType conversion table
|
||||
f(p, kLetterCaseType, 14);
|
||||
f(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)
|
||||
f(p, kNumberSpacingType, kProportionalNumbersSelector);
|
||||
f(kNumberSpacingType, kProportionalNumbersSelector);
|
||||
break;
|
||||
case mkTag('t', 'n', 'u', 'm'):
|
||||
if (value != 0)
|
||||
f(p, kNumberSpacingType, kMonospacedNumbersSelector);
|
||||
f(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)
|
||||
f(p, kVerticalPositionType, kSuperiorsSelector);
|
||||
f(kVerticalPositionType, kSuperiorsSelector);
|
||||
break;
|
||||
case mkTag('s', 'u', 'b', 's'):
|
||||
if (value != 0)
|
||||
f(p, kVerticalPositionType, kInferiorsSelector);
|
||||
f(kVerticalPositionType, kInferiorsSelector);
|
||||
break;
|
||||
case mkTag('o', 'r', 'd', 'n'):
|
||||
if (value != 0)
|
||||
f(p, kVerticalPositionType, kOrdinalsSelector);
|
||||
f(kVerticalPositionType, kOrdinalsSelector);
|
||||
break;
|
||||
case mkTag('s', 'i', 'n', 'f'):
|
||||
if (value != 0)
|
||||
f(p, kVerticalPositionType, kScientificInferiorsSelector);
|
||||
f(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)
|
||||
f(p, kFractionsType, kVerticalFractionsSelector);
|
||||
f(kFractionsType, kVerticalFractionsSelector);
|
||||
break;
|
||||
case mkTag('f', 'r', 'a', 'c'):
|
||||
if (value != 0)
|
||||
f(p, kFractionsType, kDiagonalFractionsSelector);
|
||||
f(kFractionsType, kDiagonalFractionsSelector);
|
||||
break;
|
||||
|
||||
case mkTag('z', 'e', 'r', 'o'):
|
||||
|
@ -109,57 +107,57 @@ void openTypeToAAT(char a, char b, char c, char d, uint32_t value, aatBlock f)
|
|||
f);
|
||||
break;
|
||||
case mkTag('o', 'r', 'n', 'm'):
|
||||
f(p, kOrnamentSetsType, (uint16_t) value);
|
||||
f(kOrnamentSetsType, (uint16_t) value);
|
||||
break;
|
||||
case mkTag('a', 'a', 'l', 't'):
|
||||
f(p, kCharacterAlternativesType, (uint16_t) value);
|
||||
f(kCharacterAlternativesType, (uint16_t) value);
|
||||
break;
|
||||
case mkTag('t', 'i', 't', 'l'):
|
||||
// TODO is this correct, or should we provide an else case?
|
||||
if (value != 0)
|
||||
f(p, kStyleOptionsType, kTitlingCapsSelector);
|
||||
f(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)
|
||||
f(p, kCharacterShapeType, kTraditionalCharactersSelector);
|
||||
f(kCharacterShapeType, kTraditionalCharactersSelector);
|
||||
break;
|
||||
case mkTag('s', 'm', 'p', 'l'):
|
||||
if (value != 0)
|
||||
f(p, kCharacterShapeType, kSimplifiedCharactersSelector);
|
||||
f(kCharacterShapeType, kSimplifiedCharactersSelector);
|
||||
break;
|
||||
case mkTag('j', 'p', '7', '8'):
|
||||
if (value != 0)
|
||||
f(p, kCharacterShapeType, kJIS1978CharactersSelector);
|
||||
f(kCharacterShapeType, kJIS1978CharactersSelector);
|
||||
break;
|
||||
case mkTag('j', 'p', '8', '3'):
|
||||
if (value != 0)
|
||||
f(p, kCharacterShapeType, kJIS1983CharactersSelector);
|
||||
f(kCharacterShapeType, kJIS1983CharactersSelector);
|
||||
break;
|
||||
case mkTag('j', 'p', '9', '0'):
|
||||
if (value != 0)
|
||||
f(p, kCharacterShapeType, kJIS1990CharactersSelector);
|
||||
f(kCharacterShapeType, kJIS1990CharactersSelector);
|
||||
break;
|
||||
case mkTag('e', 'x', 'p', 't'):
|
||||
if (value != 0)
|
||||
f(p, kCharacterShapeType, kExpertCharactersSelector);
|
||||
f(kCharacterShapeType, kExpertCharactersSelector);
|
||||
break;
|
||||
case mkTag('j', 'p', '0', '4'):
|
||||
if (value != 0)
|
||||
f(p, kCharacterShapeType, kJIS2004CharactersSelector);
|
||||
f(kCharacterShapeType, kJIS2004CharactersSelector);
|
||||
break;
|
||||
case mkTag('h', 'o', 'j', 'o'):
|
||||
if (value != 0)
|
||||
f(p, kCharacterShapeType, kHojoCharactersSelector);
|
||||
f(kCharacterShapeType, kHojoCharactersSelector);
|
||||
break;
|
||||
case mkTag('n', 'l', 'c', 'k'):
|
||||
if (value != 0)
|
||||
f(p, kCharacterShapeType, kNLCCharactersSelector);
|
||||
f(kCharacterShapeType, kNLCCharactersSelector);
|
||||
break;
|
||||
case mkTag('t', 'n', 'a', 'm'):
|
||||
if (value != 0)
|
||||
f(p, kCharacterShapeType, kTraditionalNamesCharactersSelector);
|
||||
f(kCharacterShapeType, kTraditionalNamesCharactersSelector);
|
||||
break;
|
||||
|
||||
case mkTag('o', 'n', 'u', 'm'):
|
||||
|
@ -168,15 +166,15 @@ void openTypeToAAT(char a, char b, char c, char d, uint32_t value, aatBlock f)
|
|||
case mkTag('l', 'n', 'u', 'm'):
|
||||
// TODO is this correct, or should we provide an else case?
|
||||
if (value != 0)
|
||||
f(p, kNumberCaseType, kLowerCaseNumbersSelector);
|
||||
f(kNumberCaseType, kLowerCaseNumbersSelector);
|
||||
break;
|
||||
case mkTag('h', 'n', 'g', 'l'):
|
||||
// TODO is this correct, or should we provide an else case?
|
||||
if (value != 0)
|
||||
f(p, kTransliterationType, kHanjaToHangulSelector);
|
||||
f(kTransliterationType, kHanjaToHangulSelector);
|
||||
break;
|
||||
case mkTag('n', 'a', 'l', 't'):
|
||||
f(p, kAnnotationType, (uint16_t) value);
|
||||
f(kAnnotationType, (uint16_t) value);
|
||||
break;
|
||||
case mkTag('r', 'u', 'b', 'y'):
|
||||
// include this for completeness
|
||||
|
@ -370,24 +368,24 @@ void openTypeToAAT(char a, char b, char c, char d, uint32_t value, aatBlock f)
|
|||
if (value != 0) {
|
||||
// include this for compatibility (some fonts that come with OS X still use this!)
|
||||
// TODO make it boolean?
|
||||
f(p, kLetterCaseType, kSmallCapsSelector);
|
||||
f(kLetterCaseType, kSmallCapsSelector);
|
||||
// this is the current one
|
||||
f(p, kLowerCaseType, kLowerCaseSmallCapsSelector);
|
||||
f(kLowerCaseType, kLowerCaseSmallCapsSelector);
|
||||
}
|
||||
break;
|
||||
case mkTag('p', 'c', 'a', 'p'):
|
||||
if (value != 0)
|
||||
f(p, kLowerCaseType, kLowerCasePetiteCapsSelector);
|
||||
f(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)
|
||||
f(p, kUpperCaseType, kUpperCaseSmallCapsSelector);
|
||||
f(kUpperCaseType, kUpperCaseSmallCapsSelector);
|
||||
break;
|
||||
case mkTag('c', '2', 'p', 'c'):
|
||||
if (value != 0)
|
||||
f(p, kUpperCaseType, kUpperCasePetiteCapsSelector);
|
||||
f(kUpperCaseType, kUpperCasePetiteCapsSelector);
|
||||
break;
|
||||
}
|
||||
// TODO handle this properly
|
||||
|
|
|
@ -131,7 +131,8 @@ struct foreachParams {
|
|||
CTFontDescriptorRef desc;
|
||||
CTFontRef font;
|
||||
|
||||
uidesc.Family = self.family;
|
||||
// TODO const-correct uiDrawFontDescriptor or change this function below
|
||||
uidesc.Family = (char *) (self.family);
|
||||
uidesc.Size = self.size;
|
||||
uidesc.Weight = self.weight;
|
||||
uidesc.Italic = self.italic;
|
||||
|
@ -170,7 +171,7 @@ static void adjustFontInRange(struct foreachParams *p, size_t start, size_t end,
|
|||
|
||||
for (i = start; i < end; i++) {
|
||||
n = [NSNumber numberWithInteger:i];
|
||||
v = (combinedFontAttr *) [p->combinedFontAttrs objectForKey:n];
|
||||
cfa = (combinedFontAttr *) [p->combinedFontAttrs objectForKey:n];
|
||||
adj(cfa);
|
||||
}
|
||||
}
|
||||
|
@ -329,7 +330,7 @@ static BOOL cfaIsEqual(combinedFontAttr *a, combinedFontAttr *b)
|
|||
|
||||
static void applyAndFreeFontAttributes(struct foreachParams *p)
|
||||
{
|
||||
CFIndex i;
|
||||
CFIndex i, n;
|
||||
combinedFontAttr *cfa, *cfab;
|
||||
CTFontRef defaultFont;
|
||||
CTFontRef font;
|
||||
|
@ -349,6 +350,7 @@ static void applyAndFreeFontAttributes(struct foreachParams *p)
|
|||
for (i = 0; i < n; i++) {
|
||||
NSNumber *nn;
|
||||
|
||||
// TODO use NSValue or some other method of NSNumber
|
||||
nn = [NSNumber numberWithInteger:i];
|
||||
cfab = (combinedFontAttr *) [p->combinedFontAttrs objectForKey:nn];
|
||||
if (cfaIsEqual(cfa, cfab))
|
||||
|
@ -357,6 +359,7 @@ static void applyAndFreeFontAttributes(struct foreachParams *p)
|
|||
// the font has changed; write out the old one
|
||||
range.length = i - range.location;
|
||||
if (cfa == nil) {
|
||||
// TODO this isn't necessary because of default font shenanigans below
|
||||
font = defaultFont;
|
||||
CFRetain(font);
|
||||
} else
|
||||
|
@ -371,6 +374,7 @@ static void applyAndFreeFontAttributes(struct foreachParams *p)
|
|||
// and finally, write out the last range
|
||||
range.length = i - range.location;
|
||||
if (cfa == nil) {
|
||||
// TODO likewise
|
||||
font = defaultFont;
|
||||
CFRetain(font);
|
||||
} else
|
||||
|
@ -414,7 +418,6 @@ CFAttributedStringRef attrstrToCoreFoundation(uiDrawTextLayoutParams *p, NSArray
|
|||
CFAttributedStringRef base;
|
||||
CFMutableAttributedStringRef mas;
|
||||
struct foreachParams fep;
|
||||
struct fontParams ffp;
|
||||
|
||||
cfstr = CFStringCreateWithCharacters(NULL, attrstrUTF16(p->String), attrstrUTF16Len(p->String));
|
||||
if (cfstr == NULL) {
|
||||
|
@ -426,11 +429,12 @@ CFAttributedStringRef attrstrToCoreFoundation(uiDrawTextLayoutParams *p, NSArray
|
|||
if (defaultAttrs == NULL) {
|
||||
// TODO
|
||||
}
|
||||
memset(&ffp, 0, sizeof (struct fontParams));
|
||||
#if 0 /* TODO */
|
||||
ffp.desc = *(p->DefaultFont);
|
||||
defaultCTFont = fontdescToCTFont(&ffp);
|
||||
CFDictionaryAddValue(defaultAttrs, kCTFontAttributeName, defaultCTFont);
|
||||
CFRelease(defaultCTFont);
|
||||
#endif
|
||||
ps = mkParagraphStyle(p);
|
||||
CFDictionaryAddValue(defaultAttrs, kCTParagraphStyleAttributeName, ps);
|
||||
CFRelease(ps);
|
||||
|
|
|
@ -258,8 +258,9 @@ CTFontDescriptorRef fontdescToCTFontDescriptor(uiDrawFontDescriptor *fd)
|
|||
CTFontDescriptorRef fontdescAppendFeatures(CTFontDescriptorRef desc, const uiOpenTypeFeatures *otf)
|
||||
{
|
||||
CTFontDescriptorRef new;
|
||||
CFMutableArrayRef featuresArray;
|
||||
CFArrayRef featuresArray;
|
||||
CFDictionaryRef attrs;
|
||||
const void *keys[1], *values[1];
|
||||
|
||||
featuresArray = otfToFeaturesArray(otf);
|
||||
keys[0] = kCTFontFeatureSettingsAttribute;
|
||||
|
|
|
@ -93,14 +93,15 @@ int uiOpenTypeFeaturesEqual(const uiOpenTypeFeatures *a, const uiOpenTypeFeature
|
|||
static int otfArrayForEach(char a, char b, char c, char d, uint32_t value, void *data)
|
||||
{
|
||||
CFMutableArrayRef outerArray = (CFMutableArrayRef) data;
|
||||
|
||||
openTypeToAAT(a, b, c, d, value, ^(uint16_t type, uint16_t selector) {
|
||||
CFDictionaryRef innerDict;
|
||||
CFNumberRef numType, numSelector;
|
||||
// not well documented, but fixed-size arrays don't support __block either (VLAs are documented as being unsupported)
|
||||
const void *keys[2], *values[2];
|
||||
|
||||
keys[0] = kCTFontFeatureTypeIdentifierKey;
|
||||
keys[1] = kCTFontFeatureSelectorIdentifierKey;
|
||||
openTypeToAAT(a, b, c, d, value, ^(uint16_t type, uint16_t selector) {
|
||||
CFDictionaryRef innerDict;
|
||||
CFNumberRef numType, numSelector;
|
||||
|
||||
numType = CFNumberCreate(NULL, kCFNumberSInt16Type,
|
||||
(const SInt16 *) (&type));
|
||||
numSelector = CFNumberCreate(NULL, kCFNumberSInt16Type,
|
||||
|
@ -115,7 +116,7 @@ static int otfArrayForEach(char a, char b, char c, char d, uint32_t value, void
|
|||
if (innerDict == NULL) {
|
||||
// TODO
|
||||
}
|
||||
CFArrayAppendValue(p->outerArray, innerDict);
|
||||
CFArrayAppendValue(outerArray, innerDict);
|
||||
CFRelease(innerDict);
|
||||
CFRelease(numSelector);
|
||||
CFRelease(numType);
|
||||
|
|
|
@ -170,7 +170,7 @@ static void setupAttributedString(void)
|
|||
spec.A = 0.75;
|
||||
uiAttributedStringSetAttribute(attrstr, &spec, start + 12, end);
|
||||
spec.Type = uiAttributeFamily;
|
||||
spec.Value = "Helvetica";
|
||||
spec.Family = "Helvetica";
|
||||
uiAttributedStringSetAttribute(attrstr, &spec, start + 8, end - 1);
|
||||
spec.Type = uiAttributeBackground;
|
||||
spec.R = 1.0;
|
||||
|
@ -245,7 +245,7 @@ static void setupAttributedString(void)
|
|||
end = start + strlen(next);
|
||||
uiAttributedStringAppendUnattributed(attrstr, next);
|
||||
spec.Type = uiAttributeFeatures;
|
||||
spec.Value = otf;
|
||||
spec.Features = otf;
|
||||
uiAttributedStringSetAttribute(attrstr, &spec, start, end);
|
||||
uiAttributedStringAppendUnattributed(attrstr, ")");
|
||||
|
||||
|
|
|
@ -256,6 +256,7 @@ _UI_EXTERN void uiDrawCaret(uiDrawContext *c, double x, double y, uiDrawTextLayo
|
|||
|
||||
typedef struct uiFontButton uiFontButton;
|
||||
#define uiFontButton(this) ((uiFontButton *) (this))
|
||||
// TODO have a function that sets an entire font descriptor to a range in a uiAttributedString at once?
|
||||
_UI_EXTERN void uiFontButtonFont(uiFontButton *b, uiDrawFontDescriptor *desc);
|
||||
// TOOD SetFont, mechanics
|
||||
_UI_EXTERN void uiFontButtonOnChanged(uiFontButton *b, void (*f)(uiFontButton *, void *), void *data);
|
||||
|
|
Loading…
Reference in New Issue