diff options
author | Liang Qi <liang.qi@qt.io> | 2020-01-04 15:32:34 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2020-01-04 15:32:34 +0100 |
commit | a503bf54705d89204007e8f887b668fe5ef519fc (patch) | |
tree | b2d1a452da39450eac78a1aeb1df116a73f64b23 /util/gradientgen/gradientgen.cpp | |
parent | e65c43fd0ffa57248e7d750570b7deae171a82f5 (diff) | |
parent | 1f87fb359fdff14e42662384a9c8a0bcb3837671 (diff) |
Merge remote-tracking branch 'origin/5.15' into dev
Conflicts:
src/corelib/tools/qvector.h
Make QVector(DataPointer dd) public to be able to properly merge
5b4b437b30b320e2cd7c9a566999a39772e5d431 from 5.15 into dev.
src/widgets/kernel/qapplication.cpp
tests/auto/tools/moc/allmocs_baseline_in.json
Done-With: Christian Ehrlicher <ch.ehrlicher@gmx.de>
Change-Id: I929ba7c036d570382d0454c2c75f6f0d96ddbc01
Diffstat (limited to 'util/gradientgen/gradientgen.cpp')
-rw-r--r-- | util/gradientgen/gradientgen.cpp | 299 |
1 files changed, 299 insertions, 0 deletions
diff --git a/util/gradientgen/gradientgen.cpp b/util/gradientgen/gradientgen.cpp new file mode 100644 index 0000000000..5dc0b53b9d --- /dev/null +++ b/util/gradientgen/gradientgen.cpp @@ -0,0 +1,299 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the utils of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <iostream> +#include <string> +#include <algorithm> + +#include <QByteArray> +#include <QVector> +#include <QJsonDocument> +#include <QJsonArray> +#include <QJsonObject> +#include <QJsonValue> +#include <QDebug> + +#include <QColor> + +using namespace std; + +static const char LICENSE_HEADER[] = +R"(/**************************************************************************** +** +** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/)"; + +class Printer { + Q_DISABLE_COPY_MOVE(Printer) +public: + Printer() = default; + + class Indenter + { + Q_DISABLE_COPY_MOVE(Indenter) + Printer &p; + public: + Indenter(Printer &p) : p(p) { p.indent(); } + ~Indenter() { p.deindent(); } + }; + + ~Printer() + { + cout << flush; + } + + void printLine(const QString &str) const + { + printLine(qPrintable(str)); + } + + void printLine(const char *str = nullptr) const + { + if (str) + cout << m_indentString << str << '\n'; + else + cout << '\n'; + } + + void indent() + { + m_indent += 4; + m_indentString = std::string(m_indent, ' '); + } + + void deindent() + { + m_indent -= 4; + m_indentString = std::string(m_indent, ' '); + } + +private: + int m_indent = 0; + std::string m_indentString; +}; + +// like QGradientStop, but with a plain int as second field +struct GradientStop +{ + double position; + int color; + + static bool sortByPosition(GradientStop s1, GradientStop s2) + { + return s1.position < s2.position; + } +}; + +static void printGradientStops(Printer &p, const QJsonArray &presets) +{ + const QString presetCaseString("case QGradient::%1:"); + const QString presetStopColorString("QColor(%1, %2, %3, %4)"); + const QString presetStopString("QGradientStop(%1, %2), "); + + const auto presetStopToGradientStop = [](const QJsonValue &presetStop) + { + const double position = presetStop[QLatin1String("position")].toDouble(); + const int color = presetStop[QLatin1String("color")].toInt(); + + return GradientStop{position, color}; + }; + + for (const QJsonValue &presetValue : presets) { + if (!presetValue.isObject()) + continue; + + QJsonObject preset = presetValue.toObject(); + + // print the case label + const QString presetName = preset[QLatin1String("name")].toString(); + p.printLine(presetCaseString.arg(presetName)); + + Printer::Indenter i(p); + + // convert the json array of stops to QGradientStop objects + const QJsonArray stops = preset[QLatin1String("stops")].toArray(); + Q_ASSERT(!stops.isEmpty()); + + QVector<GradientStop> gradientStops; + gradientStops.reserve(stops.size()); + std::transform(stops.cbegin(), + stops.cend(), + std::back_inserter(gradientStops), + presetStopToGradientStop); + + // stops should be sorted, but just in case... + std::sort(gradientStops.begin(), gradientStops.end(), + &GradientStop::sortByPosition); + + Q_ASSERT(gradientStops.size() == stops.size()); + + // convert to strings + QString result; + result.reserve(result.size() + gradientStops.size() * (presetStopString.size() + 20)); + result += "return Q_ARRAY_LITERAL(QGradientStop, "; + + for (const GradientStop &stop : qAsConst(gradientStops)) { + // gradientgen.js does not output the alpha channel, so hardcode full alpha here + Q_ASSERT(qAlpha(stop.color) == 0); + + const QString colorString = presetStopColorString + .arg(qRed(stop.color)) + .arg(qGreen(stop.color)) + .arg(qBlue(stop.color)) + .arg(255); + result += presetStopString.arg(stop.position).arg(colorString); + } + + result.chop(2); + result += ");"; + p.printLine(result); + } + + // Add an entry for NumPresets, to silence warnings about switches over enumerations + p.printLine(presetCaseString.arg("NumPresets")); + { + Printer::Indenter i(p); + p.printLine("Q_UNREACHABLE();"); + } +} + +static void printGradientData(Printer &p, const QJsonArray &presets) +{ + const QString formatString("{ { %1, %2, %3, %4 } },"); + + for (const QJsonValue &presetValue : presets) { + if (!presetValue.isObject()) { + p.printLine("{ { 0, 0, 0, 0 } },"); + } else { + QJsonObject preset = presetValue.toObject(); + const QJsonValue start = preset[QLatin1String("start")]; + const QJsonValue end = preset[QLatin1String("end")]; + + p.printLine(formatString + .arg(start[QLatin1String("x")].toDouble()) + .arg(start[QLatin1String("y")].toDouble()) + .arg(end[QLatin1String("x")].toDouble()) + .arg(end[QLatin1String("y")].toDouble())); + } + } +} + +int main() +{ + QByteArray json; + while (!cin.eof()) { + char arr[1024]; + cin.read(arr, sizeof(arr)); + json.append(arr, cin.gcount()); + } + + QJsonParseError error; + QJsonDocument jsonDocument = QJsonDocument::fromJson(json, &error); + if (jsonDocument.isNull()) + qFatal("Error: %s at offset %d", qPrintable(error.errorString()), error.offset); + + if (!jsonDocument.isArray()) + qFatal("Error: expected a document with a JSON array"); + + QJsonArray presets = jsonDocument.array(); + + Printer p; + + p.printLine(LICENSE_HEADER); + p.printLine(); + p.printLine("// This file is auto-generated by gradientgen. DO NOT EDIT!"); + p.printLine(); + + p.printLine("static QArrayDataPointerRef<QGradientStop> qt_preset_gradient_stops(QGradient::Preset preset)"); + p.printLine("{"); + { + Printer::Indenter i(p); + p.printLine("Q_ASSERT(preset < QGradient::NumPresets);"); + p.printLine("switch (preset) {"); + printGradientStops(p, presets); + p.printLine("}"); + p.printLine("Q_UNREACHABLE();"); + p.printLine("return {};"); + } + p.printLine("}"); + p.printLine(); + + p.printLine("static Q_CONSTEXPR QGradient::QGradientData qt_preset_gradient_data[] = {"); + { + Printer::Indenter i(p); + printGradientData(p, presets); + } + p.printLine("};"); + p.printLine(); + + p.printLine("static void *qt_preset_gradient_dummy()"); + p.printLine("{"); + { + Printer::Indenter i(p); + p.printLine("union {void *p; uint i;};"); + p.printLine("p = 0;"); + p.printLine("i |= uint(QGradient::ObjectMode);"); + p.printLine("return p;"); + } + p.printLine("}"); +} |