mirror of
https://github.com/chibicitiberiu/rainmeter-studio.git
synced 2024-02-24 04:33:31 +00:00
Gfx: Make D2D font family name handling more consistent with GDI+
This commit is contained in:
parent
e1b39f62b1
commit
2f8f67e2cf
@ -55,6 +55,7 @@ namespace Gfx {
|
||||
UINT CanvasD2D::c_Instances = 0;
|
||||
ID2D1Factory* CanvasD2D::c_D2D = nullptr;
|
||||
IDWriteFactory* CanvasD2D::c_DW = nullptr;
|
||||
IDWriteGdiInterop* CanvasD2D::c_DWGDIInterop = nullptr;
|
||||
IWICImagingFactory* CanvasD2D::c_WIC = nullptr;
|
||||
|
||||
CanvasD2D::CanvasD2D() : Canvas(),
|
||||
@ -102,6 +103,9 @@ bool CanvasD2D::Initialize()
|
||||
__uuidof(IDWriteFactory),
|
||||
(IUnknown**)&c_DW);
|
||||
if (FAILED(hr)) return false;
|
||||
|
||||
hr = c_DW->GetGdiInterop(&c_DWGDIInterop);
|
||||
if (FAILED(hr)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -114,6 +118,7 @@ void CanvasD2D::Finalize()
|
||||
{
|
||||
SafeRelease(&c_D2D);
|
||||
SafeRelease(&c_WIC);
|
||||
SafeRelease(&c_DWGDIInterop);
|
||||
SafeRelease(&c_DW);
|
||||
}
|
||||
}
|
||||
|
@ -98,6 +98,7 @@ private:
|
||||
static UINT c_Instances;
|
||||
static ID2D1Factory* c_D2D;
|
||||
static IDWriteFactory* c_DW;
|
||||
static IDWriteGdiInterop* c_DWGDIInterop;
|
||||
static IWICImagingFactory* c_WIC;
|
||||
};
|
||||
|
||||
|
@ -92,15 +92,46 @@ void TextFormatD2D::SetProperties(const WCHAR* fontFamily, int size, bool bold,
|
||||
{
|
||||
Dispose();
|
||||
|
||||
HRESULT hr = CanvasD2D::c_DW->CreateTextFormat(
|
||||
fontFamily,
|
||||
nullptr,
|
||||
bold ? DWRITE_FONT_WEIGHT_BOLD : DWRITE_FONT_WEIGHT_REGULAR,
|
||||
italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL,
|
||||
DWRITE_FONT_STRETCH_NORMAL,
|
||||
size * (4.0f / 3.0f),
|
||||
L"",
|
||||
&m_TextFormat);
|
||||
HRESULT hr = E_FAIL;
|
||||
|
||||
// |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.
|
||||
IDWriteFont* dwFont = CreateDWFontFromGDIFamilyName(fontFamily, bold, italic);
|
||||
if (dwFont)
|
||||
{
|
||||
WCHAR buffer[LF_FACESIZE];
|
||||
if (GetDWFontFamilyName(dwFont, buffer, _countof(buffer)))
|
||||
{
|
||||
// TODO: If |fontFamily| is e.g. 'Segoe UI Semibold' and |bold| is true, we might want
|
||||
// to make the weight heaver to match GDI+.
|
||||
hr = CanvasD2D::c_DW->CreateTextFormat(
|
||||
buffer,
|
||||
nullptr,
|
||||
dwFont->GetWeight(),
|
||||
dwFont->GetStyle(),
|
||||
DWRITE_FONT_STRETCH_NORMAL,
|
||||
size * (4.0f / 3.0f),
|
||||
L"",
|
||||
&m_TextFormat);
|
||||
}
|
||||
|
||||
dwFont->Release();
|
||||
}
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
// Fallback in case above fails.
|
||||
hr = CanvasD2D::c_DW->CreateTextFormat(
|
||||
fontFamily,
|
||||
nullptr,
|
||||
bold ? DWRITE_FONT_WEIGHT_BOLD : DWRITE_FONT_WEIGHT_REGULAR,
|
||||
italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL,
|
||||
DWRITE_FONT_STRETCH_NORMAL,
|
||||
size * (4.0f / 3.0f),
|
||||
L"",
|
||||
&m_TextFormat);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
@ -160,4 +191,58 @@ void TextFormatD2D::SetVerticalAlignment(VerticalAlignment alignment)
|
||||
}
|
||||
}
|
||||
|
||||
IDWriteFont* TextFormatD2D::CreateDWFontFromGDIFamilyName(const WCHAR* fontFamily, bool bold, bool italic)
|
||||
{
|
||||
IDWriteGdiInterop* dwGdiInterop;
|
||||
HRESULT hr = CanvasD2D::c_DW->GetGdiInterop(&dwGdiInterop);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
LOGFONT lf = {};
|
||||
wcscpy_s(lf.lfFaceName, fontFamily);
|
||||
lf.lfWidth = 12;
|
||||
lf.lfHeight = 12;
|
||||
lf.lfWeight = bold ? FW_BOLD : FW_NORMAL;
|
||||
lf.lfItalic = (BYTE)italic;
|
||||
lf.lfCharSet = DEFAULT_CHARSET;
|
||||
lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
|
||||
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
|
||||
lf.lfQuality = ANTIALIASED_QUALITY;
|
||||
lf.lfPitchAndFamily = VARIABLE_PITCH;
|
||||
|
||||
IDWriteFont* dwFont;
|
||||
hr = dwGdiInterop->CreateFontFromLOGFONT(&lf, &dwFont);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
return dwFont;
|
||||
}
|
||||
|
||||
dwGdiInterop->Release();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool TextFormatD2D::GetDWFontFamilyName(IDWriteFont* font, WCHAR* buffer, const UINT bufferSize)
|
||||
{
|
||||
bool result = false;
|
||||
IDWriteFontFamily* dwFontFamily;
|
||||
HRESULT hr = font->GetFontFamily(&dwFontFamily);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
IDWriteLocalizedStrings* dwFamilyNames;
|
||||
hr = dwFontFamily->GetFamilyNames(&dwFamilyNames);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
// TODO: Determine the best index?
|
||||
hr = dwFamilyNames->GetString(0, buffer, bufferSize);
|
||||
result = SUCCEEDED(hr);
|
||||
dwFamilyNames->Release();
|
||||
}
|
||||
|
||||
dwFontFamily->Release();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace Gfx
|
||||
|
@ -50,6 +50,14 @@ private:
|
||||
// changes.
|
||||
void CreateLayout(const WCHAR* str, UINT strLen, float maxW, float maxH);
|
||||
|
||||
// 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
|
||||
// style.
|
||||
static IDWriteFont* CreateDWFontFromGDIFamilyName(const WCHAR* fontFamily, bool bold, bool italic);
|
||||
|
||||
static bool GetDWFontFamilyName(IDWriteFont* font, WCHAR* buffer, UINT bufferSize);
|
||||
|
||||
IDWriteTextFormat* m_TextFormat;
|
||||
IDWriteTextLayout* m_TextLayout;
|
||||
IDWriteInlineObject* m_InlineEllipsis;
|
||||
|
Loading…
Reference in New Issue
Block a user