summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/xetexdir/XeTeX_mac.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/xetexdir/XeTeX_mac.c')
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeX_mac.c747
1 files changed, 0 insertions, 747 deletions
diff --git a/Build/source/texk/web2c/xetexdir/XeTeX_mac.c b/Build/source/texk/web2c/xetexdir/XeTeX_mac.c
deleted file mode 100644
index bf9fdeb98a4..00000000000
--- a/Build/source/texk/web2c/xetexdir/XeTeX_mac.c
+++ /dev/null
@@ -1,747 +0,0 @@
-/****************************************************************************\
- Part of the XeTeX typesetting system
- Copyright (c) 1994-2008 by SIL International
- Copyright (c) 2009 by Jonathan Kew
- Copyright (c) 2012, 2013 by Jiang Jiang
- Copyright (c) 2012-2015 by Khaled Hosny
-
- SIL Author(s): Jonathan Kew
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
-FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
-CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of the copyright holders
-shall not be used in advertising or otherwise to promote the sale,
-use or other dealings in this Software without prior written
-authorization from the copyright holders.
-\****************************************************************************/
-
-/* XeTeX_mac.c
- * additional plain C extensions for XeTeX - MacOS-specific routines
- */
-
-#define EXTERN extern
-#include "xetexd.h"
-
-#include <ApplicationServices/ApplicationServices.h>
-
-#include <teckit/TECkit_Engine.h>
-#include "XeTeX_ext.h"
-#include "XeTeXLayoutInterface.h"
-
-static inline double
-TeXtoPSPoints(double pts)
-{
- return pts * 72.0 / 72.27;
-}
-
-static inline double
-PStoTeXPoints(double pts)
-{
- return pts * 72.27 / 72.0;
-}
-
-static inline Fixed
-FixedPStoTeXPoints(double pts)
-{
- return D2Fix(PStoTeXPoints(pts));
-}
-
-CTFontRef
-fontFromAttributes(CFDictionaryRef attributes)
-{
- return CFDictionaryGetValue(attributes, kCTFontAttributeName);
-}
-
-CTFontRef
-fontFromInteger(integer font)
-{
- CFDictionaryRef attributes = (CFDictionaryRef) fontlayoutengine[font];
- return fontFromAttributes(attributes);
-}
-
-void
-DoAATLayout(void* p, int justify)
-{
- CFArrayRef glyphRuns;
- CFIndex i, j, runCount;
- CFIndex totalGlyphCount = 0;
- UInt16* glyphIDs;
- Fixed* glyphAdvances;
- void* glyph_info = NULL;
- FixedPoint* locations;
- CGFloat width;
-
- long txtLen;
- const UniChar* txtPtr;
-
- CFDictionaryRef attributes;
- CFStringRef string;
- CFAttributedStringRef attrString;
- CTTypesetterRef typesetter;
- CTLineRef line;
-
- memoryword* node = (memoryword*)p;
-
- unsigned f = native_font(node);
- if (fontarea[f] != AAT_FONT_FLAG) {
- fprintf(stderr, "internal error: DoAATLayout called for non-AAT font\n");
- exit(1);
- }
-
- txtLen = native_length(node);
- txtPtr = (UniChar*)(node + native_node_size);
-
- attributes = fontlayoutengine[native_font(node)];
- string = CFStringCreateWithCharactersNoCopy(NULL, txtPtr, txtLen, kCFAllocatorNull);
- attrString = CFAttributedStringCreate(NULL, string, attributes);
- CFRelease(string);
-
- typesetter = CTTypesetterCreateWithAttributedString(attrString);
- CFRelease(attrString);
- line = CTTypesetterCreateLine(typesetter, CFRangeMake(0, txtLen));
- if (justify) {
- CGFloat lineWidth = TeXtoPSPoints(Fix2D(node_width(node)));
- CTLineRef justifiedLine = CTLineCreateJustifiedLine(line, TeXtoPSPoints(Fix2D(fract1)), lineWidth);
- // TODO(jjgod): how to handle the case when justification failed? for
- // now we just fallback to use the original line.
- if (justifiedLine) {
- CFRelease(line);
- line = justifiedLine;
- }
- }
-
- glyphRuns = CTLineGetGlyphRuns(line);
- runCount = CFArrayGetCount(glyphRuns);
- totalGlyphCount = CTLineGetGlyphCount(line);
-
- if (totalGlyphCount > 0) {
- glyph_info = xmalloc(totalGlyphCount * native_glyph_info_size);
- locations = (FixedPoint*)glyph_info;
- glyphIDs = (UInt16*)(locations + totalGlyphCount);
- glyphAdvances = xmalloc(totalGlyphCount * sizeof(Fixed));
- totalGlyphCount = 0;
-
- width = 0;
- for (i = 0; i < runCount; i++) {
- CTRunRef run = CFArrayGetValueAtIndex(glyphRuns, i);
- CFIndex count = CTRunGetGlyphCount(run);
- CFDictionaryRef runAttributes = CTRunGetAttributes(run);
- CFBooleanRef vertical = CFDictionaryGetValue(runAttributes, kCTVerticalFormsAttributeName);
- // TODO(jjgod): Avoid unnecessary allocation with CTRunGetFoosPtr().
- CGGlyph* glyphs = (CGGlyph*) xmalloc(count * sizeof(CGGlyph));
- CGPoint* positions = (CGPoint*) xmalloc(count * sizeof(CGPoint));
- CGSize* advances = (CGSize*) xmalloc(count * sizeof(CGSize));
- CGFloat runWidth = CTRunGetTypographicBounds(run, CFRangeMake(0, 0), NULL, NULL, NULL);
- CTRunGetGlyphs(run, CFRangeMake(0, 0), glyphs);
- CTRunGetPositions(run, CFRangeMake(0, 0), positions);
- CTRunGetAdvances(run, CFRangeMake(0, 0), advances);
- for (j = 0; j < count; j++) {
- // XXX Core Text has that font cascading thing that will do
- // font substitution for missing glyphs, which we do not want
- // but I can not find a way to disable it yet, so if the font
- // of the resulting run is not the same font we asked for, use
- // the glyph at index 0 (usually .notdef) instead or we will be
- // showing garbage or even invalid glyphs
- if (!CFEqual(fontFromAttributes(attributes), fontFromAttributes(runAttributes)))
- glyphIDs[totalGlyphCount] = 0;
- else
- glyphIDs[totalGlyphCount] = glyphs[j];
-
- // Swap X and Y when doing vertical layout
- if (vertical == kCFBooleanTrue) {
- locations[totalGlyphCount].x = -FixedPStoTeXPoints(positions[j].y);
- locations[totalGlyphCount].y = FixedPStoTeXPoints(positions[j].x);
- } else {
- locations[totalGlyphCount].x = FixedPStoTeXPoints(positions[j].x);
- locations[totalGlyphCount].y = -FixedPStoTeXPoints(positions[j].y);
- }
- glyphAdvances[totalGlyphCount] = advances[j].width;
- totalGlyphCount++;
- }
- width += FixedPStoTeXPoints(runWidth);
- free(glyphs);
- free(positions);
- free(advances);
- }
- }
-
- native_glyph_count(node) = totalGlyphCount;
- native_glyph_info_ptr(node) = glyph_info;
-
- if (!justify) {
- node_width(node) = width;
-
- if (totalGlyphCount > 0) {
- /* this is essentially a copy from similar code in XeTeX_ext.c, easier
- * to be done here */
- if (fontletterspace[f] != 0) {
- Fixed lsDelta = 0;
- Fixed lsUnit = fontletterspace[f];
- int i;
- for (i = 0; i < totalGlyphCount; ++i) {
- if (glyphAdvances[i] == 0 && lsDelta != 0)
- lsDelta -= lsUnit;
- locations[i].x += lsDelta;
- lsDelta += lsUnit;
- }
- if (lsDelta != 0) {
- lsDelta -= lsUnit;
- node_width(node) += lsDelta;
- }
- }
- }
- }
-
- free(glyphAdvances);
- CFRelease(line);
- CFRelease(typesetter);
-}
-
-static void
-getGlyphBBoxFromCTFont(CTFontRef font, UInt16 gid, GlyphBBox* bbox)
-{
- CGRect rect;
-
- bbox->xMin = 65536.0;
- bbox->yMin = 65536.0;
- bbox->xMax = -65536.0;
- bbox->yMax = -65536.0;
-
- rect = CTFontGetBoundingRectsForGlyphs(font,
- 0, /* Use default orientation for now, handle vertical later */
- (const CGGlyph *) &gid, NULL, 1);
-
- if (CGRectIsNull(rect))
- bbox->xMin = bbox->yMin = bbox->xMax = bbox->yMax = 0;
- else {
- bbox->yMin = PStoTeXPoints(rect.origin.y);
- bbox->yMax = PStoTeXPoints(rect.origin.y + rect.size.height);
- bbox->xMin = PStoTeXPoints(rect.origin.x);
- bbox->xMax = PStoTeXPoints(rect.origin.x + rect.size.width);
- }
-}
-
-void
-GetGlyphBBox_AAT(CFDictionaryRef attributes, UInt16 gid, GlyphBBox* bbox)
- /* returns glyph bounding box in TeX points */
-{
- CTFontRef font = fontFromAttributes(attributes);
- return getGlyphBBoxFromCTFont(font, gid, bbox);
-}
-
-static double
-getGlyphWidthFromCTFont(CTFontRef font, UInt16 gid)
-{
- return PStoTeXPoints(CTFontGetAdvancesForGlyphs(font, kCTFontHorizontalOrientation, &gid, NULL, 1));
-}
-
-double
-GetGlyphWidth_AAT(CFDictionaryRef attributes, UInt16 gid)
- /* returns TeX points */
-{
- CTFontRef font = fontFromAttributes(attributes);
- return getGlyphWidthFromCTFont(font, gid);
-}
-
-void
-GetGlyphHeightDepth_AAT(CFDictionaryRef attributes, UInt16 gid, float* ht, float* dp)
- /* returns TeX points */
-{
- GlyphBBox bbox;
-
- GetGlyphBBox_AAT(attributes, gid, &bbox);
-
- *ht = bbox.yMax;
- *dp = -bbox.yMin;
-}
-
-void
-GetGlyphSidebearings_AAT(CFDictionaryRef attributes, UInt16 gid, float* lsb, float* rsb)
- /* returns TeX points */
-{
- CTFontRef font = fontFromAttributes(attributes);
- CGSize advances[1] = { CGSizeMake(0, 0) };
- double advance = CTFontGetAdvancesForGlyphs(font, 0, &gid, advances, 1);
- GlyphBBox bbox;
- getGlyphBBoxFromCTFont(font, gid, &bbox);
- *lsb = bbox.xMin;
- *rsb = PStoTeXPoints(advance) - bbox.xMax;
-}
-
-double
-GetGlyphItalCorr_AAT(CFDictionaryRef attributes, UInt16 gid)
-{
- CTFontRef font = fontFromAttributes(attributes);
- CGSize advances[1] = { CGSizeMake(0, 0) };
- double advance = CTFontGetAdvancesForGlyphs(font, 0, &gid, advances, 1);
-
- GlyphBBox bbox;
- getGlyphBBoxFromCTFont(font, gid, &bbox);
-
- if (bbox.xMax > PStoTeXPoints(advance))
- return bbox.xMax - PStoTeXPoints(advance);
- return 0;
-}
-
-static int
-mapCharToGlyphFromCTFont(CTFontRef font, UInt32 ch)
-{
- CGGlyph glyphs[2] = { 0 };
- UniChar txt[2];
- int len = 1;
-
- if (ch > 0xffff) {
- ch -= 0x10000;
- txt[0] = 0xd800 + ch / 1024;
- txt[1] = 0xdc00 + ch % 1024;
- len = 2;
- } else {
- txt[0] = ch;
- }
-
- if (CTFontGetGlyphsForCharacters(font, txt, glyphs, len))
- return glyphs[0];
-
- return 0;
-}
-
-int
-MapCharToGlyph_AAT(CFDictionaryRef attributes, UInt32 ch)
-{
- CTFontRef font = fontFromAttributes(attributes);
- return mapCharToGlyphFromCTFont(font, ch);
-}
-
-static int
-GetGlyphIDFromCTFont(CTFontRef ctFontRef, const char* glyphName)
-{
- CFStringRef glyphname = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault,
- glyphName,
- kCFStringEncodingUTF8,
- kCFAllocatorNull);
- int rval = CTFontGetGlyphWithName(ctFontRef, glyphname);
- CFRelease(glyphname);
- return rval;
-}
-
-int
-MapGlyphToIndex_AAT(CFDictionaryRef attributes, const char* glyphName)
-{
- CTFontRef font = fontFromAttributes(attributes);
- return GetGlyphIDFromCTFont(font, glyphName);
-}
-
-char*
-GetGlyphNameFromCTFont(CTFontRef ctFontRef, UInt16 gid, int* len)
-{
- CGFontRef cgfont;
- static char buffer[256];
- buffer[0] = 0;
- *len = 0;
-
- cgfont = CTFontCopyGraphicsFont(ctFontRef, 0);
- if (cgfont && gid < CGFontGetNumberOfGlyphs(cgfont)) {
- CFStringRef glyphname = CGFontCopyGlyphNameForGlyph(cgfont, gid);
- if (glyphname) {
- if (CFStringGetCString(glyphname, buffer, 256, kCFStringEncodingUTF8)) {
- *len = strlen(buffer);
- }
- CFRelease(glyphname);
- }
- CGFontRelease(cgfont);
- }
-
- return &buffer[0];
-}
-
-int
-GetFontCharRange_AAT(CFDictionaryRef attributes, int reqFirst)
-{
- if (reqFirst) {
- int ch = 0;
- while (MapCharToGlyph_AAT(attributes, ch) == 0 && ch < 0x10ffff)
- ++ch;
- return ch;
- } else {
- int ch = 0x10ffff;
- while (MapCharToGlyph_AAT(attributes, ch) == 0 && ch > 0)
- --ch;
- return ch;
- }
-}
-
-char*
-getNameFromCTFont(CTFontRef ctFontRef, CFStringRef nameKey)
-{
- char *buf;
- CFStringRef name = CTFontCopyName(ctFontRef, nameKey);
- CFIndex len = CFStringGetLength(name);
- len = len * 6 + 1;
- buf = xmalloc(len);
- if (CFStringGetCString(name, buf, len, kCFStringEncodingUTF8))
- return buf;
- free(buf);
- return NULL;
-}
-
-char*
-getFileNameFromCTFont(CTFontRef ctFontRef, uint32_t *index)
-{
- char *ret = NULL;
- CFURLRef url = NULL;
-
-#if !defined(MAC_OS_X_VERSION_10_6) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6
- /* kCTFontURLAttribute was not avialable before 10.6 */
- ATSFontRef atsFont;
- FSRef fsref;
- OSStatus status;
- atsFont = CTFontGetPlatformFont(ctFontRef, NULL);
- status = ATSFontGetFileReference(atsFont, &fsref);
- if (status == noErr)
- url = CFURLCreateFromFSRef(NULL, &fsref);
-#else
- url = (CFURLRef) CTFontCopyAttribute(ctFontRef, kCTFontURLAttribute);
-#endif
- if (url) {
- UInt8 pathname[PATH_MAX];
- if (CFURLGetFileSystemRepresentation(url, true, pathname, PATH_MAX)) {
- FT_Error error;
- FT_Face face;
-
- *index = 0;
-
- if (!gFreeTypeLibrary) {
- error = FT_Init_FreeType(&gFreeTypeLibrary);
- if (error) {
- fprintf(stderr, "FreeType initialization failed! (%d)\n", error);
- exit(1);
- }
- }
-
- error = FT_New_Face(gFreeTypeLibrary, (char *) pathname, 0, &face);
- if (!error) {
- if (face->num_faces > 1) {
- int num_faces = face->num_faces;
- char *ps_name1 = getNameFromCTFont(ctFontRef, kCTFontPostScriptNameKey);
- int i;
- *index = -1;
- FT_Done_Face (face);
- for (i = 0; i < num_faces; i++) {
- error = FT_New_Face (gFreeTypeLibrary, (char *) pathname, i, &face);
- if (!error) {
- const char *ps_name2 = FT_Get_Postscript_Name(face);
- if (strcmp(ps_name1, ps_name2) == 0) {
- *index = i;
- break;
- }
- FT_Done_Face (face);
- }
- }
- free(ps_name1);
- }
- }
-
- if (*index != -1)
- ret = strdup((char *) pathname);
- }
- CFRelease(url);
- }
-
- return ret;
-}
-
-CFDictionaryRef
-findDictionaryInArrayWithIdentifier(CFArrayRef array, const void* identifierKey, int identifier)
-{
- CFDictionaryRef dict = NULL;
-
- if (array) {
- int value = -1;
- CFIndex i;
- for (i = 0; i < CFArrayGetCount(array); i++) {
- CFDictionaryRef item = CFArrayGetValueAtIndex(array, i);
- CFNumberRef itemId = CFDictionaryGetValue(item, identifierKey);
- if (itemId) {
- CFNumberGetValue(itemId, kCFNumberIntType, &value);
- if (value == identifier) {
- dict = item;
- break;
- }
- }
- }
- }
- return dict;
-}
-
-CFDictionaryRef
-findDictionaryInArray(CFArrayRef array, const void* nameKey, const char* name, int nameLength)
-{
- CFDictionaryRef dict = NULL;
-
- if (array) {
- CFStringRef itemName;
- CFIndex i;
- itemName = CFStringCreateWithBytes(NULL, (UInt8 *) name, nameLength,
- kCFStringEncodingUTF8, false);
- for (i = 0; i < CFArrayGetCount(array); i++) {
- CFDictionaryRef item = CFArrayGetValueAtIndex(array, i);
- CFStringRef iName = CFDictionaryGetValue(item, nameKey);
- if (iName && !CFStringCompare(itemName, iName, kCFCompareCaseInsensitive)) {
- dict = item;
- break;
- }
- }
- CFRelease(itemName);
- }
- return dict;
-}
-
-CFNumberRef
-findSelectorByName(CFDictionaryRef feature, const char* name, int nameLength)
-{
- CFNumberRef selector = NULL;
- CFArrayRef selectors = CFDictionaryGetValue(feature, kCTFontFeatureTypeSelectorsKey);
- if (selectors) {
- CFDictionaryRef s = findDictionaryInArray(selectors, kCTFontFeatureSelectorNameKey, name, nameLength);
- if (s)
- selector = CFDictionaryGetValue(s, kCTFontFeatureSelectorIdentifierKey);
- }
- return selector;
-}
-
-static CFDictionaryRef
-createFeatureSettingDictionary(CFNumberRef featureTypeIdentifier, CFNumberRef featureSelectorIdentifier)
-{
- const void* settingKeys[] = { kCTFontFeatureTypeIdentifierKey, kCTFontFeatureSelectorIdentifierKey };
- const void* settingValues[] = { featureTypeIdentifier, featureSelectorIdentifier };
-
- return CFDictionaryCreate(kCFAllocatorDefault, settingKeys, settingValues, 2,
- &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-}
-
-const CFStringRef kXeTeXEmboldenAttributeName = CFSTR("XeTeXEmbolden");
-
-void*
-loadAATfont(CTFontDescriptorRef descriptor, integer scaled_size, const char* cp1)
-{
- CTFontRef font, actualFont;
- CGFloat ctSize;
- CFMutableDictionaryRef stringAttributes, attributes;
- CGAffineTransform matrix;
- CFMutableArrayRef cascadeList;
- CTFontDescriptorRef lastResort;
- double tracking = 0.0;
- float extend = 1.0;
- float slant = 0.0;
- float embolden = 0.0;
- float letterspace = 0.0;
- uint32_t rgbValue;
-
- // create a base font instance for applying further attributes
- ctSize = TeXtoPSPoints(Fix2D(scaled_size));
- font = CTFontCreateWithFontDescriptor(descriptor, ctSize, NULL);
- if (!font)
- return NULL;
-
- stringAttributes = CFDictionaryCreateMutable(NULL, 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- attributes = CFDictionaryCreateMutable(NULL, 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- if (cp1) {
- CFArrayRef features = CTFontCopyFeatures(font);
- CFMutableArrayRef featureSettings =
- CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
-
- // interpret features following ":"
- while (*cp1) {
- CFDictionaryRef feature;
- int ret;
- const char* cp2;
- const char* cp3;
- // locate beginning of name=value pair
- if (*cp1 == ':' || *cp1 == ';') // skip over separator
- ++cp1;
- while (*cp1 == ' ' || *cp1 == '\t') // skip leading whitespace
- ++cp1;
- if (*cp1 == 0) // break if end of string
- break;
-
- // scan to end of pair
- cp2 = cp1;
- while (*cp2 && (*cp2 != ';') && (*cp2 != ':'))
- ++cp2;
-
- // look for the '=' separator
- cp3 = cp1;
- while ((cp3 < cp2) && (*cp3 != '='))
- ++cp3;
- if (cp3 == cp2)
- goto bad_option;
-
- // now cp1 points to option name, cp3 to '=', cp2 to ';' or null
-
- // first try for a feature by this name
- feature = findDictionaryInArray(features, kCTFontFeatureTypeNameKey, cp1, cp3 - cp1);
- if (feature) {
- // look past the '=' separator for setting names
- int featLen = cp3 - cp1;
- int zeroInteger = 0;
- CFNumberRef zero = CFNumberCreate(NULL, kCFNumberIntType, &zeroInteger);
- ++cp3;
- while (cp3 < cp2) {
- CFNumberRef selector;
- int disable = 0;
- const char* cp4;
- // skip leading whitespace
- while (*cp3 == ' ' || *cp3 == '\t')
- ++cp3;
-
- // possibly multiple settings...
- if (*cp3 == '!') { // check for negation
- disable = 1;
- ++cp3;
- }
-
- // scan for end of setting name
- cp4 = cp3;
- while (cp4 < cp2 && *cp4 != ',')
- ++cp4;
-
- // now cp3 points to name, cp4 to ',' or ';' or null
- selector = findSelectorByName(feature, cp3, cp4 - cp3);
- if (selector && CFNumberCompare(selector, zero, NULL) >= 0) {
- CFNumberRef featureType = CFDictionaryGetValue(feature, kCTFontFeatureTypeIdentifierKey);
- CFDictionaryRef featureSetting = createFeatureSettingDictionary(featureType, selector);
- CFArrayAppendValue(featureSettings, featureSetting);
- CFRelease(featureSetting);
- } else {
- fontfeaturewarning(cp1, featLen, cp3, cp4 - cp3);
- }
-
- // point beyond setting name terminator
- cp3 = cp4 + 1;
- }
- CFRelease(zero);
-
- goto next_option;
- }
-
- // didn't find feature, try other options...
- ret = readCommonFeatures(cp1, cp2, &extend, &slant, &embolden, &letterspace, &rgbValue);
- if (ret == 1)
- goto next_option;
- else if (ret == -1)
- goto bad_option;
-
- if (strncmp(cp1, "tracking", 8) == 0) {
- CFNumberRef trackingNumber;
- cp3 = cp1 + 8;
- if (*cp3 != '=')
- goto bad_option;
- ++cp3;
- tracking = read_double(&cp3);
- trackingNumber = CFNumberCreate(NULL, kCFNumberDoubleType, &tracking);
- CFDictionaryAddValue(stringAttributes, kCTKernAttributeName, trackingNumber);
- CFRelease(trackingNumber);
- goto next_option;
- }
-
- bad_option:
- // not a name=value pair, or not recognized....
- // check for plain "vertical" before complaining
- if (strncmp(cp1, "vertical", 8) == 0) {
- cp3 = cp2;
- if (*cp3 == ';' || *cp3 == ':')
- --cp3;
- while (*cp3 == '\0' || *cp3 == ' ' || *cp3 == '\t')
- --cp3;
- if (*cp3)
- ++cp3;
- if (cp3 == cp1 + 8) {
- int orientation = kCTFontVerticalOrientation;
- CFNumberRef orientationNumber = CFNumberCreate(NULL, kCFNumberIntType, &orientation);
- CFDictionaryAddValue(attributes, kCTFontOrientationAttribute, orientationNumber);
- CFRelease(orientationNumber);
- CFDictionaryAddValue(stringAttributes, kCTVerticalFormsAttributeName, kCFBooleanTrue);
- goto next_option;
- }
- }
-
- fontfeaturewarning(cp1, cp2 - cp1, 0, 0);
-
- next_option:
- // go to next name=value pair
- cp1 = cp2;
- }
-
- if (features)
- CFRelease(features);
-
- if (CFArrayGetCount(featureSettings))
- CFDictionaryAddValue(attributes, kCTFontFeatureSettingsAttribute, featureSettings);
- CFRelease(featureSettings);
- }
-
- if ((loadedfontflags & FONT_FLAGS_COLORED) != 0) {
- CGFloat red = ((rgbValue & 0xFF000000) >> 24) / 255.0;
- CGFloat green = ((rgbValue & 0x00FF0000) >> 16) / 255.0;
- CGFloat blue = ((rgbValue & 0x0000FF00) >> 8 ) / 255.0;
- CGFloat alpha = ((rgbValue & 0x000000FF) ) / 255.0;
- CGColorRef color = CGColorCreateGenericRGB(red, green, blue, alpha);
- CFDictionaryAddValue(stringAttributes, kCTForegroundColorAttributeName, color);
- CGColorRelease(color);
- }
-
- matrix = CGAffineTransformIdentity;
- if (extend != 1.0 || slant != 0.0)
- matrix = CGAffineTransformMake(extend, 0, slant, 1.0, 0, 0);
-
- if (embolden != 0.0) {
- CFNumberRef emboldenNumber;
- embolden = embolden * Fix2D(scaled_size) / 100.0;
- emboldenNumber = CFNumberCreate(NULL, kCFNumberFloatType, &embolden);
- CFDictionaryAddValue(stringAttributes, kXeTeXEmboldenAttributeName, emboldenNumber);
- CFRelease(emboldenNumber);
- }
-
- if (letterspace != 0.0)
- loadedfontletterspace = (letterspace / 100.0) * scaled_size;
-
- // Disable Core Text font fallback (cascading) with only the last resort font
- // in the cascade list.
- cascadeList = CFArrayCreateMutable(NULL, 1, &kCFTypeArrayCallBacks);
- lastResort = CTFontDescriptorCreateWithNameAndSize(CFSTR("LastResort"), 0);
- CFArrayAppendValue(cascadeList, lastResort);
- CFRelease(lastResort);
- CFDictionaryAddValue(attributes, kCTFontCascadeListAttribute, cascadeList);
- CFRelease(cascadeList);
-
- descriptor = CTFontDescriptorCreateWithAttributes(attributes);
- CFRelease(attributes);
- actualFont = CTFontCreateCopyWithAttributes(font, ctSize, &matrix, descriptor);
- CFRelease(font);
- CFDictionaryAddValue(stringAttributes, kCTFontAttributeName, actualFont);
- CFRelease(actualFont);
-
- nativefonttypeflag = AAT_FONT_FLAG;
- return (void *) stringAttributes;
-}