// public QFontComboBox::FontFilters fontFilters() const void tst_QFontComboBox::fontFilters() { QFETCH(QFontComboBox::FontFilters, fontFilters); SubQFontComboBox box; QSignalSpy spy0(&box, SIGNAL(currentFontChanged(QFont))); QFont currentFont = box.currentFont(); box.setFontFilters(fontFilters); QCOMPARE(box.fontFilters(), fontFilters); QFontDatabase db; QStringList list = db.families(); int c = 0; const int scalableMask = (QFontComboBox::ScalableFonts | QFontComboBox::NonScalableFonts); const int spacingMask = (QFontComboBox::ProportionalFonts | QFontComboBox::MonospacedFonts); if((fontFilters & scalableMask) == scalableMask) fontFilters &= ~scalableMask; if((fontFilters & spacingMask) == spacingMask) fontFilters &= ~spacingMask; for (int i = 0; i < list.count(); ++i) { if (db.isPrivateFamily(list[i])) continue; if (fontFilters & QFontComboBox::ScalableFonts) { if (!db.isSmoothlyScalable(list[i])) continue; } else if (fontFilters & QFontComboBox::NonScalableFonts) { if (db.isSmoothlyScalable(list[i])) continue; } if (fontFilters & QFontComboBox::MonospacedFonts) { if (!db.isFixedPitch(list[i])) continue; } else if (fontFilters & QFontComboBox::ProportionalFonts) { if (db.isFixedPitch(list[i])) continue; } c++; } QCOMPARE(box.model()->rowCount(), c); if (c == 0) QCOMPARE(box.currentFont(), QFont()); QCOMPARE(spy0.count(), (currentFont != box.currentFont()) ? 1 : 0); }
void tst_QFont::italicOblique() { QFontDatabase fdb; QStringList families = fdb.families(); if (families.isEmpty()) return; QStringList::ConstIterator f_it, f_end = families.end(); for (f_it = families.begin(); f_it != f_end; ++f_it) { QString family = *f_it; QStringList styles = fdb.styles(family); QVERIFY(!styles.isEmpty()); QStringList::ConstIterator s_it, s_end = styles.end(); for (s_it = styles.begin(); s_it != s_end; ++s_it) { QString style = *s_it; if (fdb.isSmoothlyScalable(family, style)) { if (style.contains("Oblique")) { style.replace("Oblique", "Italic"); } else if (style.contains("Italic")) { style.replace("Italic", "Oblique"); } else { continue; } QFont f = fdb.font(family, style, 12); QVERIFY(f.italic()); } } } }
QStringList _k_fontList(const QFontComboBox::FontFilters &fontFilters = QFontComboBox::AllFonts) { QFontDatabase dbase; QStringList families; if (fontFilters == QFontComboBox::AllFonts) { families = dbase.families(); } else { const QFontComboBox::FontFilters scalableMask = (QFontComboBox::ScalableFonts | QFontComboBox::NonScalableFonts); const QFontComboBox::FontFilters spacingMask = (QFontComboBox::ProportionalFonts | QFontComboBox::MonospacedFonts); foreach (const QString &family, dbase.families()) { if ((fontFilters & scalableMask) && (fontFilters & scalableMask) != scalableMask) { if (bool(fontFilters & QFontComboBox::ScalableFonts) != dbase.isSmoothlyScalable(family)) continue; } if ((fontFilters & spacingMask) && (fontFilters & spacingMask) != spacingMask) { if (bool(fontFilters & QFontComboBox::MonospacedFonts) != dbase.isFixedPitch(family)) continue; } families << family; } } families.sort(); return families; }
QFont KGlobalSettings::largeFont(const QString &text) { QFontDatabase db; QStringList fam = db.families(); // Move a bunch of preferred fonts to the front. if (fam.remove("Arial")) fam.prepend("Arial"); if (fam.remove("Verdana")) fam.prepend("Verdana"); if (fam.remove("Tahoma")) fam.prepend("Tahoma"); if (fam.remove("Lucida Sans")) fam.prepend("Lucida Sans"); if (fam.remove("Lucidux Sans")) fam.prepend("Lucidux Sans"); if (fam.remove("Nimbus Sans")) fam.prepend("Nimbus Sans"); if (fam.remove("Gothic I")) fam.prepend("Gothic I"); if (_largeFont) fam.prepend(_largeFont->family()); for(QStringList::ConstIterator it = fam.begin(); it != fam.end(); ++it) { if (db.isSmoothlyScalable(*it) && !db.isFixedPitch(*it)) { QFont font(*it); font.setPixelSize(75); QFontMetrics metrics(font); int h = metrics.height(); if ((h < 60) || ( h > 90)) continue; bool ok = true; for(unsigned int i = 0; i < text.length(); i++) { if (!metrics.inFont(text[i])) { ok = false; break; } } if (!ok) continue; font.setPointSize(48); _largeFont = new QFont(font); return *_largeFont; } } _largeFont = new QFont(KGlobalSettings::generalFont()); _largeFont->setPointSize(48); return *_largeFont; }
void QFontComboBoxPrivate::_q_updateModel() { Q_Q(QFontComboBox); const int scalableMask = (QFontComboBox::ScalableFonts | QFontComboBox::NonScalableFonts); const int spacingMask = (QFontComboBox::ProportionalFonts | QFontComboBox::MonospacedFonts); QStringListModel *m = qobject_cast<QStringListModel *>(q->model()); if (!m) return; QFontFamilyDelegate *delegate = qobject_cast<QFontFamilyDelegate *>(q->view()->itemDelegate()); QFontDatabase::WritingSystem system = delegate ? delegate->writingSystem : QFontDatabase::Any; QFontDatabase fdb; QStringList list = fdb.families(system); QStringList result; int offset = 0; QFontInfo fi(currentFont); for (int i = 0; i < list.size(); ++i) { if (fdb.isPrivateFamily(list.at(i))) continue; if ((filters & scalableMask) && (filters & scalableMask) != scalableMask) { if (bool(filters & QFontComboBox::ScalableFonts) != fdb.isSmoothlyScalable(list.at(i))) continue; } if ((filters & spacingMask) && (filters & spacingMask) != spacingMask) { if (bool(filters & QFontComboBox::MonospacedFonts) != fdb.isFixedPitch(list.at(i))) continue; } result += list.at(i); if (list.at(i) == fi.family() || list.at(i).startsWith(fi.family() + QLatin1String(" ["))) offset = result.count() - 1; } list = result; //we need to block the signals so that the model doesn't emit reset //this prevents the current index from changing //it will be updated just after this ///TODO: we should finda way to avoid blocking signals and have a real update of the model { const QSignalBlocker blocker(m); m->setStringList(list); } if (list.isEmpty()) { if (currentFont != QFont()) { currentFont = QFont(); emit q->currentFontChanged(currentFont); } } else { q->setCurrentIndex(offset); } }
void Font::update( QPaintDeviceMetrics* devMetrics ) const { f.setFamily( fontDef.family.isEmpty() ? KHTMLFactory::defaultHTMLSettings()->stdFontName() : fontDef.family ); f.setItalic( fontDef.italic ); f.setWeight( fontDef.weight ); QFontDatabase db; int size = fontDef.size; int lDpiY = kMax(devMetrics->logicalDpiY(), 96); // ok, now some magic to get a nice unscaled font // all other font properties should be set before this one!!!! if( !db.isSmoothlyScalable(f.family(), db.styleString(f)) ) { QValueList<int> pointSizes = db.smoothSizes(f.family(), db.styleString(f)); // lets see if we find a nice looking font, which is not too far away // from the requested one. // kdDebug(6080) << "khtml::setFontSize family = " << f.family() << " size requested=" << size << endl; QValueList<int>::Iterator it; float diff = 1; // ### 100% deviation float bestSize = 0; for( it = pointSizes.begin(); it != pointSizes.end(); ++it ) { float newDiff = ((*it)*(lDpiY/72.) - float(size))/float(size); //kdDebug( 6080 ) << "smooth font size: " << *it << " diff=" << newDiff << endl; if(newDiff < 0) newDiff = -newDiff; if(newDiff < diff) { diff = newDiff; bestSize = *it; } } //kdDebug( 6080 ) << "best smooth font size: " << bestSize << " diff=" << diff << endl; if ( bestSize != 0 && diff < 0.2 ) // 20% deviation, otherwise we use a scaled font... size = (int)((bestSize*lDpiY) / 72); } // make sure we don't bust up X11 size = KMAX(0, KMIN(255, size)); // qDebug("setting font to %s, italic=%d, weight=%d, size=%d", fontDef.family.latin1(), fontDef.italic, // fontDef.weight, size ); f.setPixelSize( size ); fm = QFontMetrics( f ); fontDef.hasNbsp = fm.inFont( 0xa0 ); }
void tst_QFontMetrics::metrics() { QFont font; QFontDatabase fdb; // Query the QFontDatabase for a specific font, store the // result in family, style and size. QStringList families = fdb.families(); if (families.isEmpty()) return; QStringList::ConstIterator f_it, f_end = families.end(); for (f_it = families.begin(); f_it != f_end; ++f_it) { const QString &family = *f_it; QStringList styles = fdb.styles(family); QStringList::ConstIterator s_it, s_end = styles.end(); for (s_it = styles.begin(); s_it != s_end; ++s_it) { const QString &style = *s_it; if (fdb.isSmoothlyScalable(family, style)) { // smoothly scalable font... don't need to load every pointsize font = fdb.font(family, style, 12); QFontMetrics fontmetrics(font); QCOMPARE(fontmetrics.ascent() + fontmetrics.descent(), fontmetrics.height()); QCOMPARE(fontmetrics.height() + fontmetrics.leading(), fontmetrics.lineSpacing()); } else { QList<int> sizes = fdb.pointSizes(family, style); QVERIFY(!sizes.isEmpty()); QList<int>::ConstIterator z_it, z_end = sizes.end(); for (z_it = sizes.begin(); z_it != z_end; ++z_it) { const int size = *z_it; // Initialize the font, and check if it is an exact match font = fdb.font(family, style, size); QFontMetrics fontmetrics(font); QCOMPARE(fontmetrics.ascent() + fontmetrics.descent(), fontmetrics.height()); QCOMPARE(fontmetrics.height() + fontmetrics.leading(), fontmetrics.lineSpacing()); } } } } }
void QFontComboBoxPrivate::_q_updateModel() { Q_Q(QFontComboBox); const int scalableMask = (QFontComboBox::ScalableFonts | QFontComboBox::NonScalableFonts); const int spacingMask = (QFontComboBox::ProportionalFonts | QFontComboBox::MonospacedFonts); QStringListModel *m = qobject_cast<QStringListModel *>(q->model()); if (!m) return; QFontFamilyDelegate *delegate = qobject_cast<QFontFamilyDelegate *>(q->view()->itemDelegate()); QFontDatabase::WritingSystem system = delegate ? delegate->writingSystem : QFontDatabase::Any; QFontDatabase fdb; QStringList list = fdb.families(system); QStringList result; int offset = 0; QFontInfo fi(currentFont); for (int i = 0; i < list.size(); ++i) { if ((filters & scalableMask) && (filters & scalableMask) != scalableMask) { if (bool(filters & QFontComboBox::ScalableFonts) != fdb.isSmoothlyScalable(list.at(i))) continue; } if ((filters & spacingMask) && (filters & spacingMask) != spacingMask) { if (bool(filters & QFontComboBox::MonospacedFonts) != fdb.isFixedPitch(list.at(i))) continue; } result += list.at(i); if (list.at(i) == fi.family() || list.at(i).startsWith(fi.family() + QLatin1String(" ["))) offset = result.count() - 1; } list = result; m->setStringList(list); if (list.isEmpty()) { if (currentFont != QFont()) { currentFont = QFont(); emit q->currentFontChanged(currentFont); } } else { q->setCurrentIndex(offset); } }
bool Font::isFontScalable(QFontDatabase &db, const QFont &font) { if(!scalCache) scalCache = new QMap< ScalKey, ScalInfo >; ScalKey key(font); ScalInfo &s = (*scalCache)[key]; if(s == Unknown) { s = db.isSmoothlyScalable(font.family(), db.styleString(font)) ? Yes : No; if(s == No) { /* Cache size info */ if(!scalSizesCache) scalSizesCache = new QMap< ScalKey, QValueList< int > >; (*scalSizesCache)[key] = db.smoothSizes(font.family(), db.styleString(font)); } } return (s == Yes); }
void tst_QFont::exactMatch() { QFont font; // Check if a non-existing font hasn't an exact match font = QFont( "BogusFont", 33 ); QVERIFY( !font.exactMatch() ); #ifdef Q_OS_WIN QSKIP("Exact matching on windows misses a lot because of the sample chars"); #endif if (QGuiApplication::platformName() == QLatin1String("xcb")) { QVERIFY(QFont("sans").exactMatch()); QVERIFY(QFont("sans-serif").exactMatch()); QVERIFY(QFont("serif").exactMatch()); QVERIFY(QFont("monospace").exactMatch()); } QSKIP("This test is bogus on Unix with support for font aliases in fontconfig"); QFontDatabase fdb; QList<QFontDatabase::WritingSystem> systems = fdb.writingSystems(); for (int system = 0; system < systems.count(); ++system) { QStringList families = fdb.families(systems[system]); if (families.isEmpty()) return; QStringList::ConstIterator f_it, f_end = families.end(); for (f_it = families.begin(); f_it != f_end; ++f_it) { const QString &family = *f_it; if (family.contains('[')) continue; QStringList styles = fdb.styles(family); QVERIFY(!styles.isEmpty()); QStringList::ConstIterator s_it, s_end = styles.end(); for (s_it = styles.begin(); s_it != s_end; ++s_it) { const QString &style = *s_it; if (fdb.isSmoothlyScalable(family, style)) { // smoothly scalable font... don't need to load every pointsize font = fdb.font(family, style, 12); QFontInfo fontinfo(font); if (! fontinfo.exactMatch()) { // Unfortunately, this can fail, since // QFontDatabase does not fill in all font // properties. Check to make sure that the // test didn't fail for obvious reasons if (fontinfo.family().isEmpty() && fontinfo.pointSize() == 0) { // this is a box rendering engine... this can happen from // time to time, especially on X11 with iso10646-1 or // unknown font encodings continue; } #ifdef Q_OS_WIN if (font.family().startsWith("MS ") || fontinfo.family().startsWith("MS ")) { /* qDebug("Family matching skipped for MS-Alias font: %s, fontinfo: %s", font.family().latin1(), fontinfo.family().latin1()); */ } else #endif { if (!(font.family() == fontinfo.family() || fontinfo.family().contains(font.family()) || fontinfo.family().isEmpty())) { qDebug("Test about to fail for font: %s, fontinfo: %s", font.family().toLatin1().constData(), fontinfo.family().toLatin1().constData()); } QVERIFY(font.family() == fontinfo.family() || fontinfo.family().contains(font.family()) || fontinfo.family().isEmpty()); } if (font.pointSize() != -1) { QVERIFY(font.pointSize() == fontinfo.pointSize()); } else { QVERIFY(font.pixelSize() == fontinfo.pixelSize()); } QVERIFY(font.italic() == fontinfo.italic()); if (font.weight() != fontinfo.weight()) { qDebug("font is %s", font.toString().toLatin1().constData()); } QVERIFY(font.weight() == fontinfo.weight()); } else { font.setFixedPitch(!fontinfo.fixedPitch()); QFontInfo fontinfo1(font); QVERIFY( !fontinfo1.exactMatch() ); font.setFixedPitch(fontinfo.fixedPitch()); QFontInfo fontinfo2(font); QVERIFY( fontinfo2.exactMatch() ); } } #if 0 // ############## can only work if we have float point sizes in QFD else { QList<int> sizes = fdb.pointSizes(family, style); QVERIFY(!sizes.isEmpty()); QList<int>::ConstIterator z_it, z_end = sizes.end(); for (z_it = sizes.begin(); z_it != z_end; ++z_it) { const int size = *z_it; // Initialize the font, and check if it is an exact match font = fdb.font(family, style, size); QFontInfo fontinfo(font, (QFont::Script) script); if (! fontinfo.exactMatch()) { // Unfortunately, this can fail, since // QFontDatabase does not fill in all font // properties. Check to make sure that the // test didn't fail for obvious reasons if (fontinfo.family().isEmpty() && fontinfo.pointSize() == 0) { // this is a box rendering engine... this can happen from // time to time, especially on X11 with iso10646-1 or // unknown font encodings continue; } // no need to skip MS-fonts here it seems if (!(font.family() == fontinfo.family() || fontinfo.family().contains(font.family()) || fontinfo.family().isEmpty())) { qDebug("Test about to fail for font: %s, fontinfo: %s", font.family().latin1(), fontinfo.family().latin1()); } QVERIFY(font.family() == fontinfo.family() || fontinfo.family().contains(font.family()) || fontinfo.family().isEmpty()); if (font.pointSize() != -1) { QVERIFY(font.pointSize() == fontinfo.pointSize()); } else { QVERIFY(font.pixelSize() == fontinfo.pixelSize()); } QVERIFY(font.italic() == fontinfo.italic()); QVERIFY(font.weight() == fontinfo.weight()); } else { font.setFixedPitch(!fontinfo.fixedPitch()); QFontInfo fontinfo1(font, (QFont::Script) script); QVERIFY( !fontinfo1.exactMatch() ); font.setFixedPitch(fontinfo.fixedPitch()); QFontInfo fontinfo2(font, (QFont::Script) script); QVERIFY( fontinfo2.exactMatch() ); } } } #endif } } } }
void QFontDialogPrivate::updateFamilies() { Q_Q(QFontDialog); enum match_t { MATCH_NONE = 0, MATCH_LAST_RESORT = 1, MATCH_APP = 2, MATCH_FAMILY = 3 }; const QFontDialog::FontDialogOptions scalableMask = (QFontDialog::ScalableFonts | QFontDialog::NonScalableFonts); const QFontDialog::FontDialogOptions spacingMask = (QFontDialog::ProportionalFonts | QFontDialog::MonospacedFonts); const QFontDialog::FontDialogOptions options = q->options(); QFontDatabase fdb; QStringList familyNames; foreach (const QString &family, fdb.families(writingSystem)) { if (fdb.isPrivateFamily(family)) continue; if ((options & scalableMask) && (options & scalableMask) != scalableMask) { if (bool(options & QFontDialog::ScalableFonts) != fdb.isSmoothlyScalable(family)) continue; } if ((options & spacingMask) && (options & spacingMask) != spacingMask) { if (bool(options & QFontDialog::MonospacedFonts) != fdb.isFixedPitch(family)) continue; } familyNames << family; } familyList->model()->setStringList(familyNames); QString foundryName1, familyName1, foundryName2, familyName2; int bestFamilyMatch = -1; match_t bestFamilyType = MATCH_NONE; QFont f; // ##### do the right thing for a list of family names in the font. QFontDatabase::parseFontName(family, foundryName1, familyName1); QStringList::const_iterator it = familyNames.constBegin(); int i = 0; for(; it != familyNames.constEnd(); ++it, ++i) { QFontDatabase::parseFontName(*it, foundryName2, familyName2); //try to match... if (familyName1 == familyName2) { bestFamilyType = MATCH_FAMILY; if (foundryName1 == foundryName2) { bestFamilyMatch = i; break; } if (bestFamilyMatch < MATCH_FAMILY) bestFamilyMatch = i; } //and try some fall backs match_t type = MATCH_NONE; if (bestFamilyType <= MATCH_NONE && familyName2 == f.lastResortFamily()) type = MATCH_LAST_RESORT; if (bestFamilyType <= MATCH_LAST_RESORT && familyName2 == f.family()) type = MATCH_APP; // ### add fallback for writingSystem if (type != MATCH_NONE) { bestFamilyType = type; bestFamilyMatch = i; } } if (i != -1 && bestFamilyType != MATCH_NONE) familyList->setCurrentItem(bestFamilyMatch); else familyList->setCurrentItem(0); familyEdit->setText(familyList->currentText()); if (q->style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, q) && familyList->hasFocus()) familyEdit->selectAll(); updateStyles(); }