QtBase  v6.3.1
gradientgen.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2018 The Qt Company Ltd.
4 ** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
5 ** Contact: https://www.qt.io/licensing/
6 **
7 ** This file is part of the utils of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
10 ** Commercial License Usage
11 ** Licensees holding valid commercial Qt licenses may use this file in
12 ** accordance with the commercial license agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and The Qt Company. For licensing terms
15 ** and conditions see https://www.qt.io/terms-conditions. For further
16 ** information use the contact form at https://www.qt.io/contact-us.
17 **
18 ** GNU General Public License Usage
19 ** Alternatively, this file may be used under the terms of the GNU
20 ** General Public License version 3 as published by the Free Software
21 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
22 ** included in the packaging of this file. Please review the following
23 ** information to ensure the GNU General Public License requirements will
24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 **
26 ** $QT_END_LICENSE$
27 **
28 ****************************************************************************/
29 
30 #include <iostream>
31 #include <string>
32 #include <algorithm>
33 
34 #include <QByteArray>
35 #include <QDebug>
36 #include <QJsonDocument>
37 #include <QJsonArray>
38 #include <QJsonObject>
39 #include <QJsonValue>
40 #include <QList>
41 
42 #include <QColor>
43 
44 using namespace std;
45 
46 static const char LICENSE_HEADER[] =
47 R"(/****************************************************************************
48 **
49 ** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
50 ** Contact: https://www.qt.io/licensing/
51 **
52 ** This file is part of the QtGui module of the Qt Toolkit.
53 **
54 ** $QT_BEGIN_LICENSE:LGPL$
55 ** Commercial License Usage
56 ** Licensees holding valid commercial Qt licenses may use this file in
57 ** accordance with the commercial license agreement provided with the
58 ** Software or, alternatively, in accordance with the terms contained in
59 ** a written agreement between you and The Qt Company. For licensing terms
60 ** and conditions see https://www.qt.io/terms-conditions. For further
61 ** information use the contact form at https://www.qt.io/contact-us.
62 **
63 ** GNU Lesser General Public License Usage
64 ** Alternatively, this file may be used under the terms of the GNU Lesser
65 ** General Public License version 3 as published by the Free Software
66 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
67 ** packaging of this file. Please review the following information to
68 ** ensure the GNU Lesser General Public License version 3 requirements
69 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
70 **
71 ** GNU General Public License Usage
72 ** Alternatively, this file may be used under the terms of the GNU
73 ** General Public License version 2.0 or (at your option) the GNU General
74 ** Public license version 3 or any later version approved by the KDE Free
75 ** Qt Foundation. The licenses are as published by the Free Software
76 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
77 ** included in the packaging of this file. Please review the following
78 ** information to ensure the GNU General Public License requirements will
79 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
80 ** https://www.gnu.org/licenses/gpl-3.0.html.
81 **
82 ** $QT_END_LICENSE$
83 **
84 ****************************************************************************/)";
85 
86 class Printer {
88 public:
89  Printer() = default;
90 
91  class Indenter
92  {
94  Printer &p;
95  public:
96  Indenter(Printer &p) : p(p) { p.indent(); }
97  ~Indenter() { p.deindent(); }
98  };
99 
101  {
102  cout << flush;
103  }
104 
105  void printLine(const QString &str) const
106  {
107  printLine(qPrintable(str));
108  }
109 
110  void printLine(const char *str = nullptr) const
111  {
112  if (str)
113  cout << m_indentString << str << '\n';
114  else
115  cout << '\n';
116  }
117 
118  void indent()
119  {
120  m_indent += 4;
121  m_indentString = std::string(m_indent, ' ');
122  }
123 
124  void deindent()
125  {
126  m_indent -= 4;
127  m_indentString = std::string(m_indent, ' ');
128  }
129 
130 private:
131  int m_indent = 0;
132  std::string m_indentString;
133 };
134 
135 // like QGradientStop, but with a plain int as second field
137 {
138  double position;
139  int color;
140 
142  {
143  return s1.position < s2.position;
144  }
145 };
146 
147 static void printGradientStops(Printer &p, const QJsonArray &presets)
148 {
149  const QString presetCaseString("case QGradient::%1:");
150  const QString presetStopColorString("QColor(%1, %2, %3, %4)");
151  const QString presetStopString("QGradientStop(%1, %2), ");
152 
153  const auto presetStopToGradientStop = [](const QJsonValue &presetStop)
154  {
155  const double position = presetStop[QLatin1String("position")].toDouble();
156  const int color = presetStop[QLatin1String("color")].toInt();
157 
158  return GradientStop{position, color};
159  };
160 
161  for (const QJsonValue &presetValue : presets) {
162  if (!presetValue.isObject())
163  continue;
164 
165  QJsonObject preset = presetValue.toObject();
166 
167  // print the case label
168  const QString presetName = preset[QLatin1String("name")].toString();
169  p.printLine(presetCaseString.arg(presetName));
170 
172 
173  // convert the json array of stops to QGradientStop objects
174  const QJsonArray stops = preset[QLatin1String("stops")].toArray();
175  Q_ASSERT(!stops.isEmpty());
176 
177  QList<GradientStop> gradientStops;
178  gradientStops.reserve(stops.size());
179  std::transform(stops.cbegin(),
180  stops.cend(),
181  std::back_inserter(gradientStops),
182  presetStopToGradientStop);
183 
184  // stops should be sorted, but just in case...
185  std::sort(gradientStops.begin(), gradientStops.end(),
187 
188  Q_ASSERT(gradientStops.size() == stops.size());
189 
190  // convert to strings
191  QString result;
192  result.reserve(result.size() + gradientStops.size() * (presetStopString.size() + 20));
193  result += "return Q_ARRAY_LITERAL(QGradientStop, ";
194 
195  for (const GradientStop &stop : qAsConst(gradientStops)) {
196  // gradientgen.js does not output the alpha channel, so hardcode full alpha here
197  Q_ASSERT(qAlpha(stop.color) == 0);
198 
199  const QString colorString = presetStopColorString
200  .arg(qRed(stop.color))
201  .arg(qGreen(stop.color))
202  .arg(qBlue(stop.color))
203  .arg(255);
204  result += presetStopString.arg(stop.position).arg(colorString);
205  }
206 
207  result.chop(2);
208  result += ");";
209  p.printLine(result);
210  }
211 
212  // Add an entry for NumPresets, to silence warnings about switches over enumerations
213  p.printLine(presetCaseString.arg("NumPresets"));
214  {
216  p.printLine("Q_UNREACHABLE();");
217  }
218 }
219 
220 static void printGradientData(Printer &p, const QJsonArray &presets)
221 {
222  const QString formatString("{ { %1, %2, %3, %4 } },");
223 
224  for (const QJsonValue &presetValue : presets) {
225  if (!presetValue.isObject()) {
226  p.printLine("{ { 0, 0, 0, 0 } },");
227  } else {
228  QJsonObject preset = presetValue.toObject();
229  const QJsonValue start = preset[QLatin1String("start")];
230  const QJsonValue end = preset[QLatin1String("end")];
231 
232  p.printLine(formatString
233  .arg(start[QLatin1String("x")].toDouble())
234  .arg(start[QLatin1String("y")].toDouble())
235  .arg(end[QLatin1String("x")].toDouble())
236  .arg(end[QLatin1String("y")].toDouble()));
237  }
238  }
239 }
240 
241 int main()
242 {
243  QByteArray json;
244  while (!cin.eof()) {
245  char arr[1024];
246  cin.read(arr, sizeof(arr));
247  json.append(arr, cin.gcount());
248  }
249 
251  QJsonDocument jsonDocument = QJsonDocument::fromJson(json, &error);
252  if (jsonDocument.isNull())
253  qFatal("Error: %s at offset %d", qPrintable(error.errorString()), error.offset);
254 
255  if (!jsonDocument.isArray())
256  qFatal("Error: expected a document with a JSON array");
257 
258  QJsonArray presets = jsonDocument.array();
259 
260  Printer p;
261 
262  p.printLine(LICENSE_HEADER);
263  p.printLine();
264  p.printLine("// This file is auto-generated by gradientgen. DO NOT EDIT!");
265  p.printLine();
266 
267  p.printLine("static QList<QGradientStop> qt_preset_gradient_stops(QGradient::Preset preset)");
268  p.printLine("{");
269  {
271  p.printLine("Q_ASSERT(preset < QGradient::NumPresets);");
272  p.printLine("switch (preset) {");
273  printGradientStops(p, presets);
274  p.printLine("}");
275  p.printLine("Q_UNREACHABLE();");
276  p.printLine("return {};");
277  }
278  p.printLine("}");
279  p.printLine();
280 
281  p.printLine("static constexpr QGradient::QGradientData qt_preset_gradient_data[] = {");
282  {
284  printGradientData(p, presets);
285  }
286  p.printLine("};");
287  p.printLine();
288 
289  p.printLine("static void *qt_preset_gradient_dummy()");
290  p.printLine("{");
291  {
293  p.printLine("union {void *p; uint i;};");
294  p.printLine("p = 0;");
295  p.printLine("i |= uint(QGradient::ObjectMode);");
296  p.printLine("return p;");
297  }
298  p.printLine("}");
299 }
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
FT_Error error
Definition: cffdrivr.c:657
Indenter(Printer &p)
Definition: gradientgen.cpp:96
Printer()=default
void printLine(const char *str=nullptr) const
void indent()
void deindent()
void printLine(const QString &str) const
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:85
QByteArray & append(char c)
The QJsonArray class encapsulates a JSON array.
Definition: qjsonarray.h:54
bool isEmpty() const
Definition: qjsonarray.cpp:306
const_iterator cend() const
Definition: qjsonarray.h:230
qsizetype size() const
Definition: qjsonarray.cpp:288
const_iterator cbegin() const
Definition: qjsonarray.h:226
The QJsonDocument class provides a way to read and write JSON documents.
Definition: qjsondocument.h:83
bool isArray() const
bool isNull() const
QJsonArray array() const
static QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error=nullptr)
The QJsonObject class encapsulates a JSON object.
Definition: qjsonobject.h:56
The QJsonValue class encapsulates a value in JSON.
Definition: qjsonvalue.h:60
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal.
Definition: qstring.h:84
Definition: qlist.h:108
qsizetype size() const noexcept
Definition: qlist.h:414
iterator end()
Definition: qlist.h:624
iterator begin()
Definition: qlist.h:623
void reserve(qsizetype size)
Definition: qlist.h:757
The QString class provides a Unicode character string.
Definition: qstring.h:388
void chop(qsizetype n)
Definition: qstring.cpp:5955
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=QLatin1Char(' ')) const
Definition: qstring.cpp:8318
QString str
[2]
int flush
Definition: zlib.h:309
int main()
std::ostream & cout()
QHighDpiScaling::Point position(T, QHighDpiScaling::Point::Kind)
char * formatString(const char *prefix, const char *suffix, size_t numArguments,...)
Definition: qtestcase.cpp:1370
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION ParsedNumber< double > toDouble(QByteArrayView a) noexcept
Definition: qfloat16.h:381
#define Q_DISABLE_COPY_MOVE(Class)
Definition: qglobal.h:519
#define qFatal
Definition: qlogging.h:181
GLuint GLuint end
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
GLuint color
[2]
GLuint start
GLuint GLenum GLenum transform
Definition: qopenglext.h:11564
GLuint64EXT * result
[6]
Definition: qopenglext.h:10932
GLfloat GLfloat p
[1]
Definition: qopenglext.h:12698
GLsizei const GLchar *const * string
[0]
Definition: qopenglext.h:694
#define Q_ASSERT(cond)
Definition: qrandom.cpp:84
constexpr int qRed(QRgb rgb)
Definition: qrgb.h:54
constexpr int qGreen(QRgb rgb)
Definition: qrgb.h:57
constexpr int qBlue(QRgb rgb)
Definition: qrgb.h:60
constexpr int qAlpha(QRgb rgb)
Definition: qrgb.h:63
SSL_CTX int(*) void arg)
#define s2
static bool sortByPosition(GradientStop s1, GradientStop s2)
The QJsonParseError class is used to report errors during JSON parsing.
Definition: qjsondocument.h:56