summaryrefslogtreecommitdiffstats
path: root/util
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@qt.io>2018-05-25 17:12:07 +0200
committerEdward Welbourne <edward.welbourne@qt.io>2018-05-31 15:50:50 +0000
commitc4a21708ed186640f4db381dc800febdbc85941e (patch)
tree72c5414f12b15d6b5e932666a6f4bb72f0ba2bfa /util
parentc538a333db4b7526fb4d9a82c06296d2492bf000 (diff)
Provide presets for QGradient
Similar to Qt::GlobalColor, the presets allow the user to create brushes based on predefined gradients, quickly getting pretty pixels on screen. The presets are based on the linear gradients from WebGradients, a free collection of gradients, hosted at https://webgradients.com/. The few radial and blended gradient presets have been excluded. Change-Id: I1ce8f2210a6045c9edb8829ab3eddcc313549127 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Diffstat (limited to 'util')
-rw-r--r--util/gradientgen/.gitignore2
-rwxr-xr-xutil/gradientgen/gradientgen.js123
-rw-r--r--util/gradientgen/package-lock.json183
-rw-r--r--util/gradientgen/package.json13
-rw-r--r--util/gradientgen/tobinaryjson.cpp54
-rw-r--r--util/gradientgen/tobinaryjson.pro4
6 files changed, 379 insertions, 0 deletions
diff --git a/util/gradientgen/.gitignore b/util/gradientgen/.gitignore
new file mode 100644
index 0000000000..1a8e824bee
--- /dev/null
+++ b/util/gradientgen/.gitignore
@@ -0,0 +1,2 @@
+node_modules
+tobinaryjson
diff --git a/util/gradientgen/gradientgen.js b/util/gradientgen/gradientgen.js
new file mode 100755
index 0000000000..ff256d16d6
--- /dev/null
+++ b/util/gradientgen/gradientgen.js
@@ -0,0 +1,123 @@
+#! /usr/bin/env node
+
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** 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$
+**
+****************************************************************************/
+
+const _ = require('lodash');
+const fs = require('fs');
+
+const postcss = require('postcss');
+const minifyGradients = require('postcss-minify-gradients');
+const valueParser = require('postcss-value-parser');
+const parseColor = require('parse-color');
+const math = require('mathjs');
+
+const argc = process.argv.length;
+if (argc < 3) {
+ console.log("usage: gradientgen [mode] <filename>");
+ process.exit(1);
+}
+
+const filename = process.argv[argc - 1];
+const mode = argc > 3 ? process.argv[argc - 2] : '';
+
+fs.readFile(filename, (err, css) => {
+ postcss([minifyGradients]).process(css)
+ .then(result => {
+ let enums = [];
+ let gradients = [];
+
+ result.root.walkRules(rule => {
+ gradients.push(null); // Placeholder
+
+ const name = _.startCase(rule.selector).replace(/\s/g, '');
+ if (enums.indexOf(name) >= 0)
+ return; // Duplicate entry
+
+ // We can only support single gradient declarations
+ if (rule.nodes.length > 1)
+ return;
+
+ valueParser(rule.nodes[0].value).walk(node => {
+ if (node.type !== 'function')
+ return;
+
+ if (node.value !== 'linear-gradient')
+ return;
+
+ const args = node.nodes.reduce((args, arg) => {
+ if (arg.type === 'div')
+ args.push([]);
+ else if (arg.type !== 'space')
+ args[args.length - 1].push(arg.value);
+ return args;
+ }, [[]]);
+
+ let angle = valueParser.unit(args[0][0]);
+ if (angle.unit !== 'deg')
+ return;
+
+ angle = parseInt(angle.number);
+ if (angle < 0)
+ angle += 360;
+
+ // Angle is in degrees, but we need radians
+ const radians = angle * math.pi / 180;
+
+ const gradientLine = (math.abs(math.sin(radians)) + math.abs(math.cos(radians)));
+ const cathetus = fn => math.round(fn(radians - math.pi / 2) * gradientLine / 2, 10);
+
+ const x = cathetus(math.cos);
+ const y = cathetus(math.sin);
+
+ const start = { x: 0.5 - x, y: 0.5 - y };
+ const end = { x: 0.5 + x, y: 0.5 + y };
+
+ let stops = []
+ args.slice(1).forEach((arg, index) => {
+ let [color, stop = !index ? '0%' : '100%'] = arg;
+ stop = parseInt(stop) / 100;
+ color = parseColor(color).hex;
+ color = parseInt(color.slice(1), 16)
+ stops.push({ color, stop })
+ });
+
+ gradients[gradients.length - 1] = { start, end, stops };
+ });
+
+ enums.push(name);
+
+ if (mode == 'enums')
+ console.log(`${name} = ${gradients.length},`)
+ });
+
+ // Done walking declarations
+ if (mode != 'enums')
+ console.log(JSON.stringify(gradients, undefined, 4));
+ });
+});
diff --git a/util/gradientgen/package-lock.json b/util/gradientgen/package-lock.json
new file mode 100644
index 0000000000..77939b7fe3
--- /dev/null
+++ b/util/gradientgen/package-lock.json
@@ -0,0 +1,183 @@
+{
+ "name": "gradientgen",
+ "version": "0.0.1",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
+ },
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "requires": {
+ "ansi-styles": "2.2.1",
+ "escape-string-regexp": "1.0.5",
+ "has-ansi": "2.0.0",
+ "strip-ansi": "3.0.1",
+ "supports-color": "2.0.0"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
+ }
+ }
+ },
+ "complex.js": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.0.4.tgz",
+ "integrity": "sha512-Syl95HpxUTS0QjwNxencZsKukgh1zdS9uXeXX2Us0pHaqBR6kiZZi0AkZ9VpZFwHJyVIUVzI4EumjWdXP3fy6w=="
+ },
+ "decimal.js": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-9.0.1.tgz",
+ "integrity": "sha512-2h0iKbJwnImBk4TGk7CG1xadoA0g3LDPlQhQzbZ221zvG0p2YVUedbKIPsOZXKZGx6YmZMJKYOalpCMxSdDqTQ=="
+ },
+ "escape-latex": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-latex/-/escape-latex-1.0.3.tgz",
+ "integrity": "sha512-GfKaG/7FOKdIdciylIzgaShBTPjdGQ5LJ2EcKLKXPLpcMO1MvCEVotkhydEShwCINRacZr2r3fk5A1PwZ4e5sA=="
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
+ },
+ "fraction.js": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.0.4.tgz",
+ "integrity": "sha512-aK/oGatyYLTtXRHjfEsytX5fieeR5H4s8sLorzcT12taFS+dbMZejnvm9gRa8mZAPwci24ucjq9epDyaq5u8Iw=="
+ },
+ "has-ansi": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+ "requires": {
+ "ansi-regex": "2.1.1"
+ }
+ },
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
+ },
+ "javascript-natural-sort": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz",
+ "integrity": "sha1-+eIwPUUH9tdDVac2ZNFED7Wg71k="
+ },
+ "js-base64": {
+ "version": "2.4.3",
+ "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.3.tgz",
+ "integrity": "sha512-H7ErYLM34CvDMto3GbD6xD0JLUGYXR3QTcH6B/tr4Hi/QpSThnCsIp+Sy5FRTw3B0d6py4HcNkW7nO/wdtGWEw=="
+ },
+ "lodash": {
+ "version": "4.17.10",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
+ "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg=="
+ },
+ "mathjs": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-4.2.2.tgz",
+ "integrity": "sha512-AKrRfTeGrCBqYN1TYEpLIwrfZh9rKu9lH4n7K0MwTiYqN5crJ7BKh/TnErFvbUmyRVQDv87UjSfNTqeO0JA0JQ==",
+ "requires": {
+ "complex.js": "2.0.4",
+ "decimal.js": "9.0.1",
+ "escape-latex": "1.0.3",
+ "fraction.js": "4.0.4",
+ "javascript-natural-sort": "0.7.1",
+ "seed-random": "2.2.0",
+ "tiny-emitter": "2.0.2",
+ "typed-function": "1.0.3"
+ }
+ },
+ "parse-color": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/parse-color/-/parse-color-1.0.0.tgz",
+ "integrity": "sha1-e3SLlag/A/FqlPU15S1/PZRlhhk=",
+ "requires": {
+ "color-convert": "0.5.3"
+ },
+ "dependencies": {
+ "color-convert": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz",
+ "integrity": "sha1-vbbGnOZg+t/+CwAHzER+G59ygr0="
+ }
+ }
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "requires": {
+ "chalk": "1.1.3",
+ "js-base64": "2.4.3",
+ "source-map": "0.5.7",
+ "supports-color": "3.2.3"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ }
+ }
+ },
+ "postcss-minify-gradients": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz",
+ "integrity": "sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=",
+ "requires": {
+ "postcss": "5.2.18",
+ "postcss-value-parser": "3.3.0"
+ }
+ },
+ "postcss-value-parser": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz",
+ "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU="
+ },
+ "seed-random": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/seed-random/-/seed-random-2.2.0.tgz",
+ "integrity": "sha1-KpsZ4lCoFwmSMaW5mk2vgLf77VQ="
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "requires": {
+ "ansi-regex": "2.1.1"
+ }
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ },
+ "tiny-emitter": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.0.2.tgz",
+ "integrity": "sha512-2NM0auVBGft5tee/OxP4PI3d8WItkDM+fPnaRAVo6xTDI2knbz9eC5ArWGqtGlYqiH3RU5yMpdyTTO7MguC4ow=="
+ },
+ "typed-function": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-1.0.3.tgz",
+ "integrity": "sha512-sVC/1pm70oELDFMdYtFXMFqyawenLoaDiAXA3QvOAwKF/WvFNTSJN23cY2lFNL8iP0kh3T0PPKewrboO8XUVGQ=="
+ }
+ }
+}
diff --git a/util/gradientgen/package.json b/util/gradientgen/package.json
new file mode 100644
index 0000000000..35c324b8cc
--- /dev/null
+++ b/util/gradientgen/package.json
@@ -0,0 +1,13 @@
+{
+ "name": "gradientgen",
+ "version": "0.0.1",
+ "description": "Generates gradient presets for QGradient",
+ "main": "gradientgen.js",
+ "dependencies": {
+ "lodash": "^4.17.10",
+ "mathjs": "^4.2.2",
+ "parse-color": "^1.0.0",
+ "postcss-minify-gradients": "^1.0.5",
+ "postcss-value-parser": "^3.3.0"
+ }
+}
diff --git a/util/gradientgen/tobinaryjson.cpp b/util/gradientgen/tobinaryjson.cpp
new file mode 100644
index 0000000000..65fe07f4b8
--- /dev/null
+++ b/util/gradientgen/tobinaryjson.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** 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 <qdebug.h>
+#include <qjsondocument.h>
+
+using namespace std;
+
+int main()
+{
+ QByteArray json;
+ while (!cin.eof()) {
+ char arr[1024];
+ cin.read(arr, sizeof(arr));
+ json.append(arr, cin.gcount());
+ }
+
+ QJsonParseError error;
+ QJsonDocument document = QJsonDocument::fromJson(json, &error);
+ if (document.isNull()) {
+ qDebug() << "error:" << qPrintable(error.errorString()) << "at offset" << error.offset;
+ return 1;
+ }
+
+ QByteArray binaryJson = document.toBinaryData();
+ cout.write(binaryJson.constData(), binaryJson.size());
+}
diff --git a/util/gradientgen/tobinaryjson.pro b/util/gradientgen/tobinaryjson.pro
new file mode 100644
index 0000000000..8ed3509278
--- /dev/null
+++ b/util/gradientgen/tobinaryjson.pro
@@ -0,0 +1,4 @@
+SOURCES += tobinaryjson.cpp
+QT = core
+CONFIG += console
+CONFIG -= app_bundle