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 }