Add US font name to Postscript mapping, so the US name works on non-US Win8 systems too (Win7 seems to like US name)

(+[NSFont boldSystemFontWithSize:] is using "Arial Bold" and returns nil on a french Win8)
This commit is contained in:
Airy ANDRE 2013-01-09 19:17:11 +01:00
parent 110273eab5
commit 542a7dcf89

View File

@ -45,7 +45,7 @@ static int CALLBACK EnumFontFromFamilyCallBack(const EXTLOGFONTW* longFont,const
{
HFONT font = CreateFontIndirectW(&longFont->elfLogFont);
if (font) {
// Get the full face name
// Get the full face name - on Win8, this is a localized name
NSString *winName = [NSString stringWithFormat:@"%S", longFont->elfFullName];
// Font name starting with "@" are rotated versions of the font, for vertical rendering
// We don't want them - the are polluting our font list + they have the same PS name
@ -67,6 +67,46 @@ static int CALLBACK EnumFontFromFamilyCallBack(const EXTLOGFONTW* longFont,const
if (bufferSize > stringsOffset) {
uint8_t* strings = buffer + stringsOffset;
name_records_t* nameRecords = (name_records_t *)(buffer + sizeof(name_table_header_t));
// Parse all of the name records until we find a US full name there so we can have both the US name and the localized
// name in the font name -> PS name table
NSString *fontNameUS = nil;
for (int i = 0; i < count; i++) {
uint16_t platformID = CFSwapInt16BigToHost(nameRecords[i].platformID);
uint16_t platformSpecificID = CFSwapInt16BigToHost(nameRecords[i].platformSpecificID);
uint16_t languageID = CFSwapInt16BigToHost(nameRecords[i].languageID);
uint16_t nameID = CFSwapInt16BigToHost(nameRecords[i].nameID);
uint16_t length = CFSwapInt16BigToHost(nameRecords[i].length);
uint16_t offset = CFSwapInt16BigToHost(nameRecords[i].offset);
// Full name, US language
if (nameID == 4 && languageID == 0x0409) {
// First check we get a string that's in our buffer, in case of some corrupted font or font entry
if (stringsOffset + offset + length <= bufferSize) {
// Check for Win+Unicode encoding or Mac+Roman encoding
// Other entries should be ignored (see http://www.microsoft.com/typography/otspec/name.htm )
if (platformID == 3 && platformSpecificID == 1) {
// Win name - unicode encoding
NSString *name = [[[NSString alloc] initWithBytes:strings + offset length:length encoding:NSUnicodeStringEncoding] autorelease];
if ([name length]) {
if (![winName isEqualToString:name]) {
fontNameUS = name;
}
break;
}
} else if (platformID == 1 && platformSpecificID == 0) {
// Mac name - ASCII
NSString *name = [NSString stringWithCString:strings + offset length:length];
if ([name length]) {
if (![winName isEqualToString:name]) {
fontNameUS = name;
}
break;
}
}
}
}
}
// Parse all of the name records until we find some PS name there
for (int i = 0; i < count; i++) {
uint16_t platformID = CFSwapInt16BigToHost(nameRecords[i].platformID);
@ -88,16 +128,24 @@ static int CALLBACK EnumFontFromFamilyCallBack(const EXTLOGFONTW* longFont,const
if ([name length]) {
[sPSToWin32Table setObject:winName forKey:name];
[sWin32ToPSTable setObject:name forKey:winName];
if (fontNameUS) {
// Add the US font name -> PS mapping
[sWin32ToPSTable setObject:name forKey:fontNameUS];
}
}
break;
break;
} else if (platformID == 1 && platformSpecificID == 0) {
// Mac PS name - ASCII
NSString *name = [NSString stringWithCString:strings + offset length:length];
if ([name length]) {
[sPSToWin32Table setObject:winName forKey:name];
[sWin32ToPSTable setObject:name forKey:winName];
}
break;
if (fontNameUS) {
// Add the US font name -> PS mapping
[sWin32ToPSTable setObject:name forKey:fontNameUS];
}
}
break;
}
}
}
@ -124,7 +172,7 @@ static int CALLBACK EnumFamiliesCallBackW(const EXTLOGFONTW* logFont,const TEXTM
HDC dc=GetDC(NULL);
sPSToWin32Table = [[NSMutableDictionary alloc] initWithCapacity:100];
sWin32ToPSTable = [[NSMutableDictionary alloc] initWithCapacity:100];
// Get a list of all of the families
NSMutableArray *families = [NSMutableArray arrayWithCapacity:100];
LOGFONTW logFont = { 0 };
@ -270,7 +318,6 @@ static HFONT Win32FontHandleWithName(NSString *name,int unitsPerEm){
[self release];
return nil;
}
GetTextMetrics(dc,&gdiMetrics);
// default values if not truetype or truetype queries fail