From e11a3b3f3e41050e048a586a8de2bd68c5ed3cc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 28 Nov 2018 12:17:58 +0100 Subject: CoreText: Base glyph fill color logic on font smoothing algorithm Change-Id: I22be1efb1f91048745008ea1b49186b39367d122 Reviewed-by: Lars Knoll --- .../fontdatabases/mac/qfontengine_coretext.mm | 57 ++++++++++++---------- 1 file changed, 32 insertions(+), 25 deletions(-) (limited to 'src/platformsupport/fontdatabases/mac') diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index a1299154cb..3dd3f468f2 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -748,37 +748,44 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition if (!im.width() || !im.height()) return im; -#if defined(Q_OS_MACOS) - CGColorRef glyphColor = CGColorGetConstantColor(kCGColorWhite); - if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave) { - // macOS 10.14 uses a new font smoothing algorithm that takes the fill color into - // account. This means our default approach of drawing white on black to produce - // the alpha map will result in non-native looking text when then drawn as black - // on white during the final blit. As a workaround we use the application's current - // appearance to decide whether to draw with white or black fill, and then invert - // the glyph image in the latter case, producing an alpha map. This covers the - // most common use-cases, but longer term we should propagate the fill color all - // the way from the paint engine, and include it in the key for the glyph cache. - if (!qt_mac_applicationIsInDarkMode()) - glyphColor = CGColorGetConstantColor(kCGColorBlack); - } - const bool blackOnWhiteGlyphs = !hasColorGlyphs() - && CGColorEqualToColor(glyphColor, CGColorGetConstantColor(kCGColorBlack)); - if (blackOnWhiteGlyphs) - im.fill(Qt::white); - else -#endif - im.fill(0); // Faster than Qt::black - QCFType colorspace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB); QCFType ctx = CGBitmapContextCreate(im.bits(), im.width(), im.height(), 8, im.bytesPerLine(), colorspace, qt_mac_bitmapInfoForImage(im)); Q_ASSERT(ctx); - CGContextSetFontSize(ctx, fontDef.pixelSize); CGContextSetShouldAntialias(ctx, shouldAntialias()); - CGContextSetShouldSmoothFonts(ctx, shouldSmoothFont()); + + const bool shouldSmooth = shouldSmoothFont(); + CGContextSetShouldSmoothFonts(ctx, shouldSmooth); + +#if defined(Q_OS_MACOS) + auto glyphColor = [&] { + if (shouldSmooth && fontSmoothing() == Grayscale) { + // The grayscale font smoothing algorithm introduced in macOS Mojave (10.14) adjusts + // its dilation (stem darkening) parameters based on the fill color. This means our + // default approach of drawing white on black to produce the alpha map will result + // in non-native looking text when then drawn as black on white during the final blit. + // As a workaround we use the application's current appearance to decide whether to + // draw with white or black fill, and then invert the glyph image in the latter case, + // producing an alpha map. This covers the most common use-cases, but longer term we + // should propagate the fill color all the way from the paint engine, and include it + //in the key for the glyph cache. + + if (!qt_mac_applicationIsInDarkMode()) + return kCGColorBlack; + } + return kCGColorWhite; + }(); + + const bool blackOnWhiteGlyphs = glyphColor == kCGColorBlack; + if (blackOnWhiteGlyphs) + im.fill(Qt::white); + else +#endif + im.fill(0); + + CGContextSetFontSize(ctx, fontDef.pixelSize); CGAffineTransform cgMatrix = CGAffineTransformIdentity; @@ -798,7 +805,7 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition if (!hasColorGlyphs()) { CGContextSetTextMatrix(ctx, cgMatrix); #if defined(Q_OS_MACOS) - CGContextSetFillColorWithColor(ctx, glyphColor); + CGContextSetFillColorWithColor(ctx, CGColorGetConstantColor(glyphColor)); #else CGContextSetRGBFillColor(ctx, 1, 1, 1, 1); #endif -- cgit v1.2.3