File indexing completed on 2025-01-05 04:01:19

0001 /*
0002  * SPDX-FileCopyrightText: 2019-2023 Mattia Basaglia <dev@dragon.best>
0003  *
0004  * SPDX-License-Identifier: GPL-3.0-or-later
0005  */
0006 
0007 #include "svg_format.hpp"
0008 
0009 #include <QFileInfo>
0010 #include <KCompressionDevice>
0011 
0012 #include "utils/gzip.hpp"
0013 #include "svg_parser.hpp"
0014 #include "parse_error.hpp"
0015 #include "svg_renderer.hpp"
0016 #include "model/assets/assets.hpp"
0017 
0018 glaxnimate::io::Autoreg<glaxnimate::io::svg::SvgFormat> glaxnimate::io::svg::SvgFormat::autoreg;
0019 
0020 bool glaxnimate::io::svg::SvgFormat::on_open(QIODevice& file, const QString& filename, model::Document* document, const QVariantMap& options)
0021 {
0022     /// \todo layer mode setting
0023     SvgParser::GroupMode mode = SvgParser::Inkscape;
0024 
0025     auto on_error = [this](const QString& s){warning(s);};
0026     try
0027     {
0028         QSize forced_size = options["forced_size"].toSize();
0029         model::FrameTime default_time = options["default_time"].toFloat();
0030 
0031         auto default_asset_path = QFileInfo(filename).dir();
0032 
0033         if ( utils::gzip::is_compressed(file) )
0034         {
0035             KCompressionDevice decompressed(&file, false, KCompressionDevice::GZip);
0036             decompressed.open(QIODevice::ReadOnly);
0037             SvgParser(&decompressed, mode, document, on_error, this, forced_size, default_time, default_asset_path).parse_to_document();
0038             return true;
0039         }
0040 
0041         SvgParser(&file, mode, document, on_error, this, forced_size, default_time, default_asset_path).parse_to_document();
0042         return true;
0043 
0044     }
0045     catch ( const SvgParseError& err )
0046     {
0047         error(err.formatted(QFileInfo(filename).baseName()));
0048         return false;
0049     }
0050 }
0051 
0052 std::unique_ptr<app::settings::SettingsGroup> glaxnimate::io::svg::SvgFormat::save_settings(model::Composition* comp) const
0053 {
0054     CssFontType max = CssFontType::None;
0055     for ( const auto & font : comp->document()->assets()->fonts->values )
0056     {
0057         auto type = SvgRenderer::suggested_type(font.get());
0058         if ( type > max )
0059             max = type;
0060     }
0061 
0062     if ( max == CssFontType::None )
0063         return {};
0064 
0065     QVariantMap choices;
0066     if ( max >= CssFontType::Link )
0067         choices[i18n("External Stylesheet")] = int(CssFontType::Link);
0068     if ( max >= CssFontType::FontFace )
0069         choices[i18n("Font face with external url")] = int(CssFontType::FontFace);
0070     if ( max >= CssFontType::Embedded )
0071         choices[i18n("Embedded data")] = int(CssFontType::Embedded);
0072     choices[i18n("Ignore")] = int(CssFontType::None);
0073 
0074     return std::make_unique<app::settings::SettingsGroup>(app::settings::SettingList{
0075         app::settings::Setting("font_type", i18n("External Fonts"), i18n("How to include external font"),
0076                                app::settings::Setting::Int, int(qMin(max, CssFontType::FontFace)), choices)
0077     });
0078 }
0079 
0080 bool glaxnimate::io::svg::SvgFormat::on_save(QIODevice& file, const QString& filename, model::Composition* comp, const QVariantMap& options)
0081 {
0082     SvgRenderer rend(SMIL, CssFontType(options["font_type"].toInt()));
0083     rend.write_main(comp);
0084     if ( filename.endsWith(".svgz") || options.value("compressed", false).toBool() )
0085     {
0086         KCompressionDevice compressed(&file, false, KCompressionDevice::GZip);
0087         compressed.open(QIODevice::WriteOnly);
0088         rend.write(&compressed, false);
0089         compressed.close();
0090 
0091         if ( compressed.error() )
0092             warning(i18n("Could not write to file"));
0093     }
0094     else
0095     {
0096         rend.write(&file, true);
0097     }
0098 
0099     return true;
0100 }
0101