From 542a7dcf896271e5f9021febd71cf0126b4faa97 Mon Sep 17 00:00:00 2001 From: Airy ANDRE Date: Wed, 9 Jan 2013 19:17:11 +0100 Subject: [PATCH] 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) --- Onyx2D/platform_Windows/O2Font_gdi.m | 59 +++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 6 deletions(-) diff --git a/Onyx2D/platform_Windows/O2Font_gdi.m b/Onyx2D/platform_Windows/O2Font_gdi.m index 7249001b..767bd105 100644 --- a/Onyx2D/platform_Windows/O2Font_gdi.m +++ b/Onyx2D/platform_Windows/O2Font_gdi.m @@ -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