2016-04-14 18:57:58 -05:00
// 14 april 2016
2016-04-23 15:49:46 -05:00
# include "uipriv_windows.hpp"
2018-03-17 13:44:38 -05:00
# include "attrstr.hpp"
2016-04-14 18:57:58 -05:00
IDWriteFactory * dwfactory = NULL ;
2018-03-17 13:44:38 -05:00
// TOOD rename to something else, maybe
HRESULT uiprivInitDrawText ( void )
2016-04-14 18:57:58 -05:00
{
// TOOD use DWRITE_FACTORY_TYPE_ISOLATED instead?
return DWriteCreateFactory ( DWRITE_FACTORY_TYPE_SHARED ,
__uuidof ( IDWriteFactory ) ,
( IUnknown * * ) ( & dwfactory ) ) ;
}
2018-03-17 13:44:38 -05:00
void uiprivUninitDrawText ( void )
2016-04-14 18:57:58 -05:00
{
dwfactory - > Release ( ) ;
}
2018-03-17 13:44:38 -05:00
fontCollection * uiprivLoadFontCollection ( void )
2016-04-14 18:57:58 -05:00
{
fontCollection * fc ;
HRESULT hr ;
2018-03-17 13:44:38 -05:00
fc = uiprivNew ( fontCollection ) ;
2016-04-14 18:57:58 -05:00
// always get the latest available font information
hr = dwfactory - > GetSystemFontCollection ( & ( fc - > fonts ) , TRUE ) ;
if ( hr ! = S_OK )
2016-04-23 21:15:33 -05:00
logHRESULT ( L " error getting system font collection " , hr ) ;
2016-04-14 18:57:58 -05:00
fc - > userLocaleSuccess = GetUserDefaultLocaleName ( fc - > userLocale , LOCALE_NAME_MAX_LENGTH ) ;
return fc ;
}
2018-03-17 13:44:38 -05:00
void uiprivFontCollectionFree ( fontCollection * fc )
{
fc - > fonts - > Release ( ) ;
uiprivFree ( fc ) ;
}
WCHAR * uiprivFontCollectionFamilyName ( fontCollection * fc , IDWriteFontFamily * family )
2016-04-14 18:57:58 -05:00
{
IDWriteLocalizedStrings * names ;
2016-04-15 09:14:23 -05:00
WCHAR * str ;
2016-04-14 18:57:58 -05:00
HRESULT hr ;
hr = family - > GetFamilyNames ( & names ) ;
if ( hr ! = S_OK )
2016-04-23 21:15:33 -05:00
logHRESULT ( L " error getting names of font out " , hr ) ;
2018-03-17 14:49:00 -05:00
str = uiprivFontCollectionCorrectString ( fc , names ) ;
2016-04-15 09:14:23 -05:00
names - > Release ( ) ;
return str ;
}
2018-03-17 13:44:38 -05:00
WCHAR * uiprivFontCollectionCorrectString ( fontCollection * fc , IDWriteLocalizedStrings * names )
2016-04-15 09:14:23 -05:00
{
UINT32 index ;
BOOL exists ;
UINT32 length ;
WCHAR * wname ;
HRESULT hr ;
2016-04-14 18:57:58 -05:00
// this is complex, but we ignore failure conditions to allow fallbacks
// 1) If the user locale name was successfully retrieved, try it
// 2) If the user locale name was not successfully retrieved, or that locale's string does not exist, or an error occurred, try L"en-us", the US English locale
// 3) And if that fails, assume the first one
// This algorithm is straight from MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/dd368214%28v=vs.85%29.aspx
// For step 2 to work, start by setting hr to S_OK and exists to FALSE.
// TODO does it skip step 2 entirely if step 1 fails? rewrite it to be a more pure conversion of the MSDN code?
hr = S_OK ;
exists = FALSE ;
if ( fc - > userLocaleSuccess ! = 0 )
hr = names - > FindLocaleName ( fc - > userLocale , & index , & exists ) ;
if ( hr ! = S_OK | | ( hr = = S_OK & & ! exists ) )
hr = names - > FindLocaleName ( L " en-us " , & index , & exists ) ;
2017-06-17 16:15:32 -05:00
// TODO check hr again here? or did I decide that would be redundant because COM requires output arguments to be filled regardless of return value?
2016-04-14 18:57:58 -05:00
if ( ! exists )
index = 0 ;
hr = names - > GetStringLength ( index , & length ) ;
if ( hr ! = S_OK )
2016-04-23 21:15:33 -05:00
logHRESULT ( L " error getting length of font name " , hr ) ;
2016-04-14 18:57:58 -05:00
// GetStringLength() does not include the null terminator, but GetString() does
2018-04-15 17:12:58 -05:00
wname = ( WCHAR * ) uiprivAlloc ( ( length + 1 ) * sizeof ( WCHAR ) , " WCHAR[] " ) ;
2016-04-14 18:57:58 -05:00
hr = names - > GetString ( index , wname , length + 1 ) ;
if ( hr ! = S_OK )
2016-04-23 21:15:33 -05:00
logHRESULT ( L " error getting font name " , hr ) ;
2016-04-14 18:57:58 -05:00
return wname ;
}