summaryrefslogtreecommitdiffstats
path: root/tests/manual/colormanagement/main.cpp
blob: e0c1e41f77f02828db8c94160e01a0e7a328c782 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only

#include <QtGui>
#include <qpa/qplatformscreen.h>

QString debugDescription(const QColorSpace &colorSpace)
{
    QString str;
    QDebug dbg(&str);
    dbg << colorSpace;
    return str;
}

// The color space of our assets that we need to color match from.
// In real world apps this could be different for each QImage etc.
static const QColorSpace assetColorSpace = QColorSpace::AdobeRgb;

class TestWindow : public QRasterWindow
{
public:
    using QRasterWindow::QRasterWindow;
    TestWindow()
    {
        resize(900, 300);
        setFlag(Qt::NoDropShadowWindowHint);

        // Moving a window to a different screen may not result
        // in an automatic expose/paint event, as the window's
        // content might still be valid on the new screen. In
        // our case we know it's not, as we need to update the
        // screen information we reflect in the paintEvent below.
        QObject::connect(this, &QWindow::screenChanged,
                         this, qOverload<>(&QRasterWindow::update));
    }

    bool colorManaged = false;

protected:
    void paintEvent(QPaintEvent *) override
    {
        QPainter painter(this);

        auto requestedColorSpace = requestedFormat().colorSpace();
        auto windowColorSpace = format().colorSpace();
        auto screenColorSpace = screen()->handle()->colorSpace();

        auto targetColorSpace = windowColorSpace;
        if (!targetColorSpace.isValid()) {
            qWarning("Window does not report color space! Using screen color space as target");
            targetColorSpace = screenColorSpace;
        }
        auto colorTransform = assetColorSpace.transformationToColorSpace(targetColorSpace);

        if (!colorManaged && requestedColorSpace.isValid() && !colorTransform.isIdentity()) {
            qWarning() << "Requested" << requestedColorSpace << "but got"
                << targetColorSpace << "and not prepared to do color matching";
        }

        QColor colors[] = {
            QColor(Qt::red),
            QColor(Qt::green),
            QColor(Qt::blue),
            QColor(Qt::cyan),
            QColor(Qt::magenta),
            QColor(Qt::yellow)
        };
        qreal colorWidth = width() / qreal(std::size(colors));
        for (size_t i = 0; i < std::size(colors); ++i) {
            QColor color = colors[i];
            if (colorManaged)
                color = colorTransform.map(color);

            painter.fillRect(QRectF(colorWidth * i, 0, colorWidth, height()), color);
        }

        QRect rect(0, 0, width(), height());
        painter.fillRect(rect.adjusted(20, 100, -20, -100), Qt::white);
        painter.drawText(rect, Qt::AlignCenter,
            QString("Assets: %1\nRequested: %2\nWindow: %3\nScreen: %4").arg(
                debugDescription(assetColorSpace)
            ).arg(
                debugDescription(windowColorSpace)
            ).arg(
                debugDescription(windowColorSpace)
            ).arg(
                debugDescription(screenColorSpace)
            ));
    }
};

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    TestWindow defaultColorSpaceWindow;
    defaultColorSpaceWindow.setTitle(QString(
        "Color-space unaware (pass-through, assuming surface/screen is %1)").arg(
        assetColorSpace.description()));
    defaultColorSpaceWindow.show();

    TestWindow colorSpaceAwareWindow;
    colorSpaceAwareWindow.setTitle(QString(
        "Color-space aware (match %1 to surface)").arg(assetColorSpace.description()));
    colorSpaceAwareWindow.colorManaged = true;
    colorSpaceAwareWindow.show();

    TestWindow explicitColorSpaceWindow;
    explicitColorSpaceWindow.setTitle(QString(
        "Explicit %1 surface").arg(assetColorSpace.description()));
    auto format = explicitColorSpaceWindow.format();
    format.setColorSpace(assetColorSpace);
    explicitColorSpaceWindow.setFormat(format);
    explicitColorSpaceWindow.show();

    return app.exec();
}