File indexing completed on 2025-02-02 04:14:51

0001 /* This file is part of the KDE project
0002 
0003    SPDX-FileCopyrightText: 2017 L. E. Segovia <amy@amyspark.me>
0004 
0005 
0006    SPDX-License-Identifier: LGPL-2.1-or-later
0007  */
0008 #include <resources/KoSvgSymbolCollectionResource.h>
0009 
0010 #include <QDebug>
0011 #include <QVector>
0012 #include <QFile>
0013 #include <QFileInfo>
0014 #include <QBuffer>
0015 #include <QByteArray>
0016 #include <QImage>
0017 #include <QPainter>
0018 
0019 #include <klocalizedstring.h>
0020 #include <KoMarker.h>
0021 #include <KoStore.h>
0022 #include <KoDocumentResourceManager.h>
0023 #include "kis_debug.h"
0024 
0025 #include <KoShape.h>
0026 #include <KoShapeGroup.h>
0027 #include <KoShapeManager.h>
0028 #include <SvgParser.h>
0029 #include <KoMD5Generator.h>
0030 
0031 #include <FlakeDebug.h>
0032 
0033 QImage KoSvgSymbol::icon()
0034 {
0035     KoShapeGroup *group = dynamic_cast<KoShapeGroup*>(shape);
0036     KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(group, QImage());
0037 
0038     QRectF rc = group->boundingRect().normalized();
0039 
0040     QImage image(rc.width(), rc.height(), QImage::Format_ARGB32_Premultiplied);
0041     QPainter gc(&image);
0042     image.fill(Qt::gray);
0043 
0044 //        debugFlake << "Going to render. Original bounding rect:" << group->boundingRect()
0045 //                 << "Normalized: " << rc
0046 //                 << "Scale W" << 256 / rc.width() << "Scale H" << 256 / rc.height();
0047 
0048     gc.translate(-rc.x(), -rc.y());
0049     KoShapeManager::renderSingleShape(group, gc);
0050     gc.end();
0051     image = image.scaled(128, 128, Qt::KeepAspectRatio);
0052     return image;
0053 }
0054 
0055 
0056 
0057 struct KoSvgSymbolCollectionResource::Private {
0058     QVector<KoSvgSymbol*> symbols;
0059     QString title;
0060     QString description;
0061     QByteArray data;
0062 };
0063 
0064 
0065 KoSvgSymbolCollectionResource::KoSvgSymbolCollectionResource(const QString& filename)
0066     : KoResource(filename)
0067     , d(new Private())
0068 {
0069 }
0070 
0071 KoSvgSymbolCollectionResource::KoSvgSymbolCollectionResource()
0072     : KoResource(QString())
0073     , d(new Private())
0074 {
0075 }
0076 
0077 KoSvgSymbolCollectionResource::KoSvgSymbolCollectionResource(const KoSvgSymbolCollectionResource& rhs)
0078     : KoResource(QString())
0079     , d(new Private(*rhs.d))
0080 {
0081     setFilename(rhs.filename());
0082 
0083     Q_FOREACH(KoSvgSymbol *symbol, rhs.d->symbols) {
0084         d->symbols << new KoSvgSymbol(*symbol);
0085     }
0086 
0087     setValid(true);
0088 }
0089 
0090 KoResourceSP KoSvgSymbolCollectionResource::clone() const
0091 {
0092     return KoResourceSP(new KoSvgSymbolCollectionResource(*this));
0093 }
0094 
0095 KoSvgSymbolCollectionResource::~KoSvgSymbolCollectionResource()
0096 {
0097     qDeleteAll(d->symbols);
0098 }
0099 
0100 bool KoSvgSymbolCollectionResource::loadFromDevice(QIODevice *dev, KisResourcesInterfaceSP resourcesInterface)
0101 {
0102     Q_UNUSED(resourcesInterface);
0103 
0104     if (!dev->isOpen()) {
0105         dev->open(QIODevice::ReadOnly);
0106     }
0107 
0108     d->data = dev->readAll();
0109     setMD5Sum(KoMD5Generator::generateHash(d->data));
0110 
0111     dev->seek(0);
0112 
0113     QString errorMsg;
0114     int errorLine = 0;
0115     int errorColumn;
0116 
0117     QDomDocument doc = SvgParser::createDocumentFromSvg(dev, &errorMsg, &errorLine, &errorColumn);
0118     if (doc.isNull()) {
0119 
0120         errKrita << "Parsing error in " << filename() << "! Aborting!" << endl
0121         << " In line: " << errorLine << ", column: " << errorColumn << endl
0122         << " Error message: " << errorMsg << endl;
0123         errKrita << i18n("Parsing error in the main document at line %1, column %2\nError message: %3"
0124                          , errorLine , errorColumn , errorMsg);
0125         return false;
0126     }
0127 
0128     KoDocumentResourceManager manager;
0129     SvgParser parser(&manager);
0130     parser.setResolution(QRectF(0,0,100,100), 72); // initialize with default values
0131     QSizeF fragmentSize;
0132     // We're not interested in the shapes themselves
0133     qDeleteAll(parser.parseSvg(doc.documentElement(), &fragmentSize));
0134     d->symbols = parser.takeSymbols();
0135 //    debugFlake << "Loaded" << filename() << "\n\t"
0136 //             << "Title" << parser.documentTitle() << "\n\t"
0137 //             << "Description" << parser.documentDescription()
0138 //             << "\n\tgot" << d->symbols.size() << ResourceType::Symbols
0139 //             << d->symbols[0]->shape->outlineRect()
0140 //             << d->symbols[0]->shape->size();
0141 
0142     d->title = parser.documentTitle();
0143     if (d->title.isEmpty()) {
0144         d->title = filename();
0145     }
0146     setName(d->title);
0147     d->description = parser.documentDescription();
0148 
0149     if (d->symbols.size() < 1) {
0150         setValid(false);
0151         return false;
0152     }
0153     setValid(true);
0154     setImage(d->symbols[0]->icon());
0155     return true;
0156 }
0157 
0158 bool KoSvgSymbolCollectionResource::saveToDevice(QIODevice *dev) const
0159 {
0160     dev->open(QIODevice::WriteOnly);
0161     dev->write(d->data);
0162     dev->close();
0163     return true;
0164 }
0165 
0166 QString KoSvgSymbolCollectionResource::defaultFileExtension() const
0167 {
0168     return QString(".svg");
0169 }
0170 
0171 QString KoSvgSymbolCollectionResource::title() const
0172 {
0173     return d->title;
0174 }
0175 
0176 QString KoSvgSymbolCollectionResource::description() const
0177 {
0178     return d->description;
0179 }
0180 
0181 QString KoSvgSymbolCollectionResource::creator() const
0182 {
0183     return "";
0184 }
0185 
0186 QString KoSvgSymbolCollectionResource::rights() const
0187 {
0188     return "";
0189 }
0190 
0191 QString KoSvgSymbolCollectionResource::language() const
0192 {
0193     return "";
0194 }
0195 
0196 QStringList KoSvgSymbolCollectionResource::subjects() const
0197 {
0198     return QStringList();
0199 }
0200 
0201 QString KoSvgSymbolCollectionResource::license() const
0202 {
0203     return "";
0204 }
0205 
0206 QStringList KoSvgSymbolCollectionResource::permits() const
0207 {
0208     return QStringList();
0209 }
0210 
0211 QVector<KoSvgSymbol *> KoSvgSymbolCollectionResource::symbols() const
0212 {
0213     return d->symbols;
0214 }