diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp
index 70d70e342a..10be7c0015 100644
--- a/src/gui/painting/qtextureglyphcache.cpp
+++ b/src/gui/painting/qtextureglyphcache.cpp
@@ -382,14 +382,15 @@ void QImageTextureGlyphCache::fillTexture(const Coord &c,
         }
     }
 
-#ifdef CACHE_DEBUG
+#ifndef CACHE_DEBUG
 //     QPainter p(&m_image);
 //     p.drawLine(
     int margin = m_current_fontengine ? m_current_fontengine->glyphMargin(m_format) : 0;
     QPoint base(c.x + margin, c.y + margin + c.baseLineY-1);
     if (m_image.rect().contains(base))
         m_image.setPixel(base, 255);
-    m_image.save(QString::fromLatin1("cache-%1.png").arg(qint64(this)));
+    // m_image.save(QString::fromLatin1("cache-%1.png").arg(qint64(g)));
+    mask.save(QString::fromLatin1("cache-%1.png").arg(qint64(g)));
 #endif
 }
 
diff --git a/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp b/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp
index 6043406c4d..9ac91e7241 100644
--- a/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp
+++ b/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp
@@ -614,12 +614,8 @@ glyph_metrics_t QWindowsFontEngineDirectWrite::boundingBox(glyph_t g)
         QFixed bottomSideBearing = DESIGN_TO_LOGICAL(glyphMetrics.bottomSideBearing);
         QFixed width = advanceWidth - leftSideBearing - rightSideBearing;
         QFixed height = advanceHeight - topSideBearing - bottomSideBearing;
-        return glyph_metrics_t(leftSideBearing,
-                               -verticalOriginY + topSideBearing,
-                               width,
-                               height,
-                               advanceWidth,
-                               0);
+        return glyph_metrics_t(leftSideBearing, -verticalOriginY + topSideBearing, width, height,
+                               advanceWidth, 0);
     } else {
         qErrnoWarning("%s: GetDesignGlyphMetrics failed", __FUNCTION__);
     }
@@ -777,20 +773,31 @@ QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t,
     }
 
     if (SUCCEEDED(hr)) {
-        RECT rect;
-        glyphAnalysis->GetAlphaTextureBounds(DWRITE_TEXTURE_CLEARTYPE_3x1, &rect);
-
-        if (rect.top == rect.bottom || rect.left == rect.right)
-            return QImage();
-
-        QRect boundingRect = QRect(QPoint(rect.left - margin,
-                                          rect.top - margin),
-                                   QPoint(rect.right + margin,
-                                          rect.bottom + margin));
+        QRect boundingRect;
+        int width = 0;
+        int height = 0;
+
+        if (glyphFormat == GlyphFormat::Format_ARGB) {
+            // TODO: this is duplicate work!
+            auto colorBb = tryGetColrGlyphBoundingBox(t, glyphFormat, originalTransform, transform);
+            if (colorBb) {
+                boundingRect = *colorBb;
+                width = boundingRect.width();
+                height = boundingRect.height();
+            }
+        }
+        if (boundingRect.isEmpty()) {
+            RECT rect;
+            glyphAnalysis->GetAlphaTextureBounds(DWRITE_TEXTURE_CLEARTYPE_3x1, &rect);
 
+            if (rect.top == rect.bottom || rect.left == rect.right)
+                return QImage();
 
-        const int width = boundingRect.width() - 1; // -1 due to Qt's off-by-one definition of a QRect
-        const int height = boundingRect.height() - 1;
+            boundingRect = QRect(QPoint(rect.left - margin, rect.top - margin),
+                                 QPoint(rect.right + margin, rect.bottom + margin));
+            width = boundingRect.width() - 1; // -1 due to Qt's off-by-one definition of a QRect
+            height = boundingRect.height() - 1;
+        }
 
         QImage image;
         HRESULT hr = DWRITE_E_NOCOLOR;
@@ -806,7 +813,7 @@ QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t,
                                                   &enumerator);
             image = QImage(width, height, QImage::Format_ARGB32_Premultiplied);
             image.fill(0);
-        } else  {
+        } else {
             image = QImage(width, height, QImage::Format_RGB32);
             image.fill(0xffffffff);
         }
