diff --git a/common/attrlist.c b/common/attrlist.c index ca2937dc..e50ec141 100644 --- a/common/attrlist.c +++ b/common/attrlist.c @@ -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; } } diff --git a/darwin/aat.m b/darwin/aat.m index c11abccd..0c3fd5fa 100644 --- a/darwin/aat.m +++ b/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 diff --git a/darwin/attrstr.m b/darwin/attrstr.m index ba69b9ed..6cf412a4 100644 --- a/darwin/attrstr.m +++ b/darwin/attrstr.m @@ -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); diff --git a/darwin/fontmatch.m b/darwin/fontmatch.m index 56b8991d..abd38c32 100644 --- a/darwin/fontmatch.m +++ b/darwin/fontmatch.m @@ -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; diff --git a/darwin/opentype.m b/darwin/opentype.m index d6bd6652..00a76200 100644 --- a/darwin/opentype.m +++ b/darwin/opentype.m @@ -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; - 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; + // 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; 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); diff --git a/examples/drawtext/attributes.c b/examples/drawtext/attributes.c index 69bbe032..f15ba070 100644 --- a/examples/drawtext/attributes.c +++ b/examples/drawtext/attributes.c @@ -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, ")"); diff --git a/ui_attrstr.h b/ui_attrstr.h index ad4169e9..0d1b9d81 100644 --- a/ui_attrstr.h +++ b/ui_attrstr.h @@ -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);