From 27272bc58e55a653d45891e8e808a0328c8837d8 Mon Sep 17 00:00:00 2001 From: Airy ANDRE Date: Mon, 1 Sep 2014 18:57:15 +0200 Subject: [PATCH] Use CreateFontW instead of CreateFontIndirectW (I guess CreateFontIndirectW with the right flags might work too) when enumerating fonts and building the Win32 <-> Postscript names tables CreateFontIndirectW is returning the wrong font for some faces like "Minya Nouvelle Italic" (the Regular version is returned instead) --- AppKit/Win32.subproj/Win32Display.m | 23 ++++++++++----------- Onyx2D/platform_Windows/O2Font_gdi.m | 30 ++++++++++++++++++++++------ 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/AppKit/Win32.subproj/Win32Display.m b/AppKit/Win32.subproj/Win32Display.m index a99a48ee..3663c0aa 100755 --- a/AppKit/Win32.subproj/Win32Display.m +++ b/AppKit/Win32.subproj/Win32Display.m @@ -1318,14 +1318,13 @@ static HWND findWindowForScrollWheel(POINT point){ MessageBeep(MB_OK); } -static int CALLBACK buildFamily(const LOGFONTA *lofFont_old, - const TEXTMETRICA *textMetric_old,DWORD fontType,LPARAM lParam){ - LPENUMLOGFONTEX logFont=(LPENUMLOGFONTEX)lofFont_old; -// NEWTEXTMETRICEX *textMetric=(NEWTEXTMETRICEX *)textMetric_old; +static int CALLBACK buildFamily(const const EXTLOGFONTW* logFont,const TEXTMETRICW* metrics,DWORD fontType,LPARAM lParam){ + + // NEWTEXTMETRICEX *textMetric=(NEWTEXTMETRICEX *)textMetric_old; NSMutableSet *set=(NSMutableSet *)lParam; // NSString *name=[NSString stringWithCString:logFont->elfFullName]; if (logFont && logFont->elfLogFont.lfFaceName) { - NSString *name=[NSString stringWithCString:logFont->elfLogFont.lfFaceName]; + NSString *name = [NSString stringWithFormat:@"%S", logFont->elfLogFont.lfFaceName]; // 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 // as the normal ones, leading to confusion in our font picking algo @@ -1339,15 +1338,13 @@ static int CALLBACK buildFamily(const LOGFONTA *lofFont_old, -(NSSet *)allFontFamilyNames { NSMutableSet *result=[[[NSMutableSet alloc] init] autorelease]; HDC dc=GetDC(NULL); - LOGFONT logFont; - + LOGFONTW logFont = { 0 }; + logFont.lfCharSet=DEFAULT_CHARSET; - strcpy(logFont.lfFaceName,""); - logFont.lfPitchAndFamily=0; - - if(!EnumFontFamiliesExA(dc,&logFont,buildFamily,(LPARAM)result,0)) - NSLog(@"EnumFontFamiliesExA failed %d",__LINE__); - + + if(!EnumFontFamiliesExW(dc,&logFont,buildFamily,(LPARAM)result,0)) + NSLog(@"EnumFontFamiliesExW failed %d",__LINE__); + ReleaseDC(NULL,dc); return result; } diff --git a/Onyx2D/platform_Windows/O2Font_gdi.m b/Onyx2D/platform_Windows/O2Font_gdi.m index 293a11ef..faa8e2a3 100644 --- a/Onyx2D/platform_Windows/O2Font_gdi.m +++ b/Onyx2D/platform_Windows/O2Font_gdi.m @@ -43,7 +43,22 @@ typedef struct name_records_t { // Fill the name mapping dictionaries with the logFont face info static int CALLBACK EnumFontFromFamilyCallBack(const EXTLOGFONTW* logFont,const TEXTMETRICW* metrics, DWORD ignored, HDC dc) { - HFONT font = CreateFontIndirectW(&logFont->elfLogFont); + // Create a HFONT from the logFont so we can get the font tables we need to parse to get the PS name of the font + // Use CreateFontW, not CreateFontIndirectW with the received logFont + // For some mysterious reason, CreateFontIndirectW is returning the wrong font for some faces like "Minya Nouvelle Italic" + // (the Regular version is returned instead) + HFONT font = CreateFontW(0,0,0,0, + FW_NORMAL, + FALSE, + FALSE, + FALSE, + DEFAULT_CHARSET, + OUT_DEFAULT_PRECIS, + CLIP_DEFAULT_PRECIS, + DEFAULT_QUALITY, + DEFAULT_PITCH|FF_DONTCARE, + logFont->elfFullName); + if (font) { // Ignore fonts for which we can't get a full name if (logFont->elfFullName == NULL) { @@ -72,7 +87,8 @@ static int CALLBACK EnumFontFromFamilyCallBack(const EXTLOGFONTW* logFont,const return 1; } - if (SelectObject(dc, font) == HGDI_ERROR) { + HGDIOBJ selectedObject = SelectObject(dc, font); + if (selectedObject == HGDI_ERROR) { NSLog(@"Error selecting %@", winName); return 1; } @@ -81,8 +97,9 @@ static int CALLBACK EnumFontFromFamilyCallBack(const EXTLOGFONTW* logFont,const DWORD bufferSize = GetFontData(dc, CFSwapInt32HostToBig('name'), 0, NULL, 0); if (bufferSize >= 6 && bufferSize != GDI_ERROR) { uint8_t buffer[bufferSize]; + bzero(buffer, 6); if (GetFontData(dc, CFSwapInt32HostToBig('name'), 0, buffer, bufferSize) != GDI_ERROR) { - name_table_header_t *header = (name_table_header_t *)buffer; + name_table_header_t *header = (name_table_header_t *)buffer; uint16_t count = CFSwapInt16BigToHost(header->count); uint16_t stringsOffset = CFSwapInt16BigToHost(header->stringOffset); if (bufferSize > stringsOffset) { @@ -178,7 +195,7 @@ static int CALLBACK EnumFontFromFamilyCallBack(const EXTLOGFONTW* logFont,const [sWin32ToPSTable setObject:name forKey:fontNameUS]; } } - break; + break; } } } @@ -186,6 +203,7 @@ static int CALLBACK EnumFontFromFamilyCallBack(const EXTLOGFONTW* logFont,const } } } + SelectObject(dc, selectedObject); DeleteObject(font); } return 1; @@ -193,7 +211,7 @@ static int CALLBACK EnumFontFromFamilyCallBack(const EXTLOGFONTW* logFont,const // Add the logFont family to the list of known families static int CALLBACK EnumFamiliesCallBackW(const EXTLOGFONTW* logFont,const TEXTMETRICW* metrics, DWORD ignored, LPARAM p) { - NSMutableArray *families = (NSMutableArray *)p; + NSMutableSet *families = (NSMutableSet *)p; NSString *winName = [NSString stringWithFormat:@"%S", logFont->elfLogFont.lfFaceName]; [families addObject:winName]; @@ -207,7 +225,7 @@ static int CALLBACK EnumFamiliesCallBackW(const EXTLOGFONTW* logFont,const TEXTM sWin32ToPSTable = [[NSMutableDictionary alloc] initWithCapacity:100]; // Get a list of all of the families - NSMutableArray *families = [NSMutableArray arrayWithCapacity:100]; + NSMutableSet *families = [NSMutableSet setWithCapacity:100]; LOGFONTW logFont = { 0 }; logFont.lfCharSet=DEFAULT_CHARSET;