summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@qt.io>2018-08-21 15:22:01 +0200
committerTor Arne Vestbø <tor.arne.vestbo@qt.io>2018-08-24 13:42:59 +0000
commit0de4b76b9c76ddc4d7ee9790b70f39b7ee577ede (patch)
tree5fad1d1d9c2bb1573476b3af87b778b1fd11200a /src
parent48f0996449fbc302c7557832425b17e123be37c1 (diff)
macOS: Take application appearance into account when drawing glyphs
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. At the moment we do not react to changes in the application appearance, as that seems to be buggy in general in Qt (palette/style, e.g.), and those bugs need to be weeded before we can react to the theme change with confidence. Task-number: QTBUG-68824 Change-Id: Ibbfd49fcf3a091e454009c08159f46b3499e2bd0 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/kernel/qcore_mac_objc.mm19
-rw-r--r--src/corelib/kernel/qcore_mac_p.h3
-rw-r--r--src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm35
3 files changed, 51 insertions, 6 deletions
diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm
index 0d7bfad943..2e303607df 100644
--- a/src/corelib/kernel/qcore_mac_objc.mm
+++ b/src/corelib/kernel/qcore_mac_objc.mm
@@ -40,8 +40,13 @@
#include <private/qcore_mac_p.h>
-#ifdef Q_OS_OSX
-#include <AppKit/NSText.h>
+#ifdef Q_OS_MACOS
+# include <AppKit/AppKit.h>
+# if !QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14)
+@interface NSApplication (MojaveForwardDeclarations)
+@property (strong) NSAppearance *effectiveAppearance NS_AVAILABLE_MAC(10_14);
+@end
+# endif
#endif
#if defined(QT_PLATFORM_UIKIT)
@@ -166,6 +171,16 @@ QDebug operator<<(QDebug debug, const QMacAutoReleasePool *pool)
}
#endif // !QT_NO_DEBUG_STREAM
+#ifdef Q_OS_MACOS
+bool qt_mac_applicationIsInDarkMode()
+{
+ if (__builtin_available(macOS 10.14, *))
+ return [NSApp.effectiveAppearance.name hasSuffix:@"DarkAqua"];
+ else
+ return false;
+}
+#endif
+
bool qt_apple_isApplicationExtension()
{
static bool isExtension = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSExtension"];
diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h
index a0802969dd..bf540c2e35 100644
--- a/src/corelib/kernel/qcore_mac_p.h
+++ b/src/corelib/kernel/qcore_mac_p.h
@@ -180,9 +180,10 @@ private:
QString string;
};
-#ifdef Q_OS_OSX
+#ifdef Q_OS_MACOS
Q_CORE_EXPORT QChar qt_mac_qtKey2CocoaKey(Qt::Key key);
Q_CORE_EXPORT Qt::Key qt_mac_cocoaKey2QtKey(QChar keyCode);
+Q_CORE_EXPORT bool qt_mac_applicationIsInDarkMode();
#endif
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
index 98b753eff9..6543759a3d 100644
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
@@ -42,6 +42,7 @@
#include <qpa/qplatformfontdatabase.h>
#include <QtCore/qendian.h>
#include <QtCore/qsettings.h>
+#include <QtCore/qoperatingsystemversion.h>
#include <private/qimage_p.h>
@@ -652,17 +653,36 @@ bool QCoreTextFontEngine::expectsGammaCorrectedBlending() const
QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, bool aa, const QTransform &matrix)
{
-
glyph_metrics_t br = alphaMapBoundingBox(glyph, subPixelPosition, matrix, glyphFormat);
bool isColorGlyph = glyphFormat == QFontEngine::Format_ARGB;
QImage::Format imageFormat = isColorGlyph ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
QImage im(br.width.ceil().toInt(), br.height.ceil().toInt(), imageFormat);
- im.fill(0);
-
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 = !isColorGlyph
+ && CGColorEqualToColor(glyphColor, CGColorGetConstantColor(kCGColorBlack));
+ if (blackOnWhiteGlyphs)
+ im.fill(Qt::white);
+ else
+#endif
+ im.fill(0); // Faster than Qt::black
+
CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
uint cgflags = isColorGlyph ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst;
#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version
@@ -696,7 +716,11 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition
if (!isColorGlyph) {
CGContextSetTextMatrix(ctx, cgMatrix);
+#if defined(Q_OS_MACOS)
+ CGContextSetFillColorWithColor(ctx, glyphColor);
+#else
CGContextSetRGBFillColor(ctx, 1, 1, 1, 1);
+#endif
CGContextSetTextDrawingMode(ctx, kCGTextFill);
CGContextSetTextPosition(ctx, pos_x, pos_y);
@@ -721,6 +745,11 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition
CGContextRelease(ctx);
CGColorSpaceRelease(colorspace);
+#if defined(Q_OS_MACOS)
+ if (blackOnWhiteGlyphs)
+ im.invertPixels();
+#endif
+
return im;
}