Fix regressions in previous QFontDatabase patch

1. QtFontStyle::Key comparison should either use styleName or
   style, etc., but not both.
2. When initializing a QFont from QFontDatabase::font(), style
   and weight parameters should always be set even when we found
   a match styleName, in case these parameters will be used for
   comparison later.
3. Move styleName out of QtFontStyle::Key so that the code can be
   clearer and more explicit.

Change-Id: Icdee8e97568a0f31f57d2cdb8d414f47331fde75
Reviewed-by: Eskil
Reviewed-on: http://codereview.qt.nokia.com/1263
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Jiang Jiang <jiang.jiang@nokia.com>
This commit is contained in:
Jiang Jiang 2011-07-07 08:36:45 +02:00 committed by Qt by Nokia
parent c0c6dd2b02
commit 1174b69ee1
6 changed files with 64 additions and 57 deletions

View File

@ -218,17 +218,14 @@ struct QtFontStyle
Key(const QString &styleString);
Key() : style(QFont::StyleNormal),
weight(QFont::Normal), stretch(0) { }
Key(const Key &o) : styleName(o.styleName), style(o.style),
weight(o.weight), stretch(o.stretch) { }
QString styleName;
Key(const Key &o) : style(o.style), weight(o.weight), stretch(o.stretch) { }
uint style : 2;
signed int weight : 8;
signed int stretch : 12;
bool operator==(const Key & other) {
return styleName == other.styleName && style == other.style &&
weight == other.weight &&
(stretch == 0 || other.stretch == 0 || stretch == other.stretch);
return (style == other.style && weight == other.weight &&
(stretch == 0 || other.stretch == 0 || stretch == other.stretch));
}
bool operator!=(const Key &other) {
return !operator==(other);
@ -280,6 +277,7 @@ struct QtFontStyle
bool smoothScalable : 1;
signed int count : 30;
QtFontSize *pixelSizes;
QString styleName;
#ifdef Q_WS_X11
const char *weightName;
@ -293,7 +291,7 @@ struct QtFontStyle
};
QtFontStyle::Key::Key(const QString &styleString)
: styleName(styleString), style(QFont::StyleNormal), weight(QFont::Normal), stretch(0)
: style(QFont::StyleNormal), weight(QFont::Normal), stretch(0)
{
weight = getFontWeight(styleString);
@ -354,13 +352,20 @@ struct QtFontFoundry
int count;
QtFontStyle **styles;
QtFontStyle *style(const QtFontStyle::Key &, bool = false);
QtFontStyle *style(const QtFontStyle::Key &, const QString & = QString(), bool = false);
};
QtFontStyle *QtFontFoundry::style(const QtFontStyle::Key &key, bool create)
QtFontStyle *QtFontFoundry::style(const QtFontStyle::Key &key, const QString &styleName, bool create)
{
int pos = 0;
if (count) {
// if styleName for searching first if possible
if (!styleName.isEmpty()) {
for (; pos < count; pos++) {
if (styles[pos]->styleName == styleName)
return styles[pos];
}
}
int low = 0;
int high = count;
pos = count / 2;
@ -387,6 +392,7 @@ QtFontStyle *QtFontFoundry::style(const QtFontStyle::Key &key, bool create)
}
QtFontStyle *style = new QtFontStyle(key);
style->styleName = styleName;
memmove(styles + pos + 1, styles + pos, (count-pos)*sizeof(QtFontStyle *));
styles[pos] = style;
count++;
@ -815,7 +821,7 @@ void QFontDatabasePrivate::addFont(const QString &familyname, const char *foundr
}
QtFontFoundry *foundry = f->foundry(QString::fromLatin1(foundryname), true);
QtFontStyle *style = foundry->style(styleKey, true);
QtFontStyle *style = foundry->style(styleKey, QString(), true);
style->smoothScalable = (pixelSize == 0);
style->antialiased = antialiased;
QtFontSize *size = style->pixelSize(pixelSize?pixelSize:SMOOTH_SCALABLE, true);
@ -1132,7 +1138,8 @@ QString QFontDatabase::resolveFontFamilyAlias(const QString &family)
}
#endif
static QtFontStyle *bestStyle(QtFontFoundry *foundry, const QtFontStyle::Key &styleKey)
static QtFontStyle *bestStyle(QtFontFoundry *foundry, const QtFontStyle::Key &styleKey,
const QString &styleName = QString())
{
int best = 0;
int dist = 0xffff;
@ -1140,7 +1147,7 @@ static QtFontStyle *bestStyle(QtFontFoundry *foundry, const QtFontStyle::Key &st
for ( int i = 0; i < foundry->count; i++ ) {
QtFontStyle *style = foundry->styles[i];
if (!styleKey.styleName.isEmpty() && styleKey.styleName == style->key.styleName) {
if (!styleName.isEmpty() && styleName == style->styleName) {
dist = 0;
best = i;
break;
@ -1797,16 +1804,16 @@ QStringList QFontDatabase::styles(const QString &family) const
for (int k = 0; k < foundry->count; k++) {
QtFontStyle::Key ke(foundry->styles[k]->key);
ke.stretch = 0;
allStyles.style(ke, true);
allStyles.style(ke, foundry->styles[k]->styleName, true);
}
}
}
for (int i = 0; i < allStyles.count; i++) {
l.append(allStyles.styles[i]->key.styleName.isEmpty() ?
l.append(allStyles.styles[i]->styleName.isEmpty() ?
styleStringHelper(allStyles.styles[i]->key.weight,
(QFont::Style)allStyles.styles[i]->key.style) :
allStyles.styles[i]->key.styleName);
allStyles.styles[i]->styleName);
}
return l;
}
@ -1865,7 +1872,9 @@ bool QFontDatabase::isBitmapScalable(const QString &family,
QtFontFoundry *foundry = f->foundries[j];
if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
for (int k = 0; k < foundry->count; k++)
if ((style.isEmpty() || foundry->styles[k]->key == styleKey)
if ((style.isEmpty() ||
foundry->styles[k]->styleName == style ||
foundry->styles[k]->key == styleKey)
&& foundry->styles[k]->bitmapScalable && !foundry->styles[k]->smoothScalable) {
bitmapScalable = true;
goto end;
@ -1904,7 +1913,9 @@ bool QFontDatabase::isSmoothlyScalable(const QString &family, const QString &sty
QtFontFoundry *foundry = f->foundries[j];
if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
for (int k = 0; k < foundry->count; k++)
if ((style.isEmpty() || foundry->styles[k]->key == styleKey) && foundry->styles[k]->smoothScalable) {
if ((style.isEmpty() ||
foundry->styles[k]->styleName == style ||
foundry->styles[k]->key == styleKey) && foundry->styles[k]->smoothScalable) {
smoothScalable = true;
goto end;
}
@ -1937,12 +1948,12 @@ bool QFontDatabase::isScalable(const QString &family,
\sa smoothSizes(), standardSizes()
*/
QList<int> QFontDatabase::pointSizes(const QString &family,
const QString &style)
const QString &styleName)
{
#if defined(Q_WS_WIN)
// windows and macosx are always smoothly scalable
Q_UNUSED(family);
Q_UNUSED(style);
Q_UNUSED(styleName);
return standardSizes();
#else
bool smoothScalable = false;
@ -1953,7 +1964,7 @@ QList<int> QFontDatabase::pointSizes(const QString &family,
QT_PREPEND_NAMESPACE(load)(familyName);
QtFontStyle::Key styleKey(style);
QtFontStyle::Key styleKey(styleName);
QList<int> sizes;
@ -1970,7 +1981,7 @@ QList<int> QFontDatabase::pointSizes(const QString &family,
for (int j = 0; j < fam->count; j++) {
QtFontFoundry *foundry = fam->foundries[j];
if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
QtFontStyle *style = foundry->style(styleKey);
QtFontStyle *style = foundry->style(styleKey, styleName);
if (!style) continue;
if (style->smoothScalable) {
@ -2021,25 +2032,21 @@ QFont QFontDatabase::font(const QString &family, const QString &style,
QtFontFoundry *foundry = f->foundries[j];
if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
for (int k = 0; k < foundry->count; k++)
allStyles.style(foundry->styles[k]->key, true);
allStyles.style(foundry->styles[k]->key, foundry->styles[k]->styleName, true);
}
}
QtFontStyle::Key styleKey(style);
QtFontStyle *s = bestStyle(&allStyles, styleKey);
QtFontStyle *s = bestStyle(&allStyles, styleKey, style);
if (!s) // no styles found?
return QApplication::font();
if (s->key.styleName.isEmpty()) {
QFont fnt(family, pointSize, s->key.weight);
fnt.setStyle((QFont::Style)s->key.style);
return fnt;
} else {
// found a perfect match
QFont fnt(family, pointSize);
fnt.setStyleName(s->key.styleName);
return fnt;
}
QFont fnt(family, pointSize, s->key.weight);
fnt.setStyle((QFont::Style)s->key.style);
if (!s->styleName.isEmpty())
fnt.setStyleName(s->styleName);
return fnt;
}
@ -2052,11 +2059,11 @@ QFont QFontDatabase::font(const QString &family, const QString &style,
\sa pointSizes(), standardSizes()
*/
QList<int> QFontDatabase::smoothSizes(const QString &family,
const QString &style)
const QString &styleName)
{
#ifdef Q_WS_WIN
Q_UNUSED(family);
Q_UNUSED(style);
Q_UNUSED(styleName);
return QFontDatabase::standardSizes();
#else
bool smoothScalable = false;
@ -2067,7 +2074,7 @@ QList<int> QFontDatabase::smoothSizes(const QString &family,
QT_PREPEND_NAMESPACE(load)(familyName);
QtFontStyle::Key styleKey(style);
QtFontStyle::Key styleKey(styleName);
QList<int> sizes;
@ -2084,7 +2091,7 @@ QList<int> QFontDatabase::smoothSizes(const QString &family,
for (int j = 0; j < fam->count; j++) {
QtFontFoundry *foundry = fam->foundries[j];
if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
QtFontStyle *style = foundry->style(styleKey);
QtFontStyle *style = foundry->style(styleKey, styleName);
if (!style) continue;
if (style->smoothScalable) {
@ -2151,12 +2158,12 @@ bool QFontDatabase::italic(const QString &family, const QString &style) const
QtFontFoundry *foundry = f->foundries[j];
if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
for (int k = 0; k < foundry->count; k++)
allStyles.style(foundry->styles[k]->key, true);
allStyles.style(foundry->styles[k]->key, foundry->styles[k]->styleName, true);
}
}
QtFontStyle::Key styleKey(style);
QtFontStyle *s = allStyles.style(styleKey);
QtFontStyle *s = allStyles.style(styleKey, style);
return s && s->key.style == QFont::StyleItalic;
}
@ -2186,12 +2193,12 @@ bool QFontDatabase::bold(const QString &family,
if (foundryName.isEmpty() ||
foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
for (int k = 0; k < foundry->count; k++)
allStyles.style(foundry->styles[k]->key, true);
allStyles.style(foundry->styles[k]->key, foundry->styles[k]->styleName, true);
}
}
QtFontStyle::Key styleKey(style);
QtFontStyle *s = allStyles.style(styleKey);
QtFontStyle *s = allStyles.style(styleKey, style);
return s && s->key.weight >= QFont::Bold;
}
@ -2222,12 +2229,12 @@ int QFontDatabase::weight(const QString &family,
if (foundryName.isEmpty() ||
foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
for (int k = 0; k < foundry->count; k++)
allStyles.style(foundry->styles[k]->key, true);
allStyles.style(foundry->styles[k]->key, foundry->styles[k]->styleName, true);
}
}
QtFontStyle::Key styleKey(style);
QtFontStyle *s = allStyles.style(styleKey);
QtFontStyle *s = allStyles.style(styleKey, style);
return s ? s->key.weight : -1;
}

View File

@ -113,7 +113,7 @@ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
QtFontFoundry *foundry = family->foundry(foundry_name, true);
QtFontStyle::Key styleKey;
styleKey.styleName = style_name;
QString styleName = style_name;
if(QCFType<CFDictionaryRef> styles = (CFDictionaryRef)CTFontDescriptorCopyAttribute(font, kCTFontTraitsAttribute)) {
if(CFNumberRef weight = (CFNumberRef)CFDictionaryGetValue(styles, kCTFontWeightTrait)) {
Q_ASSERT(CFNumberIsFloatType(weight));
@ -134,7 +134,7 @@ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
}
}
QtFontStyle *style = foundry->style(styleKey, true);
QtFontStyle *style = foundry->style(styleKey, styleName, true);
style->smoothScalable = true;
if(QCFType<CFNumberRef> size = (CFNumberRef)CTFontDescriptorCopyAttribute(font, kCTFontSizeAttribute)) {
//qDebug() << "WHEE";
@ -207,7 +207,7 @@ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
QtFontFamily *family = db->family(familyName, true);
QtFontFoundry *foundry = family->foundry(QString(), true);
QtFontStyle *style = foundry->style(styleKey, true);
QtFontStyle *style = foundry->style(styleKey, QString(), true);
style->pixelSize(0, true);
style->smoothScalable = true;

View File

@ -73,7 +73,7 @@ Q_GUI_EXPORT void qt_registerFont(const QString &familyName, const QString &fou
}
QtFontFoundry *foundry = f->foundry(foundryname, true);
QtFontStyle *fontStyle = foundry->style(styleKey, true);
QtFontStyle *fontStyle = foundry->style(styleKey, QString(), true);
fontStyle->smoothScalable = scalable;
fontStyle->antialiased = antialiased;
QtFontSize *size = fontStyle->pixelSize(pixelSize?pixelSize:SMOOTH_SCALABLE, true);

View File

@ -508,7 +508,7 @@ static bool registerScreenDeviceFont(int screenDeviceFontIndex,
QtFontFamily *family = privateDb()->family(familyName, true);
family->fixedPitch = faceAttrib.IsMonoWidth();
QtFontFoundry *foundry = family->foundry(QString(), true);
QtFontStyle *style = foundry->style(styleKey, true);
QtFontStyle *style = foundry->style(styleKey, QString(), true);
style->smoothScalable = typefaceSupport.iIsScalable;
style->pixelSize(0, true);

View File

@ -284,7 +284,7 @@ void addFontToDatabase(QString familyName, const QString &scriptName,
family->english_name = getEnglishName(familyName);
QtFontFoundry *foundry = family->foundry(foundryName, true);
QtFontStyle *style = foundry->style(styleKey, true);
QtFontStyle *style = foundry->style(styleKey, QString(), true);
style->smoothScalable = scalable;
style->pixelSize( size, TRUE);
@ -292,14 +292,14 @@ void addFontToDatabase(QString familyName, const QString &scriptName,
if (styleKey.weight <= QFont::DemiBold) {
QtFontStyle::Key key(styleKey);
key.weight = QFont::Bold;
QtFontStyle *style = foundry->style(key, true);
QtFontStyle *style = foundry->style(key, QString(), true);
style->smoothScalable = scalable;
style->pixelSize( size, TRUE);
}
if (styleKey.style != QFont::StyleItalic) {
QtFontStyle::Key key(styleKey);
key.style = QFont::StyleItalic;
QtFontStyle *style = foundry->style(key, true);
QtFontStyle *style = foundry->style(key, QString(), true);
style->smoothScalable = scalable;
style->pixelSize( size, TRUE);
}
@ -307,7 +307,7 @@ void addFontToDatabase(QString familyName, const QString &scriptName,
QtFontStyle::Key key(styleKey);
key.weight = QFont::Bold;
key.style = QFont::StyleItalic;
QtFontStyle *style = foundry->style(key, true);
QtFontStyle *style = foundry->style(key, QString(), true);
style->smoothScalable = scalable;
style->pixelSize( size, TRUE);
}

View File

@ -680,7 +680,7 @@ static void loadXlfds(const char *reqFamily, int encoding_id)
family->fontFileIndex = -1;
family->symbol_checked = true;
QtFontFoundry *foundry = family->foundry(QLatin1String(foundryName), true);
QtFontStyle *style = foundry->style(styleKey, true);
QtFontStyle *style = foundry->style(styleKey, QString(), true);
delete [] style->weightName;
style->weightName = qstrdup(tokens[Weight]);
@ -1145,7 +1145,7 @@ static void loadFontConfig()
family->fontFileIndex = index_value;
QtFontStyle::Key styleKey;
styleKey.styleName = style_value ? QString::fromUtf8((const char *) style_value) : QString();
QString styleName = style_value ? QString::fromUtf8((const char *) style_value) : QString();
styleKey.style = (slant_value == FC_SLANT_ITALIC)
? QFont::StyleItalic
: ((slant_value == FC_SLANT_OBLIQUE)
@ -1160,7 +1160,7 @@ static void loadFontConfig()
QtFontFoundry *foundry
= family->foundry(foundry_value ? QString::fromUtf8((const char *)foundry_value) : QString(), true);
QtFontStyle *style = foundry->style(styleKey, true);
QtFontStyle *style = foundry->style(styleKey, styleName, true);
if (spacing_value < FC_MONO)
family->fixedPitch = false;
@ -1212,7 +1212,7 @@ static void loadFontConfig()
for (int i = 0; i < 4; ++i) {
styleKey.style = (i%2) ? QFont::StyleNormal : QFont::StyleItalic;
styleKey.weight = (i > 1) ? QFont::Bold : QFont::Normal;
QtFontStyle *style = foundry->style(styleKey, true);
QtFontStyle *style = foundry->style(styleKey, QString(), true);
style->smoothScalable = true;
QtFontSize *size = style->pixelSize(SMOOTH_SCALABLE, true);
QtFontEncoding *enc = size->encodingID(-1, 0, 0, 0, 0, true);
@ -1360,7 +1360,7 @@ static void initializeDb()
if (equiv) continue;
// let's fake one...
equiv = foundry->style(key, true);
equiv = foundry->style(key, QString(), true);
equiv->smoothScalable = true;
QtFontSize *equiv_size = equiv->pixelSize(SMOOTH_SCALABLE, true);