@@ -814,6 +821,13 @@ QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t,
         BOOL ok = true;
 
         if (SUCCEEDED(hr)) {
+            QPainter painter(&image);
+            painter.setPen(Qt::NoPen);
+            auto painterTransform = originalTransform
+                    * QTransform::fromTranslate(-(originalTransform.dx() + boundingRect.left()),
+                                                -(originalTransform.dy() + boundingRect.top()));
+            painter.setTransform(painterTransform);
+            painter.setRenderHint(QPainter::Antialiasing);
             while (SUCCEEDED(hr) && ok) {
                 const DWRITE_COLOR_GLYPH_RUN *colorGlyphRun = 0;
                 hr = enumerator->GetCurrentRun(&colorGlyphRun);
@@ -822,46 +836,32 @@ QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t,
                     break;
                 }
 
-                IDWriteGlyphRunAnalysis *colorGlyphsAnalysis = NULL;
-                hr = factory2->CreateGlyphRunAnalysis(
-                            &colorGlyphRun->glyphRun,
-                            &transform,
-                            renderMode,
-                            measureMode,
-                            gridFitMode,
-                            DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE,
-                            0.0, 0.0,
-                            &colorGlyphsAnalysis
-                            );
-
-                if (FAILED(hr)) {
-                    qErrnoWarning(hr, "%s: CreateGlyphRunAnalysis failed for color run", __FUNCTION__);
-                    break;
-                }
-
-                float r, g, b, a;
                 if (colorGlyphRun->paletteIndex == 0xFFFF) {
-                    r = float(color.redF());
-                    g = float(color.greenF());
-                    b = float(color.blueF());
-                    a = float(color.alphaF());
+                    painter.setBrush(color);
                 } else {
+                    float r, g, b, a;
                     r = qBound(0.0f, colorGlyphRun->runColor.r, 1.0f);
                     g = qBound(0.0f, colorGlyphRun->runColor.g, 1.0f);
                     b = qBound(0.0f, colorGlyphRun->runColor.b, 1.0f);
                     a = qBound(0.0f, colorGlyphRun->runColor.a, 1.0f);
+                    painter.setBrush(QColor::fromRgbF(r, g, b, a));
                 }
 
-                if (!qFuzzyIsNull(a)) {
-                    renderGlyphRun(&image,
-                                   r,
-                                   g,
-                                   b,
-                                   a,
-                                   colorGlyphsAnalysis,
-                                   boundingRect);
+                QPainterPath path;
+                GeometrySink sink(&path);
+                hr = colorGlyphRun->glyphRun.fontFace->GetGlyphRunOutline(
+                        colorGlyphRun->glyphRun.fontEmSize,
+                        colorGlyphRun->glyphRun.glyphIndices,
+                        colorGlyphRun->glyphRun.glyphAdvances,
+                        colorGlyphRun->glyphRun.glyphOffsets,
+                        colorGlyphRun->glyphRun.glyphCount,
+                        colorGlyphRun->glyphRun.isSideways,
+                        (colorGlyphRun->glyphRun.bidiLevel % 2) != 0,
+                        &sink);
+
+                if (!path.isEmpty()) {
+                    painter.drawPath(path);
                 }
-                colorGlyphsAnalysis->Release();
 
                 hr = enumerator->MoveNext(&ok);
                 if (FAILED(hr)) {
@@ -1031,6 +1031,9 @@ void QWindowsFontEngineDirectWrite::initFontInfo(const QFontDef &request,
             names->Release();
         }
 
+        if (face3->IsColorFont() && face3->GetPaletteEntryCount() > 0)
+            glyphFormat = QFontEngine::Format_ARGB;
+
         face3->Release();
     }
 #endif
@@ -1083,6 +1086,14 @@ glyph_metrics_t QWindowsFontEngineDirectWrite::alphaMapBoundingBox(glyph_t glyph
     transform.m21 = matrix.m21();
     transform.m22 = matrix.m22();
 
+    if (glyphFormat == GlyphFormat::Format_ARGB) {
+        auto colorBb = tryGetColrGlyphBoundingBox(glyph, format, matrix, transform);
+        if (colorBb) {
+            return glyph_metrics_t(colorBb->left(), colorBb->top(), colorBb->width(),
+                                   colorBb->height(), bbox.xoff, bbox.yoff);
+        }
+    }
+
     DWRITE_RENDERING_MODE renderMode = hintingPreferenceToRenderingMode(fontDef);
     DWRITE_MEASURING_MODE measureMode = renderModeToMeasureMode(renderMode);
     DWRITE_GRID_FIT_MODE gridFitMode = fontDef.hintingPreference == QFont::PreferNoHinting
@@ -1145,4 +1156,83 @@ QImage QWindowsFontEngineDirectWrite::bitmapForGlyph(glyph_t glyph,
     return imageForGlyph(glyph, subPixelPosition, glyphMargin(QFontEngine::Format_ARGB), t, color);
 }
 
+std::optional<QRect> QWindowsFontEngineDirectWrite::tryGetColrGlyphBoundingBox(glyph_t glyph,
+                                                                               GlyphFormat format,
+                                                                               const QTransform &matrix,
+                                                                               const DWRITE_MATRIX &transform)
+{
+    Q_UNUSED(matrix)
+    Q_UNUSED(transform)
+    UINT16 glyphIndex = glyph;
+    FLOAT glyphAdvance = 0;
+
+    DWRITE_GLYPH_OFFSET glyphOffset;
+    glyphOffset.advanceOffset = 0;
+    glyphOffset.ascenderOffset = 0;
+
+    DWRITE_GLYPH_RUN glyphRun;
+    glyphRun.fontFace = m_directWriteFontFace;
+    glyphRun.fontEmSize = fontDef.pixelSize;
+    glyphRun.glyphCount = 1;
+    glyphRun.glyphIndices = &glyphIndex;
+    glyphRun.glyphAdvances = &glyphAdvance;
+    glyphRun.isSideways = false;
+    glyphRun.bidiLevel = 0;
+    glyphRun.glyphOffsets = &glyphOffset;
+
+    QTransform finalTransform(transform.m11, transform.m12, transform.m21, transform.m22, transform.dx, transform.dy);
+
+    IDWriteFactory4 *factory4 = nullptr;
+    HRESULT hr = m_fontEngineData->directWriteFactory->QueryInterface(
+            __uuidof(IDWriteFactory4), reinterpret_cast<void **>(&factory4));
+
+    if (FAILED(hr)) {
+        return std::nullopt;
+    }
+
+    DWRITE_RENDERING_MODE renderMode = hintingPreferenceToRenderingMode(fontDef);
+    DWRITE_MEASURING_MODE measureMode = renderModeToMeasureMode(renderMode);
+
+    int margin = glyphMargin(format);
+
+    IDWriteColorGlyphRunEnumerator *enumerator = nullptr;
+    hr = factory4->TranslateColorGlyphRun(0, 0, &glyphRun, nullptr, measureMode, &transform, 0,
+                                          &enumerator);
+    if (hr == DWRITE_E_NOCOLOR || FAILED(hr)) {
+        return std::nullopt;
+    }
+
+    QRect boundingBox;
+    BOOL ok = true;
+    while (SUCCEEDED(hr) && ok) {
+        const DWRITE_COLOR_GLYPH_RUN *colorGlyphRun = 0;
+        hr = enumerator->GetCurrentRun(&colorGlyphRun);
+        if (FAILED(hr)) { // No colored runs, only outline
+            qErrnoWarning(hr, "%s: IDWriteColorGlyphRunEnumerator::GetCurrentRun failed",
+                          __FUNCTION__);
+            return std::nullopt;
+        }
+
+        QPainterPath path;
+        GeometrySink sink(&path);
+        hr = colorGlyphRun->glyphRun.fontFace->GetGlyphRunOutline(
+                colorGlyphRun->glyphRun.fontEmSize, colorGlyphRun->glyphRun.glyphIndices,
+                colorGlyphRun->glyphRun.glyphAdvances, colorGlyphRun->glyphRun.glyphOffsets,
+                colorGlyphRun->glyphRun.glyphCount, colorGlyphRun->glyphRun.isSideways,
+                (colorGlyphRun->glyphRun.bidiLevel % 2) != 0, &sink);
+
+        if (!path.isEmpty()) {
+            boundingBox = boundingBox.united(path.boundingRect().toRect());
+        }
+
+        hr = enumerator->MoveNext(&ok);
+        if (FAILED(hr)) {
+            qErrnoWarning(hr, "%s: IDWriteColorGlyphRunEnumerator::MoveNext failed", __FUNCTION__);
+            break;
+        }
+    }
+
+    return finalTransform.mapRect(QRect(boundingBox.topLeft(), boundingBox.size() + QSize(margin, margin)));
+}
+
 QT_END_NAMESPACE
diff --git a/src/gui/text/windows/qwindowsfontenginedirectwrite_p.h b/src/gui/text/windows/qwindowsfontenginedirectwrite_p.h
index df6df1ad17..f5d73f7b5a 100644
--- a/src/gui/text/windows/qwindowsfontenginedirectwrite_p.h
+++ b/src/gui/text/windows/qwindowsfontenginedirectwrite_p.h
@@ -23,6 +23,8 @@ QT_REQUIRE_CONFIG(directwrite);
 #include <QtGui/private/qfontengine_p.h>
 #include <QtCore/QSharedPointer>
 
+#include <optional>
+
 struct IDWriteFont;
 struct IDWriteFontFace;
 struct IDWriteFontFile;
@@ -31,6 +33,8 @@ struct IDWriteBitmapRenderTarget;
 struct IDWriteGdiInterop;
 struct IDWriteGlyphRunAnalysis;
 
+struct DWRITE_MATRIX;
+
 QT_BEGIN_NAMESPACE
 
 class QWindowsFontEngineData;
@@ -111,6 +115,8 @@ private:
     void renderGlyphRun(QImage *destination, float r, float g, float b, float a, IDWriteGlyphRunAnalysis *glyphAnalysis, const QRect &boundingRect);
     static QString filenameFromFontFile(IDWriteFontFile *fontFile);
 
+    std::optional<QRect> tryGetColrGlyphBoundingBox(glyph_t glyph, GlyphFormat format, const QTransform &matrix, const DWRITE_MATRIX &transform);
+
     const QSharedPointer<QWindowsFontEngineData> m_fontEngineData;
 
     IDWriteFontFace *m_directWriteFontFace;
