diff options
author | Jonathan Kew <jfkthame@googlemail.com> | 2006-07-26 16:19:45 +0000 |
---|---|---|
committer | Jonathan Kew <jfkthame@googlemail.com> | 2006-07-26 16:19:45 +0000 |
commit | 622bf4a7c90729be28a038c49e4c237ce9f31297 (patch) | |
tree | 77466d5c0a89c433bd1c08f4cbeaf410fda7b25c /Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.mm | |
parent | e88aafe4ca4779a73487925dea63e8b55dc5e251 (diff) |
added main xetex source directory
git-svn-id: svn://tug.org/texlive/trunk@1920 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.mm')
-rw-r--r-- | Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.mm | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.mm b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.mm new file mode 100644 index 00000000000..c7c7652a10c --- /dev/null +++ b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.mm @@ -0,0 +1,280 @@ +/****************************************************************************\ + Part of the XeTeX typesetting system + copyright (c) 1994-2006 by SIL International + written by Jonathan Kew + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL SIL INTERNATIONAL BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of SIL International +shall not be used in advertising or otherwise to promote the sale, +use or other dealings in this Software without prior written +authorization from SIL International. +\****************************************************************************/ + +#ifdef XETEX_MAC // this file only for Mac OS X + +#include "XeTeXFontMgr_Mac.h" + +#include <Cocoa/Cocoa.h> + +XeTeXFontMgr::NameCollection* +XeTeXFontMgr_Mac::readNames(ATSFontRef fontRef) +{ + const int BUFUNIT = 256; + static int bufSize = BUFUNIT; + static char* buffer = new char[bufSize]; + + NameCollection* names = new NameCollection; + + CFStringRef psName; + OSStatus status = ATSFontGetPostScriptName(fontRef, kATSOptionFlagsDefault, &psName); + if (status != noErr) + 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; + } + 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; + } + } + } + + if (familyNames.size() > 0) + names->familyNames = familyNames; + if (subFamilyNames.size() > 0) + names->styleNames = subFamilyNames; + + return names; +} + +void +XeTeXFontMgr_Mac::addFontsToCaches(CFArrayRef fonts) +{ + NSEnumerator* enumerator = [(NSArray*)fonts objectEnumerator]; + while (id aFont = [enumerator nextObject]) { + ATSFontRef fontRef = ATSFontFindFromPostScriptName((CFStringRef)[aFont objectAtIndex: 0], kATSOptionFlagsDefault); + NameCollection* names = readNames(fontRef); + addToMaps(fontRef, names); + delete names; + } +} + +void +XeTeXFontMgr_Mac::addFamilyToCaches(ATSFontFamilyRef familyRef) +{ + CFStringRef nameStr; + OSStatus status = ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &nameStr); + if (status == noErr) { + NSArray* members = [[NSFontManager sharedFontManager] + availableMembersOfFontFamily: (NSString*)nameStr]; + CFRelease(nameStr); + addFontsToCaches((CFArrayRef)members); + } +} + +void +XeTeXFontMgr_Mac::addFontAndSiblingsToCaches(ATSFontRef fontRef) +{ + CFStringRef name; + OSStatus status = ATSFontGetPostScriptName(fontRef, kATSOptionFlagsDefault, &name); + if (status == noErr) { + NSFont* font = [NSFont fontWithName:(NSString*)name size:10.0]; + CFRelease(name); + NSArray* members = [[NSFontManager sharedFontManager] + availableMembersOfFontFamily: [font familyName]]; + addFontsToCaches((CFArrayRef)members); + } +} + +void +XeTeXFontMgr_Mac::searchForHostPlatformFonts(const std::string& name) +{ + // the name might be: + // FullName + // Family-Style (if there's a hyphen) + // PSName + // Family + // ...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) { + // found it, so locate the family, and add all members to the caches + addFontAndSiblingsToCaches(fontRef); + return; + } + + int hyph = name.find('-'); + if (hyph > 0 && hyph < name.length() - 1) { + std::string family(name.begin(), name.begin() + hyph); + CFStringRef familyStr = CFStringCreateWithCString(kCFAllocatorDefault, family.c_str(), kCFStringEncodingUTF8); + + NSArray* familyMembers = [[NSFontManager sharedFontManager] + availableMembersOfFontFamily: (NSString*)familyStr]; + if ([familyMembers count] > 0) { + addFontsToCaches((CFArrayRef)familyMembers); + return; + } + + ATSFontFamilyRef familyRef = ATSFontFamilyFindFromName(familyStr, kATSOptionFlagsDefault); + if (familyRef != 0xffffffff) { + addFamilyToCaches(familyRef); + return; + } + } + + fontRef = ATSFontFindFromPostScriptName(nameStr, kATSOptionFlagsDefault); + if (fontRef != kATSFontRefUnspecified) { + addFontAndSiblingsToCaches(fontRef); + return; + } + + NSArray* familyMembers = [[NSFontManager sharedFontManager] + availableMembersOfFontFamily: (NSString*)nameStr]; + if ([familyMembers count] > 0) { + addFontsToCaches((CFArrayRef)familyMembers); + return; + } + + ATSFontFamilyRef familyRef = ATSFontFamilyFindFromName(nameStr, kATSOptionFlagsDefault); + if (familyRef != 0xffffffff) { + addFamilyToCaches(familyRef); + return; + } +} + +NSAutoreleasePool* pool = NULL; + +void +XeTeXFontMgr_Mac::initialize() +{ + pool = [[NSAutoreleasePool alloc] init]; +} + +void +XeTeXFontMgr_Mac::terminate() +{ + if (pool != NULL) { + [pool release]; + } +} + +#endif // XETEX_MAC |