macOS: Fix matching of font weights for application fonts

5ad2e1cea1 exposed a
latent bug when matching font weights that do not exactly
match any of the canonical weights in the system .

It seems that when we registered the font with FontManager,
it would modify the font weight to match a system weight,
while we now get raw values from the font instead.

So for Roboto Medium, for instance, we would now get
0.2 instead of 0.23, and since our conversion logic
would convert everything between Light (-0.4) to
Medium (0.23) to QFont::Normal, we would regard this
as normal weight instead of medium.

But on a linear scale, it makes more sense to match
to the closest canonical weight instead of requiring
exact matches.

Note that the definition says that the middle between
two weights should tend upwards, therefore we do the
comparisons in decreasing order.

[ChangeLog][QtGui][Text] Fixed matching of non-regular
font weights for application fonts on macOS.

Task-number: QTBUG-61520
Change-Id: Ieda4927c2c69ec72125257340cf06c683b031d05
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
Eskil Abrahamsen Blomfeldt 2017-08-16 13:20:33 +02:00
parent f9f5b35e73
commit a26a3cfbc7

View File

@ -112,25 +112,32 @@ bool QCoreTextFontEngine::ct_getSfntTable(void *user_data, uint tag, uchar *buff
QFont::Weight QCoreTextFontEngine::qtWeightFromCFWeight(float value)
{
if (value >= kCTFontWeightBlack)
return QFont::Black;
if (value >= kCTFontWeightHeavy)
return QFont::ExtraBold;
if (value >= kCTFontWeightBold)
return QFont::Bold;
if (value >= kCTFontWeightSemibold)
return QFont::DemiBold;
if (value >= kCTFontWeightMedium)
return QFont::Medium;
if (value == kCTFontWeightRegular)
return QFont::Normal;
if (value <= kCTFontWeightUltraLight)
return QFont::Thin;
if (value <= kCTFontWeightThin)
return QFont::ExtraLight;
if (value <= kCTFontWeightLight)
return QFont::Light;
return QFont::Normal;
#define COMPARE_WEIGHT_DISTANCE(ct_weight, qt_weight) \
{ \
float d; \
if ((d = qAbs(value - ct_weight)) < distance) { \
distance = d; \
ret = qt_weight; \
} \
}
float distance = qAbs(value - kCTFontWeightBlack);
QFont::Weight ret = QFont::Black;
// Compare distance to system weight to find the closest match.
// (Note: Must go from high to low, so that midpoints are rounded up)
COMPARE_WEIGHT_DISTANCE(kCTFontWeightHeavy, QFont::ExtraBold);
COMPARE_WEIGHT_DISTANCE(kCTFontWeightBold, QFont::Bold);
COMPARE_WEIGHT_DISTANCE(kCTFontWeightSemibold, QFont::DemiBold);
COMPARE_WEIGHT_DISTANCE(kCTFontWeightMedium, QFont::Medium);
COMPARE_WEIGHT_DISTANCE(kCTFontWeightRegular, QFont::Normal);
COMPARE_WEIGHT_DISTANCE(kCTFontWeightLight, QFont::Light);
COMPARE_WEIGHT_DISTANCE(kCTFontWeightThin, QFont::ExtraLight);
COMPARE_WEIGHT_DISTANCE(kCTFontWeightUltraLight, QFont::Thin);
#undef COMPARE_WEIGHT_DISTANCE
return ret;
}
static void loadAdvancesForGlyphs(CTFontRef ctfont,