ULONG GetBestFontAttributes(IDWriteFontCollection* fontCollection, const WCHAR* fontFamilyName, const FontFaceInfo& desiredAttributes)
{
    DWRITE_FONT_WEIGHT  fontWeight  = desiredAttributes.fontWeight;
    DWRITE_FONT_STYLE   fontStyle   = desiredAttributes.fontStyle;
    DWRITE_FONT_STRETCH fontStretch = desiredAttributes.fontStretch;

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

    if (SUCCEEDED(GetFontFamily(fontCollection, fontFamilyName, &fontFamily)))
    {
        if (SUCCEEDED(fontFamily->GetFirstMatchingFont(fontWeight, fontStretch, fontStyle, &font)))
        {
            fontWeight = font->GetWeight();
            fontStyle = font->GetStyle();
            fontStretch = font->GetStretch();
        }
    }

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

    FontFaceInfo fontFaceInfo(L"", fontWeight, fontStyle, fontStretch);

    return fontFaceInfo.PackedFontAttributes();
}
Exemplo n.º 2
0
static void familyChanged(struct fontDialog *f)
{
	LRESULT pos;
	BOOL selected;
	IDWriteFontFamily *family;
	IDWriteFont *font, *matchFont;
	DWRITE_FONT_WEIGHT weight;
	DWRITE_FONT_STYLE style;
	DWRITE_FONT_STRETCH stretch;
	UINT32 i, n;
	UINT32 matching;
	WCHAR *label;
	HRESULT hr;

	selected = cbGetCurSel(f->familyCombobox, &pos);
	if (!selected)		// on deselect, do nothing
		return;
	f->curFamily = pos;

	family = (IDWriteFontFamily *) cbGetItemData(f->familyCombobox, (WPARAM) (f->curFamily));

	// for the nearest style match
	// when we select a new family, we want the nearest style to the previously selected one to be chosen
	// this is how the Choose Font sample does it
	hr = family->GetFirstMatchingFont(
		f->weight,
		f->stretch,
		f->style,
		&matchFont);
	if (hr != S_OK)
		logHRESULT(L"error finding first matching font to previous style in font dialog", hr);
	// we can't just compare pointers; a "newly created" object comes out
	// the Choose Font sample appears to do this instead
	weight = matchFont->GetWeight();
	style = matchFont->GetStyle();
	stretch = matchFont->GetStretch();
	matchFont->Release();

	// TODO test mutliple streteches; all the fonts I have have only one stretch value?
	wipeStylesBox(f);
	n = family->GetFontCount();
	matching = 0;			// a safe/suitable default just in case
	for (i = 0; i < n; i++) {
		hr = family->GetFont(i, &font);
		if (hr != S_OK)
			logHRESULT(L"error getting font for filling styles box", hr);
		label = fontStyleName(f->fc, font);
		pos = cbAddString(f->styleCombobox, label);
		uiFree(label);
		cbSetItemData(f->styleCombobox, (WPARAM) pos, (LPARAM) font);
		if (font->GetWeight() == weight &&
			font->GetStyle() == style &&
			font->GetStretch() == stretch)
			matching = i;
	}

	// and now, load the match
	cbSetCurSel(f->styleCombobox, (WPARAM) matching);
	styleChanged(f);
}
Exemplo n.º 3
0
static cairo_status_t
_cairo_dwrite_font_face_create_for_toy (cairo_toy_font_face_t   *toy_face,
					cairo_font_face_t      **font_face)
{
    WCHAR *face_name;
    int face_name_len;

    if (!DWriteFactory::Instance()) {
	return (cairo_status_t)CAIRO_INT_STATUS_UNSUPPORTED;
    }

    face_name_len = MultiByteToWideChar(CP_UTF8, 0, toy_face->family, -1, NULL, 0);
    face_name = new WCHAR[face_name_len];
    MultiByteToWideChar(CP_UTF8, 0, toy_face->family, -1, face_name, face_name_len);

    IDWriteFontFamily *family = DWriteFactory::FindSystemFontFamily(face_name);
    delete face_name;
    if (!family) {
	*font_face = (cairo_font_face_t*)&_cairo_font_face_nil;
	return CAIRO_STATUS_FONT_TYPE_MISMATCH;
    }

    DWRITE_FONT_WEIGHT weight;
    switch (toy_face->weight) {
    case CAIRO_FONT_WEIGHT_BOLD:
	weight = DWRITE_FONT_WEIGHT_BOLD;
	break;
    case CAIRO_FONT_WEIGHT_NORMAL:
    default:
	weight = DWRITE_FONT_WEIGHT_NORMAL;
	break;
    }

    DWRITE_FONT_STYLE style;
    switch (toy_face->slant) {
    case CAIRO_FONT_SLANT_ITALIC:
	style = DWRITE_FONT_STYLE_ITALIC;
	break;
    case CAIRO_FONT_SLANT_OBLIQUE:
	style = DWRITE_FONT_STYLE_OBLIQUE;
	break;
    case CAIRO_FONT_SLANT_NORMAL:
    default:
	style = DWRITE_FONT_STYLE_NORMAL;
	break;
    }

    cairo_dwrite_font_face_t *face = (cairo_dwrite_font_face_t*)malloc(sizeof(cairo_dwrite_font_face_t));
    HRESULT hr = family->GetFirstMatchingFont(weight, DWRITE_FONT_STRETCH_NORMAL, style, &face->font);
    if (SUCCEEDED(hr)) {
	// Cannot use C++ style new since cairo deallocates this.
	*font_face = (cairo_font_face_t*)face;
        
	_cairo_font_face_init (&(*(_cairo_dwrite_font_face**)font_face)->base, &_cairo_dwrite_font_face_backend);
    } else {
	free(face);
    }

    return CAIRO_STATUS_SUCCESS;
}
Exemplo n.º 4
0
    /* IDWriteGdiInterop methods */
    virtual HRESULT STDMETHODCALLTYPE CreateFontFromLOGFONT(
        LOGFONTW const *logFont,
        IDWriteFont **font)
    {
        OutputDebugString("delegate_dwrite_gdi_interop::CreateFontFromLOGFONT");
        HRESULT result;
        UINT32 index;
        BOOL exists;
        result = mycoll_->FindFamilyName(logFont->lfFaceName, &index, &exists);
        if (SUCCEEDED(result)) {
            result = E_FAIL;
            if (exists != FALSE) {
                IDWriteFontFamily *family;
                result = mycoll_->GetFontFamily(index, &family);
                if (SUCCEEDED(result)) {
                    result = family->GetFirstMatchingFont(
                        (DWRITE_FONT_WEIGHT)logFont->lfWeight,
                        DWRITE_FONT_STRETCH_NORMAL,
                        DWRITE_FONT_STYLE_NORMAL,
                        font);
                    iunknown_release(family);
                }
            }
        }
	if (FAILED(result)) {
            OutputDebugString("delegate_dwrite_gdi_interop::CreateFontFromLOGFONT -> fallback");
            result = orig_this->CreateFontFromLOGFONT(logFont, font);
        }
        return result; 
    }
    const float getFontHeightToEmSizeFactor(Font& font, IDWriteFontCollection& dwFontCollection)
    {
        // To set the font size factor, we need to get the font metrics
        BOOL fontFound;
        uint32 fontIndex;

        // Search for the font in the font collection using the font name
        HRESULT hr = dwFontCollection.FindFamilyName (font.getTypefaceName().toWideCharPointer(),
                                                      &fontIndex, &fontFound);
        if (! fontFound)
            fontIndex = 0;

        IDWriteFontFamily* dwFontFamily = nullptr;
        hr = dwFontCollection.GetFontFamily (fontIndex, &dwFontFamily);

        IDWriteFont* dwFont = nullptr;
        hr = dwFontFamily->GetFirstMatchingFont (DWRITE_FONT_WEIGHT_NORMAL,
                                                 DWRITE_FONT_STRETCH_NORMAL,
                                                 DWRITE_FONT_STYLE_NORMAL, &dwFont);
        IDWriteFontFace* dwFontFace = nullptr;
        hr = dwFont->CreateFontFace (&dwFontFace);

        // Font metrics are in font design units
        DWRITE_FONT_METRICS dwFontMetrics;
        dwFontFace->GetMetrics (&dwFontMetrics);
        const float totalHeight = std::abs ((float) dwFontMetrics.ascent) + std::abs ((float) dwFontMetrics.descent);
        const float fontHeightToEmSizeFactor = (float) dwFontMetrics.designUnitsPerEm / totalHeight;

        safeRelease (&dwFontFace);
        safeRelease (&dwFont);
        safeRelease (&dwFontFamily);

        return fontHeightToEmSizeFactor;
    }
Exemplo n.º 6
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.º 7
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.º 8
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;
}