void QWindowsFontEngineDirectWrite::initFontInfo(const QFontDef &request,
        int dpi, IDWriteFont *font)
{
    fontDef = request;

    IDWriteFontFamily *fontFamily = NULL;
    HRESULT hr = font->GetFontFamily(&fontFamily);

    IDWriteLocalizedStrings *familyNames = NULL;
    if (SUCCEEDED(hr))
        hr = fontFamily->GetFamilyNames(&familyNames);

    UINT32 index = 0;

    if (SUCCEEDED(hr)) {
        BOOL exists = false;

        wchar_t localeName[LOCALE_NAME_MAX_LENGTH];
        int defaultLocaleSuccess = GetUserDefaultLocaleName(localeName, LOCALE_NAME_MAX_LENGTH);
        if (defaultLocaleSuccess)
            hr = familyNames->FindLocaleName(localeName, &index, &exists);

        if (SUCCEEDED(hr) && !exists)
            hr = familyNames->FindLocaleName(L"en-us", &index, &exists);

        if (!exists)
            index = 0;
    }

    // Get the family name.
    if (SUCCEEDED(hr)) {
        UINT32 length = 0;

        hr = familyNames->GetStringLength(index, &length);

        if (SUCCEEDED(hr)) {
            QVarLengthArray<wchar_t, 128> name(length+1);

            hr = familyNames->GetString(index, name.data(), name.size());

            if (SUCCEEDED(hr))
                fontDef.family = QString::fromWCharArray(name.constData());
        }
    }

    if (familyNames != NULL)
        familyNames->Release();
    if (fontFamily)
        fontFamily->Release();

    if (FAILED(hr))
        qErrnoWarning(hr, "initFontInfo: Failed to get family name");

    if (fontDef.pointSize < 0)
        fontDef.pointSize = fontDef.pixelSize * 72. / dpi;
    else if (fontDef.pixelSize == -1)
        fontDef.pixelSize = qRound(fontDef.pointSize * dpi / 72.);
}
Exemplo n.º 2
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);
}
Exemplo n.º 3
0
HRESULT GetFamilyNameFromDWriteFont(IDWriteFont* font, WCHAR* buffer, const UINT bufferSize)
{
	IDWriteFontFamily* dwriteFontFamily;
	HRESULT hr = font->GetFontFamily(&dwriteFontFamily);
	if (SUCCEEDED(hr))
	{
		hr = GetFamilyNameFromDWriteFontFamily(dwriteFontFamily, buffer, bufferSize);
		dwriteFontFamily->Release();
	}

	return hr;
}
Exemplo n.º 4
0
void loadInitialFontDialogParams(struct fontDialogParams *params)
{
	struct fontCollection *fc;
	IDWriteFontFamily *family;
	IDWriteFont *font;
	HRESULT hr;

	// Our preferred font is Arial 10 Regular.
	// 10 comes from the official font dialog.
	// Arial Regular is a reasonable, if arbitrary, default; it's similar to the defaults on other systems.
	// If Arial isn't found, we'll use Helvetica and then MS Sans Serif as fallbacks, and if not, we'll just grab the first font family in the collection.

	// We need the correct localized name for Regular (and possibly Arial too? let's say yes to be safe), so let's grab the strings from DirectWrite instead of hardcoding them.
	fc = loadFontCollection();
	family = tryFindFamily(fc->fonts, L"Arial");
	if (family == NULL) {
		family = tryFindFamily(fc->fonts, L"Helvetica");
		if (family == NULL) {
			family = tryFindFamily(fc->fonts, L"MS Sans Serif");
			if (family == NULL) {
				hr = fc->fonts->GetFontFamily(0, &family);
				if (hr != S_OK)
					logHRESULT(L"error getting first font out of font collection (worst case scenario)", hr);
			}
		}
	}

	// next part is simple: just get the closest match to regular
	hr = family->GetFirstMatchingFont(
		DWRITE_FONT_WEIGHT_NORMAL,
		DWRITE_FONT_STRETCH_NORMAL,
		DWRITE_FONT_STYLE_NORMAL,
		&font);
	if (hr != S_OK)
		logHRESULT(L"error getting Regular font from Arial", hr);

	params->font = font;
	params->size = 10;
	params->familyName = fontCollectionFamilyName(fc, family);
	params->styleName = fontStyleName(fc, font);

	// don't release font; we still need it
	family->Release();
	fontCollectionFree(fc);
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
int main(void)
{
	int argc;
	LPWSTR *argv;
	WCHAR *fontname, *string;
	int len;
	HDC dc;
	HFONT font, prevfont;
	IDWriteFontCollection *sysfc;
	UINT32 index;
	BOOL exists;
	IDWriteFontFamily *dwfamily;
	IDWriteFont *dwfont;
	IDWriteFontFace *dwface;
	featurePreparer *features;
	HRESULT hr;

	// TODO would using wmain() be adequate?
	argv = CommandLineToArgvW(GetCommandLineW(), &argc);
	if (argv == NULL)
		dieLE("error getting command-line arguments");
	if (argc != 3) {
		fprintf(stderr, "usage: %ws font string\n", argv[0]);
		return 1;
	}
	fontname = argv[1];
	string = argv[2];
	len = wcslen(string);

	// DirectWrite requires COM
	hr = CoInitialize(NULL);
	if (hr != S_OK)
		die("error initializing COM", hr);
	// Uniscribe requires a device context with the font to use
	dc = GetDC(NULL);
	if (dc == NULL)
		dieLE("error getting screen HDC for Uniscribe");
	// TODO DEFAULT_CHARSET might affect the results we get
	font = CreateFontW(0, 0, 0, 0, 0, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, fontname);
	if (font == NULL)
		dieLE("error creating font for Uniscribe");
	prevfont = (HFONT) SelectObject(dc, font);
	if (prevfont == NULL)
		dieLE("error selecting font into HDC for Uniscribe");
	// and initialize DirectWrite
	hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED,
		__uuidof (IDWriteFactory),
		(IUnknown **) (&dwfactory));
	if (hr != S_OK)
		die("error initializing DirectWrite", hr);
	// and load the font *there*
	hr = dwfactory->GetSystemFontCollection(&sysfc, TRUE);
	if (hr != S_OK)
		die("error loading DirectWrite system font collection", hr);
	hr = sysfc->FindFamilyName(fontname, &index, &exists);
	if (hr != S_OK)
		die("error finding DirectWrite font family", hr);
	if (!exists)
		die("font not found in DirectWrite system font collection", E_FAIL);
	hr = sysfc->GetFontFamily(index, &dwfamily);
	if (hr != S_OK)
		die("error loading DirectWrite font family", hr);
	hr = dwfamily->GetFirstMatchingFont(DWRITE_FONT_WEIGHT_NORMAL,
		DWRITE_FONT_STRETCH_NORMAL,
		DWRITE_FONT_STYLE_NORMAL,
		&dwfont);
	if (hr != S_OK)
		die("error loading DirectWrite font object", hr);
	hr = dwfont->CreateFontFace(&dwface);
	if (hr != S_OK)
		die("error creating DirectWrite font face", hr);

	// first, uniscribe only; no features are used
//	uniscribeTest(dc, string, len, NULL,
//		doScriptItemize, doScriptShape, "Uniscribe");

	// next, unprepared features (NULL values)
	features = new featurePreparer;
//features->add('z','e','r','o',1);
//features->add('f','r','a','c',1);features->prepare(len);
//	uniscribeTest(dc, string, len, features,
//		doScriptItemizeOpenType, doScriptShapeOpenType, "Uniscribe OpenType");
	directwriteAnalyzerTest(dwface, string, len, features);
	delete features;

	dwface->Release();
	dwfont->Release();
	dwfamily->Release();
	sysfc->Release();
	dwfactory->Release();
	SelectObject(dc, prevfont);
	DeleteObject(font);
	ReleaseDC(NULL, dc);
	CoUninitialize();
	return 0;
}