aboutsummaryrefslogtreecommitdiffstats
path: root/tools/svgtoqml/main.cpp
blob: 64474030dc3bc4a1e70020259bbc402e6b6081c8 (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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QCommandLineParser>
#include <QFile>
#include <QQuickWindow>
#include <QQuickItem>
#include <QtQuickVectorImageGenerator/private/qquickitemgenerator_p.h>
#include <QtQuickVectorImageGenerator/private/qquickqmlgenerator_p.h>
#include <QtQuickVectorImageGenerator/private/qquickvectorimageglobal_p.h>

#define ENABLE_GUI

int main(int argc, char *argv[])
{
#ifdef ENABLE_GUI
    QGuiApplication app(argc, argv);
#else
    QCoreApplication app(argc, argv);
#endif

    QCommandLineParser parser;
    parser.setApplicationDescription("SVG to QML converter [tech preview]");
    parser.addHelpOption();
    parser.addPositionalArgument("input", QCoreApplication::translate("main", "SVG file to read."));
    parser.addPositionalArgument("output", QCoreApplication::translate("main", "QML file to write."));

    QCommandLineOption optimizeOption("optimize-paths",
                                      QCoreApplication::translate("main", "Optimize paths for the curve renderer."));
    parser.addOption(optimizeOption);

    QCommandLineOption curveRendererOption("curve-renderer",
                                           QCoreApplication::translate("main", "Use the curve renderer in generated QML."));
    parser.addOption(curveRendererOption);

    QCommandLineOption typeNameOption(QStringList() << "t" << "type-name",
                                      QCoreApplication::translate("main", "Use <typename> for Shape."),
                                      QCoreApplication::translate("main", "typename"));
    parser.addOption(typeNameOption);

    QCommandLineOption copyrightOption("copyright-statement",
                                       QCoreApplication::translate("main", "Add <string> as a comment at the start of the generated file."),
                                       QCoreApplication::translate("main", "string"));
    parser.addOption(copyrightOption);

    QCommandLineOption outlineModeOption("outline-stroke-mode",
                                         QCoreApplication::translate("main", "Stroke the outline (contour) of the filled shape instead of "
                                                                             "the original path. Also sets optimize-paths."));
    parser.addOption(outlineModeOption);

    QCommandLineOption keepPathsOption("keep-external-paths",
                                       QCoreApplication::translate("main", "Any paths to external files will be retained in the QML output. "
                                                                           "The paths will be reformatted as relative to the output file. If "
                                                                           "this is not enabled, copies of the file will be saved to the asset output "
                                                                           "directory. Embedded data will still be saved to files, even if "
                                                                           "this option is set."));
    parser.addOption(keepPathsOption);

    QCommandLineOption assetOutputDirectoryOption("asset-output-directory",
                                                  QCoreApplication::translate("main", "If the SVG refers to external or embedded files, such as images, these "
                                                                                      "will be copied into the same directory as the output QML file by default. "
                                                                                      "Set the asset output directory to override the location."),
                                                  QCoreApplication::translate("main", "directory"));
    parser.addOption(assetOutputDirectoryOption);

    QCommandLineOption assetOutputPrefixOption("asset-output-prefix",
                                               QCoreApplication::translate("main", "If the SVG refers to external or embedded files, such as images, these "
                                                                                   "will be copied to files with unique identifiers. By default, the files will be prefixed "
                                                                                   "with \"svg_asset_\". Set the asset output prefix to override the prefix."),
                                               QCoreApplication::translate("main", "prefix"));
    parser.addOption(assetOutputPrefixOption);

#ifdef ENABLE_GUI
    QCommandLineOption guiOption(QStringList() << "v" << "view",
                                 QCoreApplication::translate("main", "Display the SVG in a window."));
    parser.addOption(guiOption);
#endif
    parser.process(app);
    const QStringList args = parser.positionalArguments();
    if (args.size() < 1) {
        parser.showHelp(1);
    }

    const QString inFileName = args.at(0);

    QString commentString = QLatin1String("Generated from SVG file %1").arg(inFileName);

    const auto outFileName = args.size() > 1 ? args.at(1) : QString{};
    const auto typeName = parser.value(typeNameOption);
    const auto assetOutputDirectory = parser.value(assetOutputDirectoryOption);
    const auto assetOutputPrefix = parser.value(assetOutputPrefixOption);
    const bool keepPaths = parser.isSet(keepPathsOption);
    auto copyrightString = parser.value(copyrightOption);

    if (!copyrightString.isEmpty()) {
        copyrightString = copyrightString.replace("\\n", "\n");
        commentString = copyrightString + u"\n" + commentString;
    }

    QQuickVectorImageGenerator::GeneratorFlags flags;
    if (parser.isSet(curveRendererOption))
        flags |= QQuickVectorImageGenerator::GeneratorFlag::CurveRenderer;
    if (parser.isSet(optimizeOption))
        flags |= QQuickVectorImageGenerator::GeneratorFlag::OptimizePaths;
    if (parser.isSet(outlineModeOption))
        flags |= (QQuickVectorImageGenerator::GeneratorFlag::OutlineStrokeMode
                  | QQuickVectorImageGenerator::GeneratorFlag::OptimizePaths);

    QQuickQmlGenerator generator(inFileName, flags, outFileName);
    generator.setShapeTypeName(typeName);
    generator.setCommentString(commentString);
    generator.setAssetFileDirectory(assetOutputDirectory);
    generator.setAssetFilePrefix(assetOutputPrefix);
    generator.setRetainFilePaths(keepPaths);
    generator.generate();

#ifdef ENABLE_GUI
    if (parser.isSet(guiOption)) {
        app.setOrganizationName("QtProject");
        const QUrl url(QStringLiteral("qrc:/main.qml"));
        QQmlApplicationEngine engine;
        QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                         &app, [&](QObject *obj, const QUrl &objUrl){
            if (!obj && url == objUrl)
                QCoreApplication::exit(-1);
            if (obj) {
                auto *containerItem = obj->findChild<QQuickItem*>(QStringLiteral("svg_item"));
                QQuickItemGenerator generator(inFileName, flags, containerItem);
                generator.generate();
            }
        });
        engine.load(url);
        return app.exec();
    }
#else
    return 0;
#endif

}