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:
		@@ -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;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user