예제 #1
0
bool CDirectWriteRenderer::GetFontMetrics(CDirectWriteFont &Font, FontMetrics *pMetrics)
{
	if (pMetrics == nullptr)
		return false;
	if (m_pRenderTarget == nullptr)
		return false;

	HRESULT hr = E_UNEXPECTED;
	IDWriteTextFormat *pTextFormat = Font.GetTextFormat();

	if (pTextFormat != nullptr) {
		IDWriteFontCollection *pFontCollection;

		hr = pTextFormat->GetFontCollection(&pFontCollection);
		if (SUCCEEDED(hr)) {
			WCHAR szName[256];

			hr = pTextFormat->GetFontFamilyName(szName, lengthof(szName));
			if (SUCCEEDED(hr)) {
				UINT32 Index;
				BOOL fExists;

				hr = pFontCollection->FindFamilyName(szName, &Index, &fExists);
				if (SUCCEEDED(hr)) {
					IDWriteFontFamily *pFontFamily;

					hr = pFontCollection->GetFontFamily(Index, &pFontFamily);
					if (SUCCEEDED(hr)) {
						IDWriteFont *pFont;

						hr = pFontFamily->GetFirstMatchingFont(
							pTextFormat->GetFontWeight(),
							pTextFormat->GetFontStretch(),
							pTextFormat->GetFontStyle(),
							&pFont);
						if (SUCCEEDED(hr)) {
							DWRITE_FONT_METRICS Metrics;

							pFont->GetMetrics(&Metrics);
							const float Ratio = pTextFormat->GetFontSize() / static_cast<float>(Metrics.designUnitsPerEm);
							pMetrics->Ascent = Metrics.ascent * Ratio;
							pMetrics->Descent = Metrics.descent * Ratio;
							pMetrics->LineGap = Metrics.lineGap * Ratio;

							pFont->Release();
						}

						pFontFamily->Release();
					}
				}
			}
		}

		pFontCollection->Release();
	}

	return SUCCEEDED(hr);
}
예제 #2
0
파일: gui_dwrite.cpp 프로젝트: Qubit0-1/vim
    HRESULT
DWriteContext::SetLOGFONT(const LOGFONTW &logFont, float fontSize)
{
    // Most of this function is copy from: http://msdn.microsoft.com/en-us/library/windows/desktop/dd941783(v=vs.85).aspx
    HRESULT hr = S_OK;

    IDWriteFont *font = NULL;
    IDWriteFontFamily *fontFamily = NULL;
    IDWriteLocalizedStrings *localizedFamilyNames = NULL;

    if (SUCCEEDED(hr))
    {
	hr = mGdiInterop->CreateFontFromLOGFONT(&logFont, &font);
    }

    // Get the font family to which this font belongs.
    if (SUCCEEDED(hr))
    {
	hr = font->GetFontFamily(&fontFamily);
    }

    // Get the family names. This returns an object that encapsulates one or
    // more names with the same meaning but in different languages.
    if (SUCCEEDED(hr))
    {
	hr = fontFamily->GetFamilyNames(&localizedFamilyNames);
    }

    // Get the family name at index zero. If we were going to display the name
    // we'd want to try to find one that matched the use locale, but for
    // purposes of creating a text format object any language will do.

    wchar_t familyName[100];
    if (SUCCEEDED(hr))
    {
	hr = localizedFamilyNames->GetString(0, familyName,
		ARRAYSIZE(familyName));
    }

    if (SUCCEEDED(hr))
    {
	// If no font size was passed in use the lfHeight of the LOGFONT.
	if (fontSize == 0)
	{
	    // Convert from pixels to DIPs.
	    fontSize = PixelsToDipsY(logFont.lfHeight);
	    if (fontSize < 0)
	    {
		// Negative lfHeight represents the size of the em unit.
		fontSize = -fontSize;
	    }
	    else
	    {
		// Positive lfHeight represents the cell height (ascent +
		// descent).
		DWRITE_FONT_METRICS fontMetrics;
		font->GetMetrics(&fontMetrics);

		// Convert the cell height (ascent + descent) from design units
		// to ems.
		float cellHeight = static_cast<float>(
			fontMetrics.ascent + fontMetrics.descent)
					       / fontMetrics.designUnitsPerEm;

		// Divide the font size by the cell height to get the font em
		// size.
		fontSize /= cellHeight;
	    }
	}
    }

    // The text format includes a locale name. Ideally, this would be the
    // language of the text, which may or may not be the same as the primary
    // language of the user. However, for our purposes the user locale will do.
    wchar_t localeName[LOCALE_NAME_MAX_LENGTH];
    if (SUCCEEDED(hr))
    {
	if (GetUserDefaultLocaleName(localeName, LOCALE_NAME_MAX_LENGTH) == 0)
	    hr = HRESULT_FROM_WIN32(GetLastError());
    }

    if (SUCCEEDED(hr))
    {
	// Create the text format object.
	hr = mDWriteFactory->CreateTextFormat(
		familyName,
		NULL, // no custom font collection
		font->GetWeight(),
		font->GetStyle(),
		font->GetStretch(),
		fontSize,
		localeName,
		&mTextFormat);
    }

    if (SUCCEEDED(hr))
    {
	mFontWeight = static_cast<DWRITE_FONT_WEIGHT>(logFont.lfWeight);
	mFontStyle = logFont.lfItalic ? DWRITE_FONT_STYLE_ITALIC
	    : DWRITE_FONT_STYLE_NORMAL;
    }

    SafeRelease(&localizedFamilyNames);
    SafeRelease(&fontFamily);
    SafeRelease(&font);

    return hr;
}