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 WCHAR* fontFamily, int size, bool bold, bool italic,
|
||||||
const FontCollection* fontCollection)
|
const FontCollection* fontCollection)
|
||||||
{
|
{
|
||||||
|
auto fontCollectionD2D = (FontCollectionD2D*)fontCollection;
|
||||||
|
|
||||||
Dispose();
|
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
|
// |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
|
// using the GDI family name and then create a text format using the DirectWrite family name
|
||||||
// obtained from it.
|
// obtained from it.
|
||||||
WCHAR dwriteFamilyName[LF_FACESIZE];
|
|
||||||
DWRITE_FONT_WEIGHT dwriteFontWeight;
|
|
||||||
DWRITE_FONT_STYLE dwriteFontStyle;
|
|
||||||
DWRITE_FONT_STRETCH dwriteFontStretch;
|
|
||||||
HRESULT hr = Util::GetDWritePropertiesFromGDIProperties(
|
HRESULT hr = Util::GetDWritePropertiesFromGDIProperties(
|
||||||
CanvasD2D::c_DWFactory, fontFamily, bold, italic, dwriteFontWeight, dwriteFontStyle,
|
CanvasD2D::c_DWFactory, fontFamily, bold, italic, dwriteFontWeight, dwriteFontStyle,
|
||||||
dwriteFontStretch, dwriteFamilyName, _countof(dwriteFamilyName));
|
dwriteFontStretch, dwriteFamilyName, _countof(dwriteFamilyName));
|
||||||
@ -121,15 +126,28 @@ void TextFormatD2D::SetProperties(
|
|||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
IDWriteFontCollection* dwriteFontCollection = nullptr;
|
IDWriteFontCollection* dwriteFontCollection = nullptr;
|
||||||
auto fontCollectionD2D = (FontCollectionD2D*)fontCollection;
|
|
||||||
|
|
||||||
// If |fontFamily| is not in the system collection, use the font collection from
|
// If |fontFamily| is not in the system collection, use the font collection from
|
||||||
// |fontCollectionD2D| if possible.
|
// |fontCollectionD2D| if possible.
|
||||||
//
|
|
||||||
// TODO: Need to check GDI family names of the collection in |fontCollectionD2D|.
|
|
||||||
if (!Util::IsFamilyInSystemFontCollection(CanvasD2D::c_DWFactory, fontFamily) &&
|
if (!Util::IsFamilyInSystemFontCollection(CanvasD2D::c_DWFactory, fontFamily) &&
|
||||||
(fontCollectionD2D && fontCollectionD2D->InitializeCollection()))
|
(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;
|
dwriteFontCollection = fontCollectionD2D->m_Collection;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,9 +155,9 @@ void TextFormatD2D::SetProperties(
|
|||||||
hr = CanvasD2D::c_DWFactory->CreateTextFormat(
|
hr = CanvasD2D::c_DWFactory->CreateTextFormat(
|
||||||
fontFamily,
|
fontFamily,
|
||||||
dwriteFontCollection,
|
dwriteFontCollection,
|
||||||
bold ? DWRITE_FONT_WEIGHT_BOLD : DWRITE_FONT_WEIGHT_REGULAR,
|
dwriteFontWeight,
|
||||||
italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL,
|
dwriteFontStyle,
|
||||||
DWRITE_FONT_STRETCH_NORMAL,
|
dwriteFontStretch,
|
||||||
size * (4.0f / 3.0f),
|
size * (4.0f / 3.0f),
|
||||||
L"",
|
L"",
|
||||||
&m_TextFormat);
|
&m_TextFormat);
|
||||||
|
@ -32,31 +32,8 @@ HRESULT GetDWritePropertiesFromGDIProperties(
|
|||||||
{
|
{
|
||||||
if (GetFamilyNameFromDWriteFont(dwriteFont, dwriteFamilyName, dwriteFamilyNameSize))
|
if (GetFamilyNameFromDWriteFont(dwriteFont, dwriteFamilyName, dwriteFamilyNameSize))
|
||||||
{
|
{
|
||||||
dwriteFontWeight = dwriteFont->GetWeight();
|
GetPropertiesFromDWriteFont(
|
||||||
if (gdiBold)
|
dwriteFont, gdiBold, gdiItalic, &dwriteFontWeight, &dwriteFontStyle, &dwriteFontStretch);
|
||||||
{
|
|
||||||
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();
|
|
||||||
|
|
||||||
hr = S_OK;
|
hr = S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,6 +43,37 @@ HRESULT GetDWritePropertiesFromGDIProperties(
|
|||||||
return hr;
|
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)
|
IDWriteFont* CreateDWriteFontFromGDIFamilyName(IDWriteFactory* factory, const WCHAR* gdiFamilyName)
|
||||||
{
|
{
|
||||||
IDWriteGdiInterop* dwGdiInterop;
|
IDWriteGdiInterop* dwGdiInterop;
|
||||||
@ -145,5 +153,72 @@ bool IsFamilyInSystemFontCollection(IDWriteFactory* factory, const WCHAR* family
|
|||||||
return result;
|
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 Util
|
||||||
} // namespace Gfx
|
} // namespace Gfx
|
||||||
|
@ -31,6 +31,11 @@ HRESULT GetDWritePropertiesFromGDIProperties(
|
|||||||
DWRITE_FONT_WEIGHT& dwriteFontWeight, DWRITE_FONT_STYLE& dwriteFontStyle,
|
DWRITE_FONT_WEIGHT& dwriteFontWeight, DWRITE_FONT_STYLE& dwriteFontStyle,
|
||||||
DWRITE_FONT_STRETCH& dwriteFontStretch, WCHAR* dwriteFamilyName, UINT dwriteFamilyNameSize);
|
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
|
// 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
|
// 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
|
// 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);
|
bool IsFamilyInSystemFontCollection(IDWriteFactory* factory, const WCHAR* familyName);
|
||||||
|
|
||||||
|
IDWriteFont* FindDWriteFontInFontCollectionByGDIFamilyName(
|
||||||
|
IDWriteFontCollection* fontCollection, const WCHAR* gdiFamilyName);
|
||||||
|
|
||||||
} // namespace Util
|
} // namespace Util
|
||||||
} // namespace Gfx
|
} // namespace Gfx
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user