ATSUFontFeatureType find_feature_by_name(ATSUFontID fontID, const char* name, int nameLength) { ATSUFontFeatureType result = 0x0000FFFF; Str255 inName; inName[0] = nameLength; int i; for (i = 0; i < inName[0]; ++i) inName[i + 1] = name[i]; ItemCount typeCount; ATSUCountFontFeatureTypes(fontID, &typeCount); if (typeCount > 0) { ATSUFontFeatureType* types = (ATSUFontFeatureType*)xmalloc(typeCount * sizeof(ATSUFontFeatureType)); ATSUGetFontFeatureTypes(fontID, typeCount, types, 0); for (i = 0; i < typeCount; ++i) { FontNameCode nameCode; ATSUGetFontFeatureNameCode(fontID, types[i], 0x0000FFFF, &nameCode); Str255 name; ByteCount nameLen; ATSUFindFontName(fontID, nameCode, kFontMacintoshPlatform, kFontNoScript, kFontNoLanguage, 255, (Ptr)&name[1], &nameLen, 0); name[0] = nameLen; if (EqualString(inName, name, false, true)) { result = types[i]; break; } } free((char*)types); } return result; }
static OSStatus AddFunkyVariationsAndFeatures( ATSUStyle styleToMangle ) { OSStatus err; ItemCount i; ATSUFontID fontID; ItemCount count; ItemCount selectorCount; ATSUFontVariationAxis variationAxis; ATSUFontVariationValue variationMinimum; ATSUFontVariationValue variationMaximum; ATSUFontVariationValue variationDefault; Boolean selectorMutex; ATSUFontFeatureType *typeBuffer = NULL; ATSUFontFeatureSelector *selectorBuffer = NULL; Boolean *defaultBuffer = NULL; ItemCount selectorBufferSize = 0; // get the fontID from the style err = ATSUGetAttribute( styleToMangle, kATSUFontTag, sizeof( ATSUStyle ), &fontID, NULL ); require_noerr( err, AddFunkyVariationsAndFeatures_err ); // get a count of all of the variations supported by the current font err = ATSUCountFontVariations( fontID, &count ); require_noerr( err, AddFunkyVariationsAndFeatures_err ); // loop through, setting all of the variations to the max! for ( i = 0; i < count; i++ ) { // get the settings for the variations err = ATSUGetIndFontVariation( fontID, i, &variationAxis, &variationMinimum, &variationMaximum, &variationDefault ); require_noerr( err, AddFunkyVariationsAndFeatures_err ); // set the variation for this font to the max! err = ATSUSetVariations( styleToMangle, 1, &variationAxis, &variationMaximum ); require_noerr( err, AddFunkyVariationsAndFeatures_err ); } // get a count of all of the features err = ATSUCountFontFeatureTypes( fontID, &count ); require_noerr( err, AddFunkyVariationsAndFeatures_err ); // allocate a buffer for the feature types typeBuffer = (ATSUFontFeatureType *) malloc( sizeof( ATSUFontFeatureType ) * count ); require_action( typeBuffer != NULL, AddFunkyVariationsAndFeatures_err, err = paramErr ); // get all of the font features err = ATSUGetFontFeatureTypes( fontID, count, typeBuffer, &selectorCount ); require_noerr( err, AddFunkyVariationsAndFeatures_err ); // loop through, setting all of the features for ( i = 0; i < count; i++ ) { // get the selector count err = ATSUCountFontFeatureSelectors( fontID, typeBuffer[i], &selectorCount ); require_noerr( err, AddFunkyVariationsAndFeatures_err ); // if the selector buffer size is greater than what we had before, // then allocate some new buffers. Just use realloc, as when // the buffers are pointing to NULL, it will simply act as malloc. if ( selectorBufferSize < count ) { ItemCount newCount; // set the new size to be twice the old size newCount = 2 * count; // allocate the selectorBuffer selectorBuffer = (ATSUFontFeatureSelector *) realloc( selectorBuffer, newCount * sizeof( ATSUFontFeatureSelector ) ); require_action( selectorBuffer != NULL, AddFunkyVariationsAndFeatures_err, err = memFullErr ); // allocate the defaultBuffer defaultBuffer = (Boolean *) realloc( defaultBuffer, newCount * sizeof( Boolean ) ); require_action( defaultBuffer != NULL, AddFunkyVariationsAndFeatures_err, err = memFullErr ); selectorBufferSize = newCount; } // get the font feature selectors err = ATSUGetFontFeatureSelectors( fontID, typeBuffer[i], selectorBufferSize, selectorBuffer, defaultBuffer, &selectorCount, &selectorMutex ); require_noerr( err, AddFunkyVariationsAndFeatures_err ); // if the features are not mutually exclusive, then go ahead and // set them all. if ( selectorMutex == false ) { ItemCount j; // loop through and set all of the features for ( j = 0; j < selectorCount; j++ ) { if ( defaultBuffer[j] == false ) { err = ATSUSetFontFeatures( styleToMangle, 1, &typeBuffer[i], &selectorBuffer[j] ); require_noerr( err, AddFunkyVariationsAndFeatures_err ); } } } else { // just set the last option, then since we can't set them all err = ATSUSetFontFeatures( styleToMangle, 1, &typeBuffer[i], &selectorBuffer[selectorCount - 1] ); require_noerr( err, AddFunkyVariationsAndFeatures_err ); } } // that should be enough style perversion for now! AddFunkyVariationsAndFeatures_err: if ( typeBuffer != NULL ) { free( typeBuffer ); } if ( selectorBuffer != NULL ) { free( selectorBuffer ); } if ( defaultBuffer != NULL ) { free( defaultBuffer ); } return err; }