Exemplo n.º 1
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);
}
HRESULT GetFonts(IDWriteFontCollection* fontCollection, const WCHAR* fontFamilyName, IN OUT std::vector<IDWriteFont*>& fonts)
{
    HRESULT hr = S_OK;

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

    hr = GetFontFamily(fontCollection, fontFamilyName, &fontFamily);

    if (SUCCEEDED(hr))
    {
        UINT32 fontCount = fontFamily->GetFontCount();

        // Read font variant in the family.
        try
        {
            for (UINT32 i = 0; i != fontCount; ++i)
            {
                hr = fontFamily->GetFont(i, &font);
                if (FAILED(hr))
                    break;

                fonts.push_back(font);
                SafeDetach(&font);
            }
        }
        catch (...)
        {
            hr = ExceptionToHResult();
        }
    }

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

    return hr;
}
Exemplo n.º 3
0
void QWinRTFontDatabase::populateFamily(const QString &familyName)
{
    IDWriteFontFamily *fontFamily = m_fontFamilies.value(familyName);
    if (!fontFamily) {
        qWarning("The font family %s was not found.", qPrintable(familyName));
        return;
    }

    bool fontRegistered = false;
    const int fontCount = fontFamily->GetFontCount();
    for (int j = 0; j < fontCount; ++j) {
        ComPtr<IDWriteFont> font;
        HRESULT hr = fontFamily->GetFont(j, &font);
        if (FAILED(hr)) {
            qWarning("Unable to get font: %s", qPrintable(qt_error_string(hr)));
            continue;
        }

        // Skip simulated faces
        if (font->GetSimulations() != DWRITE_FONT_SIMULATIONS_NONE)
            continue;

        ComPtr<IDWriteFontFace> baseFontFace;
        hr = font->CreateFontFace(&baseFontFace);
        if (FAILED(hr)) {
            qWarning("Unable to create base font face: %s", qPrintable(qt_error_string(hr)));
            continue;
        }
        ComPtr<IDWriteFontFace1> fontFace;
        hr = baseFontFace.As(&fontFace);
        if (FAILED(hr)) {
            qWarning("Unable to create font face: %s", qPrintable(qt_error_string(hr)));
            continue;
        }

        // We can't deal with multi-file fonts
        quint32 fileCount;
        hr = fontFace->GetFiles(&fileCount, NULL);
        if (FAILED(hr)) {
            qWarning("Unable to get font file count: %s", qPrintable(qt_error_string(hr)));
            continue;
        }
        if (fileCount != 1)
            continue;

        ComPtr<IDWriteLocalizedStrings> informationalStrings;
        BOOL exists;
        hr = font->GetInformationalStrings(DWRITE_INFORMATIONAL_STRING_MANUFACTURER,
                                           &informationalStrings, &exists);
        if (FAILED(hr)) {
            qWarning("Unable to get font foundry: %s", qPrintable(qt_error_string(hr)));
            continue;
        }
        QString foundryName;
        if (exists) {
            quint32 length;
            hr = informationalStrings->GetStringLength(0, &length);
            if (FAILED(hr))
                qWarning("Unable to get foundry name length: %s", qPrintable(qt_error_string(hr)));
            if (SUCCEEDED(hr)) {
                QVector<wchar_t> buffer(length + 1);
                hr = informationalStrings->GetString(0, buffer.data(), buffer.size());
                if (FAILED(hr))
                    qWarning("Unable to get foundry name: %s", qPrintable(qt_error_string(hr)));
                if (SUCCEEDED(hr))
                    foundryName = QString::fromWCharArray(buffer.data(), length);
            }
        }

        QFont::Weight weight;
        switch (font->GetWeight()) {
        case DWRITE_FONT_WEIGHT_THIN:
        case DWRITE_FONT_WEIGHT_EXTRA_LIGHT:
        case DWRITE_FONT_WEIGHT_LIGHT:
        case DWRITE_FONT_WEIGHT_SEMI_LIGHT:
            weight = QFont::Light;
            break;
        default:
        case DWRITE_FONT_WEIGHT_NORMAL:
        case DWRITE_FONT_WEIGHT_MEDIUM:
            weight = QFont::Normal;
            break;
        case DWRITE_FONT_WEIGHT_DEMI_BOLD:
            weight = QFont::DemiBold;
            break;
        case DWRITE_FONT_WEIGHT_BOLD:
        case DWRITE_FONT_WEIGHT_EXTRA_BOLD:
            weight = QFont::Bold;
            break;
        case DWRITE_FONT_WEIGHT_BLACK:
        case DWRITE_FONT_WEIGHT_EXTRA_BLACK:
            weight = QFont::Black;
            break;
        }

        QFont::Style style;
        switch (font->GetStyle()) {
        default:
        case DWRITE_FONT_STYLE_NORMAL:
            style = QFont::StyleNormal;
            break;
        case DWRITE_FONT_STYLE_OBLIQUE:
            style = QFont::StyleOblique;
            break;
        case DWRITE_FONT_STYLE_ITALIC:
            style = QFont::StyleItalic;
            break;
        }

        QFont::Stretch stretch;
        switch (font->GetStretch()) {
        default:
        case DWRITE_FONT_STRETCH_UNDEFINED:
        case DWRITE_FONT_STRETCH_NORMAL:
            stretch = QFont::Unstretched;
            break;
        case DWRITE_FONT_STRETCH_ULTRA_CONDENSED:
            stretch = QFont::UltraCondensed;
            break;
        case DWRITE_FONT_STRETCH_EXTRA_CONDENSED:
            stretch = QFont::ExtraCondensed;
            break;
        case DWRITE_FONT_STRETCH_CONDENSED:
            stretch = QFont::Condensed;
            break;
        case DWRITE_FONT_STRETCH_SEMI_CONDENSED:
            stretch = QFont::SemiCondensed;
            break;
        case DWRITE_FONT_STRETCH_SEMI_EXPANDED:
            stretch = QFont::SemiExpanded;
            break;
        case DWRITE_FONT_STRETCH_EXPANDED:
            stretch = QFont::Expanded;
            break;
        case DWRITE_FONT_STRETCH_EXTRA_EXPANDED:
            stretch = QFont::ExtraExpanded;
            break;
        case DWRITE_FONT_STRETCH_ULTRA_EXPANDED:
            stretch = QFont::UltraExpanded;
            break;
        }

        const bool fixedPitch = fontFace->IsMonospacedFont();

        quint32 unicodeRange[4];
        quint32 actualRangeCount;
        hr = fontFace->GetUnicodeRanges(
                    2, reinterpret_cast<DWRITE_UNICODE_RANGE *>(unicodeRange), &actualRangeCount);
        if (FAILED(hr) && hr != E_NOT_SUFFICIENT_BUFFER) { // Ignore insufficient buffer; we only need 4 indices
            qWarning("Unable to get font unicode range: %s", qPrintable(qt_error_string(hr)));
            continue;
        }
        quint32 codePageRange[2] = { 0, 0 };
        QSupportedWritingSystems writingSystems =
                QPlatformFontDatabase::writingSystemsFromTrueTypeBits(unicodeRange, codePageRange);

        IDWriteFontFile *fontFile;
        hr = fontFace->GetFiles(&fileCount, &fontFile);
        if (FAILED(hr)) {
            qWarning("Unable to get font file: %s", qPrintable(qt_error_string(hr)));
            continue;
        }

        FontDescription description = { fontFace->GetIndex(), QUuid::createUuid().toByteArray() };
        m_fonts.insert(fontFile, description);
        registerFont(familyName, QString(), foundryName, weight, style, stretch,
                     true, true, 0, fixedPitch, writingSystems, fontFile);
        fontRegistered = true;
    }

    // Always populate something to avoid an assert
    if (!fontRegistered) {
        registerFont(familyName, QString(), QString(), QFont::Normal, QFont::StyleNormal,
                     QFont::Unstretched, false, false, 0, false, QSupportedWritingSystems(), 0);
    }
}