diff --git src/gui/dialogs/qfontdialog.cpp src/gui/dialogs/qfontdialog.cpp index d791462..1c409cd 100644 --- src/gui/dialogs/qfontdialog.cpp +++ src/gui/dialogs/qfontdialog.cpp @@ -554,6 +554,17 @@ void QFontDialogPrivate::updateFamilies() updateStyles(); } +static bool qstringContainsFromList(QString &style, QStringList &checkList, Qt::CaseSensitivity mode=Qt::CaseSensitive) +{ + QString pattern; + Q_FOREACH(pattern, checkList) { + if (style.contains(pattern,mode)) { + return true; + } + } + return false; +} + /* Updates the contents of the "font style" list box. This function can be reimplemented if you have special requirements. @@ -563,6 +574,10 @@ void QFontDialogPrivate::updateStyles() Q_Q(QFontDialog); QStringList styles = fdb.styles(familyList->currentText()); styleList->model()->setStringList(styles); + // RJVB +// qDebug() << "QFontDialogPrivate::updateStyles() familyList=" +// << familyList << "style=" << style +// << "styles=" << styles << "styleList=" << styleList; if (styles.isEmpty()) { styleEdit->clear(); @@ -572,21 +587,47 @@ void QFontDialogPrivate::updateStyles() bool found = false; bool first = true; QString cstyle = style; + // RJVB 20150419 + QStringList lightStyles, bookStyles, normalStyles, demiBoldStyles, blackStyles, slantStyles; + lightStyles << "Thin" << "Light"; + bookStyles << "Book"; + normalStyles << "Normal" << "Regular"; + demiBoldStyles << "DemiBold" << "Demi Bold" << "SemiBold" << "Semi Bold" << "Medium"; + blackStyles << "Black" << "Ultra" << "Heavy" << "UltraBold"; + slantStyles << "Italic" << "Oblique"; redo: + if (style.contains("Light", Qt::CaseInsensitive) && !styles.contains("Light", Qt::CaseInsensitive)) { + // this is a Book weight that was "demoted" to Light because Qt doesn't recognise Book as a separate style, + // so we add Book as a valid synonym to lightStyles. + lightStyles << "Book"; + } for (int i = 0; i < (int)styleList->count(); i++) { - if (cstyle == styleList->text(i)) { + QString istyle = styleList->text(i); + if (cstyle == istyle) { styleList->setCurrentItem(i); found = true; break; } + // RJVB 20150419: handle style synonyms + if ((qstringContainsFromList(cstyle, lightStyles, Qt::CaseInsensitive) && qstringContainsFromList(istyle, lightStyles, Qt::CaseInsensitive)) + || (qstringContainsFromList(cstyle, bookStyles, Qt::CaseInsensitive) && qstringContainsFromList(istyle, bookStyles, Qt::CaseInsensitive)) + || (qstringContainsFromList(cstyle, normalStyles, Qt::CaseInsensitive) && qstringContainsFromList(istyle, normalStyles, Qt::CaseInsensitive)) + || (qstringContainsFromList(cstyle, demiBoldStyles, Qt::CaseInsensitive) && qstringContainsFromList(istyle, demiBoldStyles, Qt::CaseInsensitive)) + || (qstringContainsFromList(cstyle, blackStyles, Qt::CaseInsensitive) && qstringContainsFromList(istyle, blackStyles, Qt::CaseInsensitive))) { + if ((qstringContainsFromList(cstyle, slantStyles, Qt::CaseInsensitive) == qstringContainsFromList(istyle, slantStyles, Qt::CaseInsensitive))) { + styleList->setCurrentItem(i); + found = true; + break; + } + } } if (!found && first) { - if (cstyle.contains(QLatin1String("Italic"))) { + if (cstyle.contains(QLatin1String("Italic"), Qt::CaseInsensitive)) { cstyle.replace(QLatin1String("Italic"), QLatin1String("Oblique")); first = false; goto redo; - } else if (cstyle.contains(QLatin1String("Oblique"))) { + } else if (cstyle.contains(QLatin1String("Oblique"), Qt::CaseInsensitive)) { cstyle.replace(QLatin1String("Oblique"), QLatin1String("Italic")); first = false; goto redo; @@ -815,6 +856,8 @@ void QFontDialog::setCurrentFont(const QFont &font) QFontInfo fi(font); d->size = fi.pointSize(); } + // RJVB +// qDebug() << "QFontDialog::setCurrentFont" << font << "style=" << d->style << "size=" << d->size; d->strikeout->setChecked(font.strikeOut()); d->underline->setChecked(font.underline()); d->updateFamilies(); diff --git src/gui/dialogs/qfontdialog_mac.mm src/gui/dialogs/qfontdialog_mac.mm index d557a7a..3bfa381 100644 --- src/gui/dialogs/qfontdialog_mac.mm +++ src/gui/dialogs/qfontdialog_mac.mm @@ -512,25 +512,65 @@ void QFontDialogPrivate::setFont(void *delegate, const QFont &font) #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 if (qstrcmp(fe->name(), "CoreText") == 0) { nsFont = reinterpret_cast(static_cast(fe)->ctfont); + // RJVB +// qDebug() << "setFont" << fe << "gives:"; +// NSLog(@"setFont(%@)", nsFont); } else #endif { int weight = 5; NSFontTraitMask mask = 0; - if (font.style() == QFont::StyleItalic) { + if (font.style() == QFont::StyleItalic || font.style() == QFont::StyleOblique) { mask |= NSItalicFontMask; } - if (font.weight() == QFont::Bold) { - weight = 9; - mask |= NSBoldFontMask; + // RJVB + // Thin,Light -> 3, Book -> 4 + // Normal/Regular -> 5 + // Medium/SemiBold/Demibold -> 6,7,8 + // Bold -> 9 + // Ultra/Black/Heavy -> 10,11 + QByteArray *weights = NULL; + switch (font.weight()) { + case QFont::Light: + weights = new QByteArray("3,4"); + break; + case QFont::Normal: + weights = new QByteArray("5"); + break; + case QFont::DemiBold: + weights = new QByteArray("6,7,8"); + break; + case QFont::Bold: + weights = new QByteArray("9"); + break; + case QFont::Black: + weights = new QByteArray("10,11"); + break; } NSFontManager *mgr = [NSFontManager sharedFontManager]; QFontInfo fontInfo(font); - nsFont = [mgr fontWithFamily:qt_mac_QStringToNSString(fontInfo.family()) - traits:mask - weight:weight - size:fontInfo.pointSize()]; + if (weights) { + nsFont = NULL; + for (int i = 0 ; i < weights->size() && !nsFont ; ++i) { + weight = (*weights)[i] - '0'; + nsFont = [mgr fontWithFamily:qt_mac_QStringToNSString(fontInfo.family()) + traits:mask + weight:weight + size:fontInfo.pointSize()]; + } + delete weights; + } + else { + if (font.weight() == QFont::Bold) { + weight = 9; + mask |= NSBoldFontMask; + } + nsFont = [mgr fontWithFamily:qt_mac_QStringToNSString(fontInfo.family()) + traits:mask + weight:weight + size:fontInfo.pointSize()]; + } } [mgr setSelectedFont:const_cast(nsFont) isMultiple:NO]; diff --git src/gui/kernel/qt_mac.cpp src/gui/kernel/qt_mac.cpp index fb241ce..5c54299 100644 --- src/gui/kernel/qt_mac.cpp +++ src/gui/kernel/qt_mac.cpp @@ -71,7 +71,10 @@ QFont qfontForThemeFont(ThemeFontID themeID) CFNumberRef num = static_cast(CFDictionaryGetValue(dict, kCTFontWeightTrait)); float fW; CFNumberGetValue(num, kCFNumberFloat32Type, &fW); - QFont::Weight wght = fW > 0. ? QFont::Bold : QFont::Normal; + // RJVB 20150415 + extern QFont::Weight weightFromInteger(int weight); // in qfontdatabase.cpp + //QFont::Weight wght = fW > 0. ? QFont::Bold : QFont::Normal; + QFont::Weight wght = weightFromInteger((int)fW*500+500); num = static_cast(CFDictionaryGetValue(dict, kCTFontSlantTrait)); CFNumberGetValue(num, kCFNumberFloatType, &fW); bool italic = (fW != 0.0); diff --git src/gui/text/qfontdatabase.cpp src/gui/text/qfontdatabase.cpp index 4c2ace4..a60a5ee 100644 --- src/gui/text/qfontdatabase.cpp +++ src/gui/text/qfontdatabase.cpp @@ -103,26 +103,42 @@ static int getFontWeight(const QString &weightString) QString s = weightString.toLower(); // Test in decreasing order of commonness - if (s == QLatin1String("medium") || + // RJVB 20150415: "Medium" is *not* normal weight, but equivalent to Semi/DemiBold; + // however "regular" == "normal" + if (s == QLatin1String("regular") || s == QLatin1String("normal") - || s.compare(QApplication::translate("QFontDatabase", "Normal"), Qt::CaseInsensitive) == 0) + || s.compare(QApplication::translate("QFontDatabase", "Normal"), Qt::CaseInsensitive) == 0 + || s.compare(QApplication::translate("QFontDatabase", "Regular"), Qt::CaseInsensitive) == 0) return QFont::Normal; if (s == QLatin1String("bold") || s.compare(QApplication::translate("QFontDatabase", "Bold"), Qt::CaseInsensitive) == 0) return QFont::Bold; + // RJVB 20150415: add SemiBold and Medium if (s == QLatin1String("demibold") || s == QLatin1String("demi bold") - || s.compare(QApplication::translate("QFontDatabase", "Demi Bold"), Qt::CaseInsensitive) == 0) + || s == QLatin1String("semibold") || s == QLatin1String("semi bold") + || s == QLatin1String("medium") + || s.compare(QApplication::translate("QFontDatabase", "Demi Bold"), Qt::CaseInsensitive) == 0 + || s.compare(QApplication::translate("QFontDatabase", "Semi Bold"), Qt::CaseInsensitive) == 0 + || s.compare(QApplication::translate("QFontDatabase", "Medium"), Qt::CaseInsensitive) == 0) return QFont::DemiBold; - if (s == QLatin1String("black") - || s.compare(QApplication::translate("QFontDatabase", "Black"), Qt::CaseInsensitive) == 0) + // RJVB 20150415: add Heavy and Ultra + if (s == QLatin1String("black") || s == QLatin1String("Heavy") || s == QLatin1String("Ultra") || s == QLatin1String("UltraBold") + || s.compare(QApplication::translate("QFontDatabase", "Black"), Qt::CaseInsensitive) == 0 + || s.compare(QApplication::translate("QFontDatabase", "Heavy"), Qt::CaseInsensitive) == 0 + || s.compare(QApplication::translate("QFontDatabase", "UltraBold"), Qt::CaseInsensitive) == 0 + || s.compare(QApplication::translate("QFontDatabase", "Ultra"), Qt::CaseInsensitive) == 0) return QFont::Black; - if (s == QLatin1String("light")) + // RJVB 20150415: add Book and Thin + if (s == QLatin1String("light") || s == QLatin1String("book") || s == QLatin1String("Thin") + || s.compare(QApplication::translate("QFontDatabase", "Book"), Qt::CaseInsensitive) == 0) return QFont::Light; if (s.contains(QLatin1String("bold")) || s.contains(QApplication::translate("QFontDatabase", "Bold"), Qt::CaseInsensitive)) { - if (s.contains(QLatin1String("demi")) - || s.compare(QApplication::translate("QFontDatabase", "Demi"), Qt::CaseInsensitive) == 0) + if (s.contains(QLatin1String("demi")) || s.contains(QLatin1String("semi")) || s.contains(QLatin1String("medium")) + || s.compare(QApplication::translate("QFontDatabase", "Demi"), Qt::CaseInsensitive) == 0 + || s.compare(QApplication::translate("QFontDatabase", "Semi"), Qt::CaseInsensitive) == 0 + || s.compare(QApplication::translate("QFontDatabase", "Medium"), Qt::CaseInsensitive) == 0) return (int) QFont::DemiBold; return (int) QFont::Bold; } @@ -131,8 +147,10 @@ static int getFontWeight(const QString &weightString) || s.compare(QApplication::translate("QFontDatabase", "Light"), Qt::CaseInsensitive) == 0) return (int) QFont::Light; - if (s.contains(QLatin1String("black")) - || s.compare(QApplication::translate("QFontDatabase", "Black"), Qt::CaseInsensitive) == 0) + if (s.contains(QLatin1String("black")) || s.contains(QLatin1String("heavy")) || s.contains(QLatin1String("ultra")) + || s.compare(QApplication::translate("QFontDatabase", "Black"), Qt::CaseInsensitive) == 0 + || s.compare(QApplication::translate("QFontDatabase", "heavy"), Qt::CaseInsensitive) == 0 + || s.compare(QApplication::translate("QFontDatabase", "ultra"), Qt::CaseInsensitive) == 0) return (int) QFont::Black; return (int) QFont::Normal; @@ -147,7 +165,8 @@ QFont::Weight weightFromInteger(int weight) return QFont::Normal; else if (weight < 700) return QFont::DemiBold; - else if (weight < 800) + // Ultra and ExtraBold are 750, and heavier than Bold (ex: Nanum, Novarese BQ) + else if (weight < 750) return QFont::Bold; else return QFont::Black; @@ -2024,6 +2043,9 @@ QFont QFontDatabase::font(const QString &family, const QString &style, if (!s) // no styles found? return QApplication::font(); + // RJVB +// qDebug() << "QFontDatabase::font(" << family << "," << style << "," << pointSize << ")" +// << "will load font with weight" << s->key.weight << "and style" << s->styleName << s->key.style; QFont fnt(family, pointSize, s->key.weight); fnt.setStyle((QFont::Style)s->key.style); if (!s->styleName.isEmpty()) diff --git src/gui/text/qfontdatabase_mac.cpp src/gui/text/qfontdatabase_mac.cpp index 816a7bd..be0ae55 100644 --- src/gui/text/qfontdatabase_mac.cpp +++ src/gui/text/qfontdatabase_mac.cpp @@ -168,8 +168,34 @@ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) { Q_ASSERT(CFNumberIsFloatType(weight)); double d; if(CFNumberGetValue(weight, kCFNumberDoubleType, &d)) { - //qDebug() << "BOLD" << (QString)family_name << d; - styleKey.weight = (d > 0.0) ? QFont::Bold : QFont::Normal; + if (!qgetenv("QT_DUMP_FONT_STYLE_WEIGHTS").isEmpty()) { + extern int getCTFontWeightFromDescriptor(CTFontDescriptorRef fontRef, int size); + qDebug() << "Font" << (QString)family_name << "style" << styleName << "weight=" << d + << "NSFont weight{12pt,18pt}=" << getCTFontWeightFromDescriptor(font,12) << getCTFontWeightFromDescriptor(font,18); + } + //styleKey.weight = (d > 0.0) ? QFont::Bold : QFont::Normal; + // RJVB 20150415: do a true breakdown of the various known font weights rather than a binary + // classification as in the line above. We could also use weightFromInteger(d*500+500) ... + if (d == 0.0) { + // Normal or Regular : (0) + styleKey.weight = QFont::Normal; + } + else if (d < 0.0) { + // Thin (-0.6), Light (-0.4) or Book (-0.23 !) + styleKey.weight = QFont::Light; + } + else if (d < 0.4) { + // Demi Bold, Semi Bold or Medium (0.23 or 0.3) + styleKey.weight = QFont::DemiBold; + } + else if (d < 0.5) { + // Bold (0.4) + styleKey.weight = QFont::Bold; + } + else{ + // ExtraBold or Ultra (0.5), Heavy or Black (0.62) + styleKey.weight = QFont::Black; + } } } if(CFNumberRef italic = (CFNumberRef)CFDictionaryGetValue(styles, kCTFontSlantTrait)) { @@ -202,7 +228,7 @@ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) { //qDebug() << "WTF?"; } } -} else +} else #endif { #ifndef QT_MAC_USE_COCOA @@ -450,7 +476,7 @@ static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt) return; ATSFontActivateFromFileReference(&ref, kATSFontContextLocal, kATSFontFormatUnspecified, 0, kATSOptionFlagsDefault, &handle); - } else + } else #endif { #ifndef Q_WS_MAC64 diff --git src/gui/text/qfontengine_coretext.mm src/gui/text/qfontengine_coretext.mm index 204d685..5ec541d 100644 --- src/gui/text/qfontengine_coretext.mm +++ src/gui/text/qfontengine_coretext.mm @@ -451,14 +451,32 @@ int getTraitValue(CFDictionaryRef allTraits, CFStringRef trait) CFNumberRef traitNum = (CFNumberRef) CFDictionaryGetValue(allTraits, trait); float v = 0; CFNumberGetValue(traitNum, kCFNumberFloatType, &v); - // the value we get from CFNumberRef is from -1.0 to 1.0 + // the value we get from CFNumberRef is from -1.0 to 1.0 : + // Thin (-0.6), Light (-0.4) or Book (-0.23 !) + // Normal or Regular : (0) + // Demi Bold, Semi Bold or Medium (0.23 or 0.3) + // Bold (0.4) + // ExtraBold or Ultra (0.5), Heavy or Black (0.62) int value = v * 500 + 500; + // value: + // Thin (200), Light (300) or Book (385 !) + // Normal or Regular : (500) + // Demi Bold, Semi Bold or Medium (615 or 650) + // Bold (700) + // ExtraBold or Ultra (750), Heavy or Black (810) return value; } return 0; } +// RJVB +int getCTFontWeightFromDescriptor(CTFontDescriptorRef fontRef, int size) +{ + NSFont *font = [NSFont fontWithDescriptor:(NSFontDescriptor*)fontRef size:(CGFloat)size]; + return [[NSFontManager sharedFontManager] weightOfFont:font]; +} + void QCoreTextFontEngine::init() { Q_ASSERT(ctfont != NULL); diff --git src/plugins/platforms/fontdatabases/coretext/qcoretextfontdatabase.mm src/plugins/platforms/fontdatabases/coretext/qcoretextfontdatabase.mm index 312015f..1380b02 100644 --- src/plugins/platforms/fontdatabases/coretext/qcoretextfontdatabase.mm +++ src/plugins/platforms/fontdatabases/coretext/qcoretextfontdatabase.mm @@ -137,9 +137,12 @@ void QCoreTextFontDatabase::populateFontDatabase() if (CFNumberRef weight = (CFNumberRef)CFDictionaryGetValue(styles, kCTFontWeightTrait)) { Q_ASSERT(CFNumberIsFloatType(weight)); double d; + // RJVB 20150415 + extern QFont::Weight weightFromInteger(int weight); if (CFNumberGetValue(weight, kCFNumberDoubleType, &d)) { - if (d > 0.0) - fontWeight = QFont::Bold; + //if (d > 0.0) + // fontWeight = QFont::Bold; + fontWeight = weightFromInteger((int)d * 500 + 500); } } if (CFNumberRef italic = (CFNumberRef)CFDictionaryGetValue(styles, kCTFontSlantTrait)) { diff --git tools/qtconfig/mainwindow.cpp tools/qtconfig/mainwindow.cpp index 1bb6e4e..96a95b8 100644 --- tools/qtconfig/mainwindow.cpp +++ tools/qtconfig/mainwindow.cpp @@ -183,6 +183,17 @@ static void setStyleHelper(QWidget *w, QStyle *s) w->setStyle(s); } +static bool qstringContainsFromList(QString &style, QStringList &checkList, Qt::CaseSensitivity mode=Qt::CaseSensitive) +{ + QString pattern; + Q_FOREACH(pattern, checkList) { + if (style.contains(pattern,mode)) { + return true; + } + } + return false; +} + MainWindow::MainWindow() : ui(new Ui::MainWindow), editPalette(palette()), @@ -347,6 +358,21 @@ MainWindow::MainWindow() ui->fontStyleCombo->addItems(styles); QString stylestring = db.styleString(QApplication::font()); + + // RJVB 20150419 + QStringList lightStyles, bookStyles, normalStyles, demiBoldStyles, blackStyles, slantStyles; + lightStyles << "Thin" << "Light"; + bookStyles << "Book"; + normalStyles << "Normal" << "Regular"; + demiBoldStyles << "DemiBold" << "Demi Bold" << "SemiBold" << "Semi Bold" << "Medium"; + blackStyles << "Black" << "Ultra" << "Heavy" << "UltraBold"; + slantStyles << "Italic" << "Oblique"; + + if (stylestring.contains("Light", Qt::CaseInsensitive) && !styles.contains("Light", Qt::CaseInsensitive)) { + // this is a Book weight that was "demoted" to Light because Qt doesn't recognise Book as a separate style, + // so we add Book as a valid synonym to lightStyles. + lightStyles << "Book"; + } sit = styles.begin(); i = 0; possible = -1; @@ -355,6 +381,16 @@ MainWindow::MainWindow() break; if ((*sit).contains(stylestring)) possible = i; + // RJVB 20150416: handle style synonyms + if ((qstringContainsFromList(stylestring, lightStyles, Qt::CaseInsensitive) && qstringContainsFromList((*sit), lightStyles, Qt::CaseInsensitive)) + || (qstringContainsFromList(stylestring, bookStyles, Qt::CaseInsensitive) && qstringContainsFromList((*sit), bookStyles, Qt::CaseInsensitive)) + || (qstringContainsFromList(stylestring, normalStyles, Qt::CaseInsensitive) && qstringContainsFromList((*sit), normalStyles, Qt::CaseInsensitive)) + || (qstringContainsFromList(stylestring, demiBoldStyles, Qt::CaseInsensitive) && qstringContainsFromList((*sit), demiBoldStyles, Qt::CaseInsensitive)) + || (qstringContainsFromList(stylestring, blackStyles, Qt::CaseInsensitive) && qstringContainsFromList((*sit), blackStyles, Qt::CaseInsensitive))) { + if ((qstringContainsFromList(stylestring, slantStyles, Qt::CaseInsensitive) == qstringContainsFromList((*sit), slantStyles, Qt::CaseInsensitive))) { + break; + } + } i++; sit++;