diff options
Diffstat (limited to 'Build')
25 files changed, 1461 insertions, 1729 deletions
diff --git a/Build/source/texk/web2c/xetexdir/FontTableCache.cpp b/Build/source/texk/web2c/xetexdir/FontTableCache.cpp index d8d3ed54714..48b0520aed7 100644 --- a/Build/source/texk/web2c/xetexdir/FontTableCache.cpp +++ b/Build/source/texk/web2c/xetexdir/FontTableCache.cpp @@ -60,7 +60,7 @@ FontTableCache::FontTableCache() void FontTableCache::initialize() { - fTableCache = (FontTableCacheEntry *) malloc((fTableCacheSize) * sizeof(FontTableCacheEntry)); + fTableCache = (FontTableCacheEntry *) xmalloc((fTableCacheSize) * sizeof(FontTableCacheEntry)); if (fTableCache == NULL) { fTableCacheSize = 0; diff --git a/Build/source/texk/web2c/xetexdir/XeTeXFontInst.cpp b/Build/source/texk/web2c/xetexdir/XeTeXFontInst.cpp index 2013c442e2b..837640d1d48 100644 --- a/Build/source/texk/web2c/xetexdir/XeTeXFontInst.cpp +++ b/Build/source/texk/web2c/xetexdir/XeTeXFontInst.cpp @@ -43,10 +43,6 @@ authorization from the copyright holders. #include "XeTeXLayoutInterface.h" #include "XeTeXswap.h" -#ifdef XETEX_MAC -#include <Carbon/Carbon.h> -#endif - #include "XeTeX_ext.h" #include "sfnt.h" @@ -118,7 +114,7 @@ void XeTeXFontInst::initialize(int &status) postTable = (const POSTTable *) readFontTable(kPOST); if (postTable != NULL) { - fItalicAngle = Fix2D(SWAP(UInt32(postTable->italicAngle))); + fItalicAngle = Fix2D(SWAP(uint32_t(postTable->italicAngle))); deleteTable(postTable); } diff --git a/Build/source/texk/web2c/xetexdir/XeTeXFontInst.h b/Build/source/texk/web2c/xetexdir/XeTeXFontInst.h index 3c49bccc126..811c8d53bb2 100644 --- a/Build/source/texk/web2c/xetexdir/XeTeXFontInst.h +++ b/Build/source/texk/web2c/xetexdir/XeTeXFontInst.h @@ -52,10 +52,6 @@ authorization from the copyright holders. #include "XeTeXFontMgr.h" #include "XeTeX_ext.h" -extern "C" { - void *xmalloc(size_t); // from kpathsea -}; - // create specific subclasses for each supported platform class XeTeXFontInst : protected FontTableCache diff --git a/Build/source/texk/web2c/xetexdir/XeTeXFontInst_Mac.cpp b/Build/source/texk/web2c/xetexdir/XeTeXFontInst_Mac.cpp index 5a4c26e15d9..741ab5be0f3 100644 --- a/Build/source/texk/web2c/xetexdir/XeTeXFontInst_Mac.cpp +++ b/Build/source/texk/web2c/xetexdir/XeTeXFontInst_Mac.cpp @@ -2,6 +2,8 @@ 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, 2013 by Khaled Hosny SIL Author(s): Jonathan Kew @@ -41,10 +43,10 @@ authorization from the copyright holders. #include "XeTeXFontInst_Mac.h" #include "XeTeX_ext.h" -XeTeXFontInst_Mac::XeTeXFontInst_Mac(ATSFontRef atsFont, float pointSize, int &status) +XeTeXFontInst_Mac::XeTeXFontInst_Mac(CTFontDescriptorRef descriptor, float pointSize, int &status) : XeTeXFontInst(pointSize, status) - , fFontRef(atsFont) - , fStyle(0) + , fDescriptor(descriptor) + , fFontRef(0) , fFirstCharCode(-1) , fLastCharCode(-1) { @@ -57,26 +59,36 @@ XeTeXFontInst_Mac::XeTeXFontInst_Mac(ATSFontRef atsFont, float pointSize, int &s XeTeXFontInst_Mac::~XeTeXFontInst_Mac() { - if (fStyle != 0) - ATSUDisposeStyle(fStyle); + if (fDescriptor != 0) + CFRelease(fDescriptor); + if (fFontRef != 0) + CFRelease(fFontRef); } -static hb_bool_t _get_glyph(hb_font_t* hbFont, void* fontData, hb_codepoint_t unicode, hb_codepoint_t variationSelector, hb_codepoint_t* glyph, void* userData) +static hb_bool_t _get_glyph(hb_font_t*, void* font, hb_codepoint_t ch, hb_codepoint_t vs, hb_codepoint_t* glyph, void*) { - *glyph = MapCharToGlyph_AAT((ATSUStyle) fontData, unicode); + *glyph = mapCharToGlyphFromCTFont((CTFontRef) font, ch, vs); return !!glyph; } -static hb_position_t _get_glyph_h_advance(hb_font_t* hbFont, void* fontData, hb_codepoint_t glyph, void* userData) +static hb_position_t _get_glyph_h_advance(hb_font_t*, void* font, hb_codepoint_t glyph, void*) { - float width = GetGlyphWidth_AAT((ATSUStyle) fontData, glyph); - return width * 64; + CGGlyph cgGlyph = glyph; + float advance = CTFontGetAdvancesForGlyphs((CTFontRef) font, kCTFontHorizontalOrientation, &cgGlyph, 0, 1); + return advance * 64; } -static hb_bool_t _get_glyph_extents(hb_font_t* hbFont, void* fontData, hb_codepoint_t glyph, hb_glyph_extents_t* extents, void* userData) +static hb_position_t _get_glyph_v_advance(hb_font_t*, void* font, hb_codepoint_t glyph, void*) +{ + CGGlyph cgGlyph = glyph; + float advance = CTFontGetAdvancesForGlyphs((CTFontRef) font, kCTFontVerticalOrientation, &cgGlyph, 0, 1); + return advance * 64; +} + +static hb_bool_t _get_glyph_extents(hb_font_t*, void* font, hb_codepoint_t glyph, hb_glyph_extents_t* extents, void*) { GlyphBBox bbox; - GetGlyphBBox_AAT((ATSUStyle) fontData, glyph, &bbox); + getGlyphBBoxFromCTFont((CTFontRef) font, glyph, &bbox); extents->x_bearing = bbox.xMin; extents->y_bearing = bbox.yMax; extents->width = bbox.xMax - bbox.xMin; @@ -91,13 +103,14 @@ static hb_font_funcs_t* _get_font_funcs() _font_funcs = hb_font_funcs_create(); hb_font_funcs_set_glyph_func(_font_funcs, _get_glyph, 0, 0); hb_font_funcs_set_glyph_h_advance_func(_font_funcs, _get_glyph_h_advance, 0, 0); + hb_font_funcs_set_glyph_v_advance_func(_font_funcs, _get_glyph_v_advance, 0, 0); hb_font_funcs_set_glyph_extents_func(_font_funcs, _get_glyph_extents, 0, 0); hb_font_funcs_make_immutable(_font_funcs); return _font_funcs; } -static hb_blob_t* _get_font_table(hb_face_t* face, hb_tag_t tag, void* userData) +static hb_blob_t* _get_font_table(hb_face_t*, hb_tag_t tag, void* userData) { XeTeXFontInst* font = (XeTeXFontInst*) userData; uint32_t length; @@ -109,70 +122,72 @@ static hb_blob_t* _get_font_table(hb_face_t* face, hb_tag_t tag, void* userData) void XeTeXFontInst_Mac::initialize(int &status) { - if (fFontRef == 0) { + if (fDescriptor == 0) { status = 1; return; } - XeTeXFontInst::initialize(status); - if (status != 0) - fFontRef = 0; - - if (ATSUCreateStyle(&fStyle) == noErr) { - ATSUFontID font = FMGetFontFromATSFontRef(fFontRef); - Fixed size = D2Fix(fPointSize * 72.0 / 72.27); /* convert TeX to Quartz points */ - ATSStyleRenderingOptions options = kATSStyleNoHinting; - ATSUAttributeTag tags[3] = { kATSUFontTag, kATSUSizeTag, kATSUStyleRenderingOptionsTag }; - ByteCount valueSizes[3] = { sizeof(ATSUFontID), sizeof(Fixed), sizeof(ATSStyleRenderingOptions) }; - ATSUAttributeValuePtr values[3] = { &font, &size, &options }; - ATSUSetAttributes(fStyle, 3, tags, valueSizes, values); + fDescriptor = 0; + + // Create a copy of original font descriptor with font cascading (fallback) disabled + CFArrayRef emptyCascadeList = CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks); + const void* values[] = { emptyCascadeList }; + static const void* attributeKeys[] = { kCTFontCascadeListAttribute }; + CFDictionaryRef attributes = CFDictionaryCreate(NULL, attributeKeys, values, 1, + &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFRelease(emptyCascadeList); + + fDescriptor = CTFontDescriptorCreateCopyWithAttributes(fDescriptor, attributes); + CFRelease(attributes); + fFontRef = CTFontCreateWithFontDescriptor(fDescriptor, fPointSize * 72.0 / 72.27, NULL); + if (fFontRef) { + fFilename = getFileNameFromCTFont(fFontRef); /* for HarfBuzz */ hb_face_t* lFace = hb_face_create_for_tables(_get_font_table, this, 0); hb_face_set_upem (lFace, fUnitsPerEM); hbFont = hb_font_create(lFace); - hb_font_set_funcs(hbFont, _get_font_funcs(), fStyle, 0); + hb_font_set_funcs(hbFont, _get_font_funcs(), (void*) fFontRef, 0); hb_font_set_scale(hbFont, fPointSize, fPointSize); hb_font_set_ppem(hbFont, fPointSize, fPointSize); - } - else { + } else { status = 1; - fFontRef = 0; + CFRelease(fDescriptor); + fDescriptor = 0; } - return; + XeTeXFontInst::initialize(status); } const void *XeTeXFontInst_Mac::readTable(OTTag tag, uint32_t *length) const { - OSStatus status = ATSFontGetTable(fFontRef, tag, 0, 0, 0, (ByteCount*)length); - if (status != noErr) { + if (!fFontRef) { *length = 0; return NULL; } - void* table = xmalloc(*length * sizeof(char)); - if (table != NULL) { - status = ATSFontGetTable(fFontRef, tag, 0, *length, table, (ByteCount*)length); - if (status != noErr) { - *length = 0; - free((void*) table); - return NULL; - } + CFDataRef tableData = CTFontCopyTable(fFontRef, tag, 0); + if (!tableData) { + *length = 0; + return NULL; } + *length = CFDataGetLength(tableData); + UInt8* table = (UInt8*) xmalloc(*length * sizeof(UInt8)); + if (table != NULL) + CFDataGetBytes(tableData, CFRangeMake(0, *length), table); - return table; + return table; } void XeTeXFontInst_Mac::getGlyphBounds(GlyphID gid, GlyphBBox* bbox) { - GetGlyphBBox_AAT(fStyle, gid, bbox); + getGlyphBBoxFromCTFont(fFontRef, gid, bbox); } GlyphID XeTeXFontInst_Mac::mapCharToGlyph(UChar32 ch) const { - return MapCharToGlyph_AAT(fStyle, ch); + return mapCharToGlyphFromCTFont(fFontRef, ch, 0); } GlyphID @@ -181,7 +196,7 @@ XeTeXFontInst_Mac::mapGlyphToIndex(const char* glyphName) const GlyphID rval = XeTeXFontInst::mapGlyphToIndex(glyphName); if (rval) return rval; - return GetGlyphIDFromCGFont(fFontRef, glyphName); + return GetGlyphIDFromCTFont(fFontRef, glyphName); } const char* @@ -190,7 +205,7 @@ XeTeXFontInst_Mac::getGlyphName(GlyphID gid, int& nameLen) const char* rval = XeTeXFontInst::getGlyphName(gid, nameLen); if (rval) return rval; - return GetGlyphNameFromCGFont(fFontRef, gid, &nameLen); + return GetGlyphNameFromCTFont(fFontRef, gid, &nameLen); } UChar32 diff --git a/Build/source/texk/web2c/xetexdir/XeTeXFontInst_Mac.h b/Build/source/texk/web2c/xetexdir/XeTeXFontInst_Mac.h index e3ab7bce439..f0c41ac4ac5 100644 --- a/Build/source/texk/web2c/xetexdir/XeTeXFontInst_Mac.h +++ b/Build/source/texk/web2c/xetexdir/XeTeXFontInst_Mac.h @@ -2,6 +2,7 @@ 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 SIL Author(s): Jonathan Kew @@ -50,14 +51,14 @@ class XeTeXFontInst_Mac : public XeTeXFontInst protected: const void *readTable(OTTag tag, uint32_t *length) const; - ATSFontRef fFontRef; - ATSUStyle fStyle; + CTFontDescriptorRef fDescriptor; + CTFontRef fFontRef; int fFirstCharCode; int fLastCharCode; public: - XeTeXFontInst_Mac(ATSFontRef atsFont, float pointSize, int &status); + XeTeXFontInst_Mac(CTFontDescriptorRef descriptor, float pointSize, int &status); virtual ~XeTeXFontInst_Mac(); diff --git a/Build/source/texk/web2c/xetexdir/XeTeXFontMgr.cpp b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr.cpp index 3521a6b9b35..f07de6aedc3 100644 --- a/Build/source/texk/web2c/xetexdir/XeTeXFontMgr.cpp +++ b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr.cpp @@ -519,7 +519,7 @@ XeTeXFontMgr::getOpSizeRecAndStyleFlags(Font* theFont) if (os2Table != NULL) { theFont->weight = SWAP(os2Table->usWeightClass); theFont->width = SWAP(os2Table->usWidthClass); - UInt16 sel = SWAP(os2Table->fsSelection); + uint16_t sel = SWAP(os2Table->fsSelection); theFont->isReg = (sel & (1 << 6)) != 0; theFont->isBold = (sel & (1 << 5)) != 0; theFont->isItalic = (sel & (1 << 0)) != 0; @@ -527,7 +527,7 @@ XeTeXFontMgr::getOpSizeRecAndStyleFlags(Font* theFont) const HEADTable* headTable = (const HEADTable*)getFontTablePtr(font, kHEAD); if (headTable != NULL) { - UInt16 ms = SWAP(headTable->macStyle); + uint16_t ms = SWAP(headTable->macStyle); if ((ms & (1 << 0)) != 0) theFont->isBold = true; if ((ms & (1 << 1)) != 0) @@ -536,7 +536,7 @@ XeTeXFontMgr::getOpSizeRecAndStyleFlags(Font* theFont) const POSTTable* postTable = (const POSTTable*)getFontTablePtr(font, kPOST); if (postTable != NULL) { - theFont->slant = (int)(1000 * (tan(Fix2D(-SWAP(UInt32(postTable->italicAngle))) * M_PI / 180.0))); + theFont->slant = (int)(1000 * (tan(Fix2D(-SWAP(uint32_t(postTable->italicAngle))) * M_PI / 180.0))); } deleteFont(font); } diff --git a/Build/source/texk/web2c/xetexdir/XeTeXFontMgr.h b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr.h index 358d540ad0b..941e30d4d4e 100644 --- a/Build/source/texk/web2c/xetexdir/XeTeXFontMgr.h +++ b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr.h @@ -2,6 +2,7 @@ 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 SIL Author(s): Jonathan Kew @@ -34,8 +35,8 @@ authorization from the copyright holders. #define __XETEX_FONT_MANAGER_H #ifdef XETEX_MAC -#include <Carbon/Carbon.h> -typedef ATSFontRef PlatformFontRef; +#include <ApplicationServices/ApplicationServices.h> +typedef CTFontDescriptorRef PlatformFontRef; #else #include <fontconfig/fontconfig.h> #include <ft2build.h> @@ -140,9 +141,9 @@ protected: Family* parent; PlatformFontRef fontRef; OpSizeRec opSizeInfo; - UInt16 weight; - UInt16 width; - SInt16 slant; + uint16_t weight; + uint16_t width; + int16_t slant; bool isReg; bool isBold; bool isItalic; @@ -163,12 +164,12 @@ protected: } std::map<std::string,Font*>* styles; - UInt16 minWeight; - UInt16 maxWeight; - UInt16 minWidth; - UInt16 maxWidth; - SInt16 minSlant; - SInt16 maxSlant; + uint16_t minWeight; + uint16_t maxWeight; + uint16_t minWidth; + uint16_t maxWidth; + int16_t minSlant; + int16_t maxSlant; }; class NameCollection { @@ -197,11 +198,7 @@ protected: virtual void getOpSizeRecAndStyleFlags(Font* theFont); virtual void searchForHostPlatformFonts(const std::string& name) = 0; -#ifdef XETEX_MAC - virtual NameCollection* readNames(ATSUFontID fontID) = 0; -#else virtual NameCollection* readNames(PlatformFontRef fontRef) = 0; -#endif void die(const char*s, int i) const; /* for fatal internal errors! */ }; diff --git a/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.h b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.h index 7adbe97a4ee..fe19cef7c97 100644 --- a/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.h +++ b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.h @@ -2,6 +2,7 @@ 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 SIL Author(s): Jonathan Kew @@ -53,16 +54,20 @@ protected: virtual void searchForHostPlatformFonts(const std::string& name); - virtual NameCollection* readNames(ATSUFontID fontID); + virtual NameCollection* readNames(CTFontDescriptorRef fontRef); virtual std::string getPlatformFontDesc(PlatformFontRef font) const; private: void addFontsToCaches(CFArrayRef fonts); - void addFamilyToCaches(ATSFontFamilyRef familyRef); + void addFamilyToCaches(CTFontDescriptorRef familyRef); - void addFontAndSiblingsToCaches(ATSFontRef fontRef); + void addFontAndSiblingsToCaches(CTFontDescriptorRef fontRef); + + void appendNameToList(CTFontRef font, + std::list<std::string>* nameList, + CFStringRef nameKey); }; #endif /* __XETEX_FONT_MGR_MAC_H */ diff --git a/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.mm b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.mm index bcc122adf01..a1b997c0573 100644 --- a/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.mm +++ b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.mm @@ -2,6 +2,7 @@ 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 SIL Author(s): Jonathan Kew @@ -36,133 +37,70 @@ authorization from the copyright holders. #include <Cocoa/Cocoa.h> -XeTeXFontMgr::NameCollection* -XeTeXFontMgr_Mac::readNames(ATSFontRef fontRef) +CTFontDescriptorRef findFontWithName(CFStringRef name, CFStringRef key) { - const int BUFUNIT = 256; - static int bufSize = BUFUNIT; - static char* buffer = new char[bufSize]; + CFStringRef keys[] = { key }; + CFTypeRef values[] = { name }; + CFDictionaryRef attributes = CFDictionaryCreate(NULL, (const void **) &keys, (const void **) &values, 1, + &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CTFontDescriptorRef descriptor = CTFontDescriptorCreateWithAttributes(attributes); + CFRelease(attributes); + + CFSetRef mandatoryAttributes = CFSetCreate(NULL, (const void **) &keys, 1, &kCFTypeSetCallBacks); + CFArrayRef matches = CTFontDescriptorCreateMatchingFontDescriptors(descriptor, mandatoryAttributes); + CFRelease(mandatoryAttributes); + CFRelease(descriptor); + + CTFontDescriptorRef matched = NULL; + if (matches) { + if (CFArrayGetCount(matches)) { + matched = (CTFontDescriptorRef) CFArrayGetValueAtIndex(matches, 0); + CFRetain(matched); + } + CFRelease(matches); + } + return matched; +} + +void +XeTeXFontMgr_Mac::appendNameToList(CTFontRef font, + std::list<std::string>* nameList, + CFStringRef nameKey) +{ + CFStringRef name = CTFontCopyName(font, nameKey); + if (name) { + appendToList(nameList, [(NSString *) name UTF8String]); + CFRelease(name); + } + CFStringRef language; + name = CTFontCopyLocalizedName(font, nameKey, &language); + if (name) { + appendToList(nameList, [(NSString *) name UTF8String]); + CFRelease(name); + } +} +XeTeXFontMgr::NameCollection* +XeTeXFontMgr_Mac::readNames(CTFontDescriptorRef fontRef) +{ NameCollection* names = new NameCollection; - CFStringRef psName; - OSStatus status = ATSFontGetPostScriptName(fontRef, kATSOptionFlagsDefault, &psName); - if (status != noErr) + CFStringRef psName = (CFStringRef) CTFontDescriptorCopyAttribute(fontRef, kCTFontNameAttribute); + if (!psName) return names; - - // extract UTF-8 form of name - CFIndex length = CFStringGetLength(psName); // in 16-bit character units - if (length > 0) { - length = length * 6 + 1; - if (length >= bufSize) { - delete[] buffer; - bufSize = ((length / BUFUNIT) + 1) * BUFUNIT; - buffer = new char[bufSize]; - } - if (CFStringGetCString(psName, buffer, bufSize, kCFStringEncodingUTF8)) - names->psName = buffer; - } + + NSAutoreleasePool *pool = [NSAutoreleasePool new]; + + names->psName = [(NSString *) psName UTF8String]; CFRelease(psName); - ATSUFontID fontID = FMGetFontFromATSFontRef(fontRef); - - ItemCount nameCount; - status = ATSUCountFontNames(fontID, &nameCount); - if (status != noErr) - die("ATSUCountFontNames failed, status=%d", status); - - std::list<std::string> familyNames; - std::list<std::string> subFamilyNames; - - for (int n = 0; n < nameCount; ++n) { - ByteCount nameLength; - FontNameCode nameCode; - FontPlatformCode namePlatform; - FontScriptCode nameScript; - FontLanguageCode nameLang; - status = ATSUGetIndFontName(fontID, n, 0, 0, &nameLength, - &nameCode, &namePlatform, &nameScript, &nameLang); - if (status != noErr && status != kATSUNoFontNameErr) - die("ATSUGetIndFontName failed, status=%d", status); - if (status == noErr && nameLength > 0) { - switch (nameCode) { - case kFontFullName: - case kFontFamilyName: - case kFontStyleName: - case 16: // preferred family -- use instead of family, if present - case 17: // preferred subfamily -- use instead of style, if present - { - bool preferredName = false; - TextEncoding encoding; - CFStringRef nameStr = 0; - if (nameLength >= bufSize) { - delete[] buffer; - bufSize = ((nameLength / BUFUNIT) + 1) * BUFUNIT; - buffer = new char[bufSize]; - } - status = ATSUGetIndFontName(fontID, n, bufSize, buffer, &nameLength, - &nameCode, &namePlatform, &nameScript, &nameLang); - if (namePlatform == kFontMacintoshPlatform) { - GetTextEncodingFromScriptInfo(nameScript, nameLang, 0, &encoding); - nameStr = CFStringCreateWithBytes(0, (UInt8*)buffer, nameLength, encoding, false); - if (nameScript == kFontRomanScript && nameLang == kFontEnglishLanguage) - preferredName = true; - } - else if ((namePlatform == kFontUnicodePlatform) || (namePlatform == kFontMicrosoftPlatform)) - nameStr = CFStringCreateWithCharacters(0, (UniChar*)buffer, nameLength / 2); - if (nameStr != 0) { - std::list<std::string>* nameList = NULL; - switch (nameCode) { - case kFontFullName: - nameList = &names->fullNames; - break; - case kFontFamilyName: - nameList = &names->familyNames; - break; - case kFontStyleName: - nameList = &names->styleNames; - break; - case 16: - nameList = &familyNames; - break; - case 17: - nameList = &subFamilyNames; - break; - } - - // extract UTF-8 form of name - length = CFStringGetLength(nameStr); // in 16-bit character units - if (length > 0) { - length = length * 6 + 1; - if (length >= bufSize) { - delete[] buffer; - bufSize = ((length / BUFUNIT) + 1) * BUFUNIT; - buffer = new char[bufSize]; - } - if (CFStringGetCString(nameStr, buffer, bufSize, kCFStringEncodingUTF8)) { - if (buffer[0] != 0) { - if (nameList != NULL) { - if (preferredName) - prependToList(nameList, buffer); - else - appendToList(nameList, buffer); - } - } - } - } - - CFRelease(nameStr); - } - } - break; - } - } - } + CTFontRef font = CTFontCreateWithFontDescriptor(fontRef, 0.0, 0); + appendNameToList(font, &names->fullNames, kCTFontFullNameKey); + appendNameToList(font, &names->familyNames, kCTFontFamilyNameKey); + appendNameToList(font, &names->styleNames, kCTFontStyleNameKey); + CFRelease(font); - if (familyNames.size() > 0) - names->familyNames = familyNames; - if (subFamilyNames.size() > 0) - names->styleNames = subFamilyNames; + [pool release]; return names; } @@ -172,7 +110,7 @@ XeTeXFontMgr_Mac::addFontsToCaches(CFArrayRef fonts) { NSEnumerator* enumerator = [(NSArray*)fonts objectEnumerator]; while (id aFont = [enumerator nextObject]) { - ATSFontRef fontRef = ATSFontFindFromPostScriptName((CFStringRef)[aFont objectAtIndex: 0], kATSOptionFlagsDefault); + CTFontDescriptorRef fontRef = findFontWithName((CFStringRef)[aFont objectAtIndex: 0], kCTFontNameAttribute); NameCollection* names = readNames(fontRef); addToMaps(fontRef, names); delete names; @@ -180,11 +118,10 @@ XeTeXFontMgr_Mac::addFontsToCaches(CFArrayRef fonts) } void -XeTeXFontMgr_Mac::addFamilyToCaches(ATSFontFamilyRef familyRef) +XeTeXFontMgr_Mac::addFamilyToCaches(CTFontDescriptorRef familyRef) { - CFStringRef nameStr; - OSStatus status = ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &nameStr); - if (status == noErr) { + CFStringRef nameStr = (CFStringRef) CTFontDescriptorCopyAttribute(familyRef, kCTFontFamilyNameAttribute); + if (nameStr) { NSArray* members = [[NSFontManager sharedFontManager] availableMembersOfFontFamily: (NSString*)nameStr]; CFRelease(nameStr); @@ -193,11 +130,10 @@ XeTeXFontMgr_Mac::addFamilyToCaches(ATSFontFamilyRef familyRef) } void -XeTeXFontMgr_Mac::addFontAndSiblingsToCaches(ATSFontRef fontRef) +XeTeXFontMgr_Mac::addFontAndSiblingsToCaches(CTFontDescriptorRef fontRef) { - CFStringRef name; - OSStatus status = ATSFontGetPostScriptName(fontRef, kATSOptionFlagsDefault, &name); - if (status == noErr) { + CFStringRef name = (CFStringRef) CTFontDescriptorCopyAttribute(fontRef, kCTFontNameAttribute); + if (name) { NSFont* font = [NSFont fontWithName:(NSString*)name size:10.0]; CFRelease(name); NSArray* members = [[NSFontManager sharedFontManager] @@ -217,10 +153,11 @@ XeTeXFontMgr_Mac::searchForHostPlatformFonts(const std::string& name) // ...so we need to try it as each of these CFStringRef nameStr = CFStringCreateWithCString(kCFAllocatorDefault, name.c_str(), kCFStringEncodingUTF8); - ATSFontRef fontRef = ATSFontFindFromName(nameStr, kATSOptionFlagsDefault); - if (fontRef != kATSFontRefUnspecified) { + CTFontDescriptorRef matched = findFontWithName(nameStr, kCTFontDisplayNameAttribute); + if (matched) { // found it, so locate the family, and add all members to the caches - addFontAndSiblingsToCaches(fontRef); + addFontAndSiblingsToCaches(matched); + CFRelease(matched); return; } @@ -236,16 +173,18 @@ XeTeXFontMgr_Mac::searchForHostPlatformFonts(const std::string& name) return; } - ATSFontFamilyRef familyRef = ATSFontFamilyFindFromName(familyStr, kATSOptionFlagsDefault); - if (familyRef != 0xffffffff) { - addFamilyToCaches(familyRef); + matched = findFontWithName(familyStr, kCTFontFamilyNameAttribute); + if (matched) { + addFamilyToCaches(matched); + CFRelease(matched); return; } } - fontRef = ATSFontFindFromPostScriptName(nameStr, kATSOptionFlagsDefault); - if (fontRef != kATSFontRefUnspecified) { - addFontAndSiblingsToCaches(fontRef); + matched = findFontWithName(nameStr, kCTFontNameAttribute); + if (matched) { + addFontAndSiblingsToCaches(matched); + CFRelease(matched); return; } @@ -256,9 +195,10 @@ XeTeXFontMgr_Mac::searchForHostPlatformFonts(const std::string& name) return; } - ATSFontFamilyRef familyRef = ATSFontFamilyFindFromName(nameStr, kATSOptionFlagsDefault); - if (familyRef != 0xffffffff) { - addFamilyToCaches(familyRef); + matched = findFontWithName(nameStr, kCTFontFamilyNameAttribute); + if (matched) { + addFamilyToCaches(matched); + CFRelease(matched); return; } } @@ -280,18 +220,20 @@ XeTeXFontMgr_Mac::terminate() } std::string -XeTeXFontMgr_Mac::getPlatformFontDesc(PlatformFontRef font) const +XeTeXFontMgr_Mac::getPlatformFontDesc(PlatformFontRef descriptor) const { - FSSpec fileSpec; std::string path; - if (ATSFontGetFileSpecification(font, &fileSpec) == noErr) { - FSRef fileRef; - if (FSpMakeFSRef(&fileSpec, &fileRef) == noErr) { + CTFontRef ctFont = CTFontCreateWithFontDescriptor(descriptor, 0.0, 0); + if (ctFont) { + CFURLRef url = (CFURLRef) CTFontCopyAttribute(ctFont, kCTFontURLAttribute); + if (url) { UInt8 posixPath[PATH_MAX]; - if (FSRefMakePath(&fileRef, posixPath, PATH_MAX) == noErr) { + if (CFURLGetFileSystemRepresentation(url, true, posixPath, PATH_MAX)) { path = (char*)posixPath; } + CFRelease(url); } + CFRelease(ctFont); } if (path.length() == 0) path = "[unknown]"; diff --git a/Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.cpp b/Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.cpp index dd0509c29a4..4920d321d9b 100644 --- a/Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.cpp +++ b/Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.cpp @@ -54,7 +54,7 @@ struct XeTeXLayoutEngine_rec char** ShaperList; // the requested shapers char* shaper; // the actually used shaper int nFeatures; - UInt32 rgbValue; + uint32_t rgbValue; float extend; float slant; float embolden; @@ -68,13 +68,13 @@ struct XeTeXLayoutEngine_rec // key is combined value representing (font_id << 16) + glyph // value is glyph bounding box in TeX points -static std::map<UInt32,GlyphBBox> sGlyphBoxes; +static std::map<uint32_t,GlyphBBox> sGlyphBoxes; int -getCachedGlyphBBox(UInt16 fontID, UInt16 glyphID, GlyphBBox* bbox) +getCachedGlyphBBox(uint16_t fontID, uint16_t glyphID, GlyphBBox* bbox) { - UInt32 key = ((UInt32)fontID << 16) + glyphID; - std::map<UInt32,GlyphBBox>::const_iterator i = sGlyphBoxes.find(key); + uint32_t key = ((uint32_t)fontID << 16) + glyphID; + std::map<uint32_t,GlyphBBox>::const_iterator i = sGlyphBoxes.find(key); if (i == sGlyphBoxes.end()) { return 0; } @@ -83,9 +83,9 @@ getCachedGlyphBBox(UInt16 fontID, UInt16 glyphID, GlyphBBox* bbox) } void -cacheGlyphBBox(UInt16 fontID, UInt16 glyphID, const GlyphBBox* bbox) +cacheGlyphBBox(uint16_t fontID, uint16_t glyphID, const GlyphBBox* bbox) { - UInt32 key = ((UInt32)fontID << 16) + glyphID; + uint32_t key = ((uint32_t)fontID << 16) + glyphID; sGlyphBoxes[key] = *bbox; } /*******************************************************************/ @@ -99,7 +99,7 @@ XeTeXFont createFont(PlatformFontRef fontRef, Fixed pointSize) { int status = 0; #ifdef XETEX_MAC - XeTeXFontInst* font = new XeTeXFontInst_Mac((ATSFontRef)fontRef, Fix2D(pointSize), status); + XeTeXFontInst* font = new XeTeXFontInst_Mac(fontRef, Fix2D(pointSize), status); #else FcChar8* pathname = 0; FcPatternGetString(fontRef, FC_FILE, 0, &pathname); @@ -175,7 +175,7 @@ void deleteFont(XeTeXFont font) delete (XeTeXFontInst*)font; } -void* getFontTablePtr(XeTeXFont font, UInt32 tableTag) +void* getFontTablePtr(XeTeXFont font, uint32_t tableTag) { return const_cast<void*>(((XeTeXFontInst*)font)->getFontTable(tableTag)); } @@ -186,7 +186,7 @@ Fixed getSlant(XeTeXFont font) return D2Fix(tan(-italAngle * M_PI / 180.0)); } -static UInt32 +static uint32_t getLargerScriptListTable(XeTeXFont font, hb_tag_t** scriptList, hb_tag_t* tableTag) { hb_face_t* face = hb_font_get_face(((XeTeXFontInst*)font)->hbFont); @@ -217,16 +217,16 @@ getLargerScriptListTable(XeTeXFont font, hb_tag_t** scriptList, hb_tag_t* tableT } } -UInt32 countScripts(XeTeXFont font) +uint32_t countScripts(XeTeXFont font) { return getLargerScriptListTable(font, NULL, NULL); } -UInt32 getIndScript(XeTeXFont font, UInt32 index) +uint32_t getIndScript(XeTeXFont font, uint32_t index) { hb_tag_t* scriptList; - UInt32 scriptCount = getLargerScriptListTable(font, &scriptList, NULL); + uint32_t scriptCount = getLargerScriptListTable(font, &scriptList, NULL); if (scriptList == NULL) return 0; @@ -236,13 +236,13 @@ UInt32 getIndScript(XeTeXFont font, UInt32 index) return 0; } -UInt32 countScriptLanguages(XeTeXFont font, UInt32 script) +uint32_t countScriptLanguages(XeTeXFont font, uint32_t script) { hb_face_t* face = hb_font_get_face(((XeTeXFontInst*)font)->hbFont); hb_tag_t* scriptList; hb_tag_t tableTag; - UInt32 scriptCount = getLargerScriptListTable(font, &scriptList, &tableTag); + uint32_t scriptCount = getLargerScriptListTable(font, &scriptList, &tableTag); if (scriptList == NULL) return 0; @@ -254,13 +254,13 @@ UInt32 countScriptLanguages(XeTeXFont font, UInt32 script) return 0; } -UInt32 getIndScriptLanguage(XeTeXFont font, UInt32 script, UInt32 index) +uint32_t getIndScriptLanguage(XeTeXFont font, uint32_t script, uint32_t index) { hb_face_t* face = hb_font_get_face(((XeTeXFontInst*)font)->hbFont); hb_tag_t* scriptList; hb_tag_t tableTag; - UInt32 scriptCount = getLargerScriptListTable(font, &scriptList, &tableTag); + uint32_t scriptCount = getLargerScriptListTable(font, &scriptList, &tableTag); if (scriptList == NULL) return 0; @@ -279,10 +279,10 @@ UInt32 getIndScriptLanguage(XeTeXFont font, UInt32 script, UInt32 index) return 0; } -UInt32 countFeatures(XeTeXFont font, UInt32 script, UInt32 language) +uint32_t countFeatures(XeTeXFont font, uint32_t script, uint32_t language) { hb_face_t* face = hb_font_get_face(((XeTeXFontInst*)font)->hbFont); - UInt32 total = 0; + uint32_t total = 0; for (int i = 0; i < 2; ++i) { uint32_t scriptIndex, langIndex = 0; @@ -297,7 +297,7 @@ UInt32 countFeatures(XeTeXFont font, UInt32 script, UInt32 language) return total; } -UInt32 getIndFeature(XeTeXFont font, UInt32 script, UInt32 language, UInt32 index) +uint32_t getIndFeature(XeTeXFont font, uint32_t script, uint32_t language, uint32_t index) { hb_face_t* face = hb_font_get_face(((XeTeXFontInst*)font)->hbFont); @@ -321,7 +321,7 @@ UInt32 getIndFeature(XeTeXFont font, UInt32 script, UInt32 language, UInt32 inde return 0; } -UInt32 countGraphiteFeatures(XeTeXLayoutEngine engine) +uint32_t countGraphiteFeatures(XeTeXLayoutEngine engine) { uint32_t rval = 0; @@ -334,7 +334,7 @@ UInt32 countGraphiteFeatures(XeTeXLayoutEngine engine) return rval; } -UInt32 getGraphiteFeatureCode(XeTeXLayoutEngine engine, UInt32 index) +uint32_t getGraphiteFeatureCode(XeTeXLayoutEngine engine, uint32_t index) { uint32_t rval = 0; @@ -349,7 +349,7 @@ UInt32 getGraphiteFeatureCode(XeTeXLayoutEngine engine, UInt32 index) return rval; } -UInt32 countGraphiteFeatureSettings(XeTeXLayoutEngine engine, UInt32 featureID) +uint32_t countGraphiteFeatureSettings(XeTeXLayoutEngine engine, uint32_t featureID) { uint32_t rval = 0; @@ -364,7 +364,7 @@ UInt32 countGraphiteFeatureSettings(XeTeXLayoutEngine engine, UInt32 featureID) return rval; } -UInt32 getGraphiteFeatureSettingCode(XeTeXLayoutEngine engine, UInt32 featureID, UInt32 index) +uint32_t getGraphiteFeatureSettingCode(XeTeXLayoutEngine engine, uint32_t featureID, uint32_t index) { uint32_t rval = 0; @@ -379,10 +379,9 @@ UInt32 getGraphiteFeatureSettingCode(XeTeXLayoutEngine engine, UInt32 featureID, return rval; } -void getGraphiteFeatureLabel(XeTeXLayoutEngine engine, UInt32 featureID, char* buf) +char * +getGraphiteFeatureLabel(XeTeXLayoutEngine engine, uint32_t featureID) { - buf[0] = '\0'; - hb_face_t* hbFace = hb_font_get_face(engine->font->hbFont); gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace); @@ -391,21 +390,15 @@ void getGraphiteFeatureLabel(XeTeXLayoutEngine engine, UInt32 featureID, char* b uint32_t len = 0; uint16_t langID = 0x409; - buf = (char*) gr_fref_label(feature, &langID, gr_utf8, &len); - - if (len > 128 + 1) { // 128 is set in XeTeX_ext.c - buf = (char*) realloc(buf, len + 1); - buf = (char*) gr_fref_label(feature, &langID, gr_utf8, &len); - } - - buf[len + 1] = '\0'; + return (char *) gr_fref_label(feature, &langID, gr_utf8, &len); } + + return NULL; } -void getGraphiteFeatureSettingLabel(XeTeXLayoutEngine engine, UInt32 featureID, UInt32 settingID, char* buf) +char * +getGraphiteFeatureSettingLabel(XeTeXLayoutEngine engine, uint32_t featureID, uint32_t settingID) { - buf[0] = '\0'; - hb_face_t* hbFace = hb_font_get_face(engine->font->hbFont); gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace); @@ -416,18 +409,12 @@ void getGraphiteFeatureSettingLabel(XeTeXLayoutEngine engine, UInt32 featureID, uint32_t len = 0; uint16_t langID = 0x409; - buf = (char*) gr_fref_value_label(feature, i, &langID, gr_utf8, &len); - - if (len > 128 + 1) { // 128 is set in XeTeX_ext.c - buf = (char*) realloc(buf, len + 1); - buf = (char*) gr_fref_value_label(feature, i, &langID, gr_utf8, &len); - } - - buf[len + 1] = '\0'; - break; + return (char *) gr_fref_value_label(feature, i, &langID, gr_utf8, &len); } } } + + return NULL; } bool @@ -449,10 +436,13 @@ findGraphiteFeature(XeTeXLayoutEngine engine, const char* s, const char* e, int* ++cp; while (cp < e && (*cp == ' ' || *cp == '\t')) ++cp; - if (cp >= e) + + if (cp >= e) { // no setting was specified, so we just use the first // XXX the default is not always the first? + *v = 1; return true; + } *v = findGraphiteFeatureSettingNamed(engine, *f, cp, e - cp); if (*v == -1) @@ -492,7 +482,7 @@ long findGraphiteFeatureNamed(XeTeXLayoutEngine engine, const char* name, int na return rval; } -long findGraphiteFeatureSettingNamed(XeTeXLayoutEngine engine, UInt32 id, const char* name, int namelength) +long findGraphiteFeatureSettingNamed(XeTeXLayoutEngine engine, uint32_t id, const char* name, int namelength) { long rval = -1; @@ -523,12 +513,12 @@ long findGraphiteFeatureSettingNamed(XeTeXLayoutEngine engine, UInt32 id, const return rval; } -float getGlyphWidth(XeTeXFont font, UInt32 gid) +float getGlyphWidth(XeTeXFont font, uint32_t gid) { return ((XeTeXFontInst*)font)->getGlyphWidth(gid); } -UInt32 +uint32_t countGlyphs(XeTeXFont font) { return ((XeTeXFontInst*)font)->getNumGlyphs(); @@ -555,7 +545,7 @@ float getEmboldenFactor(XeTeXLayoutEngine engine) } XeTeXLayoutEngine createLayoutEngine(PlatformFontRef fontRef, XeTeXFont font, char* script, char* language, - hb_feature_t* features, int nFeatures, char **shapers, UInt32 rgbValue, + hb_feature_t* features, int nFeatures, char **shapers, uint32_t rgbValue, float extend, float slant, float embolden) { XeTeXLayoutEngine result = new XeTeXLayoutEngine_rec; @@ -582,7 +572,7 @@ void deleteLayoutEngine(XeTeXLayoutEngine engine) delete engine->font; } -int layoutChars(XeTeXLayoutEngine engine, UInt16 chars[], SInt32 offset, SInt32 count, SInt32 max, +int layoutChars(XeTeXLayoutEngine engine, uint16_t chars[], int32_t offset, int32_t count, int32_t max, bool rightToLeft) { bool res; @@ -657,7 +647,7 @@ int layoutChars(XeTeXLayoutEngine engine, UInt16 chars[], SInt32 offset, SInt32 return glyphCount; } -void getGlyphs(XeTeXLayoutEngine engine, UInt32 glyphs[]) +void getGlyphs(XeTeXLayoutEngine engine, uint32_t glyphs[]) { int glyphCount = hb_buffer_get_length(engine->hbBuffer); hb_glyph_info_t *hbGlyphs = hb_buffer_get_glyph_infos(engine->hbBuffer, NULL); @@ -675,6 +665,7 @@ void getGlyphPositions(XeTeXLayoutEngine engine, float positions[]) float x = 0, y = 0; if (engine->font->getLayoutDirVertical()) { + // XXX this does not seem to match the old behaviour x -= hbPositions[0].y_offset / 64.0; // hack to compensate offset of 1st glyph for (i = 0; i < glyphCount; i++) { positions[2*i] = -(x + hbPositions[i].y_offset / 64.0); /* negative is forwards */ @@ -720,12 +711,12 @@ int getDefaultDirection(XeTeXLayoutEngine engine) return UBIDI_DEFAULT_LTR; } -UInt32 getRgbValue(XeTeXLayoutEngine engine) +uint32_t getRgbValue(XeTeXLayoutEngine engine) { return engine->rgbValue; } -void getGlyphBounds(XeTeXLayoutEngine engine, UInt32 glyphID, GlyphBBox* bbox) +void getGlyphBounds(XeTeXLayoutEngine engine, uint32_t glyphID, GlyphBBox* bbox) { engine->font->getGlyphBounds(glyphID, bbox); if (engine->extend != 0.0) { @@ -734,17 +725,17 @@ void getGlyphBounds(XeTeXLayoutEngine engine, UInt32 glyphID, GlyphBBox* bbox) } } -float getGlyphWidthFromEngine(XeTeXLayoutEngine engine, UInt32 glyphID) +float getGlyphWidthFromEngine(XeTeXLayoutEngine engine, uint32_t glyphID) { return engine->extend * engine->font->getGlyphWidth(glyphID); } -void getGlyphHeightDepth(XeTeXLayoutEngine engine, UInt32 glyphID, float* height, float* depth) +void getGlyphHeightDepth(XeTeXLayoutEngine engine, uint32_t glyphID, float* height, float* depth) { engine->font->getGlyphHeightDepth(glyphID, height, depth); } -void getGlyphSidebearings(XeTeXLayoutEngine engine, UInt32 glyphID, float* lsb, float* rsb) +void getGlyphSidebearings(XeTeXLayoutEngine engine, uint32_t glyphID, float* lsb, float* rsb) { engine->font->getGlyphSidebearings(glyphID, lsb, rsb); if (engine->extend != 0.0) { @@ -753,12 +744,12 @@ void getGlyphSidebearings(XeTeXLayoutEngine engine, UInt32 glyphID, float* lsb, } } -float getGlyphItalCorr(XeTeXLayoutEngine engine, UInt32 glyphID) +float getGlyphItalCorr(XeTeXLayoutEngine engine, uint32_t glyphID) { return engine->extend * engine->font->getGlyphItalCorr(glyphID); } -UInt32 mapCharToGlyph(XeTeXLayoutEngine engine, UInt32 charCode) +uint32_t mapCharToGlyph(XeTeXLayoutEngine engine, uint32_t charCode) { return engine->font->mapCharToGlyph(charCode); } @@ -768,9 +759,9 @@ UInt32 mapCharToGlyph(XeTeXLayoutEngine engine, UInt32 charCode) int findGlyphInPostTable(const char* buffer, int tableSize, const char* glyphName) { - const postTable* p = (const postTable*)buffer; - UInt16 g = 0; - switch (SWAP(p->format)) { + const POSTTable* p = (const POSTTable*)buffer; + uint16_t g = 0; + switch (SWAP(p->version)) { case 0x00010000: { const char* cp; @@ -784,11 +775,11 @@ findGlyphInPostTable(const char* buffer, int tableSize, const char* glyphName) case 0x00020000: { - const UInt16* n = (UInt16*)(p + 1); - UInt16 numGlyphs = SWAP(*n++); - const UInt8* ps = (const UInt8*)(n + numGlyphs); + const uint16_t* n = (uint16_t*)(p + 1); + uint16_t numGlyphs = SWAP(*n++); + const uint8_t* ps = (const uint8_t*)(n + numGlyphs); std::vector<std::string> newNames; - while (ps < (const UInt8*)buffer + tableSize) { + while (ps < (const uint8_t*)buffer + tableSize) { newNames.push_back(std::string((char*)ps + 1, *ps)); ps += *ps + 1; } @@ -824,10 +815,10 @@ findGlyphInPostTable(const char* buffer, int tableSize, const char* glyphName) } const char* -getGlyphNamePtr(const char* buffer, int tableSize, UInt16 gid, int* len) +getGlyphNamePtr(const char* buffer, int tableSize, uint16_t gid, int* len) { - const postTable* p = (const postTable*)buffer; - switch (SWAP(p->format)) { + const POSTTable* p = (const POSTTable*)buffer; + switch (SWAP(p->version)) { case 0x00010000: { if (gid < 258) { @@ -839,11 +830,11 @@ getGlyphNamePtr(const char* buffer, int tableSize, UInt16 gid, int* len) case 0x00020000: { - const UInt16* n = (UInt16*)(p + 1); - UInt16 numGlyphs = SWAP(*n++); - const UInt8* ps = (const UInt8*)(n + numGlyphs); - std::vector<const UInt8*> namePtrs; - while (ps < (const UInt8*)buffer + tableSize) { + const uint16_t* n = (uint16_t*)(p + 1); + uint16_t numGlyphs = SWAP(*n++); + const uint8_t* ps = (const uint8_t*)(n + numGlyphs); + std::vector<const uint8_t*> namePtrs; + while (ps < (const uint8_t*)buffer + tableSize) { namePtrs.push_back(ps); ps += *ps + 1; } @@ -891,7 +882,7 @@ getFontCharRange(XeTeXLayoutEngine engine, int reqFirst) } const char* -getGlyphName(XeTeXFont font, UInt16 gid, int* len) +getGlyphName(XeTeXFont font, uint16_t gid, int* len) { return ((XeTeXFontInst*)font)->getGlyphName(gid, *len); } @@ -906,7 +897,7 @@ static gr_segment* grSegment = NULL; static const gr_slot* grPrevSlot = NULL; bool -initGraphiteBreaking(XeTeXLayoutEngine engine, const UniChar* txtPtr, int txtLen) +initGraphiteBreaking(XeTeXLayoutEngine engine, const uint16_t* txtPtr, int txtLen) { hb_face_t* hbFace = hb_font_get_face(engine->font->hbFont); gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace); diff --git a/Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.h b/Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.h index 6542345da09..b2a4b0f0fc2 100644 --- a/Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.h +++ b/Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.h @@ -34,10 +34,6 @@ authorization from the copyright holders. #ifndef XETEX_LAYOUT_INTERFACE_H #define XETEX_LAYOUT_INTERFACE_H 1 -#ifdef XETEX_MAC -#include <Carbon/Carbon.h> -#endif - #ifdef __cplusplus extern "C" { #endif @@ -64,17 +60,12 @@ extern "C" { extern char gPrefEngine; -int getCachedGlyphBBox(UInt16 fontID, UInt16 glyphID, GlyphBBox* bbox); -void cacheGlyphBBox(UInt16 fontID, UInt16 glyphID, const GlyphBBox* bbox); +int getCachedGlyphBBox(uint16_t fontID, uint16_t glyphID, GlyphBBox* bbox); +void cacheGlyphBBox(uint16_t fontID, uint16_t glyphID, const GlyphBBox* bbox); void terminatefontmanager(); -#ifdef XETEX_MAC -XeTeXFont createFont(ATSFontRef atsFont, Fixed pointSize); -#else -// appropriate functions for other platforms XeTeXFont createFont(PlatformFontRef fontRef, Fixed pointSize); -#endif XeTeXFont createFontFromFile(const char* filename, int index, Fixed pointSize); void setFontLayoutDir(XeTeXFont font, int vertical); @@ -92,21 +83,21 @@ double getDesignSize(XeTeXFont font); void deleteFont(XeTeXFont font); -void* getFontTablePtr(XeTeXFont font, UInt32 tableTag); +void* getFontTablePtr(XeTeXFont font, uint32_t tableTag); Fixed getSlant(XeTeXFont font); -UInt32 countScripts(XeTeXFont font); -UInt32 getIndScript(XeTeXFont font, UInt32 index); -UInt32 countScriptLanguages(XeTeXFont font, UInt32 script); -UInt32 getIndScriptLanguage(XeTeXFont font, UInt32 script, UInt32 index); -UInt32 countFeatures(XeTeXFont font, UInt32 script, UInt32 language); -UInt32 getIndFeature(XeTeXFont font, UInt32 script, UInt32 language, UInt32 index); -float getGlyphWidth(XeTeXFont font, UInt32 gid); -UInt32 countGlyphs(XeTeXFont font); +uint32_t countScripts(XeTeXFont font); +uint32_t getIndScript(XeTeXFont font, uint32_t index); +uint32_t countScriptLanguages(XeTeXFont font, uint32_t script); +uint32_t getIndScriptLanguage(XeTeXFont font, uint32_t script, uint32_t index); +uint32_t countFeatures(XeTeXFont font, uint32_t script, uint32_t language); +uint32_t getIndFeature(XeTeXFont font, uint32_t script, uint32_t language, uint32_t index); +float getGlyphWidth(XeTeXFont font, uint32_t gid); +uint32_t countGlyphs(XeTeXFont font); XeTeXLayoutEngine createLayoutEngine(PlatformFontRef fontRef, XeTeXFont font, char* script, char* language, - hb_feature_t* features, int nFeatures, char **shapers, UInt32 rgbValue, + hb_feature_t* features, int nFeatures, char **shapers, uint32_t rgbValue, float extend, float slant, float embolden); void deleteLayoutEngine(XeTeXLayoutEngine engine); @@ -118,10 +109,10 @@ float getExtendFactor(XeTeXLayoutEngine engine); float getSlantFactor(XeTeXLayoutEngine engine); float getEmboldenFactor(XeTeXLayoutEngine engine); -int layoutChars(XeTeXLayoutEngine engine, UInt16* chars, SInt32 offset, SInt32 count, SInt32 max, +int layoutChars(XeTeXLayoutEngine engine, uint16_t* chars, int32_t offset, int32_t count, int32_t max, bool rightToLeft); -void getGlyphs(XeTeXLayoutEngine engine, UInt32* glyphs); +void getGlyphs(XeTeXLayoutEngine engine, uint32_t* glyphs); void getGlyphPositions(XeTeXLayoutEngine engine, float* positions); @@ -131,30 +122,30 @@ void getAscentAndDescent(XeTeXLayoutEngine engine, float* ascent, float* descent int getDefaultDirection(XeTeXLayoutEngine engine); -UInt32 getRgbValue(XeTeXLayoutEngine engine); +uint32_t getRgbValue(XeTeXLayoutEngine engine); -void getGlyphBounds(XeTeXLayoutEngine engine, UInt32 glyphID, GlyphBBox* bbox); +void getGlyphBounds(XeTeXLayoutEngine engine, uint32_t glyphID, GlyphBBox* bbox); -float getGlyphWidthFromEngine(XeTeXLayoutEngine engine, UInt32 glyphID); +float getGlyphWidthFromEngine(XeTeXLayoutEngine engine, uint32_t glyphID); -void getGlyphHeightDepth(XeTeXLayoutEngine engine, UInt32 glyphID, float* height, float* depth); +void getGlyphHeightDepth(XeTeXLayoutEngine engine, uint32_t glyphID, float* height, float* depth); -void getGlyphSidebearings(XeTeXLayoutEngine engine, UInt32 glyphID, float* lsb, float* rsb); +void getGlyphSidebearings(XeTeXLayoutEngine engine, uint32_t glyphID, float* lsb, float* rsb); -float getGlyphItalCorr(XeTeXLayoutEngine engine, UInt32 glyphID); +float getGlyphItalCorr(XeTeXLayoutEngine engine, uint32_t glyphID); -UInt32 mapCharToGlyph(XeTeXLayoutEngine engine, UInt32 charCode); +uint32_t mapCharToGlyph(XeTeXLayoutEngine engine, uint32_t charCode); int mapGlyphToIndex(XeTeXLayoutEngine engine, const char* glyphName); int findGlyphInPostTable(const char* p, int tableSize, const char* glyphName); -const char* getGlyphName(XeTeXFont font, UInt16 gid, int* len); +const char* getGlyphName(XeTeXFont font, uint16_t gid, int* len); int getFontCharRange(XeTeXLayoutEngine engine, int reqFirst); /* graphite interface functions... */ -bool initGraphiteBreaking(XeTeXLayoutEngine engine, const UniChar* txtPtr, int txtLen); +bool initGraphiteBreaking(XeTeXLayoutEngine engine, const uint16_t* txtPtr, int txtLen); int findNextGraphiteBreak(void); bool usingOpenType(XeTeXLayoutEngine engine); @@ -163,14 +154,14 @@ bool isOpenTypeMathFont(XeTeXLayoutEngine engine); bool findGraphiteFeature(XeTeXLayoutEngine engine, const char* s, const char* e, int* f, int* v); -UInt32 countGraphiteFeatures(XeTeXLayoutEngine engine); -UInt32 getGraphiteFeatureCode(XeTeXLayoutEngine engine, UInt32 index); -UInt32 countGraphiteFeatureSettings(XeTeXLayoutEngine engine, UInt32 feature); -UInt32 getGraphiteFeatureSettingCode(XeTeXLayoutEngine engine, UInt32 feature, UInt32 index); -void getGraphiteFeatureLabel(XeTeXLayoutEngine engine, UInt32 feature, char* buf); -void getGraphiteFeatureSettingLabel(XeTeXLayoutEngine engine, UInt32 feature, UInt32 setting, char* buf); +uint32_t countGraphiteFeatures(XeTeXLayoutEngine engine); +uint32_t getGraphiteFeatureCode(XeTeXLayoutEngine engine, uint32_t index); +uint32_t countGraphiteFeatureSettings(XeTeXLayoutEngine engine, uint32_t feature); +uint32_t getGraphiteFeatureSettingCode(XeTeXLayoutEngine engine, uint32_t feature, uint32_t index); +char* getGraphiteFeatureLabel(XeTeXLayoutEngine engine, uint32_t feature); +char* getGraphiteFeatureSettingLabel(XeTeXLayoutEngine engine, uint32_t feature, uint32_t setting); long findGraphiteFeatureNamed(XeTeXLayoutEngine engine, const char* name, int namelength); -long findGraphiteFeatureSettingNamed(XeTeXLayoutEngine engine, UInt32 feature, const char* name, int namelength); +long findGraphiteFeatureSettingNamed(XeTeXLayoutEngine engine, uint32_t feature, const char* name, int namelength); #ifdef __cplusplus }; diff --git a/Build/source/texk/web2c/xetexdir/XeTeXOTMath.cpp b/Build/source/texk/web2c/xetexdir/XeTeXOTMath.cpp index e2c2e9e82ca..a2260a9271e 100644 --- a/Build/source/texk/web2c/xetexdir/XeTeXOTMath.cpp +++ b/Build/source/texk/web2c/xetexdir/XeTeXOTMath.cpp @@ -67,13 +67,13 @@ static int32_t getCoverage(const Coverage* coverage, GlyphID g) return -1; } -static SInt16 getMathConstant(XeTeXFontInst* fontInst, mathConstantIndex whichConstant) +static int16_t getMathConstant(XeTeXFontInst* fontInst, mathConstantIndex whichConstant) { const char* table = (const char*)fontInst->getFontTable(kMATH); if (table == NULL) return 0; - const UInt16* constants = (const UInt16*)(table + SWAP(((const MathTableHeader*)table)->mathConstants)); + const uint16_t* constants = (const uint16_t*)(table + SWAP(((const MathTableHeader*)table)->mathConstants)); if (whichConstant < firstMathValueRecord) { /* it's a simple 16-bit value */ @@ -81,7 +81,7 @@ static SInt16 getMathConstant(XeTeXFontInst* fontInst, mathConstantIndex whichCo } else if (whichConstant <= lastMathValueRecord) { const MathValueRecord* valueRecords = (const MathValueRecord*) - ((char*)constants + firstMathValueRecord * sizeof(UInt16) - firstMathValueRecord * sizeof(MathValueRecord)); + ((char*)constants + firstMathValueRecord * sizeof(uint16_t) - firstMathValueRecord * sizeof(MathValueRecord)); return SWAP(valueRecords[whichConstant].value); } else if (whichConstant <= lastMathConstant) { diff --git a/Build/source/texk/web2c/xetexdir/XeTeX_ext.c b/Build/source/texk/web2c/xetexdir/XeTeX_ext.c index 390243a28d6..f20b5db3ba2 100644 --- a/Build/source/texk/web2c/xetexdir/XeTeX_ext.c +++ b/Build/source/texk/web2c/xetexdir/XeTeX_ext.c @@ -3,6 +3,7 @@ Copyright (c) 1994-2008 by SIL International Copyright (c) 2009, 2011 by Jonathan Kew Copyright (c) 2012, 2013 by Khaled Hosny + Copyright (c) 2012, 2013 by Jiang Jiang SIL Author(s): Jonathan Kew @@ -56,12 +57,6 @@ authorization from the copyright holders. #define EXTERN extern #include "xetexd.h" -#ifdef XETEX_MAC -#undef input /* this is defined in texmfmp.h, but we don't need it and it confuses the carbon headers */ -#undef output -#include <Carbon/Carbon.h> -#endif - #include "XeTeX_ext.h" #include <teckit/TECkit_Engine.h> @@ -97,7 +92,7 @@ authorization from the copyright holders. /* tables/values used in UTF-8 interpretation - code is based on ConvertUTF.[ch] sample code published by the Unicode consortium */ -const UInt32 +const uint32_t offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, @@ -107,7 +102,7 @@ offsetsFromUTF8[6] = { 0x82082080UL }; -const UInt8 +const uint8_t bytesFromUTF8[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, @@ -119,20 +114,20 @@ bytesFromUTF8[256] = { 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 }; -const UInt8 +const uint8_t firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; const int halfShift = 10; -const UInt32 halfBase = 0x0010000UL; -const UInt32 halfMask = 0x3FFUL; -const UInt32 kSurrogateHighStart = 0xD800UL; -const UInt32 kSurrogateHighEnd = 0xDBFFUL; -const UInt32 kSurrogateLowStart = 0xDC00UL; -const UInt32 kSurrogateLowEnd = 0xDFFFUL; -const UInt32 byteMask = 0x000000BFUL; -const UInt32 byteMark = 0x00000080UL; +const uint32_t halfBase = 0x0010000UL; +const uint32_t halfMask = 0x3FFUL; +const uint32_t kSurrogateHighStart = 0xD800UL; +const uint32_t kSurrogateHighEnd = 0xDBFFUL; +const uint32_t kSurrogateLowStart = 0xDC00UL; +const uint32_t kSurrogateLowEnd = 0xDFFFUL; +const uint32_t byteMask = 0x000000BFUL; +const uint32_t byteMark = 0x00000080UL; /* if the user specifies a paper size or output driver program */ @@ -157,7 +152,7 @@ void initversionstring(char **versions) "Compiled with Graphite2 version %d.%d.%d; using %d.%d.%d\n" "Compiled with HarfBuzz version %s; using %s\n" #ifdef XETEX_MAC - "Using Mac OS X Carbon, Cocoa & QuickTime frameworks\n" + "Using Mac OS X Core Text, Cocoa & ImageIO frameworks\n" #else "Compiled with fontconfig version %d.%d.%d; using %d.%d.%d\n" "Compiled with libpng version %s; using %s\n" @@ -293,12 +288,12 @@ conversion_error(int errcode) #endif static void -apply_normalization(UInt32* buf, int len, int norm) +apply_normalization(uint32_t* buf, int len, int norm) { static TECkit_Converter normalizers[2] = { NULL, NULL }; TECkit_Status status; - UInt32 inUsed, outUsed; + uint32_t inUsed, outUsed; TECkit_Converter *normPtr = &normalizers[norm - 1]; if (*normPtr == NULL) { status = TECkit_CreateConverter(NULL, 0, 1, @@ -310,7 +305,7 @@ apply_normalization(UInt32* buf, int len, int norm) } } - status = TECkit_ConvertBuffer(*normPtr, (Byte*)buf, len * sizeof(UInt32), &inUsed, + status = TECkit_ConvertBuffer(*normPtr, (Byte*)buf, len * sizeof(uint32_t), &inUsed, (Byte*)&buffer[first], sizeof(*buffer) * (bufsize - first), &outUsed, 1); if (status != kStatus_NoError) buffer_overflow(); @@ -327,14 +322,14 @@ int input_line(UFILE* f) { static char* byteBuffer = NULL; -static UInt32 *utf32Buf = NULL; +static uint32_t *utf32Buf = NULL; int i, tmpLen; int norm = getinputnormalizationstate(); last = first; if (f->encodingMode == ICUMAPPING) { - UInt32 bytesRead = 0; + uint32_t bytesRead = 0; UConverter* cnv; int outLen; UErrorCode errorCode = 0; @@ -368,7 +363,7 @@ static UInt32 *utf32Buf = NULL; case 1: // NFC case 2: // NFD if (utf32Buf == NULL) - utf32Buf = (UInt32*)xmalloc(bufsize * sizeof(*utf32Buf)); + utf32Buf = (uint32_t*)xmalloc(bufsize * sizeof(*utf32Buf)); tmpLen = ucnv_toAlgorithmic(UCNV_UTF32_NativeEndian, cnv, (char*)utf32Buf, bufsize * sizeof(*utf32Buf), byteBuffer, bytesRead, &errorCode); @@ -466,7 +461,7 @@ static UBreakIterator* brkIter = NULL; static int brkLocaleStrNum = 0; void -linebreakstart(int f, integer localeStrNum, const UniChar* text, integer textLength) +linebreakstart(int f, integer localeStrNum, const uint16_t* text, integer textLength) { UErrorCode status; char* locale = (char*)gettexstring(localeStrNum); @@ -593,7 +588,7 @@ printchars(const unsigned short* str, int len) #define UTF16_NATIVE kForm_UTF16LE #endif -void* +static void* load_mapping_file(const char* s, const char* e, char byteMapping) { char* mapPath; @@ -608,7 +603,7 @@ load_mapping_file(const char* s, const char* e, char byteMapping) FILE* mapFile = fopen(mapPath, FOPEN_RBIN_MODE); free(mapPath); if (mapFile) { - UInt32 mappingSize; + uint32_t mappingSize; Byte* mapping; TECkit_Status status; fseek(mapFile, 0, SEEK_END); @@ -679,7 +674,7 @@ applytfmfontmapping(void* cnv, int c) { UniChar in = c; Byte out[2]; - UInt32 inUsed, outUsed; + uint32_t inUsed, outUsed; TECkit_Status status = TECkit_ConvertBuffer((TECkit_Converter)cnv, (const Byte*)&in, sizeof(in), &inUsed, out, sizeof(out), &outUsed, 1); if (outUsed < 1) @@ -758,8 +753,8 @@ read_tag_with_param(const char* cp, int* param) unsigned int read_rgb_a(const char** cp) { - UInt32 rgbValue = 0; - UInt32 alpha = 0; + uint32_t rgbValue = 0; + uint32_t alpha = 0; int i; for (i = 0; i < 6; ++i) { if ((**cp >= '0') && (**cp <= '9')) @@ -792,7 +787,7 @@ read_rgb_a(const char** cp) } int -readCommonFeatures(const char* feat, const char* end, float* extend, float* slant, float* embolden, float* letterspace, UInt32* rgbValue) +readCommonFeatures(const char* feat, const char* end, float* extend, float* slant, float* embolden, float* letterspace, uint32_t* rgbValue) // returns 1 to go to next_option, -1 for bad_option, 0 to continue { const char* sep; @@ -871,12 +866,14 @@ readFeatureNumber(const char* s, const char* e, int* f, int* v) while ((*s == ' ') || (*s == '\t')) ++s; if (*s++ != '=') { - if (s >= e) + if (s >= e) { // no setting was specified, so we just use the first // XXX the default is not always the first? + *v = 1; return true; - else + } else { return false; + } } if (*s < '0' || *s > '9') return false; @@ -925,7 +922,7 @@ loadOTfont(PlatformFontRef fontRef, XeTeXFont font, Fixed scaled_size, const cha hb_tag_t tag; - UInt32 rgbValue = 0x000000FF; + uint32_t rgbValue = 0x000000FF; float extend = 1.0; float slant = 0.0; @@ -998,12 +995,9 @@ loadOTfont(PlatformFontRef fontRef, XeTeXFont font, Fixed scaled_size, const cha || findGraphiteFeature(engine, cp1, cp2, &tag, &value)) { features = xrealloc(features, (nFeatures + 1) * sizeof(hb_feature_t)); features[nFeatures].tag = tag; + features[nFeatures].value = value; features[nFeatures].start = 0; features[nFeatures].end = (unsigned int) -1; - if (value == 0) - features[nFeatures].value = 1; - else - features[nFeatures].value = value; nFeatures++; goto next_option; } @@ -1243,13 +1237,13 @@ findnativefont(unsigned char* uname, integer scaled_size) deleteFont(font); } } - + #ifdef XETEX_MAC /* decide whether to use AAT or OpenType rendering with this font */ if (getReqEngine() == 'A') goto load_aat; #endif - + font = createFont(fontRef, scaled_size); if (font != 0) { #ifdef XETEX_MAC @@ -1267,6 +1261,7 @@ findnativefont(unsigned char* uname, integer scaled_size) rval = loadAATfont(fontRef, scaled_size, featString); } #endif + /* append the style and feature strings, so that \show\fontID will give a full result */ if (varString != NULL && *varString != 0) { strcat((char*)nameoffile + 1, "/"); @@ -1296,9 +1291,8 @@ releasefontengine(void* engine, int type_flag) { #ifdef XETEX_MAC if (type_flag == AAT_FONT_FLAG) { - ATSUDisposeStyle((ATSUStyle)engine); - } - else + CFRelease((CFDictionaryRef)engine); + } else #endif if (type_flag == OTGR_FONT_FLAG) { deleteLayoutEngine((XeTeXLayoutEngine)engine); @@ -1432,20 +1426,21 @@ otfontget3(integer what, void* pEngine, integer param1, integer param2, integer void grprintfontname(integer what, void* pEngine, integer param1, integer param2) { - char name[128]; - int n = 0; + char* name = NULL; XeTeXLayoutEngine engine = (XeTeXLayoutEngine)pEngine; switch (what) { case XeTeX_feature_name: - getGraphiteFeatureLabel(engine, param1, &name[0]); + name = getGraphiteFeatureLabel(engine, param1); break; case XeTeX_selector_name: - getGraphiteFeatureSettingLabel(engine, param1, param2, &name[0]); + name = getGraphiteFeatureSettingLabel(engine, param1, param2); break; } - while (name[n] != '\0') - ++n; - printchars((unsigned short*) &name[0], n); + + if (name != NULL) { + printcstring(name); + gr_label_destroy(name); + } } integer @@ -1487,15 +1482,17 @@ grfontgetnamed1(integer what, void* pEngine, integer param) #ifdef XETEX_MAC static UInt32 -atsuColorToRGBA32(ATSURGBAlphaColor a) +cgColorToRGBA32(CGColorRef color) { - UInt32 rval = (UInt8)(a.red * 255.0 + 0.5); + const CGFloat *components = CGColorGetComponents(color); + + UInt32 rval = (UInt8)(components[0] * 255.0 + 0.5); rval <<= 8; - rval += (UInt8)(a.green * 255.0 + 0.5); + rval += (UInt8)(components[1] * 255.0 + 0.5); rval <<= 8; - rval += (UInt8)(a.blue * 255.0 + 0.5); + rval += (UInt8)(components[2] * 255.0 + 0.5); rval <<= 8; - rval += (UInt8)(a.alpha * 255.0 + 0.5); + rval += (UInt8)(components[3] * 255.0 + 0.5); return rval; } #endif @@ -1506,13 +1503,13 @@ int makeXDVGlyphArrayData(void* pNode) { unsigned char* cp; - UInt16* glyphIDs; + uint16_t* glyphIDs; memoryword* p = pNode; void* glyph_info; FixedPoint* locations; int opcode; Fixed wid; - UInt16 glyphCount = native_glyph_count(p); + uint16_t glyphCount = native_glyph_count(p); int i = glyphCount * native_glyph_info_size + 8; /* to guarantee enough space in the buffer */ if (i > xdvBufSize) { @@ -1524,7 +1521,7 @@ makeXDVGlyphArrayData(void* pNode) glyph_info = native_glyph_info_ptr(p); locations = (FixedPoint*)glyph_info; - glyphIDs = (UInt16*)(locations + glyphCount); + glyphIDs = (uint16_t*)(locations + glyphCount); opcode = XDV_GLYPH_STRING; for (i = 0; i < glyphCount; ++i) @@ -1561,7 +1558,7 @@ makeXDVGlyphArrayData(void* pNode) } for (i = 0; i < glyphCount; ++i) { - UInt16 g = glyphIDs[i]; + uint16_t g = glyphIDs[i]; *cp++ = (g >> 8) & 0xff; *cp++ = g & 0xff; } @@ -1572,16 +1569,16 @@ makeXDVGlyphArrayData(void* pNode) int makefontdef(integer f) { - UInt16 flags = 0; - UInt32 variationCount = 0; - UInt32 rgba; + uint16_t flags = 0; + uint32_t variationCount = 0; + uint32_t rgba; Fixed size; const char* psName; const char* famName; const char* styName; - UInt8 psLen; - UInt8 famLen; - UInt8 styLen; + uint8_t psLen; + uint8_t famLen; + uint8_t styLen; int fontDefLength; char* cp; PlatformFontRef fontRef = 0; @@ -1590,39 +1587,46 @@ makefontdef(integer f) float embolden = 0.0; #ifdef XETEX_MAC - ATSUStyle style = NULL; + CFDictionaryRef attributes = NULL; + CFDictionaryRef variation = NULL; + if (fontarea[f] == AAT_FONT_FLAG) { flags = XDV_FLAG_FONTTYPE_ATSUI; + attributes = (CFDictionaryRef) fontlayoutengine[f]; + CTFontRef font = CFDictionaryGetValue(attributes, kCTFontAttributeName); + variation = CTFontCopyVariation(font); + if (variation) { + variationCount = CFDictionaryGetCount(variation); + CFRelease(variation); + } - style = (ATSUStyle)fontlayoutengine[f]; - ATSUGetAllFontVariations(style, 0, 0, 0, &variationCount); - - ATSUFontID fontID; - ATSUGetAttribute(style, kATSUFontTag, sizeof(ATSUFontID), &fontID, 0); - - fontRef = FMGetATSFontRefFromFont(fontID); - getNames(fontRef, &psName, &famName, &styName); - /* returns ptrs to strings that belong to the font - do not free! */ + psName = getFileNameFromCTFont(font); + if (psName) { + famName = ""; + styName = ""; + } else { + psName = getNameFromCTFont(font, kCTFontPostScriptNameKey); + famName = getNameFromCTFont(font, kCTFontFamilyNameKey); + styName = getNameFromCTFont(font, kCTFontStyleNameKey); + } - ATSUVerticalCharacterType vert; - ATSUGetAttribute(style, kATSUVerticalCharacterTag, sizeof(ATSUVerticalCharacterType), &vert, 0); - if (vert == kATSUStronglyVertical) + if (CFDictionaryGetValue(attributes, kCTVerticalFormsAttributeName)) flags |= XDV_FLAG_VERTICAL; - - ATSURGBAlphaColor atsuColor; - ATSUGetAttribute(style, kATSURGBAlphaColorTag, sizeof(ATSURGBAlphaColor), &atsuColor, 0); - rgba = atsuColorToRGBA32(atsuColor); - CGAffineTransform t; - ATSUGetAttribute(style, kATSUFontMatrixTag, sizeof(CGAffineTransform), &t, 0); + CGColorRef color = (CGColorRef) CFDictionaryGetValue(attributes, kCTForegroundColorAttributeName); + if (color) + rgba = cgColorToRGBA32(color); + + CGAffineTransform t = CTFontGetMatrix(font); extend = t.a; slant = t.b; - float tmp = 0.0; - if (ATSUGetAttribute(style, kXeTeXEmboldenTag, sizeof(float), &tmp, 0) != kATSUNotSetErr) - embolden = tmp; + CFNumberRef emboldenNumber = CFDictionaryGetValue(attributes, kXeTeXEmboldenAttributeName); + if (emboldenNumber) + CFNumberGetValue(emboldenNumber, kCFNumberFloatType, &embolden); - ATSUGetAttribute(style, kATSUSizeTag, sizeof(Fixed), &size, 0); + CGFloat fSize = CTFontGetSize(font); + size = D2Fix(fSize); } else #endif @@ -1682,16 +1686,6 @@ makefontdef(integer f) flags |= XDV_FLAG_COLORED; } -#ifdef XETEX_MAC - if (variationCount > 0) { - fontDefLength += - 2 /* number of variations */ - + 4 * variationCount - + 4 * variationCount; /* axes and values */ - flags |= XDV_FLAG_VARIATIONS; - } -#endif - if (extend != 1.0) { fontDefLength += 4; flags |= XDV_FLAG_EXTEND; @@ -1716,14 +1710,14 @@ makefontdef(integer f) *(Fixed*)cp = SWAP32(size); cp += 4; - *(UInt16*)cp = SWAP16(flags); + *(uint16_t*)cp = SWAP16(flags); cp += 2; - *(UInt8*)cp = psLen; + *(uint8_t*)cp = psLen; cp += 1; - *(UInt8*)cp = famLen; + *(uint8_t*)cp = famLen; cp += 1; - *(UInt8*)cp = styLen; + *(uint8_t*)cp = styLen; cp += 1; memcpy(cp, psName, psLen); cp += psLen; @@ -1733,45 +1727,23 @@ makefontdef(integer f) cp += styLen; if ((fontflags[f] & FONT_FLAGS_COLORED) != 0) { - *(UInt32*)cp = SWAP32(rgba); + *(uint32_t*)cp = SWAP32(rgba); cp += 4; } -#ifdef XETEX_MAC - if (variationCount > 0) { - *(UInt16*)cp = SWAP16(variationCount); - cp += 2; - if (variationCount > 0) { - ATSUGetAllFontVariations(style, variationCount, - (UInt32*)(cp), - (SInt32*)(cp + 4 * variationCount), - 0); - while (variationCount > 0) { - /* (potentially) swap two 32-bit values per variation setting, - and advance cp past them all */ - *(UInt32*)(cp) = SWAP32(*(UInt32*)(cp)); - cp += 4; - *(UInt32*)(cp) = SWAP32(*(UInt32*)(cp)); - cp += 4; - --variationCount; - } - } - } -#endif - if (flags & XDV_FLAG_EXTEND) { Fixed f = D2Fix(extend); - *(UInt32*)(cp) = SWAP32(f); + *(uint32_t*)(cp) = SWAP32(f); cp += 4; } if (flags & XDV_FLAG_SLANT) { Fixed f = D2Fix(slant); - *(UInt32*)(cp) = SWAP32(f); + *(uint32_t*)(cp) = SWAP32(f); cp += 4; } if (flags & XDV_FLAG_EMBOLDEN) { Fixed f = D2Fix(embolden); - *(UInt32*)(cp) = SWAP32(f); + *(uint32_t*)(cp) = SWAP32(f); cp += 4; } @@ -1779,12 +1751,12 @@ makefontdef(integer f) } int -applymapping(void* pCnv, const UniChar* txtPtr, int txtLen) +applymapping(void* pCnv, const uint16_t* txtPtr, int txtLen) { TECkit_Converter cnv = (TECkit_Converter)pCnv; - UInt32 inUsed, outUsed; + uint32_t inUsed, outUsed; TECkit_Status status; - static UInt32 outLength = 0; + static uint32_t outLength = 0; /* allocate outBuffer if not big enough */ if (outLength < txtLen * sizeof(UniChar) + 32) { @@ -1837,9 +1809,9 @@ getnativecharheightdepth(integer font, integer ch, scaled* height, scaled* depth #ifdef XETEX_MAC if (fontarea[font] == AAT_FONT_FLAG) { - ATSUStyle style = (ATSUStyle)(fontlayoutengine[font]); - int gid = MapCharToGlyph_AAT(style, ch); - GetGlyphHeightDepth_AAT(style, gid, &ht, &dp); + CFDictionaryRef attributes = (CFDictionaryRef)(fontlayoutengine[font]); + int gid = MapCharToGlyph_AAT(attributes, ch); + GetGlyphHeightDepth_AAT(attributes, gid, &ht, &dp); } else #endif @@ -1887,9 +1859,9 @@ getnativecharsidebearings(integer font, integer ch, scaled* lsb, scaled* rsb) #ifdef XETEX_MAC if (fontarea[font] == AAT_FONT_FLAG) { - ATSUStyle style = (ATSUStyle)(fontlayoutengine[font]); - int gid = MapCharToGlyph_AAT(style, ch); - GetGlyphSidebearings_AAT(style, gid, &l, &r); + CFDictionaryRef attributes = (CFDictionaryRef)(fontlayoutengine[font]); + int gid = MapCharToGlyph_AAT(attributes, ch); + GetGlyphSidebearings_AAT(attributes, gid, &l, &r); } else #endif @@ -1915,11 +1887,11 @@ getglyphbounds(integer font, integer edge, integer gid) #ifdef XETEX_MAC if (fontarea[font] == AAT_FONT_FLAG) { - ATSUStyle style = (ATSUStyle)(fontlayoutengine[font]); + CFDictionaryRef attributes = (CFDictionaryRef)(fontlayoutengine[font]); if (edge & 1) - GetGlyphSidebearings_AAT(style, gid, &a, &b); + GetGlyphSidebearings_AAT(attributes, gid, &a, &b); else - GetGlyphHeightDepth_AAT(style, gid, &a, &b); + GetGlyphHeightDepth_AAT(attributes, gid, &a, &b); } else #endif @@ -1954,9 +1926,9 @@ getnativecharwd(integer f, integer c) scaled wd = 0; #ifdef XETEX_MAC if (fontarea[f] == AAT_FONT_FLAG) { - ATSUStyle style = (ATSUStyle)(fontlayoutengine[f]); - int gid = MapCharToGlyph_AAT(style, c); - wd = D2Fix(GetGlyphWidth_AAT(style, gid)); + CFDictionaryRef attributes = (CFDictionaryRef)(fontlayoutengine[f]); + int gid = MapCharToGlyph_AAT(attributes, c); + wd = D2Fix(GetGlyphWidth_AAT(attributes, gid)); } else #endif @@ -1972,12 +1944,12 @@ getnativecharwd(integer f, integer c) return wd; } -UInt16 +uint16_t get_native_glyph(void* pNode, unsigned index) { memoryword* node = (memoryword*)pNode; FixedPoint* locations = (FixedPoint*)native_glyph_info_ptr(node); - UInt16* glyphIDs = (UInt16*)(locations + native_glyph_count(node)); + uint16_t* glyphIDs = (uint16_t*)(locations + native_glyph_count(node)); if (index >= native_glyph_count(node)) return 0; else @@ -1997,13 +1969,13 @@ measure_native_node(void* pNode, int use_glyph_metrics) { memoryword* node = (memoryword*)pNode; int txtLen = native_length(node); - const UniChar* txtPtr = (UniChar*)(node + native_node_size); + uint16_t* txtPtr = (uint16_t*)(node + native_node_size); unsigned f = native_font(node); #ifdef XETEX_MAC if (fontarea[f] == AAT_FONT_FLAG) { - /* we're using this font in AAT mode, so fontlayoutengine[f] is actually an ATSUStyle */ + /* we're using this font in AAT mode, so fontlayoutengine[f] is actually a CFDictionaryRef */ DoAtsuiLayout(node, 0); } else @@ -2014,7 +1986,7 @@ measure_native_node(void* pNode, int use_glyph_metrics) XeTeXLayoutEngine engine = (XeTeXLayoutEngine)(fontlayoutengine[f]); FixedPoint* locations; - UInt16* glyphIDs; + uint16_t* glyphIDs; int realGlyphCount = 0; /* need to find direction runs within the text, and call layoutChars separately for each */ @@ -2023,7 +1995,7 @@ measure_native_node(void* pNode, int use_glyph_metrics) float x, y; void* glyph_info = 0; static float* positions = 0; - static UInt32* glyphs = 0; + static uint32_t* glyphs = 0; UBiDi* pBiDi = ubidi_open(); @@ -2042,24 +2014,24 @@ measure_native_node(void* pNode, int use_glyph_metrics) int32_t logicalStart, length; for (runIndex = 0; runIndex < nRuns; ++runIndex) { dir = ubidi_getVisualRun(pBiDi, runIndex, &logicalStart, &length); - realGlyphCount += layoutChars(engine, (UniChar*)txtPtr, logicalStart, length, txtLen, (dir == UBIDI_RTL)); + realGlyphCount += layoutChars(engine, txtPtr, logicalStart, length, txtLen, (dir == UBIDI_RTL)); } if (realGlyphCount > 0) { double x, y; glyph_info = xmalloc(realGlyphCount * native_glyph_info_size); locations = (FixedPoint*)glyph_info; - glyphIDs = (UInt16*)(locations + realGlyphCount); + glyphIDs = (uint16_t*)(locations + realGlyphCount); realGlyphCount = 0; x = y = 0.0; for (runIndex = 0; runIndex < nRuns; ++runIndex) { int nGlyphs; dir = ubidi_getVisualRun(pBiDi, runIndex, &logicalStart, &length); - nGlyphs = layoutChars(engine, (UniChar*)txtPtr, logicalStart, length, txtLen, + nGlyphs = layoutChars(engine, txtPtr, logicalStart, length, txtLen, (dir == UBIDI_RTL)); - glyphs = xmalloc(nGlyphs * sizeof(UInt32)); + glyphs = xmalloc(nGlyphs * sizeof(uint32_t)); positions = xmalloc((nGlyphs * 2 + 2) * sizeof(float)); getGlyphs(engine, glyphs); @@ -2086,9 +2058,9 @@ measure_native_node(void* pNode, int use_glyph_metrics) } else { int i; - realGlyphCount = layoutChars(engine, (UniChar*)txtPtr, 0, txtLen, txtLen, (dir == UBIDI_RTL)); + realGlyphCount = layoutChars(engine, txtPtr, 0, txtLen, txtLen, (dir == UBIDI_RTL)); - glyphs = xmalloc(realGlyphCount * sizeof(UInt32)); + glyphs = xmalloc(realGlyphCount * sizeof(uint32_t)); positions = xmalloc((realGlyphCount * 2 + 2) * sizeof(float)); getGlyphs(engine, glyphs); @@ -2097,7 +2069,7 @@ measure_native_node(void* pNode, int use_glyph_metrics) if (realGlyphCount > 0) { glyph_info = xmalloc(realGlyphCount * native_glyph_info_size); locations = (FixedPoint*)glyph_info; - glyphIDs = (UInt16*)(locations + realGlyphCount); + glyphIDs = (uint16_t*)(locations + realGlyphCount); for (i = 0; i < realGlyphCount; ++i) { glyphIDs[i] = glyphs[i]; locations[i].x = D2Fix(positions[2*i]); @@ -2147,7 +2119,7 @@ measure_native_node(void* pNode, int use_glyph_metrics) else { /* this iterates over the glyph data whether it comes from ATSUI or ICU layout */ FixedPoint* locations = (FixedPoint*)native_glyph_info_ptr(node); - UInt16* glyphIDs = (UInt16*)(locations + native_glyph_count(node)); + uint16_t* glyphIDs = (uint16_t*)(locations + native_glyph_count(node)); float yMin = 65536.0; float yMax = -65536.0; int i; @@ -2159,7 +2131,7 @@ measure_native_node(void* pNode, int use_glyph_metrics) if (getCachedGlyphBBox(f, glyphIDs[i], &bbox) == 0) { #ifdef XETEX_MAC if (fontarea[f] == AAT_FONT_FLAG) - GetGlyphBBox_AAT((ATSUStyle)(fontlayoutengine[f]), glyphIDs[i], &bbox); + GetGlyphBBox_AAT((CFDictionaryRef)(fontlayoutengine[f]), glyphIDs[i], &bbox); else #endif if (fontarea[f] == OTGR_FONT_FLAG) @@ -2189,11 +2161,11 @@ get_native_italic_correction(void* pNode) unsigned n = native_glyph_count(node); if (n > 0) { FixedPoint* locations = (FixedPoint*)native_glyph_info_ptr(node); - UInt16* glyphIDs = (UInt16*)(locations + n); + uint16_t* glyphIDs = (uint16_t*)(locations + n); #ifdef XETEX_MAC if (fontarea[f] == AAT_FONT_FLAG) - return D2Fix(GetGlyphItalCorr_AAT((ATSUStyle)(fontlayoutengine[f]), glyphIDs[n-1])) + return D2Fix(GetGlyphItalCorr_AAT((CFDictionaryRef)(fontlayoutengine[f]), glyphIDs[n-1])) + fontletterspace[f]; #endif if (fontarea[f] == OTGR_FONT_FLAG) @@ -2209,12 +2181,12 @@ Fixed get_native_glyph_italic_correction(void* pNode) { memoryword* node = pNode; - UInt16 gid = native_glyph(node); + uint16_t gid = native_glyph(node); unsigned f = native_font(node); #ifdef XETEX_MAC if (fontarea[f] == AAT_FONT_FLAG) - return D2Fix(GetGlyphItalCorr_AAT((ATSUStyle)(fontlayoutengine[f]), gid)); + return D2Fix(GetGlyphItalCorr_AAT((CFDictionaryRef)(fontlayoutengine[f]), gid)); #endif if (fontarea[f] == OTGR_FONT_FLAG) return D2Fix(getGlyphItalCorr((XeTeXLayoutEngine)(fontlayoutengine[f]), gid)); @@ -2226,7 +2198,7 @@ void measure_native_glyph(void* pNode, int use_glyph_metrics) { memoryword* node = pNode; - UInt16 gid = native_glyph(node); + uint16_t gid = native_glyph(node); unsigned f = native_font(node); float ht = 0.0; @@ -2234,15 +2206,10 @@ measure_native_glyph(void* pNode, int use_glyph_metrics) #ifdef XETEX_MAC if (fontarea[f] == AAT_FONT_FLAG) { - ATSUStyle style = (ATSUStyle)(fontlayoutengine[f]); - ATSGlyphIdealMetrics metrics; - OSStatus status = ATSUGlyphGetIdealMetrics(style, 1, &gid, 0, &metrics); - /* returns values in Quartz points, so we need to convert to TeX points */ - if (status == noErr) { - node_width(node) = D2Fix(metrics.advance.x * 72.27 / 72.0); - if (use_glyph_metrics) - GetGlyphHeightDepth_AAT(style, gid, &ht, &dp); - } + CFDictionaryRef attributes = (CFDictionaryRef)(fontlayoutengine[f]); + node_width(node) = D2Fix(GetGlyphWidth_AAT(attributes, gid)); + if (use_glyph_metrics) + GetGlyphHeightDepth_AAT(attributes, gid, &ht, &dp); } else #endif @@ -2275,7 +2242,7 @@ mapchartoglyph(integer font, integer ch) return 0; #ifdef XETEX_MAC if (fontarea[font] == AAT_FONT_FLAG) - return MapCharToGlyph_AAT((ATSUStyle)(fontlayoutengine[font]), ch); + return MapCharToGlyph_AAT((CFDictionaryRef)(fontlayoutengine[font]), ch); else #endif if (fontarea[font] == OTGR_FONT_FLAG) @@ -2292,7 +2259,7 @@ mapglyphtoindex(integer font) { #ifdef XETEX_MAC if (fontarea[font] == AAT_FONT_FLAG) - return MapGlyphToIndex_AAT((ATSUStyle)(fontlayoutengine[font]), (const char*)nameoffile + 1); + return MapGlyphToIndex_AAT((CFDictionaryRef)(fontlayoutengine[font]), (const char*)nameoffile + 1); else #endif if (fontarea[font] == OTGR_FONT_FLAG) @@ -2308,7 +2275,7 @@ getfontcharrange(integer font, int first) { #ifdef XETEX_MAC if (fontarea[font] == AAT_FONT_FLAG) - return GetFontCharRange_AAT((ATSUStyle)(fontlayoutengine[font]), first); + return GetFontCharRange_AAT((CFDictionaryRef)(fontlayoutengine[font]), first); else #endif if (fontarea[font] == OTGR_FONT_FLAG) @@ -2333,115 +2300,41 @@ double Fix2D(Fixed f) /* these are here, not XeTeX_mac.c, because we need stubs on other platforms */ void -atsugetfontmetrics(ATSUStyle style, integer* ascent, integer* descent, integer* xheight, integer* capheight, integer* slant) +atsugetfontmetrics(CFDictionaryRef attributes, integer* ascent, integer* descent, integer* xheight, integer* capheight, integer* slant) { #ifdef XETEX_MAC - *ascent = *descent = *xheight = *capheight = *slant = 0; - - ATSUFontID fontID; - OSStatus status = ATSUGetAttribute(style, kATSUFontTag, sizeof(ATSUFontID), &fontID, 0); - if (status != noErr) - return; - - ATSFontRef fontRef = FMGetATSFontRefFromFont(fontID); - - Fixed size; - status = ATSUGetAttribute(style, kATSUSizeTag, sizeof(Fixed), &size, 0); - if (status != noErr) - return; - /* size from the ATSUStyle is in Quartz points; convert to TeX points here */ - double floatSize = Fix2D(size) * 72.27 / 72.0; - - ATSFontMetrics metrics; - status = ATSFontGetHorizontalMetrics(fontRef, kATSOptionFlagsDefault, &metrics); - if (status != noErr) - return; - - *ascent = D2Fix(metrics.ascent * floatSize); - *descent = D2Fix(metrics.descent * floatSize); + CTFontRef font = fontFromAttributes(attributes); - if (metrics.italicAngle != 0.0) { - if (fabs(metrics.italicAngle) < 0.090) - metrics.italicAngle *= 1000.0; /* hack around apparent ATS bug */ - *slant = D2Fix(tan(-metrics.italicAngle * M_PI / 180.0)); - } - else { - /* try to get a (possibly synthetic) POST table, as ATSFontGetHorizontalMetrics - doesn't seem to return this value for OT/CFF fonts */ - ByteCount tableSize; - if (ATSFontGetTable(fontRef, kPOST, 0, 0, 0, &tableSize) == noErr) { - struct POSTTable* post = xmalloc(tableSize); - ATSFontGetTable(fontRef, kPOST, 0, tableSize, post, 0); - *slant = D2Fix(tan(Fix2D( - SWAP32(post->italicAngle)) * M_PI / 180.0)); - free(post); - } - } - - CGAffineTransform t; - ATSUGetAttribute(style, kATSUFontMatrixTag, sizeof(CGAffineTransform), &t, 0); - if (t.a != 1.0) - *slant = D2Fix(Fix2D(*slant) * t.a); - if (t.b != 0.0) - *slant += D2Fix(t.b); - - if (0 && metrics.xHeight != 0.0) { - /* currently not using this, as the values from ATS don't seem quite what I'd expect */ - *xheight = D2Fix(metrics.xHeight * floatSize); - *capheight = D2Fix(metrics.capHeight * floatSize); - } - else { - int glyphID = MapCharToGlyph_AAT(style, 'x'); - float ht, dp; - if (glyphID != 0) { - GetGlyphHeightDepth_AAT(style, glyphID, &ht, &dp); - *xheight = D2Fix(ht); - } - else - *xheight = *ascent / 2; /* arbitrary figure if there's no 'x' in the font */ - - glyphID = MapCharToGlyph_AAT(style, 'X'); - if (glyphID != 0) { - GetGlyphHeightDepth_AAT(style, glyphID, &ht, &dp); - *capheight = D2Fix(ht); - } - else - *capheight = *ascent; /* arbitrary figure if there's no 'X' in the font */ - } + *ascent = D2Fix(CTFontGetAscent(font)); + *descent = D2Fix(CTFontGetDescent(font)); + *xheight = D2Fix(CTFontGetXHeight(font)); + *capheight = D2Fix(CTFontGetCapHeight(font)); + *slant = D2Fix(tan(-CTFontGetSlantAngle(font) * M_PI / 180.0)); #endif } int -atsufontget(int what, ATSUStyle style) +atsufontget(int what, CFDictionaryRef attributes) { int rval = -1; #ifdef XETEX_MAC - ATSUFontID fontID; - ATSUGetAttribute(style, kATSUFontTag, sizeof(ATSUFontID), &fontID, 0); - ItemCount count; + CTFontRef font = fontFromAttributes(attributes); + CFArrayRef list; switch (what) { case XeTeX_count_glyphs: - { - ByteCount tableSize; - ATSFontRef fontRef = FMGetATSFontRefFromFont(fontID); - if (ATSFontGetTable(fontRef, kMAXP, 0, 0, 0, &tableSize) == noErr) { - struct MAXPTable* table = xmalloc(tableSize); - ATSFontGetTable(fontRef, kMAXP, 0, tableSize, table, 0); - rval = SWAP16(table->numGlyphs); - free(table); - } - } + rval = CTFontGetGlyphCount(font); break; case XeTeX_count_variations: - if (ATSUCountFontVariations(fontID, &count) == noErr) - rval = count; - break; - case XeTeX_count_features: - if (ATSUCountFontFeatureTypes(fontID, &count) == noErr) - rval = count; + list = (what == XeTeX_count_variations ? CTFontCopyVariationAxes(font) + : CTFontCopyFeatures(font)); + if (list) { + rval = CFArrayGetCount(list); + CFRelease(list); + } break; } #endif @@ -2449,59 +2342,88 @@ atsufontget(int what, ATSUStyle style) } int -atsufontget1(int what, ATSUStyle style, int param) +atsufontget1(int what, CFDictionaryRef attributes, int param) { int rval = -1; #ifdef XETEX_MAC - ATSUFontID fontID; - ATSUGetAttribute(style, kATSUFontTag, sizeof(ATSUFontID), &fontID, 0); - - ATSUFontVariationAxis axis; - ATSUFontVariationValue value; - ItemCount count; - Boolean exclusive; + CTFontRef font = fontFromAttributes(attributes); + switch (what) { case XeTeX_variation: - if (ATSUGetIndFontVariation(fontID, param, &axis, 0, 0, 0) == noErr) - rval = axis; + { + CFArrayRef axes = CTFontCopyVariationAxes(font); + if (!axes) + break; + if (CFArrayGetCount(axes) > param) { + CFDictionaryRef variation = CFArrayGetValueAtIndex(axes, param); + CFNumberRef identifier = CFDictionaryGetValue(variation, kCTFontVariationAxisIdentifierKey); + CFNumberGetValue(identifier, kCFNumberIntType, &rval); + } + CFRelease(axes); break; + } case XeTeX_variation_min: case XeTeX_variation_max: case XeTeX_variation_default: - if (ATSUCountFontVariations(fontID, &count) == noErr) - while (count-- > 0) - if (ATSUGetIndFontVariation(fontID, count, &axis, - (what == XeTeX_variation_min) ? &value : 0, - (what == XeTeX_variation_max) ? &value : 0, - (what == XeTeX_variation_default) ? &value : 0) == noErr) - if (axis == param) { - rval = value; - break; - } + { + CFArrayRef axes = CTFontCopyVariationAxes(font); + if (!axes) + break; + CFDictionaryRef variation = findDictionaryInArrayWithIdentifier(axes, kCTFontVariationAxisIdentifierKey, param); + CFStringRef key = (what == XeTeX_variation_min ? kCTFontVariationAxisMinimumValueKey : + (what == XeTeX_variation_max ? kCTFontVariationAxisMaximumValueKey : + kCTFontVariationAxisDefaultValueKey)); + CFNumberRef value = CFDictionaryGetValue(variation, key); + if (value) + CFNumberGetValue(value, kCFNumberIntType, &rval); + CFRelease(axes); break; + } case XeTeX_feature_code: - if (ATSUCountFontFeatureTypes(fontID, &count) == noErr) { - if (param < count) { - ATSUFontFeatureType* types = xmalloc(count * sizeof(ATSUFontFeatureType)); - if (ATSUGetFontFeatureTypes(fontID, count, types, 0) == noErr) - rval = types[param]; - free(types); - } + { + CFArrayRef features = CTFontCopyFeatures(font); + if (!features) + break; + if (CFArrayGetCount(features) > param) { + CFDictionaryRef feature = CFArrayGetValueAtIndex(features, param); + CFNumberRef identifier = CFDictionaryGetValue(feature, kCTFontFeatureTypeIdentifierKey); + CFNumberGetValue(identifier, kCFNumberIntType, &rval); } + CFRelease(features); break; + } case XeTeX_is_exclusive_feature: - if (ATSUGetFontFeatureSelectors(fontID, param, 0, 0, 0, 0, &exclusive) == noErr) - rval = exclusive ? 1 : 0; + { + CFArrayRef features = CTFontCopyFeatures(font); + if (!features) + break; + CFDictionaryRef feature = findDictionaryInArrayWithIdentifier(features, kCTFontFeatureTypeIdentifierKey, param); + CFBooleanRef value; + Boolean found = CFDictionaryGetValueIfPresent(feature, kCTFontFeatureTypeExclusiveKey, (const void **)&value); + if (found) + rval = CFBooleanGetValue(value); + CFRelease(features); break; + } case XeTeX_count_selectors: - if (ATSUCountFontFeatureSelectors(fontID, param, &count) == noErr) - rval = count; + { + CFArrayRef features = CTFontCopyFeatures(font); + if (!features) + break; + CFDictionaryRef feature = findDictionaryInArrayWithIdentifier(features, kCTFontFeatureTypeIdentifierKey, param); + if (feature) { + CFArrayRef selectors = CFDictionaryGetValue(feature, kCTFontFeatureTypeSelectorsKey); + if (selectors) + rval = CFArrayGetCount(selectors); + } + CFRelease(features); break; + } } #endif @@ -2509,36 +2431,40 @@ atsufontget1(int what, ATSUStyle style, int param) } int -atsufontget2(int what, ATSUStyle style, int param1, int param2) +atsufontget2(int what, CFDictionaryRef attributes, int param1, int param2) { int rval = -1; #ifdef XETEX_MAC - ATSUFontID fontID; - ATSUGetAttribute(style, kATSUFontTag, sizeof(ATSUFontID), &fontID, 0); - - ItemCount count; - if (ATSUCountFontFeatureSelectors(fontID, param1, &count) == noErr) { - ATSUFontFeatureSelector* selectors = xmalloc(count * sizeof(ATSUFontFeatureSelector)); - Boolean* isDefault = xmalloc(count * sizeof(Boolean)); - if (ATSUGetFontFeatureSelectors(fontID, param1, count, selectors, isDefault, 0, 0) == noErr) { - switch (what) { - case XeTeX_selector_code: - if (param2 < count) - rval = selectors[param2]; - break; - - case XeTeX_is_default_selector: - while (count-- > 0) - if (selectors[count] == param2) { - rval = isDefault[count] ? 1 : 0; - break; + CTFontRef font = fontFromAttributes(attributes); + CFArrayRef features = CTFontCopyFeatures(font); + if (features) { + CFDictionaryRef feature = findDictionaryInArrayWithIdentifier(features, kCTFontFeatureTypeIdentifierKey, param1); + if (feature) { + CFArrayRef selectors = CFDictionaryGetValue(feature, kCTFontFeatureTypeSelectorsKey); + if (selectors) { + CFDictionaryRef selector; + switch (what) { + case XeTeX_selector_code: + if (CFArrayGetCount(selectors) > param2) { + selector = CFArrayGetValueAtIndex(selectors, param2); + CFNumberRef identifier = CFDictionaryGetValue(selector, kCTFontFeatureSelectorIdentifierKey); + CFNumberGetValue(identifier, kCFNumberIntType, &rval); + } + break; + case XeTeX_is_default_selector: + selector = findDictionaryInArrayWithIdentifier(selectors, kCTFontFeatureSelectorIdentifierKey, param2); + if (selector) { + CFBooleanRef isDefault; + Boolean found = CFDictionaryGetValueIfPresent(selector, kCTFontFeatureSelectorDefaultKey, (const void **)&isDefault); + if (found) + rval = CFBooleanGetValue(isDefault); } - break; + break; + } } } - free(isDefault); - free(selectors); + CFRelease(features); } #endif @@ -2546,26 +2472,41 @@ atsufontget2(int what, ATSUStyle style, int param1, int param2) } int -atsufontgetnamed(int what, ATSUStyle style) +atsufontgetnamed(int what, CFDictionaryRef attributes) { int rval = -1; #ifdef XETEX_MAC - ATSUFontID fontID; - ATSUGetAttribute(style, kATSUFontTag, sizeof(ATSUFontID), &fontID, 0); - + CTFontRef font = fontFromAttributes(attributes); + switch (what) { case XeTeX_find_variation_by_name: - rval = find_axis_by_name(fontID, (const char*)nameoffile + 1, namelength); - if (rval == 0) + { + CFArrayRef axes = CTFontCopyVariationAxes(font); + CFDictionaryRef variation = findDictionaryInArray(axes, kCTFontVariationAxisNameKey, + (const char*)nameoffile + 1, namelength); + if (variation) { + CFNumberRef identifier = CFDictionaryGetValue(variation, kCTFontVariationAxisIdentifierKey); + CFNumberGetValue(identifier, kCFNumberIntType, &rval); + } else rval = -1; + CFRelease(axes); break; + } case XeTeX_find_feature_by_name: - rval = find_feature_by_name(fontID, (const char*)nameoffile + 1, namelength); - if (rval == 0x0000FFFF) + { + CFArrayRef features = CTFontCopyFeatures(font); + CFDictionaryRef feature = findDictionaryInArray(features, kCTFontFeatureTypeNameKey, + (const char*)nameoffile + 1, namelength); + if (feature) { + CFNumberRef identifier = CFDictionaryGetValue(feature, kCTFontFeatureTypeIdentifierKey); + CFNumberGetValue(identifier, kCFNumberIntType, &rval); + } else rval = -1; + CFRelease(features); break; + } } #endif @@ -2573,20 +2514,22 @@ atsufontgetnamed(int what, ATSUStyle style) } int -atsufontgetnamed1(int what, ATSUStyle style, int param) +atsufontgetnamed1(int what, CFDictionaryRef attributes, int param) { int rval = -1; #ifdef XETEX_MAC - ATSUFontID fontID; - ATSUGetAttribute(style, kATSUFontTag, sizeof(ATSUFontID), &fontID, 0); - - switch (what) { - case XeTeX_find_selector_by_name: - rval = find_selector_by_name(fontID, param, (const char*)nameoffile + 1, namelength); - if (rval == 0x0000FFFF) - rval = -1; - break; + CTFontRef font = fontFromAttributes(attributes); + + if (what == XeTeX_find_selector_by_name) { + CFArrayRef features = CTFontCopyFeatures(font); + CFDictionaryRef feature = findDictionaryInArrayWithIdentifier(features, kCTFontFeatureTypeIdentifierKey, param); + if (feature) { + CFNumberRef selector = findSelectorByName(feature, (const char*)nameoffile + 1, namelength); + if (selector) + CFNumberGetValue(selector, kCFNumberIntType, &rval); + } + CFRelease(features); } #endif @@ -2594,109 +2537,46 @@ atsufontgetnamed1(int what, ATSUStyle style, int param) } void -atsuprintfontname(int what, ATSUStyle style, int param1, int param2) +atsuprintfontname(int what, CFDictionaryRef attributes, int param1, int param2) { #ifdef XETEX_MAC - ATSUFontID fontID; - ATSUGetAttribute(style, kATSUFontTag, sizeof(ATSUFontID), &fontID, 0); - - FontNameCode code; - OSStatus status = -1; - ItemCount count, i; - Boolean found = 0; - - switch (what) { - case XeTeX_variation_name: - status = ATSUCountFontVariations(fontID, &count); - if (status == noErr) { - for (i = 0; i < count; ++i) { - ATSUFontVariationAxis axis; - ATSUFontVariationValue min, max, def; - status = ATSUGetIndFontVariation(fontID, i, &axis, &min, &max, &def); - if (status == noErr && axis == param1) { - status = ATSUGetFontVariationNameCode(fontID, param1, &code); - found = 1; - break; - } - } + CTFontRef font = fontFromAttributes(attributes); + CFStringRef name = NULL; + if (what == XeTeX_variation_name) { + CFArrayRef axes = CTFontCopyVariationAxes(font); + CFDictionaryRef variation = findDictionaryInArrayWithIdentifier(axes, + kCTFontVariationAxisIdentifierKey, + param1); + if (variation) + name = CFDictionaryGetValue(variation, kCTFontVariationAxisNameKey); + CFRelease(axes); + } + else if (what == XeTeX_feature_name || XeTeX_selector_name) { + CFArrayRef features = CTFontCopyFeatures(font); + CFDictionaryRef feature = findDictionaryInArrayWithIdentifier(features, + kCTFontFeatureTypeIdentifierKey, + param1); + if (feature) { + if (what == XeTeX_feature_name) + name = CFDictionaryGetValue(feature, kCTFontFeatureTypeNameKey); + else { + CFArrayRef selectors = CFDictionaryGetValue(feature, kCTFontFeatureTypeSelectorsKey); + CFDictionaryRef selector = findDictionaryInArrayWithIdentifier(selectors, + kCTFontFeatureSelectorIdentifierKey, + param2); + if (selector) + name = CFDictionaryGetValue(selector, kCTFontFeatureSelectorNameKey); } - break; - - case XeTeX_feature_name: - case XeTeX_selector_name: - status = ATSUCountFontFeatureTypes(fontID, &count); - if (status == noErr) { - ATSUFontFeatureType* features = xmalloc(count * sizeof(ATSUFontFeatureType)); - status = ATSUGetFontFeatureTypes(fontID, count, features, &count); - if (status == noErr) { - for (i = 0; i < count; ++i) { - if (features[i] == param1) { - /* the requested feature code is valid */ - if (what == XeTeX_feature_name) { - status = ATSUGetFontFeatureNameCode(fontID, param1, kATSUNoSelector, &code); - found = 1; - } - else { - status = ATSUCountFontFeatureSelectors(fontID, param1, &count); - if (status == noErr) { - ATSUFontFeatureSelector* selectors = xmalloc(count * sizeof(ATSUFontFeatureSelector)); - Boolean* onByDefault = xmalloc(count * sizeof(Boolean)); - Boolean exclusive; - status = ATSUGetFontFeatureSelectors(fontID, param1, count, selectors, onByDefault, &count, &exclusive); - if (status == noErr) { - for (i = 0; i < count; ++i) { - if (selectors[i] == param2) { - /* feature/selector combination is valid */ - status = ATSUGetFontFeatureNameCode(fontID, param1, param2, &code); - found = 1; - break; - } - } - } - free(onByDefault); - free(selectors); - } - } - break; - } - } - } - free(features); - } - break; + } + CFRelease(features); } - if (found && status == noErr) { -#define NAME_BUF_SIZE 1024 - ByteCount len = 0; - char name[NAME_BUF_SIZE]; /* should be more than enough for any sensible font name */ - do { - if (ATSUFindFontName(fontID, code, kFontMacintoshPlatform, kFontRomanScript, kFontEnglishLanguage, NAME_BUF_SIZE, name, &len, 0) == noErr) break; - if (ATSUFindFontName(fontID, code, kFontMacintoshPlatform, kFontRomanScript, kFontNoLanguageCode, NAME_BUF_SIZE, name, &len, 0) == noErr) break; - } while (0); - if (len > 0) { - /* need to convert MacRoman name to Unicode */ - CFStringRef str = CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8*)name, len, kCFStringEncodingMacRoman, false); - if (str != NULL) { - len = CFStringGetLength(str); - UniChar* buf = xmalloc(len * sizeof(UniChar)); - CFStringGetCharacters(str, CFRangeMake(0, len), buf); - printchars(buf, len); - free(buf); - CFRelease(str); - } - } - else { - do { - if (ATSUFindFontName(fontID, code, kFontUnicodePlatform, kFontNoScriptCode, kFontEnglishLanguage, NAME_BUF_SIZE, name, &len, 0) == noErr) break; - if (ATSUFindFontName(fontID, code, kFontMicrosoftPlatform, kFontNoScriptCode, kFontEnglishLanguage, NAME_BUF_SIZE, name, &len, 0) == noErr) break; - if (ATSUFindFontName(fontID, code, kFontUnicodePlatform, kFontNoScriptCode, kFontNoLanguageCode, NAME_BUF_SIZE, name, &len, 0) == noErr) break; - if (ATSUFindFontName(fontID, code, kFontMicrosoftPlatform, kFontNoScriptCode, kFontNoLanguageCode, NAME_BUF_SIZE, name, &len, 0) == noErr) break; - } while (0); - if (len > 0) { - printchars((unsigned short*)(&name[0]), len / 2); - } - } + if (name) { + CFIndex len = CFStringGetLength(name); + UniChar* buf = xmalloc(len * sizeof(UniChar)); + CFStringGetCharacters(name, CFRangeMake(0, len), buf); + printchars(buf, len); + free(buf); } #endif } @@ -2708,8 +2588,7 @@ printglyphname(integer font, integer gid) int len = 0; #ifdef XETEX_MAC if (fontarea[font] == AAT_FONT_FLAG) { - ATSUStyle style = (ATSUStyle)(fontlayoutengine[font]); - s = GetGlyphName_AAT(style, gid, &len); + s = GetGlyphNameFromCTFont(fontFromInteger(font), gid, &len); } else #endif @@ -2729,7 +2608,7 @@ int u_open_in(unicodefile* f, integer filefmt, const_string fopen_mode, integer mode, integer encodingData) { boolean rval; - *f = malloc(sizeof(UFILE)); + *f = xmalloc(sizeof(UFILE)); (*f)->encodingMode = 0; (*f)->conversionData = 0; (*f)->savedChar = -1; @@ -2886,7 +2765,7 @@ get_uni_c(UFILE* f) case UTF8: c = rval = getc(f->f); if (rval != EOF) { - UInt16 extraBytes = bytesFromUTF8[rval]; + uint16_t extraBytes = bytesFromUTF8[rval]; switch (extraBytes) { /* note: code falls through cases! */ case 3: c = getc(f->f); if (c < 0x80 || c >= 0xc0) goto bad_utf8; @@ -2969,18 +2848,18 @@ void makeutf16name() { unsigned char* s = nameoffile + 1; - UInt32 rval; - UInt16* t; + uint32_t rval; + uint16_t* t; static int name16len = 0; if (name16len <= namelength) { if (nameoffile16 != 0) free(nameoffile16); name16len = namelength + 10; - nameoffile16 = xmalloc(name16len * sizeof(UInt16)); + nameoffile16 = xmalloc(name16len * sizeof(uint16_t)); } t = nameoffile16; while (s <= nameoffile + namelength) { - UInt16 extraBytes; + uint16_t extraBytes; rval = *(s++); extraBytes = bytesFromUTF8[rval]; switch (extraBytes) { /* note: code falls through cases! */ @@ -3018,10 +2897,10 @@ integer get_native_word_cp(void* pNode, int side) { memoryword* node = (memoryword*)pNode; FixedPoint* locations = (FixedPoint*)native_glyph_info_ptr(node); - UInt16* glyphIDs = (UInt16*)(locations + native_glyph_count(node)); - UInt16 glyphCount = native_glyph_count(node); + uint16_t* glyphIDs = (uint16_t*)(locations + native_glyph_count(node)); + uint16_t glyphCount = native_glyph_count(node); integer f = native_font(node); - UInt16 actual_glyph; + uint16_t actual_glyph; if (glyphCount == 0) return 0; diff --git a/Build/source/texk/web2c/xetexdir/XeTeX_ext.h b/Build/source/texk/web2c/xetexdir/XeTeX_ext.h index 828801de5d1..73368232034 100644 --- a/Build/source/texk/web2c/xetexdir/XeTeX_ext.h +++ b/Build/source/texk/web2c/xetexdir/XeTeX_ext.h @@ -2,6 +2,8 @@ Part of the XeTeX typesetting system Copyright (c) 1994-2008 by SIL International Copyright (c) 2009, 2011 by Jonathan Kew + Copyright (c) 2012, 2013 by Jiang Jiang + Copyright (c) 2012, 2013 by Khaled Hosny SIL Author(s): Jonathan Kew @@ -35,28 +37,13 @@ authorization from the copyright holders. #include <unicode/utypes.h> #include <w2c/c-auto.h> /* needed for SIZEOF_LONG and NO_DUMP_SHARE */ -/***** copied from TeX/texk/web2c/config.h -- difficult to include in C++ source files ******/ -#ifndef INTEGER_TYPE - -#if SIZEOF_LONG > 4 && !defined (NO_DUMP_SHARE) -/* If we have 64-bit longs and want to share format files (with 32-bit - machines), use `int'. */ -#define INTEGER_IS_INT +#ifdef __cplusplus +extern "C" { +#endif +#include <w2c/config.h> +#ifdef __cplusplus +} #endif - -#ifdef INTEGER_IS_INT -#define INTEGER_TYPE int -#define INTEGER_MAX INT_MAX -#define INTEGER_MIN INT_MIN -#else -#define INTEGER_TYPE long -#define INTEGER_MAX LONG_MAX -#define INTEGER_MIN LONG_MIN -#endif /* not INTEGER_IS_INT */ - -typedef INTEGER_TYPE integer; -#endif /* not INTEGER_TYPE */ -/***** end of config.h stuff *****/ #ifndef XETEX_UNICODE_FILE_DEFINED typedef struct UFILE* unicodefile; @@ -75,21 +62,10 @@ typedef struct UFILE* unicodefile; but otherwise we'll need these substitute definitions */ #ifdef XETEX_MAC -#include <Carbon/Carbon.h> +#include <CoreFoundation/CoreFoundation.h> +#include <ApplicationServices/ApplicationServices.h> #else -#ifndef __TECkit_Common_H__ -typedef unsigned char UInt8; -typedef unsigned short UInt16; -typedef unsigned int UInt32; -typedef UInt16 UniChar; -#endif - -typedef signed char SInt8; -typedef short SInt16; -typedef int SInt32; - -typedef SInt32 OSStatus; -typedef SInt32 Fixed; +typedef int32_t Fixed; typedef struct { Fixed x; Fixed y; @@ -155,7 +131,7 @@ typedef uint16_t GlyphID; #define native_font(node) node[native_info_offset].qqqq.b1 #define native_glyph_count(node) node[native_info_offset].qqqq.b3 #define native_glyph_info_ptr(node) node[native_glyph_info_offset].ptr -#define native_glyph_info_size 10 /* info for each glyph is location (FixedPoint) + glyph ID (UInt16) */ +#define native_glyph_info_size 10 /* info for each glyph is location (FixedPoint) + glyph ID (uint16_t) */ #define native_glyph(p) native_length(p) /* glyph ID field in a glyph_node */ @@ -175,19 +151,6 @@ typedef uint16_t GlyphID; #define kMAXP HB_TAG('m','a','x','p') #define kOS_2 HB_TAG('O','S','/','2') -struct postTable { - Fixed format; - Fixed italicAngle; - SInt16 underlinePosition; - SInt16 underlineThickness; - UInt16 isFixedPitch; - UInt16 reserved; - UInt32 minMemType42; - UInt32 maxMemType42; - UInt32 minMemType1; - UInt32 maxMemType1; -}; - typedef struct { float xMin; @@ -198,19 +161,19 @@ typedef struct /* For Unicode encoding form interpretation... */ -extern const UInt32 offsetsFromUTF8[6]; -extern const UInt8 bytesFromUTF8[256]; -extern const UInt8 firstByteMark[7]; +extern const uint32_t offsetsFromUTF8[6]; +extern const uint8_t bytesFromUTF8[256]; +extern const uint8_t firstByteMark[7]; extern const int halfShift; -extern const UInt32 halfBase; -extern const UInt32 halfMask; -extern const UInt32 kSurrogateHighStart; -extern const UInt32 kSurrogateHighEnd; -extern const UInt32 kSurrogateLowStart; -extern const UInt32 kSurrogateLowEnd; -extern const UInt32 byteMask; -extern const UInt32 byteMark; +extern const uint32_t halfBase; +extern const uint32_t halfMask; +extern const uint32_t kSurrogateHighStart; +extern const uint32_t kSurrogateHighEnd; +extern const uint32_t kSurrogateLowStart; +extern const uint32_t kSurrogateLowEnd; +extern const uint32_t byteMask; +extern const uint32_t byteMark; extern const char *papersize; extern const char *outputdriver; @@ -243,6 +206,10 @@ extern FT_Library gFreeTypeLibrary; #include "XeTeXLayoutInterface.h" +#ifdef XETEX_MAC +extern const CFStringRef kXeTeXEmboldenAttributeName; +#endif + #ifdef __cplusplus extern "C" { #endif @@ -250,15 +217,14 @@ extern "C" { void setinputfileencoding(unicodefile f, integer mode, integer encodingData); void uclose(unicodefile f); - void linebreakstart(int f, integer localeStrNum, const UniChar* text, integer textLength); + void linebreakstart(int f, integer localeStrNum, const uint16_t* text, integer textLength); int linebreaknext(); int getencodingmodeandinfo(integer* info); void printutf8str(const unsigned char* str, int len); void printchars(const unsigned short* str, int len); - void* load_mapping_file(const char* s, const char* e, char byteMapping); void* findnativefont(unsigned char* name, integer scaled_size); void releasefontengine(void* engine, int type_flag); - int readCommonFeatures(const char* feat, const char* end, float* extend, float* slant, float* embolden, float* letterspace, UInt32* rgbValue); + int readCommonFeatures(const char* feat, const char* end, float* extend, float* slant, float* embolden, float* letterspace, uint32_t* rgbValue); /* the metrics params here are really TeX 'scaled' values, but that typedef isn't available every place this is included */ void otgetfontmetrics(void* engine, integer* ascent, integer* descent, integer* xheight, integer* capheight, integer* slant); @@ -279,7 +245,7 @@ extern "C" { integer otfontget3(integer what, void* engine, integer param1, integer param2, integer param3); int makeXDVGlyphArrayData(void* p); int makefontdef(integer f); - int applymapping(void* cnv, const UniChar* txtPtr, int txtLen); + int applymapping(void* cnv, const uint16_t* txtPtr, int txtLen); void store_justified_native_glyphs(void* node); void measure_native_node(void* node, int use_glyph_metrics); Fixed get_native_italic_correction(void* node); @@ -289,7 +255,7 @@ extern "C" { integer mapglyphtoindex(integer font); integer getfontcharrange(integer font, int first); void printglyphname(integer font, integer gid); - UInt16 get_native_glyph(void* pNode, unsigned index); + uint16_t get_native_glyph(void* pNode, unsigned index); void grprintfontname(integer what, void* pEngine, integer param1, integer param2); integer grfontgetnamed(integer what, void* pEngine); @@ -298,7 +264,7 @@ extern "C" { double read_double(const char** s); unsigned int read_rgb_a(const char** cp); - const char* getGlyphNamePtr(const char* buffer, int tableSize, UInt16 gid, int* len); + const char* getGlyphNamePtr(const char* buffer, int tableSize, uint16_t gid, int* len); int countpdffilepages(); int find_pic_file(char** path, realrect* bounds, int pdfBoxType, int page); @@ -317,45 +283,43 @@ extern "C" { int applytfmfontmapping(void* mapping, int c); #ifndef XETEX_MAC -typedef void* ATSUStyle; /* dummy declaration just so the stubs can compile */ +typedef void* CFDictionaryRef; /* dummy declaration just so the stubs can compile */ #endif - int atsufontget(int what, ATSUStyle style); - int atsufontget1(int what, ATSUStyle style, int param); - int atsufontget2(int what, ATSUStyle style, int param1, int param2); - int atsufontgetnamed(int what, ATSUStyle style); - int atsufontgetnamed1(int what, ATSUStyle style, int param); - void atsuprintfontname(int what, ATSUStyle style, int param1, int param2); + int atsufontget(int what, CFDictionaryRef attrs); + int atsufontget1(int what, CFDictionaryRef attrs, int param); + int atsufontget2(int what, CFDictionaryRef attrs, int param1, int param2); + int atsufontgetnamed(int what, CFDictionaryRef attrs); + int atsufontgetnamed1(int what, CFDictionaryRef attrs, int param); + void atsuprintfontname(int what, CFDictionaryRef attrs, int param1, int param2); /* the metrics params here are really TeX 'scaled' (or MacOS 'Fixed') values, but that typedef isn't available every place this is included */ - void atsugetfontmetrics(ATSUStyle style, integer* ascent, integer* descent, integer* xheight, integer* capheight, integer* slant); + void atsugetfontmetrics(CFDictionaryRef attrs, integer* ascent, integer* descent, integer* xheight, integer* capheight, integer* slant); #ifdef XETEX_MAC -#if defined(MAC_OS_X_VERSION_10_7) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7) - #include <ApplicationServices/ApplicationServices.h> - /* These functions have been removed on 10.7; as a workaround, just do - * a cast as the ATSFontRef and ATSUFontID should have the same value... */ - #define FMGetFontFromATSFontRef(x) ((ATSUFontID) x) - #define FMGetATSFontRefFromFont(x) ((ATSFontRef) x) -#endif - /* functions in XeTeX_mac.c */ - void* loadAATfont(ATSFontRef fontRef, integer scaled_size, const char* cp1); + void* loadAATfont(CTFontDescriptorRef descriptor, integer scaled_size, const char* cp1); void DoAtsuiLayout(void* node, int justify); - void GetGlyphBBox_AAT(ATSUStyle style, UInt16 gid, GlyphBBox* bbox); - float GetGlyphWidth_AAT(ATSUStyle style, UInt16 gid); - void GetGlyphHeightDepth_AAT(ATSUStyle style, UInt16 gid, float* ht, float* dp); - void GetGlyphSidebearings_AAT(ATSUStyle style, UInt16 gid, float* lsb, float* rsb); - int MapCharToGlyph_AAT(ATSUStyle style, UInt32 ch); - int MapGlyphToIndex_AAT(ATSUStyle style, const char* glyphName); - int GetGlyphIDFromCGFont(ATSFontRef atsFontRef, const char* glyphName); - float GetGlyphItalCorr_AAT(ATSUStyle style, UInt16 gid); - char* GetGlyphName_AAT(ATSUStyle style, UInt16 gid, int* len); - char* GetGlyphNameFromCGFont(ATSFontRef atsFontRef, UInt16 gid, int* len); - int GetFontCharRange_AAT(ATSUStyle style, int reqFirst); - ATSUFontVariationAxis find_axis_by_name(ATSUFontID fontID, const char* name, int nameLength); - ATSUFontFeatureType find_feature_by_name(ATSUFontID fontID, const char* name, int nameLength); - ATSUFontFeatureSelector find_selector_by_name(ATSUFontID fontID, ATSUFontFeatureType featureType, const char* name, int nameLength); + void GetGlyphBBox_AAT(CFDictionaryRef fontAttrs, uint16_t gid, GlyphBBox* bbox); + double GetGlyphWidth_AAT(CFDictionaryRef fontAttrs, uint16_t gid); + void GetGlyphHeightDepth_AAT(CFDictionaryRef fontAttrs, uint16_t gid, float* ht, float* dp); + void GetGlyphSidebearings_AAT(CFDictionaryRef fontAttrs, uint16_t gid, float* lsb, float* rsb); + double GetGlyphItalCorr_AAT(CFDictionaryRef fontAttrs, uint16_t gid); + int MapCharToGlyph_AAT(CFDictionaryRef fontAttrs, uint32_t ch); + int MapGlyphToIndex_AAT(CFDictionaryRef attributes, const char* glyphName); + char* GetGlyphNameFromCTFont(CTFontRef ctFontRef, uint16_t gid, int* len); + int GetGlyphIDFromCTFont(CTFontRef ctFontRef, const char* glyphName); + CFDictionaryRef findDictionaryInArray(CFArrayRef array, const void* nameKey, const char* name, int nameLength); + CFDictionaryRef findDictionaryInArrayWithIdentifier(CFArrayRef array, const void* identifierKey, int identifier); + CFNumberRef findSelectorByName(CFDictionaryRef feature, const char* name, int nameLength); + char* getNameFromCTFont(CTFontRef ctFontRef, CFStringRef nameKey); + char* getFileNameFromCTFont(CTFontRef ctFontRef); + int GetFontCharRange_AAT(CFDictionaryRef fontAttrs, int reqFirst); + CTFontRef fontFromAttributes(CFDictionaryRef fontAttrs); + CTFontRef fontFromInteger(integer font); + void getGlyphBBoxFromCTFont(CTFontRef ctFontRef, uint16_t gid, GlyphBBox* bbox); + int mapCharToGlyphFromCTFont(CTFontRef font, uint32_t ch, uint32_t vs); + double getGlyphWidthFromCTFont(CTFontRef font, uint16_t gid); #endif #ifdef __cplusplus }; diff --git a/Build/source/texk/web2c/xetexdir/XeTeX_mac.c b/Build/source/texk/web2c/xetexdir/XeTeX_mac.c index bef5ef3c8ac..4f0f186bdf4 100644 --- a/Build/source/texk/web2c/xetexdir/XeTeX_mac.c +++ b/Build/source/texk/web2c/xetexdir/XeTeX_mac.c @@ -2,6 +2,8 @@ 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, 2013 by Khaled Hosny SIL Author(s): Jonathan Kew @@ -43,9 +45,7 @@ authorization from the copyright holders. #define EXTERN extern #include "xetexd.h" -#undef input /* this is defined in texmfmp.h, but we don't need it and it confuses the carbon headers */ -#include <Carbon/Carbon.h> -#include <QuickTime/QuickTime.h> +#include <ApplicationServices/ApplicationServices.h> #include <teckit/TECkit_Engine.h> #include "XeTeX_ext.h" @@ -53,22 +53,6 @@ authorization from the copyright holders. #include "XeTeXswap.h" -static ATSUTextLayout sTextLayout = 0; - -static void -InitializeLayout() -{ - OSStatus status = ATSUCreateTextLayout(&sTextLayout); - ATSUFontFallbacks fallbacks; - status = ATSUCreateFontFallbacks(&fallbacks); - status = ATSUSetObjFontFallbacks(fallbacks, 0, 0, kATSULastResortOnlyFallback); - ATSUAttributeTag tag = kATSULineFontFallbacksTag; - ByteCount valueSize = sizeof(fallbacks); - ATSUAttributeValuePtr value = &fallbacks; - status = ATSUSetLayoutControls(sTextLayout, 1, &tag, &valueSize, &value); - status = ATSUSetTransientFontMatching(sTextLayout, true); -} - static inline double TeXtoPSPoints(double pts) { @@ -82,15 +66,20 @@ PStoTeXPoints(double pts) } static inline Fixed -FixedTeXtoPSPoints(Fixed pts) +FixedPStoTeXPoints(double pts) { - return D2Fix(TeXtoPSPoints(Fix2D(pts))); + return D2Fix(PStoTeXPoints(pts)); } -static inline Fixed -FixedPStoTeXPoints(Fixed pts) +CTFontRef fontFromAttributes(CFDictionaryRef attributes) +{ + return CFDictionaryGetValue(attributes, kCTFontAttributeName); +} + +CTFontRef fontFromInteger(integer font) { - return D2Fix(PStoTeXPoints(Fix2D(pts))); + CFDictionaryRef attributes = (CFDictionaryRef) fontlayoutengine[font]; + return fontFromAttributes(attributes); } void @@ -104,336 +93,168 @@ DoAtsuiLayout(void* p, int justify) exit(1); } - if (sTextLayout == 0) - InitializeLayout(); - - OSStatus status = noErr; - long txtLen = native_length(node); const UniChar* txtPtr = (UniChar*)(node + native_node_size); - status = ATSUSetTextPointerLocation(sTextLayout, txtPtr, 0, txtLen, txtLen); - - // we're using this font in AAT mode, so fontlayoutengine[f] is actually an ATSUStyle - ATSUStyle style = (ATSUStyle)(fontlayoutengine[native_font(node)]); - status = ATSUSetRunStyle(sTextLayout, style, 0, txtLen); + CFDictionaryRef attributes = fontlayoutengine[native_font(node)]; + CFStringRef string = CFStringCreateWithCharactersNoCopy(NULL, txtPtr, txtLen, kCFAllocatorNull); + CFAttributedStringRef attrString = CFAttributedStringCreate(NULL, string, attributes); + CFRelease(string); - ATSUAttributeTag tags[] = { kATSULineWidthTag, kATSULineJustificationFactorTag }; - ItemCount numTags = sizeof(tags) / sizeof(ATSUAttributeTag); + CTTypesetterRef typesetter = CTTypesetterCreateWithAttributedString(attrString); + CTLineRef line = CTTypesetterCreateLine(typesetter, CFRangeMake(0, txtLen)); if (justify) { - ByteCount valSizes[] = { sizeof(Fixed), sizeof(Fract) }; - Fixed wid = FixedTeXtoPSPoints(node_width(node)); - Fract just = fract1; - ATSUAttributeValuePtr valPtrs[] = { &wid, &just }; - status = ATSUSetLayoutControls(sTextLayout, numTags, tags, valSizes, valPtrs); - } - - ItemCount count; - ATSLayoutRecord* layoutRec = NULL; - status = ATSUDirectGetLayoutDataArrayPtrFromTextLayout(sTextLayout, 0, - kATSUDirectDataLayoutRecordATSLayoutRecordCurrent, (void*)&layoutRec, &count); - - int i; - int realGlyphCount = 0; - int lastRealGlyph = 0; - for (i = 0; i < count; ++i) - if (layoutRec[i].glyphID < 0xfffe) { - lastRealGlyph = i; - ++realGlyphCount; + 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; } + } - void* glyph_info = xmalloc(realGlyphCount * native_glyph_info_size); - FixedPoint* locations = (FixedPoint*)glyph_info; - UInt16* glyphIDs = (UInt16*)(locations + realGlyphCount); + CFArrayRef glyphRuns = CTLineGetGlyphRuns(line); + CFIndex i, runCount = CFArrayGetCount(glyphRuns); + CFIndex totalGlyphCount = CTLineGetGlyphCount(line); + UInt16* realGlyphIDs = xmalloc(totalGlyphCount * sizeof(UInt16)); + void* glyph_info = xmalloc(totalGlyphCount * native_glyph_info_size); + FixedPoint* locations = (FixedPoint*)glyph_info; + Fixed lsUnit = justify ? 0 : fontletterspace[f]; + Fixed lsDelta = 0; - Fixed lsUnit = justify ? 0 : fontletterspace[f]; - Fixed lsDelta = 0; - - realGlyphCount = 0; - for (i = 0; i < count; ++i) { - if (layoutRec[i].glyphID < 0xfffe) { - if ((layoutRec[i].flags & kATSGlyphInfoIsAttachment) && (lsDelta != 0)) - lsDelta -= lsUnit; - glyphIDs[realGlyphCount] = layoutRec[i].glyphID; - locations[realGlyphCount].y = 0; /* FIXME: won't handle baseline offsets */ - locations[realGlyphCount].x = FixedPStoTeXPoints(layoutRec[i].realPos) + lsDelta; - lsDelta += lsUnit; - ++realGlyphCount; + int realGlyphCount = 0; + CGFloat lastGlyphAdvance = 0; + for (i = 0; i < runCount; i++) { + CTRunRef run = CFArrayGetValueAtIndex(glyphRuns, i); + CFIndex count = CTRunGetGlyphCount(run); + // 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)); + CTRunGetGlyphs(run, CFRangeMake(0, 0), glyphs); + CTRunGetPositions(run, CFRangeMake(0, 0), positions); + CTRunGetAdvances(run, CFRangeMake(0, 0), advances); + CFIndex j; + for (j = 0; j < count; j++) { + if (glyphs[j] < 0xfffe) { + realGlyphIDs[realGlyphCount] = glyphs[j]; + locations[realGlyphCount].x = FixedPStoTeXPoints(positions[j].x) + lsDelta; + lastGlyphAdvance = advances[j].width; + locations[realGlyphCount].y = FixedPStoTeXPoints(positions[j].y); + lsDelta += lsUnit; + realGlyphCount++; + } } + free(advances); + free(glyphs); + free(positions); } if (lsDelta != 0) lsDelta -= lsUnit; + UInt16* glyphIDs = (UInt16*)(locations + realGlyphCount); + memcpy(glyphIDs, realGlyphIDs, realGlyphCount * sizeof(UInt16)); + free(realGlyphIDs); + native_glyph_count(node) = realGlyphCount; native_glyph_info_ptr(node) = glyph_info; - - if (!justify) - node_width(node) = FixedPStoTeXPoints(layoutRec[count-1].realPos) + lsDelta; - - ATSUDirectReleaseLayoutDataArrayPtr(NULL, kATSUDirectDataLayoutRecordATSLayoutRecordCurrent, (void*)&layoutRec); - - if (justify) - ATSUClearLayoutControls(sTextLayout, numTags, tags); -} - -static OSStatus QuadraticClosePath(void *callBackDataPtr) -{ - return 0; -} - -static OSStatus QuadraticCurve(const Float32Point *pt1, const Float32Point *controlPt, const Float32Point *pt2, void *callBackDataPtr) -{ - GlyphBBox* data = (GlyphBBox*)callBackDataPtr; - - if (pt1->x < data->xMin) - data->xMin = pt1->x; - if (pt1->x > data->xMax) - data->xMax = pt1->x; - if (pt1->y < data->yMin) - data->yMin = pt1->y; - if (pt1->y > data->yMax) - data->yMax = pt1->y; - - if (pt2->x < data->xMin) - data->xMin = pt2->x; - if (pt2->x > data->xMax) - data->xMax = pt2->x; - if (pt2->y < data->yMin) - data->yMin = pt2->y; - if (pt2->y > data->yMax) - data->yMax = pt2->y; - - if (controlPt->x < data->xMin) - data->xMin = controlPt->x; - if (controlPt->x > data->xMax) - data->xMax = controlPt->x; - if (controlPt->y < data->yMin) - data->yMin = controlPt->y; - if (controlPt->y > data->yMax) - data->yMax = controlPt->y; - - return 0; -} - -static OSStatus QuadraticLine(const Float32Point *pt1, const Float32Point *pt2, void *callBackDataPtr) -{ - GlyphBBox* data = (GlyphBBox*)callBackDataPtr; - - if (pt1->x < data->xMin) - data->xMin = pt1->x; - if (pt1->x > data->xMax) - data->xMax = pt1->x; - if (pt1->y < data->yMin) - data->yMin = pt1->y; - if (pt1->y > data->yMax) - data->yMax = pt1->y; - - if (pt2->x < data->xMin) - data->xMin = pt2->x; - if (pt2->x > data->xMax) - data->xMax = pt2->x; - if (pt2->y < data->yMin) - data->yMin = pt2->y; - if (pt2->y > data->yMax) - data->yMax = pt2->y; - - return 0; -} - -static OSStatus QuadraticNewPath(void *callBackDataPtr) -{ - return 0; -} - -static OSStatus CubicMoveTo(const Float32Point *pt, void *callBackDataPtr) -{ - GlyphBBox* data = (GlyphBBox*)callBackDataPtr; - - if (pt->x < data->xMin) - data->xMin = pt->x; - if (pt->x > data->xMax) - data->xMax = pt->x; - if (pt->y < data->yMin) - data->yMin = pt->y; - if (pt->y > data->yMax) - data->yMax = pt->y; - - return 0; -} - -static OSStatus CubicLineTo(const Float32Point *pt, void *callBackDataPtr) -{ - GlyphBBox* data = (GlyphBBox*)callBackDataPtr; - - if (pt->x < data->xMin) - data->xMin = pt->x; - if (pt->x > data->xMax) - data->xMax = pt->x; - if (pt->y < data->yMin) - data->yMin = pt->y; - if (pt->y > data->yMax) - data->yMax = pt->y; - - return 0; -} - -static OSStatus CubicCurveTo(const Float32Point *pt1, const Float32Point *pt2, const Float32Point *pt3, void *callBackDataPtr) -{ - GlyphBBox* data = (GlyphBBox*)callBackDataPtr; - - if (pt1->x < data->xMin) - data->xMin = pt1->x; - if (pt1->x > data->xMax) - data->xMax = pt1->x; - if (pt1->y < data->yMin) - data->yMin = pt1->y; - if (pt1->y > data->yMax) - data->yMax = pt1->y; - - if (pt2->x < data->xMin) - data->xMin = pt2->x; - if (pt2->x > data->xMax) - data->xMax = pt2->x; - if (pt2->y < data->yMin) - data->yMin = pt2->y; - if (pt2->y > data->yMax) - data->yMax = pt2->y; - - if (pt3->x < data->xMin) - data->xMin = pt3->x; - if (pt3->x > data->xMax) - data->xMax = pt3->x; - if (pt3->y < data->yMin) - data->yMin = pt3->y; - if (pt3->y > data->yMax) - data->yMax = pt3->y; - return 0; -} + if (!justify) { + node_width(node) = + (realGlyphCount > 0 ? locations[realGlyphCount - 1].x : 0) + + FixedPStoTeXPoints(lastGlyphAdvance) + + lsDelta; + } -static OSStatus CubicClosePath(void *callBackDataPtr) -{ - return 0; + CFRelease(line); + CFRelease(typesetter); } -void GetGlyphBBox_AAT(ATSUStyle style, UInt16 gid, GlyphBBox* bbox) - /* returns glyph bounding box in TeX points */ +void getGlyphBBoxFromCTFont(CTFontRef font, UInt16 gid, GlyphBBox* bbox) { - ATSCurveType curveType; - OSStatus status; - bbox->xMin = 65536.0; bbox->yMin = 65536.0; bbox->xMax = -65536.0; bbox->yMax = -65536.0; - status = ATSUGetNativeCurveType(style, &curveType); - if (status == noErr) { - OSStatus cbStatus; - - if (curveType == kATSCubicCurveType) { - static ATSCubicMoveToUPP cubicMoveToProc; - static ATSCubicLineToUPP cubicLineToProc; - static ATSCubicCurveToUPP cubicCurveToProc; - static ATSCubicClosePathUPP cubicClosePathProc; - if (cubicMoveToProc == NULL) { - cubicMoveToProc = NewATSCubicMoveToUPP(&CubicMoveTo); - cubicLineToProc = NewATSCubicLineToUPP(&CubicLineTo); - cubicCurveToProc = NewATSCubicCurveToUPP(&CubicCurveTo); - cubicClosePathProc = NewATSCubicClosePathUPP(&CubicClosePath); - } - status = ATSUGlyphGetCubicPaths(style, gid, - cubicMoveToProc, cubicLineToProc, cubicCurveToProc, cubicClosePathProc, - bbox, &cbStatus); - } - else { - static ATSQuadraticNewPathUPP quadraticNewPathProc; - static ATSQuadraticLineUPP quadraticLineProc; - static ATSQuadraticCurveUPP quadraticCurveProc; - static ATSQuadraticClosePathUPP quadraticClosePathProc; - if (quadraticNewPathProc == NULL) { - quadraticNewPathProc = NewATSQuadraticNewPathUPP(&QuadraticNewPath); - quadraticLineProc = NewATSQuadraticLineUPP(&QuadraticLine); - quadraticCurveProc = NewATSQuadraticCurveUPP(&QuadraticCurve); - quadraticClosePathProc = NewATSQuadraticClosePathUPP(&QuadraticClosePath); - } - status = ATSUGlyphGetQuadraticPaths(style, gid, - quadraticNewPathProc, quadraticLineProc, quadraticCurveProc, quadraticClosePathProc, - bbox, &cbStatus); - } - } + CGRect rect = CTFontGetBoundingRectsForGlyphs(font, + 0, /* Use default orientation for now, handle vertical later */ + (const CGGlyph *) &gid, NULL, 1); - if (status != noErr || bbox->xMin == 65536.0) + if (CGRectIsNull(rect)) bbox->xMin = bbox->yMin = bbox->xMax = bbox->yMax = 0; else { // convert PS to TeX points and flip y-axis - float tmp = bbox->yMin; - bbox->yMin = -bbox->yMax * 72.27 / 72.0; - bbox->yMax = -tmp * 72.27 / 72.0; - bbox->xMin *= 72.27 / 72.0; - bbox->xMax *= 72.27 / 72.0; + // TODO: do we need to flip for bounding rect returned by Core Text? + bbox->yMin = -PStoTeXPoints(rect.origin.y + rect.size.height); + bbox->yMax = -PStoTeXPoints(rect.origin.y); + bbox->xMin = PStoTeXPoints(rect.origin.x); + bbox->xMax = PStoTeXPoints(rect.origin.x + rect.size.width); } } -float GetGlyphWidth_AAT(ATSUStyle style, UInt16 gid) +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); +} + +double getGlyphWidthFromCTFont(CTFontRef font, UInt16 gid) +{ + CGSize advances[1] = { CGSizeMake(0, 0) }; + return PStoTeXPoints(CTFontGetAdvancesForGlyphs(font, 0, &gid, advances, 1)); +} + +double GetGlyphWidth_AAT(CFDictionaryRef attributes, UInt16 gid) /* returns TeX points */ { - ATSGlyphIdealMetrics metrics; - OSStatus status = ATSUGlyphGetIdealMetrics(style, 1, &gid, 0, &metrics); - if (status == noErr) - return PStoTeXPoints(metrics.advance.x); - else - return 0; + CTFontRef font = fontFromAttributes(attributes); + return getGlyphWidthFromCTFont(font, gid); } -void GetGlyphHeightDepth_AAT(ATSUStyle style, UInt16 gid, float* ht, float* dp) +void GetGlyphHeightDepth_AAT(CFDictionaryRef attributes, UInt16 gid, float* ht, float* dp) /* returns TeX points */ { GlyphBBox bbox; - GetGlyphBBox_AAT(style, gid, &bbox); + GetGlyphBBox_AAT(attributes, gid, &bbox); *ht = bbox.yMax; *dp = -bbox.yMin; } -void GetGlyphSidebearings_AAT(ATSUStyle style, UInt16 gid, float* lsb, float* rsb) +void GetGlyphSidebearings_AAT(CFDictionaryRef attributes, UInt16 gid, float* lsb, float* rsb) /* returns TeX points */ { - ATSGlyphIdealMetrics metrics; - OSStatus status = ATSUGlyphGetIdealMetrics(style, 1, &gid, 0, &metrics); - if (status == noErr) { - GlyphBBox bbox; - GetGlyphBBox_AAT(style, gid, &bbox); - *lsb = bbox.xMin; - *rsb = PStoTeXPoints(metrics.advance.x) - bbox.xMax; - } - else { - *lsb = *rsb = 0; - } + 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; } -float GetGlyphItalCorr_AAT(ATSUStyle style, UInt16 gid) +double GetGlyphItalCorr_AAT(CFDictionaryRef attributes, UInt16 gid) { - float rval = 0.0; - ATSGlyphIdealMetrics metrics; - OSStatus status = ATSUGlyphGetIdealMetrics(style, 1, &gid, 0, &metrics); - if (status == noErr) { - GlyphBBox bbox; - GetGlyphBBox_AAT(style, gid, &bbox); - if (bbox.xMax > PStoTeXPoints(metrics.advance.x)) - rval = bbox.xMax - PStoTeXPoints(metrics.advance.x); - } - return rval; + 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; } -int MapCharToGlyph_AAT(ATSUStyle style, UInt32 ch) +int mapCharToGlyphFromCTFont(CTFontRef font, UInt32 ch, UInt32 vs) { - UniChar txt[2]; + UniChar txt[4]; int len = 1; - - if (sTextLayout == 0) - InitializeLayout(); if (ch > 0xffff) { ch -= 0x10000; @@ -444,448 +265,377 @@ int MapCharToGlyph_AAT(ATSUStyle style, UInt32 ch) else txt[0] = ch; - OSStatus status = ATSUSetTextPointerLocation(sTextLayout, &txt[0], 0, len, len); - if (status != noErr) - return 0; - status = ATSUSetRunStyle(sTextLayout, style, 0, len); - if (status != noErr) - return 0; - - ByteCount bufferSize = sizeof(ATSUGlyphInfoArray); - ATSUGlyphInfoArray info; - status = ATSUGetGlyphInfo(sTextLayout, 0, len, &bufferSize, &info); - if (status == noErr) { - if (bufferSize > 0 && info.numGlyphs > 0) - return info.glyphs[0].glyphID; + if (vs) { + if (vs > 0xffff) { + vs -= 0x10000; + txt[len] = 0xd800 + vs / 1024; + txt[len + 1] = 0xdc00 + vs % 1024; + len += 2; + } else { + txt[len] = vs; + len += 1; + } } + + CGGlyph glyphs[2] = { 0 }; + if (CTFontGetGlyphsForCharacters(font, txt, glyphs, len)) + return glyphs[0]; + return 0; } -int MapGlyphToIndex_AAT(ATSUStyle style, const char* glyphName) +int MapCharToGlyph_AAT(CFDictionaryRef attributes, UInt32 ch) { - ATSUFontID fontID; - ATSUGetAttribute(style, kATSUFontTag, sizeof(ATSUFontID), &fontID, 0); - - ATSFontRef fontRef = FMGetATSFontRefFromFont(fontID); - - ByteCount length; - OSStatus status = ATSFontGetTable(fontRef, kPOST, 0, 0, 0, &length); - if (status != noErr) - goto ats_failed; - - void* table = xmalloc(length); - status = ATSFontGetTable(fontRef, kPOST, 0, length, table, &length); - if (status != noErr) { - free(table); - goto ats_failed; - } - - int rval = findGlyphInPostTable(table, length, glyphName); - free(table); - - if (rval) - return rval; - -ats_failed: - return GetGlyphIDFromCGFont(fontRef, glyphName); + CTFontRef font = fontFromAttributes(attributes); + return mapCharToGlyphFromCTFont(font, ch, 0); } -int GetGlyphIDFromCGFont(ATSFontRef atsFontRef, const char* glyphName) +int MapGlyphToIndex_AAT(CFDictionaryRef attributes, const char* glyphName) { -#if defined(MAC_OS_X_VERSION_10_5) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) - if (&CGFontGetGlyphWithGlyphName == NULL) - return 0; - - int rval = 0; - CFStringRef psname; - OSStatus status = ATSFontGetPostScriptName(atsFontRef, 0, &psname); - if ((status == noErr) && psname) { - CGFontRef cgfont = CGFontCreateWithFontName(psname); - CFRelease(psname); - if (cgfont) { - CFStringRef glyphname = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, - glyphName, - kCFStringEncodingUTF8, - kCFAllocatorNull); - rval = CGFontGetGlyphWithGlyphName(cgfont, glyphname); - CFRelease(glyphname); - CGFontRelease(cgfont); - } - } - return rval; -#else - return 0; -#endif + CTFontRef font = fontFromAttributes(attributes); + return GetGlyphIDFromCTFont(font, glyphName); } -char* -GetGlyphName_AAT(ATSUStyle style, UInt16 gid, int* len) +int GetGlyphIDFromCTFont(CTFontRef ctFontRef, const char* glyphName) { - static char buffer[256]; - const char* namePtr; - - ATSUFontID fontID; - ATSUGetAttribute(style, kATSUFontTag, sizeof(ATSUFontID), &fontID, 0); - - ATSFontRef fontRef = FMGetATSFontRefFromFont(fontID); - - ByteCount length; - OSStatus status = ATSFontGetTable(fontRef, kPOST, 0, 0, 0, &length); - if (status != noErr) - goto ats_failed; - - void* table = xmalloc(length); - status = ATSFontGetTable(fontRef, kPOST, 0, length, table, &length); - if (status != noErr) { - free(table); - goto ats_failed; - } - - buffer[0] = 0; - namePtr = getGlyphNamePtr(table, length, gid, len); - if (*len > 255) - *len = 255; - if (namePtr) { - memcpy(buffer, namePtr, *len); - buffer[*len] = 0; - } - - free(table); - - if (buffer[0]) - return &buffer[0]; - -ats_failed: - return GetGlyphNameFromCGFont(fontRef, gid, len); + CFStringRef glyphname = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, + glyphName, + kCFStringEncodingUTF8, + kCFAllocatorNull); + int rval = CTFontGetGlyphWithName(ctFontRef, glyphname); + CFRelease(glyphname); + return rval; } char* -GetGlyphNameFromCGFont(ATSFontRef atsFontRef, UInt16 gid, int* len) +GetGlyphNameFromCTFont(CTFontRef ctFontRef, UInt16 gid, int* len) { *len = 0; static char buffer[256]; buffer[0] = 0; -#if defined(MAC_OS_X_VERSION_10_5) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) if (&CGFontCopyGlyphNameForGlyph == NULL) return &buffer[0]; - CFStringRef psname; - OSStatus status = ATSFontGetPostScriptName(atsFontRef, 0, &psname); - if ((status == noErr) && psname) { - CGFontRef cgfont = CGFontCreateWithFontName(psname); - CFRelease(psname); - if (cgfont && gid < CGFontGetNumberOfGlyphs(cgfont)) { - CFStringRef glyphname = CGFontCopyGlyphNameForGlyph(cgfont, gid); - if (glyphname) { - if (CFStringGetCString(glyphname, buffer, 256, kCFStringEncodingUTF8)) { - *len = strlen(buffer); - } - CFRelease(glyphname); + CGFontRef 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); } - CGFontRelease(cgfont); + CFRelease(glyphname); } + CGFontRelease(cgfont); } -#endif return &buffer[0]; } int -GetFontCharRange_AAT(ATSUStyle style, int reqFirst) +GetFontCharRange_AAT(CFDictionaryRef attributes, int reqFirst) { if (reqFirst) { int ch = 0; - while (MapCharToGlyph_AAT(style, ch) == 0 && ch < 0x10ffff) + while (MapCharToGlyph_AAT(attributes, ch) == 0 && ch < 0x10ffff) ++ch; return ch; } else { int ch = 0x10ffff; - while (MapCharToGlyph_AAT(style, ch) == 0 && ch > 0) + while (MapCharToGlyph_AAT(attributes, ch) == 0 && ch > 0) --ch; return ch; } } -ATSUFontVariationAxis -find_axis_by_name(ATSUFontID fontID, const char* name, int nameLength) +char* getNameFromCTFont(CTFontRef ctFontRef, CFStringRef nameKey) { - ATSUFontVariationAxis result = 0; - - Str255 inName; - inName[0] = nameLength; - int i; - for (i = 0; i < inName[0]; ++i) - inName[i + 1] = name[i]; - - ItemCount varCount; - ATSUCountFontVariations(fontID, &varCount); - if (varCount > 0) { - for (i = 0; i < varCount; ++i) { - ATSUFontVariationAxis axis; - ATSUGetIndFontVariation(fontID, i, &axis, 0, 0, 0); - FontNameCode nameCode; - ATSUGetFontVariationNameCode(fontID, axis, &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 = axis; - break; + CFStringRef name = CTFontCopyName(ctFontRef, nameKey); + CFIndex len = CFStringGetLength(name); + len = len * 6 + 1; + char *buf = xmalloc(len); + if (CFStringGetCString(name, buf, len, kCFStringEncodingUTF8)) + return buf; + free(buf); + return 0; +} + +char* getFileNameFromCTFont(CTFontRef ctFontRef) +{ + char *ret = NULL; + + CFURLRef url = (CFURLRef) CTFontCopyAttribute(ctFontRef, kCTFontURLAttribute); + if (url) { + UInt8 pathname[PATH_MAX]; + if (CFURLGetFileSystemRepresentation(url, true, pathname, PATH_MAX)) { + int index = 0; + + /* finding face index by searching for preceding font ids with the same FSRef */ + /* logic copied from FreeType but without using ATS/FS APIs */ + ATSFontRef id1 = CTFontGetPlatformFont(ctFontRef, NULL); + ATSFontRef id2 = id1 - 1; + while (id2 > 0) { + FSRef dummy; + if (noErr != ATSFontGetFileReference(id2, &dummy)) /* check if id2 is valid, any better way? */ + break; + CTFontRef ctFontRef2 = CTFontCreateWithPlatformFont(id2, 0.0, NULL, NULL); + CFURLRef url2 = (CFURLRef) CTFontCopyAttribute(ctFontRef2, kCTFontURLAttribute); + if (!url2) + break; + if (!CFEqual(url, url2)) + break; + id2--; } + index = id1 - (id2 + 1); + + char buf[20]; + if (index > 0) + sprintf(buf, ":%d", index); + else + buf[0] = '\0'; + + ret = xmalloc(strlen((char*) pathname) + 2 + strlen(buf) + 1); + sprintf(ret, "[%s%s]", pathname, buf); } + CFRelease(url); } - - return result; + + return ret; } -ATSUFontFeatureType -find_feature_by_name(ATSUFontID fontID, const char* name, int nameLength) +CFDictionaryRef findDictionaryInArrayWithIdentifier(CFArrayRef array, + const void* identifierKey, + int identifier) { - 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]; + if (!array) + return NULL; + + CFDictionaryRef dict = NULL; + 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; } } - free((char*)types); } - - return result; + return dict; } -ATSUFontFeatureSelector -find_selector_by_name(ATSUFontID fontID, ATSUFontFeatureType featureType, const char* name, int nameLength) +CFDictionaryRef findDictionaryInArray(CFArrayRef array, const void* nameKey, + const char* name, int nameLength) { - ATSUFontFeatureSelector result = 0x0000FFFF; - - Str255 inName; - inName[0] = nameLength; - int i; - for (i = 0; i < inName[0]; ++i) - inName[i + 1] = name[i]; - - ItemCount selectorCount; - ATSUCountFontFeatureSelectors(fontID, featureType, &selectorCount); - if (selectorCount > 0) { - ATSUFontFeatureSelector* selectors = (ATSUFontFeatureSelector*)xmalloc(selectorCount * sizeof(ATSUFontFeatureSelector)); - ATSUGetFontFeatureSelectors(fontID, featureType, selectorCount, selectors, 0, 0, 0); - for (i = 0; i < selectorCount; ++i) { - FontNameCode nameCode; - ATSUGetFontFeatureNameCode(fontID, featureType, selectors[i], &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 = selectors[i]; - break; - } + if (!array) + return NULL; + + CFDictionaryRef dict = NULL; + CFStringRef itemName = CFStringCreateWithBytes(NULL, name, nameLength, + kCFStringEncodingUTF8, false); + CFIndex i; + 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; } - free((char*)selectors); } - - return result; + CFRelease(itemName); + return dict; +} + +CFNumberRef findSelectorByName(CFDictionaryRef feature, const char* name, int nameLength) +{ + CFArrayRef selectors = CFDictionaryGetValue(feature, kCTFontFeatureTypeSelectorsKey); + CFDictionaryRef s = findDictionaryInArray(selectors, kCTFontFeatureSelectorNameKey, name, nameLength); + CFNumberRef selector = NULL; + 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(ATSFontRef fontRef, long scaled_size, const char* cp1) +loadAATfont(CTFontDescriptorRef descriptor, integer scaled_size, const char* cp1) { - ATSUFontID fontID = FMGetFontFromATSFontRef(fontRef); - ATSUStyle style = 0; - OSStatus status = ATSUCreateStyle(&style); - float extend = 1.0; - float slant = 0.0; - float embolden = 0.0; - float letterspace = 0.0; - int i; - - if (status == noErr) { - UInt32 rgbValue; - Fixed tracking = 0x80000000; - Fixed atsuSize = FixedTeXtoPSPoints(scaled_size); - - ATSStyleRenderingOptions options = kATSStyleNoHinting; - Fract hangInhibit = fract1; - ATSUAttributeTag tags[] = { kATSUFontTag, kATSUSizeTag, kATSUStyleRenderingOptionsTag, kATSUHangingInhibitFactorTag }; - ByteCount sizes[] = { sizeof(ATSUFontID), sizeof(Fixed), sizeof(ATSStyleRenderingOptions), sizeof(Fract) }; - ATSUAttributeValuePtr attrs[] = { &fontID, &atsuSize, &options, &hangInhibit }; - ATSUSetAttributes(style, sizeof(tags) / sizeof(ATSUAttributeTag), tags, sizes, attrs); - -#define FEAT_ALLOC_CHUNK 8 -#define VAR_ALLOC_CHUNK 4 - - if (cp1 != NULL) { - int allocFeats = FEAT_ALLOC_CHUNK; - UInt16* featureTypes = (UInt16*)xmalloc(allocFeats * sizeof(UInt16)); - UInt16* selectorValues = (UInt16*)xmalloc(allocFeats * sizeof(UInt16)); - int numFeatures = 0; - - int allocVars = VAR_ALLOC_CHUNK; - UInt32* axes = (UInt32*)xmalloc(allocVars * sizeof(UInt32)); - SInt32* values = (SInt32*)xmalloc(allocVars * sizeof(SInt32)); - int numVariations = 0; - - // interpret features & variations following ":" - while (*cp1) { - // 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 - const char* cp2 = cp1; - while (*cp2 && *cp2 != ';' && *cp2 != ':') - ++cp2; - - // look for the '=' separator - const char* 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 - ATSUFontFeatureType featureType; - featureType = find_feature_by_name(fontID, cp1, cp3 - cp1); - if (featureType != 0x0000FFFF) { - // look past the '=' separator for setting names - int featLen = cp3 - cp1; - ++cp3; - while (cp3 < cp2) { - // skip leading whitespace - while (*cp3 == ' ' || *cp3 == '\t') - ++cp3; - - // possibly multiple settings... - int disable = 0; - if (*cp3 == '!') { // check for negation - disable = 1; - ++cp3; - } - - // scan for end of setting name - const char* cp4 = cp3; - while (cp4 < cp2 && *cp4 != ',') - ++cp4; - - // now cp3 points to name, cp4 to ',' or ';' or null - ATSUFontFeatureSelector selectorValue = find_selector_by_name(fontID, featureType, cp3, cp4 - cp3); - if (selectorValue != 0x0000FFFF) { - if (numFeatures == allocFeats) { - allocFeats += FEAT_ALLOC_CHUNK; - featureTypes = xrealloc(featureTypes, allocFeats * sizeof(UInt16)); - selectorValues = xrealloc(selectorValues, allocFeats * sizeof(UInt16)); - } - featureTypes[numFeatures] = featureType; - selectorValues[numFeatures] = selectorValue + disable; - ++numFeatures; - } - else { - fontfeaturewarning(cp1, featLen, cp3, cp4 - cp3); - } - - // point beyond setting name terminator - cp3 = cp4 + 1; + CGFloat ctSize = TeXtoPSPoints(Fix2D(scaled_size)); + // create a base font instance for applying further attributes + CTFontRef font = CTFontCreateWithFontDescriptor(descriptor, ctSize, NULL); + + if (!font) + return NULL; + + CFMutableDictionaryRef stringAttributes = + CFDictionaryCreateMutable(NULL, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + CFMutableDictionaryRef attributes = + CFDictionaryCreateMutable(NULL, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + double tracking = 0.0; + float extend = 1.0; + float slant = 0.0; + float embolden = 0.0; + float letterspace = 0.0; + UInt32 rgbValue; + if (cp1) { + CFArrayRef features = CTFontCopyFeatures(font); + CFArrayRef axes = CTFontCopyVariationAxes(font); + CFMutableArrayRef featureSettings = + CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + CFMutableDictionaryRef variation = + CFDictionaryCreateMutable(NULL, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + // interpret features & variations following ":" + while (*cp1) { + // 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 + const char* cp2 = cp1; + while (*cp2 && *cp2 != ';' && *cp2 != ':') + ++cp2; + + // look for the '=' separator + const char* 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 + CFDictionaryRef feature = findDictionaryInArray(features, kCTFontFeatureTypeNameKey, cp1, cp3 - cp1); + if (feature) { + // look past the '=' separator for setting names + int featLen = cp3 - cp1; + ++cp3; + int zeroInteger = 0; + CFNumberRef zero = CFNumberCreate(NULL, kCFNumberIntType, &zeroInteger); + while (cp3 < cp2) { + // skip leading whitespace + while (*cp3 == ' ' || *cp3 == '\t') + ++cp3; + + // possibly multiple settings... + int disable = 0; + if (*cp3 == '!') { // check for negation + disable = 1; + ++cp3; } - - goto next_option; + + // scan for end of setting name + const char* cp4 = cp3; + while (cp4 < cp2 && *cp4 != ',') + ++cp4; + + // now cp3 points to name, cp4 to ',' or ';' or null + CFNumberRef 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; } - - // try to find a variation by this name - ATSUFontVariationAxis axis; - axis = find_axis_by_name(fontID, cp1, cp3 - cp1); - if (axis != 0) { - // look past the '=' separator for the value + CFRelease(zero); + + goto next_option; + } + + // try to find a variation by this name + CFDictionaryRef axis = findDictionaryInArray(axes, kCTFontVariationAxisNameKey, cp1, cp3 - cp1); + if (axis) { + // look past the '=' separator for the value + ++cp3; + double value = 0.0, decimal = 1.0; + bool negate = false; + if (*cp3 == '-') { ++cp3; - double value = 0.0, decimal = 1.0; - bool negate = false; - if (*cp3 == '-') { - ++cp3; - negate = true; - } - while (cp3 < cp2) { - int v = *cp3 - '0'; - if (v >= 0 && v <= 9) { - if (decimal != 1.0) { - value += v / decimal; - decimal *= 10.0; - } - else - value = value * 10.0 + v; - } - else if (*cp3 == '.') { - if (decimal != 1.0) - break; - decimal = 10.0; + negate = true; + } + while (cp3 < cp2) { + int v = *cp3 - '0'; + if (v >= 0 && v <= 9) { + if (decimal != 1.0) { + value += v / decimal; + decimal *= 10.0; } else - break; - ++cp3; + value = value * 10.0 + v; } - if (negate) - value = -value; - if (numVariations == allocVars) { - allocVars += VAR_ALLOC_CHUNK; - axes = xrealloc(axes, allocVars * sizeof(UInt32)); - values = xrealloc(values, allocVars * sizeof(SInt32)); + else if (*cp3 == '.') { + if (decimal != 1.0) + break; + decimal = 10.0; } - axes[numVariations] = axis; - values[numVariations] = value * 65536.0; // D2Fix(value); - ++numVariations; - - goto next_option; - } - - // didn't find feature or variation, try other options.... - - i = readCommonFeatures(cp1, cp2, &extend, &slant, &embolden, &letterspace, &rgbValue); - if (i == 1) - goto next_option; - else if (i == -1) - goto bad_option; - - if (strncmp(cp1, "tracking", 8) == 0) { - cp3 = cp1 + 8; - if (*cp3 != '=') - goto bad_option; + else + break; ++cp3; - double val = read_double(&cp3); - tracking = D2Fix(val); - goto next_option; } - + if (negate) + value = -value; + + CFNumberRef axisIdentifier = CFDictionaryGetValue(axis, kCTFontVariationAxisIdentifierKey); + CFNumberRef axisValue = CFNumberCreate(NULL, kCFNumberDoubleType, &value); + CFDictionaryAddValue(variation, axisIdentifier, axisValue); + CFRelease(axisValue); + + goto next_option; + } + + // didn't find feature or variation, try other options... + int 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) { + cp3 = cp1 + 8; + if (*cp3 != '=') + goto bad_option; + ++cp3; + tracking = read_double(&cp3); + CFNumberRef trackingNumber = CFNumberCreate(NULL, kCFNumberDoubleType, &tracking); + CFDictionaryAddValue(stringAttributes, kCTKernAttributeName, trackingNumber); + CFRelease(trackingNumber); + goto next_option; + } + bad_option: - // not a name=value pair, or not recognized.... + // not a name=value pair, or not recognized.... // check for plain "vertical" before complaining if (strncmp(cp1, "vertical", 8) == 0) { cp3 = cp2; @@ -896,75 +646,69 @@ loadAATfont(ATSFontRef fontRef, long scaled_size, const char* cp1) if (*cp3) ++cp3; if (cp3 == cp1 + 8) { - ATSUVerticalCharacterType vert = kATSUStronglyVertical; - tags[0] = kATSUVerticalCharacterTag; - sizes[0] = sizeof(ATSUVerticalCharacterType); - attrs[0] = | - ATSUSetAttributes(style, 1, tags, sizes, attrs); + 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 (numFeatures > 0) - ATSUSetFontFeatures(style, numFeatures, featureTypes, selectorValues); - - if (numVariations > 0) - ATSUSetVariations(style, numVariations, axes, values); - - if ((loadedfontflags & FONT_FLAGS_COLORED) != 0) { - ATSURGBAlphaColor rgba; - rgba.red = ((rgbValue & 0xFF000000) >> 24) / 255.0; - rgba.green = ((rgbValue & 0x00FF0000) >> 16) / 255.0; - rgba.blue = ((rgbValue & 0x0000FF00) >> 8 ) / 255.0; - rgba.alpha = ((rgbValue & 0x000000FF) ) / 255.0; - tags[0] = kATSURGBAlphaColorTag; - sizes[0] = sizeof(ATSURGBAlphaColor); - attrs[0] = &rgba; - ATSUSetAttributes(style, 1, tags, sizes, attrs); - } - - if (tracking != 0x80000000) { - tags[0] = kATSUTrackingTag; - sizes[0] = sizeof(Fixed); - attrs[0] = &tracking; - ATSUSetAttributes(style, 1, tags, sizes, attrs); - } - - if (extend != 1.0 || slant != 0.0) { - CGAffineTransform t = { extend, slant, 0, 1.0, 0, 0 }; - tags[0] = kATSUFontMatrixTag; - sizes[0] = sizeof(CGAffineTransform); - attrs[0] = &t; - ATSUSetAttributes(style, 1, tags, sizes, attrs); - } - - if (embolden != 0.0) { - embolden = embolden * Fix2D(scaled_size) / 100.0; - tags[0] = kXeTeXEmboldenTag; - sizes[0] = sizeof(float); - attrs[0] = &embolden; - ATSUSetAttributes(style, 1, tags, sizes, attrs); - } - - if (letterspace != 0.0) - loadedfontletterspace = (letterspace / 100.0) * scaled_size; - - free((char*)featureTypes); - free((char*)selectorValues); - free((char*)axes); - free((char*)values); } + + if (features) + CFRelease(features); + if (axes) + CFRelease(axes); + + if (CFArrayGetCount(featureSettings)) + CFDictionaryAddValue(attributes, kCTFontFeatureSettingsAttribute, featureSettings); + CFRelease(featureSettings); + + if (CFDictionaryGetCount(variation)) + CFDictionaryAddValue(attributes, kCTFontVariationAttribute, variation); + CFRelease(variation); + } + + 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); + } + + CGAffineTransform matrix = CGAffineTransformIdentity; + if (extend != 1.0 || slant != 0.0) + matrix = CGAffineTransformMake(extend, slant, 0, 1.0, 0, 0); + + if (embolden != 0.0) { + embolden = embolden * Fix2D(scaled_size) / 100.0; + CFNumberRef emboldenNumber = CFNumberCreate(NULL, kCFNumberFloatType, &embolden); + CFDictionaryAddValue(stringAttributes, kXeTeXEmboldenAttributeName, emboldenNumber); + CFRelease(emboldenNumber); } + if (letterspace != 0.0) + loadedfontletterspace = (letterspace / 100.0) * scaled_size; + + descriptor = CTFontDescriptorCreateWithAttributes(attributes); + CFRelease(attributes); + CTFontRef actualFont = CTFontCreateCopyWithAttributes(font, ctSize, &matrix, descriptor); + CFRelease(font); + CFDictionaryAddValue(stringAttributes, kCTFontAttributeName, actualFont); + CFRelease(actualFont); + nativefonttypeflag = AAT_FONT_FLAG; - return style; + return (void *) stringAttributes; } int @@ -1005,10 +749,6 @@ find_pic_file(char** path, realrect* bounds, int pdfBoxType, int page) picFileURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (UInt8*)pic_path, strlen(pic_path), false); if (picFileURL != NULL) { - /* get an FSRef for the URL we constructed */ - FSRef picFileRef; - CFURLGetFSRef(picFileURL, &picFileRef); - if (pdfBoxType > 0) { CGPDFDocumentRef document = CGPDFDocumentCreateWithURL(picFileURL); if (document != NULL) { @@ -1077,22 +817,26 @@ find_pic_file(char** path, realrect* bounds, int pdfBoxType, int page) } } else { - /* make an FSSpec for the file, and try to import it as a pic */ - FSSpec picFileSpec; - result = FSGetCatalogInfo(&picFileRef, kFSCatInfoNone, NULL, NULL, &picFileSpec, NULL); - if (result == noErr) { - ComponentInstance ci; - result = GetGraphicsImporterForFile(&picFileSpec, &ci); - if (result == noErr) { - ImageDescriptionHandle desc = NULL; - result = GraphicsImportGetImageDescription(ci, &desc); - bounds->x = 0; - bounds->y = 0; - bounds->wd = (*desc)->width * 72.27 / Fix2D((*desc)->hRes); - bounds->ht = (*desc)->height * 72.27 / Fix2D((*desc)->vRes); - DisposeHandle((Handle)desc); - (void)CloseComponent(ci); - } + CGImageSourceRef picFileSource = CGImageSourceCreateWithURL(picFileURL, NULL); + if (picFileSource) { + CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(picFileSource, 0, NULL); + + CFNumberRef imageWidth = CFDictionaryGetValue(properties, kCGImagePropertyPixelWidth); + CFNumberRef imageHeight = CFDictionaryGetValue(properties, kCGImagePropertyPixelHeight); + CFNumberRef DPIWidth = CFDictionaryGetValue(properties, kCGImagePropertyDPIWidth); + CFNumberRef DPIHeight = CFDictionaryGetValue(properties, kCGImagePropertyDPIHeight); + int w = 0, h = 0, hRes = 72, vRes = 72; + CFNumberGetValue(imageWidth, kCFNumberIntType, &w); + CFNumberGetValue(imageHeight, kCFNumberIntType, &h); + CFNumberGetValue(DPIWidth, kCFNumberIntType, &hRes); + CFNumberGetValue(DPIHeight, kCFNumberIntType, &vRes); + + bounds->x = 0; + bounds->y = 0; + bounds->wd = w * 72.27 / hRes; + bounds->ht = h * 72.27 / vRes; + CFRelease(properties); + CFRelease(picFileSource); } } diff --git a/Build/source/texk/web2c/xetexdir/XeTeX_pic.c b/Build/source/texk/web2c/xetexdir/XeTeX_pic.c index 9481dce5f54..a4ae4724da1 100644 --- a/Build/source/texk/web2c/xetexdir/XeTeX_pic.c +++ b/Build/source/texk/web2c/xetexdir/XeTeX_pic.c @@ -33,7 +33,7 @@ authorization from the copyright holders. /* XeTeX_pic.c interface between xetex and graphics files - (not used on OS X -- we use QuickTime graphics importers instead) + (not used on OS X -- we use ImageIO graphics importers instead) only needs to get image dimensions, not actually load/process the file */ diff --git a/Build/source/texk/web2c/xetexdir/XeTeXswap.h b/Build/source/texk/web2c/xetexdir/XeTeXswap.h index f51dd0d6101..ffdcc2e2a01 100644 --- a/Build/source/texk/web2c/xetexdir/XeTeXswap.h +++ b/Build/source/texk/web2c/xetexdir/XeTeXswap.h @@ -35,8 +35,8 @@ authorization from the copyright holders. #include <unicode/platform.h> // ICU's platform.h defines U_IS_BIG_ENDIAN for us -static inline UInt16 -SWAP16(const UInt16 p) +static inline uint16_t +SWAP16(const uint16_t p) { #if U_IS_BIG_ENDIAN return p; @@ -45,8 +45,8 @@ SWAP16(const UInt16 p) #endif } -static inline UInt32 -SWAP32(const UInt32 p) +static inline uint32_t +SWAP32(const uint32_t p) { #if U_IS_BIG_ENDIAN return p; @@ -56,28 +56,28 @@ SWAP32(const UInt32 p) } #ifdef __cplusplus -static inline UInt16 -SWAP(UInt16 p) +static inline uint16_t +SWAP(uint16_t p) { return SWAP16(p); } -static inline UInt32 -SWAP(UInt32 p) +static inline uint32_t +SWAP(uint32_t p) { return SWAP32(p); } -static inline SInt16 -SWAP(SInt16 p) +static inline int16_t +SWAP(int16_t p) { - return (SInt16)SWAP16((UInt16)p); + return (int16_t)SWAP16((uint16_t)p); } -static inline SInt32 -SWAP(SInt32 p) +static inline int32_t +SWAP(int32_t p) { - return (SInt32)SWAP32((UInt32)p); + return (int32_t)SWAP32((uint32_t)p); } #endif diff --git a/Build/source/texk/web2c/xetexdir/am/xetex.am b/Build/source/texk/web2c/xetexdir/am/xetex.am index e2665c2ab24..eef92eb9a09 100644 --- a/Build/source/texk/web2c/xetexdir/am/xetex.am +++ b/Build/source/texk/web2c/xetexdir/am/xetex.am @@ -33,7 +33,7 @@ xetex_dependencies += $(ICU_DEPEND) $(TECKIT_DEPEND) $(HARFBUZZ_DEPEND) $(GRAPHI if XETEX_MACOSX xetex_cppflags += -DXETEX_MAC -xetex_LDFLAGS = -framework Carbon -framework Cocoa -framework QuickTime +xetex_LDFLAGS = -framework ApplicationServices -framework Cocoa else !XETEX_MACOSX diff --git a/Build/source/texk/web2c/xetexdir/pdfimage.cpp b/Build/source/texk/web2c/xetexdir/pdfimage.cpp index 51b740ea06d..8b3a9e3ba09 100644 --- a/Build/source/texk/web2c/xetexdir/pdfimage.cpp +++ b/Build/source/texk/web2c/xetexdir/pdfimage.cpp @@ -32,12 +32,6 @@ authorization from the copyright holders. #include "pdfimage.h" -#include <dirent.h> -#include <poppler-config.h> -#include <goo/GooString.h> -#include <goo/gmem.h> -#include <goo/gfile.h> - #include "PDFDoc.h" #include "Catalog.h" #include "Page.h" diff --git a/Build/source/texk/web2c/xetexdir/trans.c b/Build/source/texk/web2c/xetexdir/trans.c index 9e2ab0e5b70..405347756b8 100644 --- a/Build/source/texk/web2c/xetexdir/trans.c +++ b/Build/source/texk/web2c/xetexdir/trans.c @@ -34,78 +34,54 @@ authorization from the copyright holders. void makeidentity(transform* t) { -#ifdef XETEX_MAC - *t = CGAffineTransformMake(1.0, 0.0, 0.0, 1.0, 0.0, 0.0); -#else t->a = 1.0; t->b = 0.0; t->c = 0.0; t->d = 1.0; t->x = 0.0; t->y = 0.0; -#endif } void makescale(transform* t, double xscale, double yscale) { -#ifdef XETEX_MAC - *t = CGAffineTransformMakeScale(xscale, yscale); -#else t->a = xscale; t->b = 0.0; t->c = 0.0; t->d = yscale; t->x = 0.0; t->y = 0.0; -#endif } void maketranslation(transform* t, double dx, double dy) { -#ifdef XETEX_MAC - *t = CGAffineTransformMakeTranslation(dx, dy); -#else t->a = 1.0; t->b = 0.0; t->c = 0.0; t->d = 1.0; t->x = dx; t->y = dy; -#endif } #include <stdio.h> void makerotation(transform* t, double a) { -#ifdef XETEX_MAC - *t = CGAffineTransformMakeRotation(a); -#else t->a = cos(a); t->b = sin(a); t->c = -sin(a); t->d = cos(a); t->x = 0.0; t->y = 0.0; -#endif } void transformpoint(realpoint* p, const transform* t) { -#ifdef XETEX_MAC - CGPoint r = CGPointApplyAffineTransform(*(CGPoint*)p, *t); - *p = *(realpoint*)&r; -#else realpoint r; r.x = t->a * p->x + t->c * p->y + t->x; r.y = t->b * p->x + t->d * p->y + t->y; *p = r; -#endif } void transformconcat(transform* t1, const transform* t2) { -#ifdef XETEX_MAC - *t1 = CGAffineTransformConcat(*t1, *t2); -#else transform r; r.a = t1->a * t2->a + t1->b * t2->c + 0.0 * t2->x; r.b = t1->a * t2->b + t1->b * t2->d + 0.0 * t2->y; @@ -114,5 +90,4 @@ void transformconcat(transform* t1, const transform* t2) r.x = t1->x * t2->a + t1->y * t2->c + 1.0 * t2->x; r.y = t1->x * t2->b + t1->y * t2->d + 1.0 * t2->y; *t1 = r; -#endif } diff --git a/Build/source/texk/web2c/xetexdir/trans.h b/Build/source/texk/web2c/xetexdir/trans.h index 88facea6d63..fa5957c62db 100644 --- a/Build/source/texk/web2c/xetexdir/trans.h +++ b/Build/source/texk/web2c/xetexdir/trans.h @@ -33,14 +33,6 @@ authorization from the copyright holders. #ifndef _TRANS_H_ #define _TRANS_H_ -#ifdef XETEX_MAC - -#include <Carbon/Carbon.h> - -typedef CGAffineTransform transform; - -#else - #include <math.h> /* apparently M_PI isn't defined by <math.h> under VC++ */ #ifndef M_PI @@ -56,8 +48,6 @@ typedef struct { double y; } transform; -#endif - typedef struct { float x; float y; @@ -80,13 +70,6 @@ typedef struct { #define bField(t) (t).b #define cField(t) (t).c #define dField(t) (t).d -#ifdef XETEX_MAC /* transform fields have different names */ -#define txField(t) (t).tx -#define tyField(t) (t).ty -#else -#define txField(t) (t).x -#define tyField(t) (t).y -#endif #define xField(t) (t).x #define yField(t) (t).y diff --git a/Build/source/texk/web2c/xetexdir/xetex.defines b/Build/source/texk/web2c/xetexdir/xetex.defines index c854df94519..4ad5cd2abf9 100644 --- a/Build/source/texk/web2c/xetexdir/xetex.defines +++ b/Build/source/texk/web2c/xetexdir/xetex.defines @@ -170,8 +170,6 @@ authorization from the copyright holders. @define function dField(); @define function xField(); @define function yField(); -@define function txField(); -@define function tyField(); @define function wdField(); @define function htField(); @define function applymapping(); diff --git a/Build/source/texk/web2c/xetexdir/xetex.h b/Build/source/texk/web2c/xetexdir/xetex.h index b159a5668ef..5e990bc7c05 100644 --- a/Build/source/texk/web2c/xetexdir/xetex.h +++ b/Build/source/texk/web2c/xetexdir/xetex.h @@ -114,12 +114,6 @@ authorization from the copyright holders. #undef Xchr #define Xchr(x) (x) -#ifdef XETEX_MAC -#undef input /* this is defined in texmfmp.h, but we don't need it and it confuses the carbon headers */ -#undef output -#include <Carbon/Carbon.h> /* for Mac OS X, it's handy to have the Carbon APIs available */ -#endif - #include "trans.h" /* functions for affine transform operations */ #include <teckit/TECkit_Common.h> /* include this before XeTeX_ext.h */ #include "XeTeX_ext.h" /* other extension functions */ diff --git a/Build/source/texk/web2c/xetexdir/xetex.web b/Build/source/texk/web2c/xetexdir/xetex.web index d368c3e4596..0f08195561a 100644 --- a/Build/source/texk/web2c/xetexdir/xetex.web +++ b/Build/source/texk/web2c/xetexdir/xetex.web @@ -142,6 +142,7 @@ % been a ``labor of love'' and the author hopes that users enjoy it. % Here is TeX material that gets inserted after \input webmac +\input xetexwebmac \def\hang{\hangindent 3em\noindent\ignorespaces} \def\hangg#1 {\hang\hbox{#1 }} \def\textindent#1{\hangindent2.5em\noindent\hbox to2.5em{\hss#1 }\ignorespaces} @@ -7135,8 +7136,7 @@ together with the corresponding |primitive| calls. @d chr_cmd(#)==begin print(#); if chr_code < @"10000 then print_ASCII(chr_code) - {non-Plane 0 Unicodes can't be sent through |print_ASCII|} - else begin print("number "); print_hex(chr_code) end; + else print_char(chr_code); {non-Plane 0 Unicodes can't be sent through |print_ASCII|} end @<Declare the procedure called |print_cmd_chr|@>= @@ -12706,10 +12706,7 @@ begin if tracing_lost_chars>0 then print_nl("Missing character: There is no "); @.Missing character@> if c < @"10000 then print_ASCII(c) - else begin { non-Plane 0 Unicodes can't be sent through |print_ASCII| } - print("character number "); - print_hex(c); - end; + else print_char(c); {non-Plane 0 Unicodes can't be sent through |print_ASCII|} print(" in font "); slow_print(font_name[f]); print_char("!"); end_diagnostic(false); end; @@ -13876,8 +13873,8 @@ end; @ Extra stuff for justifiable AAT text; need to merge runs of words and normal spaces. -@d is_native_word_node(#) == ((not is_char_node(#)) and (type(#) = whatsit_node) and (subtype(#) = native_word_node)) -@d is_glyph_node(#) == ((not is_char_node(#)) and (type(#) = whatsit_node) and (subtype(#) = glyph_node)) +@d is_native_word_node(#) == (((#)<>null and (not is_char_node(#)) and (type(#) = whatsit_node) and (subtype(#) = native_word_node))) +@d is_glyph_node(#) == (((#)<>null and (not is_char_node(#)) and (type(#) = whatsit_node) and (subtype(#) = glyph_node))) @<Merge sequences of words using AAT fonts and inter-word spaces into single nodes@>= p := list_ptr(this_box); @@ -13897,7 +13894,7 @@ check_next: {found a normal space; if the next node is another word in the same font, we'll merge} q := link(q); @<Advance |q| past ignorable nodes@>; - if (q <> null) and is_native_word_node(q) and (native_font(q) = native_font(r)) then begin + if is_native_word_node(q) and (native_font(q) = native_font(r)) then begin p := q; {record new tail of run in |p|} k := k + 1 + native_length(q); q := link(q); @@ -13905,7 +13902,7 @@ check_next: end; goto end_node_run; end; - if (q <> null) and is_native_word_node(q) and (native_font(q) = native_font(r)) then begin + if is_native_word_node(q) and (native_font(q) = native_font(r)) then begin p := q; {record new tail of run in |p|} q := link(q); goto check_next; @@ -15383,8 +15380,11 @@ fraction_noad:@<Display fraction noad |p|@>; @<Declare procedures needed for displaying the elements of mlists@>= procedure print_fam_and_char(@!p:pointer); {prints family and character} +var c:integer; begin print_esc("fam"); print_int(fam(p) mod @"100); print_char(" "); -print_ASCII(qo(character(p)) + (fam(p) div @"100) * @"10000); +c:=(cast_to_ushort(character(p)) + ((plane_and_fam_field(p) div @"100) * @"10000)); +if c < @"10000 then print_ASCII(c) +else print_char(c); {non-Plane 0 Unicodes can't be sent through |print_ASCII|} end; @# procedure print_delimiter(@!p:pointer); {prints a delimiter as 24-bit hex value} @@ -16995,8 +16995,11 @@ if x<>null then begin @<Switch to a larger native-font accent if available and appropriate@>; {determine horiz positioning} - sa:=get_ot_math_accent_pos(f,native_glyph(p)); - if sa=@"7FFFFFFF then sa:=half(width(y)); + if is_glyph_node(p) then + begin sa:=get_ot_math_accent_pos(f,native_glyph(p)); + if sa=@"7FFFFFFF then sa:=half(width(y)); + end + else sa:=half(width(y)); if is_bottom_acc(q) or (s=@"7FFFFFFF) then s:=half(w); shift_amount(y):=s-sa; end else @@ -17492,7 +17495,7 @@ var p,@!s,@!x,@!y,@!z:pointer; {temporary registers for box construction} @!t:integer; {subsidiary size code} @!save_f:internal_font_number; begin p:=new_hlist(q); -if is_char_node(p) or (p<>null and is_glyph_node(p)) then +if is_char_node(p) or is_glyph_node(p) then begin shift_up:=0; shift_down:=0; end else begin z:=hpack(p,natural); @@ -17603,11 +17606,14 @@ The following definitions should be kept in sync with \.{XeTeXOTMath.cpp}. @<Attach subscript OpenType math kerning@>= begin save_f:=cur_f;@/ fetch(subscr(q)); +sub_kern:=0; g:=0; if is_new_mathfont(cur_f) then begin s:=new_native_character(cur_f, qo(cur_c)); g:=get_native_glyph(s, 0); end; -sub_kern:=get_ot_math_kern(native_font(p), native_glyph(p), cur_f, g, sub_cmd, shift_down); +if is_glyph_node(p) then + sub_kern:=get_ot_math_kern(native_font(p), native_glyph(p), cur_f, g, sub_cmd, shift_down); + if sub_kern<>0 then p:=attach_hkern_to_new_hlist(q, sub_kern); cur_f:=save_f; end; @@ -17615,11 +17621,14 @@ end; @ @<Attach superscript OpenType math kerning@>= begin save_f:=cur_f;@/ fetch(supscr(q)); +sup_kern:=0; g:=0; if is_new_mathfont(cur_f) then begin s:=new_native_character(cur_f, qo(cur_c)); g:=get_native_glyph(s, 0); end; -sup_kern:=get_ot_math_kern(native_font(p), native_glyph(p), cur_f, g, sup_cmd, shift_up); +if is_glyph_node(p) then + sup_kern:=get_ot_math_kern(native_font(p), native_glyph(p), cur_f, g, sup_cmd, shift_up); + if (sup_kern<>0) and (math_type(subscr(q))=empty) then {if there is a superscript the kern will be added to |shift_amount(x)|} p:=attach_hkern_to_new_hlist(q, sup_kern); @@ -26610,7 +26619,10 @@ char_given: begin print_esc("char"); print_hex(chr_code); end; math_given: begin print_esc("mathchar"); print_hex(chr_code); end; -XeTeX_math_given: begin print_esc("Umathchar"); print_hex(chr_code); +XeTeX_math_given: begin print_esc("Umathchar"); + print_hex(math_class_field(chr_code)); + print_hex(math_fam_field(chr_code)); + print_hex(math_char_field(chr_code)); end; @ We temporarily define |p| to be |relax|, so that an occurrence of |p| @@ -28902,7 +28914,7 @@ begin end else if (type(pp) = disc_node) then begin ppp := link(pp); - if (ppp <> null) and is_native_word_node(ppp) + if is_native_word_node(ppp) and (native_font(ppp) = native_font(p)) then begin pp := link(ppp); goto restart; @@ -29535,8 +29547,8 @@ begin pic_transform2(tail) := D2Fix(bField(t)); pic_transform3(tail) := D2Fix(cField(t)); pic_transform4(tail) := D2Fix(dField(t)); - pic_transform5(tail) := D2Fix(txField(t)); - pic_transform6(tail) := D2Fix(tyField(t)); + pic_transform5(tail) := D2Fix(xField(t)); + pic_transform6(tail) := D2Fix(yField(t)); memcpy(addressof(mem[tail + pic_node_size]), pic_path, strlen(pic_path)); libc_free(pic_path); diff --git a/Build/source/texk/web2c/xetexdir/xetexwebmac.tex b/Build/source/texk/web2c/xetexdir/xetexwebmac.tex new file mode 100644 index 00000000000..771d58df240 --- /dev/null +++ b/Build/source/texk/web2c/xetexdir/xetexwebmac.tex @@ -0,0 +1,255 @@ +% standard macros for WEB listings (in addition to PLAIN.TEX) +% +% pdfTeX adjustments mainained by Han The Thanh <hanthethanh@gmx.net>. +% XeTeX adjustments mainited by Khaled Hosny <khaledhosny@eglug.org> +% +\xdef\fmtversion{\fmtversion+WEBMAC4.1} % identifies current set of macros +\parskip 0pt % no stretch between paragraphs +\parindent 1em % for paragraphs and for the first line of Pascal text + +\font\eightrm=cmr8 \let\sc=\eightrm % NOT a caps-and-small-caps font! +\let\mainfont=\tenrm +\font\titlefont=cmr7 scaled\magstep4 % title on the contents page +\font\ttitlefont=cmtt10 scaled\magstep2 % typewriter type in title +\font\tentex=cmtex10 % TeX extended character set (used in strings) +\fontdimen7\tentex=0pt % no extra space after punctuation + +\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers +\def\|#1{\hbox{$#1$}} % one-letter identifiers look a bit better this way +\def\{\hbox{\bf#1\/}} % boldface type for reserved words +\def\.#1{\hbox{\tentex % typewriter type for strings + \let\\=\BS % backslash in a string + \let\'=\RQ % right quote in a string + \let\`=\LQ % left quote in a string + \let\{=\LB % left brace in a string + \let\}=\RB % right brace in a string + \let\~=\TL % tilde in a string + \let\ =\SP % space in a string + \let\_=\UL % underline in a string + \let\&=\AM % ampersand in a string + #1}} +\def\#{\hbox{\tt\char`\#}} % parameter sign +\def\${\hbox{\tt\char`\$}} % dollar sign +\def\%{\hbox{\tt\char`\%}} % percent sign +\def\^{\ifmmode\mathchar"222 \else\char`^ \fi} % pointer or hat +% circumflex accents can be obtained from \^^D instead of \^ +\def\AT!{@} % at sign for control text + +\chardef\AM=`\& % ampersand character in a string +\chardef\BS=`\\ % backslash in a string +\chardef\LB=`\{ % left brace in a string +\def\LQ{{\tt\char'22}} % left quote in a string +\chardef\RB=`\} % right brace in a string +\def\RQ{{\tt\char'23}} % right quote in a string +\def\SP{{\tt\char`\ }} % (visible) space in a string +\chardef\TL=`\~ % tilde in a string +\chardef\UL=`\_ % underline character in a string + +\newbox\bak \setbox\bak=\hbox to -1em{} % backspace one em +\newbox\bakk\setbox\bakk=\hbox to -2em{} % backspace two ems + +\newcount\ind % current indentation in ems +\def\1{\global\advance\ind by1\hangindent\ind em} % indent one more notch +\def\2{\global\advance\ind by-1} % indent one less notch +\def\3#1{\hfil\penalty#10\hfilneg} % optional break within a statement +\def\4{\copy\bak} % backspace one notch +\def\5{\hfil\penalty-1\hfilneg\kern2.5em\copy\bakk\ignorespaces}% optional break +\def\6{\ifmmode\else\par % forced break + \hangindent\ind em\noindent\kern\ind em\copy\bakk\ignorespaces\fi} +\def\7{\Y\6} % forced break and a little extra space + +\let\yskip=\smallskip +\def\to{\mathrel{.\,.}} % double dot, used only in math mode + +% Some changes for xetex +\def\note#1#2.{\Y\noindent{\hangindent2em\baselineskip10pt\eightrm#1~\pdfnote#2..\par}} + +\def\linkcolor#1{\special{color push rgb 0.4 0.6 1.0}#1\special{color pop}} +\def\link#1#2{\special{pdf:bann<</Type/Annot/Subtype/Link/Border[0 0 0]/A<</S/GoTo/D(#1)>>>>}\linkcolor{#2}\special{pdf:eann}} + +\newtoks\toksA +\newtoks\toksB +\newtoks\toksC +\newtoks\toksD +\newcount\countA +\countA=0 +\def\pdfnote#1.{\setbox0=\hbox{\toksA={#1.}\toksB={}\maketoks}\the\toksA} +\def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} +\def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks} +\def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}} +\def\maketoks{% + \expandafter\poptoks\the\toksA|ENDTOKS| + \ifx\first0\adn0 + \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3 + \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6 + \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9 + \else + \ifnum0=\countA\else\makenote\fi + \ifx\first.\let\next=\done\else + \let\next=\maketoks + \addtokens{\toksB}{\the\toksD} + \ifx\first,\addtokens{\toksB}{\space}\fi + \fi + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi + \next +} +\def\n#1{\link{#1}{#1}} +\def\makenote{\addtokens{\toksB}% + {\noexpand\n{\the\toksC}}\toksC={}\global\countA=0} +\def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} + +\def\lapstar{\rlap{*}} +\def\startsection{\Q{\let\*=\empty\special{pdf:dest (\modstar) [@thispage /XYZ @xpos @ypos null]}}% + \noindent{\let\*=\lapstar\bf\modstar.\quad}} +\def\defin#1{\global\advance\ind by 2 \1\&{#1 }} % begin `define' or `format' +\def\A{\note{See also section}} % crossref for doubly defined section name +\def\As{\note{See also sections}} % crossref for multiply defined section name +\def\B{\mathopen{\.{@\{}}} % begin controlled comment +\def\C#1{\ifmmode\gdef\XX{\null$\null}\else\gdef\XX{}\fi % Pascal comments + \XX\hfil\penalty-1\hfilneg\quad$\{\,$#1$\,\}$\XX} +\def\D{\defin{define}} % macro definition +\def\E{\cdot10^} % exponent in floating point constant +\def\ET{ and~} % conjunction between two section numbers +\def\ETs{, and~} % conjunction between the last two of several section numbers +\def\F{\defin{format}} % format definition +\let\G=\ge % greater than or equal sign +\def\H#1{\hbox{\rm\char"7D\tt#1}} % hexadecimal constant +\let\I=\ne % unequal sign +\def\J{\.{@\&}} % TANGLE's join operation +\let\K=\gets % left arrow +\let\L=\le % less than or equal sign +\outer\def\M#1.{\MN#1.\ifon\vfil\penalty-100\vfilneg % beginning of section + \vskip12ptminus3pt\startsection\ignorespaces} +\outer\def\N#1.#2.{\MN#1.\vfil\eject % beginning of starred section + \def\rhead{\uppercase{\ignorespaces#2}} % define running headline + \message{*\modno} % progress report + \edef\next{\write\cont{\Z{#2}{\modno}{\the\pageno}}}\next % to contents file + \ifon\startsection{\bf\ignorespaces#2.\quad}\ignorespaces} +\def\MN#1.{\par % common code for \M, \N + {\xdef\modstar{#1}\let\*=\empty\xdef\modno{#1}} + \ifx\modno\modstar \onmaybe \else\ontrue \fi \mark{\modno}} +\def\O#1{\hbox{\rm\char'23\kern-.2em\it#1\/\kern.05em}} % octal constant +\def\P{\rightskip=0pt plus 100pt minus 10pt % go into Pascal mode + \sfcode`;=3000 + \pretolerance 10000 + \hyphenpenalty 10000 \exhyphenpenalty 10000 + \global\ind=2 \1\ \unskip} +\def\Q{\rightskip=0pt % get out of Pascal mode + \sfcode`;=1500 \pretolerance 200 \hyphenpenalty 50 \exhyphenpenalty 50 } +\let\R=\lnot % logical not +\let\S=\equiv % equivalence sign +\def\T{\mathclose{\.{@\}}}} % terminate controlled comment +\def\U{\note{This code is used in section}} % crossref for use of a section +\def\Us{\note{This code is used in sections}} % crossref for uses of a section +\let\V=\lor % logical or +\let\W=\land % logical and +\def\X#1:#2\X{\ifmmode\gdef\XX{\null$\null}\else\gdef\XX{}\fi % section name + \XX$\langle\,$#2{\eightrm\kern.5em\pdfnote#1.}$\,\rangle$\XX} +\def\Y{\par\yskip} +\let\Z=\let % now you can \send the control sequence \Z +\def\){\hbox{\.{@\$}}} % sign for string pool check sum +\def\]{\hbox{\.{@\\}}} % sign for forced line break +\def\=#1{\kern2pt\hbox{\vrule\vtop{\vbox{\hrule + \hbox{\strut\kern2pt\.{#1}\kern2pt}} + \hrule}\vrule}\kern2pt} % verbatim string +\let\~=\ignorespaces +\let\*=* + +\def\onmaybe{\let\ifon=\maybe} \let\maybe=\iftrue +\newif\ifon \newif\iftitle \newif\ifpagesaved +\def\lheader{\mainfont\the\pageno\eightrm\qquad\rhead\hfill\title\qquad + \tensy x\mainfont\topmark} % top line on left-hand pages +\def\rheader{\tensy x\mainfont\topmark\eightrm\qquad\title\hfill\rhead + \qquad\mainfont\the\pageno} % top line on right-hand pages +\def\page{\box255 } +\def\normaloutput#1#2#3{\ifodd\pageno\hoffset=\pageshift\fi + \shipout\vbox{ + \vbox to\fullpageheight{ + \iftitle\global\titlefalse + \else\hbox to\pagewidth{\vbox to10pt{}\ifodd\pageno #3\else#2\fi}\fi + \vfill#1}} % parameter #1 is the page itself + \global\advance\pageno by1} + +\def\rhead{\.{WEB} OUTPUT} % this running head is reset by starred sections +\def\title{} % an optional title can be set by the user +\def\topofcontents{\centerline{\titlefont\title} + \vfill} % this material will start the table of contents page +\def\botofcontents{\vfill} % this material will end the table of contents page +\def\contentspagenumber{0} % default page number for table of contents +\newdimen\pagewidth \pagewidth=6.5in % the width of each page +\newdimen\pageheight \pageheight=8.7in % the height of each page +\newdimen\fullpageheight \fullpageheight=9in % page height including headlines +\newdimen\pageshift \pageshift=0in % shift righthand pages wrt lefthand ones +\def\magnify#1{\mag=#1\pagewidth=6.5truein\pageheight=8.7truein + \fullpageheight=9truein\setpage} +\def\setpage{\hsize\pagewidth\vsize\pageheight} % use after changing page size +\def\contentsfile{CONTENTS} % file that gets table of contents info +\def\readcontents{\input CONTENTS} + +\newwrite\cont +\output{\setbox0=\page % the first page is garbage + \openout\cont=\contentsfile + \global\output{\normaloutput\page\lheader\rheader}} +\setpage +\vbox to \vsize{} % the first \topmark won't be null + +\def\ch{\note{The following sections were changed by the change file:} + \let\*=\relax} +\newbox\sbox % saved box preceding the index +\newbox\lbox % lefthand column in the index +\def\inx{\par\vskip6pt plus 1fil % we are beginning the index + \write\cont{} % ensure that the contents file isn't empty + \closeout\cont % the contents information has been fully gathered + \output{\ifpagesaved\normaloutput{\box\sbox}\lheader\rheader\fi + \global\setbox\sbox=\page \global\pagesavedtrue} + \pagesavedfalse \eject % eject the page-so-far and predecessors + \setbox\sbox\vbox{\unvbox\sbox} % take it out of its box + \vsize=\pageheight \advance\vsize by -\ht\sbox % the remaining height + \hsize=.5\pagewidth \advance\hsize by -10pt + % column width for the index (20pt between cols) + \parfillskip 0pt plus .6\hsize % try to avoid almost empty lines + \def\lr{L} % this tells whether the left or right column is next + \output{\if L\lr\global\setbox\lbox=\page \gdef\lr{R} + \else\normaloutput{\vbox to\pageheight{\box\sbox\vss + \hbox to\pagewidth{\box\lbox\hfil\page}}}\lheader\rheader + \global\vsize\pageheight\gdef\lr{L}\global\pagesavedfalse\fi} + \message{Index:} + \parskip 0pt plus .5pt + \outer\def\:##1, {\par\hangindent2em\noindent##1:\kern1em\pdfnote} % index entry + \let\ttentry=\. \def\.##1{\ttentry{##1\kern.2em}} % give \tt a little room + \def\[##1]{$\underline{##1}$} % underlined index item + \rm \rightskip0pt plus 2.5em \tolerance 10000 \let\*=\lapstar + \hyphenpenalty 10000 \parindent0pt} +\def\fin{\par\vfill\eject % this is done when we are ending the index + \ifpagesaved\null\vfill\eject\fi % output a null index column + \if L\lr\else\null\vfill\eject\fi % finish the current page + \parfillskip 0pt plus 1fil + \def\rhead{NAMES OF THE SECTIONS} + \message{Section names:} + \output{\normaloutput\page\lheader\rheader} + \setpage + \def\note##1##2.{\hfil\penalty-1\hfilneg\quad{\eightrm##1~\pdfnote##2..}} + \linepenalty=10 % try to conserve lines + \def\U{\note{Used in section}} % crossref for use of a section + \def\Us{\note{Used in sections}} % crossref for uses of a section + \def\:{\par\hangindent 2em}\let\*=*\let\.=\ttentry} +\def\con{\par\vfill\eject % finish the section names + \rightskip 0pt \hyphenpenalty 50 \tolerance 200 + \setpage + \output{\normaloutput\page\lheader\rheader} + \titletrue % prepare to output the table of contents + \pageno=\contentspagenumber \def\rhead{TABLE OF CONTENTS} + \message{Table of contents:} + \topofcontents + \line{\hfil Section\hbox to3em{\hss Page}} + \def\Z##1##2##3{\line{\link{##2}{\ignorespaces##1 + \leaders\hbox to .5em{.\hfil}\hfil\ ##2} + \hbox to3em{\hss##3}}} + \readcontents\relax % read the contents info + \botofcontents \makeoutlines\end} % print the contents page(s) and terminate + +\newcount\countB +\def\makeoutlines{% + \def\?##1]{}\def\Z##1##2##3{\special{pdf:out 1 <</Title(##1)/A<</S/GoTo/D(##2)>>>>}} + \input CONTENTS\relax} +\endinput |