[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [krita/kazakov/svg-loading] /: Implement saving of raster image shapes
From:       Dmitry Kazakov <dimula73 () gmail ! com>
Date:       2016-12-01 16:44:25
Message-ID: E1cCUTB-0003HN-D6 () code ! kde ! org
[Download RAW message or body]

Git commit c8bef112bd0cfbf226cafaa7b1ee7d2bad1c04bc by Dmitry Kazakov.
Committed on 01/12/2016 at 15:30.
Pushed by dkazakov into branch 'kazakov/svg-loading'.

Implement saving of raster image shapes

1) Implement saving of images as embedded in base64
2) Implement loading of base64-embedded images

M  +41   -1    libs/flake/svg/SvgUtil.cpp
M  +4    -1    libs/flake/svg/SvgUtil.h
M  +43   -4    plugins/flake/imageshape/ImageShape.cpp

https://commits.kde.org/krita/c8bef112bd0cfbf226cafaa7b1ee7d2bad1c04bc

diff --git a/libs/flake/svg/SvgUtil.cpp b/libs/flake/svg/SvgUtil.cpp
index d1cb38a..7c0098c 100644
--- a/libs/flake/svg/SvgUtil.cpp
+++ b/libs/flake/svg/SvgUtil.cpp
@@ -382,12 +382,52 @@ QPointF \
                SvgUtil::PreserveAspectRatioParser::rectAnchorPoint(const QRectF &rc) \
                co
                    alignedValue(rc.y(), rc.y() + rc.height(), yAlignment));
 }
 
-SvgUtil::PreserveAspectRatioParser::Alignment \
SvgUtil::PreserveAspectRatioParser::alignmentFromString(const QString &str) { \
+QString SvgUtil::PreserveAspectRatioParser::toString() const +{
+    QString result;
+
+    if (!defer &&
+        xAlignment == Middle &&
+        yAlignment == Middle &&
+        mode == Qt::KeepAspectRatio) {
+
+        return result;
+    }
+
+    if (defer) {
+        result += "defer ";
+    }
+
+    if (mode == Qt::IgnoreAspectRatio) {
+        result += "none";
+    } else {
+        result += QString("x%1Y%2")
+            .arg(alignmentToString(xAlignment))
+            .arg(alignmentToString(yAlignment));
+
+        if (mode == Qt::KeepAspectRatioByExpanding) {
+            result += " slice";
+        }
+    }
+
+    return result;
+}
+
+SvgUtil::PreserveAspectRatioParser::Alignment \
SvgUtil::PreserveAspectRatioParser::alignmentFromString(const QString &str) const {  \
return  str == "max" ? Max :
         str == "mid" ? Middle : Min;
 }
 
+QString SvgUtil::PreserveAspectRatioParser::alignmentToString(SvgUtil::PreserveAspectRatioParser::Alignment \
alignment) const +{
+    return
+        alignment == Max ? "Max" :
+        alignment == Min ? "Min" :
+        "Mid";
+
+}
+
 qreal SvgUtil::PreserveAspectRatioParser::alignedValue(qreal min, qreal max, \
SvgUtil::PreserveAspectRatioParser::Alignment alignment)  {
     qreal result = min;
diff --git a/libs/flake/svg/SvgUtil.h b/libs/flake/svg/SvgUtil.h
index f533522..b361fa3 100644
--- a/libs/flake/svg/SvgUtil.h
+++ b/libs/flake/svg/SvgUtil.h
@@ -122,8 +122,11 @@ public:
 
         QPointF rectAnchorPoint(const QRectF &rc) const;
 
+        QString toString() const;
+
     private:
-        Alignment alignmentFromString(const QString &str);
+        Alignment alignmentFromString(const QString &str) const;
+        QString alignmentToString(Alignment alignment) const;
         static qreal alignedValue(qreal min, qreal max, Alignment alignment);
     };
 };
diff --git a/plugins/flake/imageshape/ImageShape.cpp \
b/plugins/flake/imageshape/ImageShape.cpp index 7241a6b..fd259cb 100644
--- a/plugins/flake/imageshape/ImageShape.cpp
+++ b/plugins/flake/imageshape/ImageShape.cpp
@@ -24,9 +24,14 @@
 #include <QPainter>
 #include <KoViewConverter.h>
 #include <SvgLoadingContext.h>
+#include <SvgSavingContext.h>
 #include <SvgUtil.h>
 #include <QFileInfo>
 #include <QBuffer>
+#include <KisMimeDatabase.h>
+#include <KoXmlWriter.h>
+#include "kis_dom_utils.h"
+#include <QRegularExpression>
 
 struct Q_DECL_HIDDEN ImageShape::Private
 {
@@ -99,8 +104,30 @@ bool ImageShape::loadOdf(const KoXmlElement &element, \
KoShapeLoadingContext &con  
 bool ImageShape::saveSvg(SvgSavingContext &context)
 {
-    Q_UNUSED(context);
-    return false;
+    const QString uid = context.createUID("image");
+
+    context.shapeWriter().startElement("image");
+    context.shapeWriter().addAttribute("id", uid);
+    context.shapeWriter().addAttribute("transform", \
SvgUtil::transformToString(transformation())); +    \
context.shapeWriter().addAttribute("width", \
QString("%1px").arg(KisDomUtils::toString(size().width()))); +    \
context.shapeWriter().addAttribute("height", \
QString("%1px").arg(KisDomUtils::toString(size().height()))); +
+    QString aspectString = m_d->ratioParser->toString();
+    if (!aspectString.isEmpty()) {
+        context.shapeWriter().addAttribute("preserveAspectRatio", aspectString);
+    }
+
+    QByteArray ba;
+    QBuffer buffer(&ba);
+    buffer.open(QIODevice::WriteOnly);
+    if (m_d->image.save(&buffer, "PNG")) {
+        const QString mimeType = KisMimeDatabase::mimeTypeForSuffix("*.png");
+        context.shapeWriter().addAttribute("xlink:href", "data:"+ mimeType + \
";base64," + ba.toBase64()); +    }
+
+    context.shapeWriter().endElement(); // image
+
+    return true;
 }
 
 bool ImageShape::loadSvg(const KoXmlElement &element, SvgLoadingContext &context)
@@ -118,7 +145,19 @@ bool ImageShape::loadSvg(const KoXmlElement &element, \
SvgLoadingContext &context  }
 
     QString fileName = element.attribute("xlink:href");
-    QByteArray data = context.fetchExternalFile(fileName);
+
+    QByteArray data;
+
+    if (fileName.startsWith("data:")) {
+
+        QRegularExpression re("data:(.+?);base64,(.+)");
+        QRegularExpressionMatch match = re.match(fileName);
+
+        data = match.captured(2).toLatin1();
+        data = QByteArray::fromBase64(data);
+    } else {
+        data = context.fetchExternalFile(fileName);
+    }
 
     if (!data.isEmpty()) {
         QBuffer buffer(&data);
@@ -137,7 +176,7 @@ bool ImageShape::loadSvg(const KoXmlElement &element, \
SvgLoadingContext &context  QRectF(QPointF(), size()),
                                   QRect(QPoint(), m_d->image.size()),
                                   &m_d->viewBoxTransform);
-        }
+    }
 
     if (m_d->ratioParser->defer) {
         // TODO:


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic