mirror of
https://github.com/chibicitiberiu/rainmeter-studio.git
synced 2024-02-24 04:33:31 +00:00
Gfx: Improve D2D local font support
This commit is contained in:
parent
3a70f91d15
commit
d04bb46009
@ -93,15 +93,20 @@ void TextFormatD2D::SetProperties(
|
||||
const WCHAR* fontFamily, int size, bool bold, bool italic,
|
||||
const FontCollection* fontCollection)
|
||||
{
|
||||
auto fontCollectionD2D = (FontCollectionD2D*)fontCollection;
|
||||
|
||||
Dispose();
|
||||
|
||||
WCHAR dwriteFamilyName[LF_FACESIZE];
|
||||
DWRITE_FONT_WEIGHT dwriteFontWeight =
|
||||
bold ? DWRITE_FONT_WEIGHT_BOLD : DWRITE_FONT_WEIGHT_REGULAR;
|
||||
DWRITE_FONT_STYLE dwriteFontStyle =
|
||||
italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL;
|
||||
DWRITE_FONT_STRETCH dwriteFontStretch = DWRITE_FONT_STRETCH_NORMAL;
|
||||
|
||||
// |fontFamily| uses the GDI/GDI+ font naming convention so try to create DirectWrite font
|
||||
// using the GDI family name and then create a text format using the DirectWrite family name
|
||||
// obtained from it.
|
||||
WCHAR dwriteFamilyName[LF_FACESIZE];
|
||||
DWRITE_FONT_WEIGHT dwriteFontWeight;
|
||||
DWRITE_FONT_STYLE dwriteFontStyle;
|
||||
DWRITE_FONT_STRETCH dwriteFontStretch;
|
||||
HRESULT hr = Util::GetDWritePropertiesFromGDIProperties(
|
||||
CanvasD2D::c_DWFactory, fontFamily, bold, italic, dwriteFontWeight, dwriteFontStyle,
|
||||
dwriteFontStretch, dwriteFamilyName, _countof(dwriteFamilyName));
|
||||
@ -121,15 +126,28 @@ void TextFormatD2D::SetProperties(
|
||||
if (FAILED(hr))
|
||||
{
|
||||
IDWriteFontCollection* dwriteFontCollection = nullptr;
|
||||
auto fontCollectionD2D = (FontCollectionD2D*)fontCollection;
|
||||
|
||||
// If |fontFamily| is not in the system collection, use the font collection from
|
||||
// |fontCollectionD2D| if possible.
|
||||
//
|
||||
// TODO: Need to check GDI family names of the collection in |fontCollectionD2D|.
|
||||
if (!Util::IsFamilyInSystemFontCollection(CanvasD2D::c_DWFactory, fontFamily) &&
|
||||
(fontCollectionD2D && fontCollectionD2D->InitializeCollection()))
|
||||
{
|
||||
IDWriteFont* dwriteFont = Util::FindDWriteFontInFontCollectionByGDIFamilyName(
|
||||
fontCollectionD2D->m_Collection, fontFamily);
|
||||
if (dwriteFont)
|
||||
{
|
||||
hr = Util::GetFamilyNameFromDWriteFont(
|
||||
dwriteFont, dwriteFamilyName, _countof(dwriteFamilyName));
|
||||
{
|
||||
fontFamily = dwriteFamilyName;
|
||||
Util::GetPropertiesFromDWriteFont(
|
||||
dwriteFont, bold, italic, &dwriteFontWeight, &dwriteFontStyle,
|
||||
&dwriteFontStretch);
|
||||
}
|
||||
|
||||
dwriteFont->Release();
|
||||
}
|
||||
|
||||
dwriteFontCollection = fontCollectionD2D->m_Collection;
|
||||
}
|
||||
|
||||
@ -137,9 +155,9 @@ void TextFormatD2D::SetProperties(
|
||||
hr = CanvasD2D::c_DWFactory->CreateTextFormat(
|
||||
fontFamily,
|
||||
dwriteFontCollection,
|
||||
bold ? DWRITE_FONT_WEIGHT_BOLD : DWRITE_FONT_WEIGHT_REGULAR,
|
||||
italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL,
|
||||
DWRITE_FONT_STRETCH_NORMAL,
|
||||
dwriteFontWeight,
|
||||
dwriteFontStyle,
|
||||
dwriteFontStretch,
|
||||
size * (4.0f / 3.0f),
|
||||
L"",
|
||||
&m_TextFormat);
|
||||
|
@ -32,31 +32,8 @@ HRESULT GetDWritePropertiesFromGDIProperties(
|
||||
{
|
||||
if (GetFamilyNameFromDWriteFont(dwriteFont, dwriteFamilyName, dwriteFamilyNameSize))
|
||||
{
|
||||
dwriteFontWeight = dwriteFont->GetWeight();
|
||||
if (gdiBold)
|
||||
{
|
||||
if (dwriteFontWeight == DWRITE_FONT_WEIGHT_NORMAL)
|
||||
{
|
||||
dwriteFontWeight = DWRITE_FONT_WEIGHT_BOLD;
|
||||
}
|
||||
else if (dwriteFontWeight < DWRITE_FONT_WEIGHT_ULTRA_BOLD)
|
||||
{
|
||||
// If 'gdiFamilyName' was e.g. 'Segoe UI Light', |dwFontWeight| wil be equal to
|
||||
// DWRITE_FONT_WEIGHT_LIGHT. If |gdiBold| is true in that case, we need to
|
||||
// increase the weight a little more for similar results with GDI+.
|
||||
// TODO: Is +100 enough?
|
||||
dwriteFontWeight = (DWRITE_FONT_WEIGHT)(dwriteFontWeight + 100);
|
||||
}
|
||||
}
|
||||
|
||||
dwriteFontStyle = dwriteFont->GetStyle();
|
||||
if (gdiItalic && dwriteFontStyle == DWRITE_FONT_STYLE_NORMAL)
|
||||
{
|
||||
dwriteFontStyle = DWRITE_FONT_STYLE_ITALIC;
|
||||
}
|
||||
|
||||
dwriteFontStretch = dwriteFont->GetStretch();
|
||||
|
||||
GetPropertiesFromDWriteFont(
|
||||
dwriteFont, gdiBold, gdiItalic, &dwriteFontWeight, &dwriteFontStyle, &dwriteFontStretch);
|
||||
hr = S_OK;
|
||||
}
|
||||
|
||||
@ -66,6 +43,37 @@ HRESULT GetDWritePropertiesFromGDIProperties(
|
||||
return hr;
|
||||
}
|
||||
|
||||
void GetPropertiesFromDWriteFont(
|
||||
IDWriteFont* dwriteFont, const bool bold, const bool italic,
|
||||
DWRITE_FONT_WEIGHT* dwriteFontWeight, DWRITE_FONT_STYLE* dwriteFontStyle,
|
||||
DWRITE_FONT_STRETCH* dwriteFontStretch)
|
||||
{
|
||||
*dwriteFontWeight = dwriteFont->GetWeight();
|
||||
if (bold)
|
||||
{
|
||||
if (*dwriteFontWeight == DWRITE_FONT_WEIGHT_NORMAL)
|
||||
{
|
||||
*dwriteFontWeight = DWRITE_FONT_WEIGHT_BOLD;
|
||||
}
|
||||
else if (*dwriteFontWeight < DWRITE_FONT_WEIGHT_ULTRA_BOLD)
|
||||
{
|
||||
// If 'gdiFamilyName' was e.g. 'Segoe UI Light', |dwFontWeight| wil be equal to
|
||||
// DWRITE_FONT_WEIGHT_LIGHT. If |gdiBold| is true in that case, we need to
|
||||
// increase the weight a little more for similar results with GDI+.
|
||||
// TODO: Is +100 enough?
|
||||
*dwriteFontWeight = (DWRITE_FONT_WEIGHT)(*dwriteFontWeight + 100);
|
||||
}
|
||||
}
|
||||
|
||||
*dwriteFontStyle = dwriteFont->GetStyle();
|
||||
if (italic && *dwriteFontStyle == DWRITE_FONT_STYLE_NORMAL)
|
||||
{
|
||||
*dwriteFontStyle = DWRITE_FONT_STYLE_ITALIC;
|
||||
}
|
||||
|
||||
*dwriteFontStretch = dwriteFont->GetStretch();
|
||||
}
|
||||
|
||||
IDWriteFont* CreateDWriteFontFromGDIFamilyName(IDWriteFactory* factory, const WCHAR* gdiFamilyName)
|
||||
{
|
||||
IDWriteGdiInterop* dwGdiInterop;
|
||||
@ -145,5 +153,72 @@ bool IsFamilyInSystemFontCollection(IDWriteFactory* factory, const WCHAR* family
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT GetGDIFamilyNameFromDWriteFont(IDWriteFont* font, WCHAR* buffer, UINT bufferSize)
|
||||
{
|
||||
bool result = false;
|
||||
IDWriteLocalizedStrings* strings;
|
||||
BOOL stringsExist;
|
||||
HRESULT hr = font->GetInformationalStrings(
|
||||
DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES, &strings, &stringsExist);
|
||||
if (SUCCEEDED(hr) && stringsExist)
|
||||
{
|
||||
hr = strings->GetString(0, buffer, bufferSize);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
IDWriteFont* FindDWriteFontInFontFamilyByGDIFamilyName(
|
||||
IDWriteFontFamily* fontFamily, const WCHAR* gdiFamilyName)
|
||||
{
|
||||
const UINT32 fontFamilyFontCount = fontFamily->GetFontCount();
|
||||
for (UINT32 j = 0; j < fontFamilyFontCount; ++j)
|
||||
{
|
||||
IDWriteFont* font;
|
||||
HRESULT hr = fontFamily->GetFont(j, &font);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
WCHAR buffer[LF_FACESIZE];
|
||||
if (GetGDIFamilyNameFromDWriteFont(font, buffer, _countof(buffer)) &&
|
||||
_wcsicmp(gdiFamilyName, buffer) == 0)
|
||||
{
|
||||
return font;
|
||||
}
|
||||
|
||||
font->Release();
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
IDWriteFont* FindDWriteFontInFontCollectionByGDIFamilyName(
|
||||
IDWriteFontCollection* fontCollection, const WCHAR* gdiFamilyName)
|
||||
{
|
||||
const UINT32 fontCollectionFamilyCount = fontCollection->GetFontFamilyCount();
|
||||
for (UINT32 i = 0; i < fontCollectionFamilyCount; ++i)
|
||||
{
|
||||
IDWriteFontFamily* fontFamily;
|
||||
HRESULT hr = fontCollection->GetFontFamily(i, &fontFamily);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
IDWriteFont* font = FindDWriteFontInFontFamilyByGDIFamilyName(
|
||||
fontFamily, gdiFamilyName);
|
||||
fontFamily->Release();
|
||||
|
||||
if (font)
|
||||
{
|
||||
return font;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace Util
|
||||
} // namespace Gfx
|
||||
|
@ -31,6 +31,11 @@ HRESULT GetDWritePropertiesFromGDIProperties(
|
||||
DWRITE_FONT_WEIGHT& dwriteFontWeight, DWRITE_FONT_STYLE& dwriteFontStyle,
|
||||
DWRITE_FONT_STRETCH& dwriteFontStretch, WCHAR* dwriteFamilyName, UINT dwriteFamilyNameSize);
|
||||
|
||||
void GetPropertiesFromDWriteFont(
|
||||
IDWriteFont* dwriteFont, const bool bold, const bool italic,
|
||||
DWRITE_FONT_WEIGHT* dwriteFontWeight, DWRITE_FONT_STYLE* dwriteFontStyle,
|
||||
DWRITE_FONT_STRETCH* dwriteFontStretch);
|
||||
|
||||
// Creates a IDWriteFont using the GDI family name instead of the DirectWrite family name. For
|
||||
// example, 'Segoe UI' and 'Segoe UI Semibold' are separate family names with GDI whereas
|
||||
// DirectWrite uses the family name 'Segoe UI' for both and differentiates them by the font
|
||||
@ -44,6 +49,9 @@ HRESULT GetFamilyNameFromDWriteFontFamily(
|
||||
|
||||
bool IsFamilyInSystemFontCollection(IDWriteFactory* factory, const WCHAR* familyName);
|
||||
|
||||
IDWriteFont* FindDWriteFontInFontCollectionByGDIFamilyName(
|
||||
IDWriteFontCollection* fontCollection, const WCHAR* gdiFamilyName);
|
||||
|
||||
} // namespace Util
|
||||
} // namespace Gfx
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user