File indexing completed on 2025-02-02 04:54:38

0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 // SPDX-FileCopyrightText: 2018 Kevin Ottens <ervin@kde.org>
0003 
0004 /*
0005  * Adapted by Louis Schul <schul9louis@gmail.com>
0006  * in 2023 for Klevernotes
0007  */
0008 
0009 #include "sketchserializer.h"
0010 
0011 #include <functional>
0012 #include <memory>
0013 
0014 #include <QImageWriter>
0015 #include <QPainter>
0016 #include <QSvgGenerator>
0017 #include <QUrl>
0018 
0019 #include "sketchmodel.h"
0020 
0021 #include <cstddef>
0022 #include <memory>
0023 #include <type_traits>
0024 #include <utility>
0025 
0026 class Serializer
0027 {
0028 public:
0029     Serializer(std::unique_ptr<QPaintDevice> &&device, const std::function<void(QPaintDevice *)> writer = {})
0030         : m_device(std::move(device))
0031         , m_writer(writer)
0032     {
0033     }
0034 
0035     ~Serializer()
0036     {
0037         if (m_writer)
0038             m_writer(m_device.get());
0039     }
0040 
0041     QPaintDevice *device() const
0042     {
0043         return m_device.get();
0044     }
0045 
0046 private:
0047     std::unique_ptr<QPaintDevice> m_device;
0048     std::function<void(QPaintDevice *)> m_writer;
0049 };
0050 
0051 std::unique_ptr<Serializer> createSerializer(const QSize &size, const QString &fileName)
0052 {
0053     if (fileName.endsWith(QStringLiteral(".svg"))) {
0054         auto generator = std::make_unique<QSvgGenerator>();
0055         generator->setFileName(fileName);
0056         generator->setViewBox(QRect{{0, 0}, size});
0057         return std::make_unique<Serializer>(std::move(generator));
0058     } else {
0059         auto image = std::make_unique<QImage>(size, QImage::Format_RGB32);
0060         image->fill(Qt::white);
0061 
0062         auto writeImage = [fileName](QPaintDevice *image) {
0063             QImageWriter writer(fileName);
0064             writer.write(*static_cast<QImage *>(image));
0065         };
0066 
0067         return std::make_unique<Serializer>(std::move(image), writeImage);
0068     }
0069 }
0070 
0071 void SketchSerializer::serialize(SketchModel *model, const QSize &size, const QUrl &fileUrl)
0072 {
0073     Q_ASSERT(fileUrl.isLocalFile());
0074 
0075     auto strokes = model->strokes();
0076     auto serializer = createSerializer(size, fileUrl.toLocalFile());
0077     auto painter = std::make_unique<QPainter>(serializer->device());
0078     painter->setRenderHint(QPainter::Antialiasing);
0079 
0080     for (const auto &stroke : std::as_const(strokes)) {
0081         m_strokepainter.render(stroke, painter.get());
0082     }
0083 }
0084 
0085 QRect SketchSerializer::getCropRect()
0086 {
0087     int lowestX = (m_strokepainter.lowestX - 50 < 0) ? 0 : m_strokepainter.lowestX - 50;
0088     int lowestY = (m_strokepainter.lowestY - 50 < 0) ? 0 : m_strokepainter.lowestY - 50;
0089     int highestX = (m_strokepainter.highestX + 50 > 1024) ? 1024 : m_strokepainter.highestX + 50;
0090     int highestY = (m_strokepainter.highestY + 50 > 1024) ? 1024 : m_strokepainter.highestY + 50;
0091 
0092     return QRect(QPoint(lowestX, lowestY), QPoint(highestX, highestY));
0093 }