diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 11:50:49 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 11:50:49 +0000 |
commit | c853ffb5b2f75f5a889ed2e3ef89b818a736e87a (patch) | |
tree | 7d13a0883bb7936b84d6ecdd7bc332b41ed04bee /src/ui/svg-renderer.cpp | |
parent | Initial commit. (diff) | |
download | inkscape-c853ffb5b2f75f5a889ed2e3ef89b818a736e87a.tar.xz inkscape-c853ffb5b2f75f5a889ed2e3ef89b818a736e87a.zip |
Adding upstream version 1.3+ds.upstream/1.3+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/ui/svg-renderer.cpp')
-rw-r--r-- | src/ui/svg-renderer.cpp | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/src/ui/svg-renderer.cpp b/src/ui/svg-renderer.cpp new file mode 100644 index 0000000..523580c --- /dev/null +++ b/src/ui/svg-renderer.cpp @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/** + * SVG to Pixbuf renderer + * + * Author: + * Michael Kowalski + * + * Copyright (C) 2020-2021 Michael Kowalski + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include "svg-renderer.h" +#include "io/file.h" +#include "xml/repr.h" +#include "object/sp-root.h" +#include "display/cairo-utils.h" +#include "helper/pixbuf-ops.h" +#include "util/units.h" + +namespace Inkscape { + +Glib::ustring rgba_to_css_color(double r, double g, double b) { + char buffer[16]; + sprintf(buffer, "#%02x%02x%02x", + static_cast<int>(r * 0xff + 0.5), + static_cast<int>(g * 0xff + 0.5), + static_cast<int>(b * 0xff + 0.5) + ); + return Glib::ustring(buffer); +} + +Glib::ustring rgba_to_css_color(const Gdk::RGBA& color) { + return rgba_to_css_color(color.get_red(), color.get_green(), color.get_blue()); +} + +Glib::ustring rgba_to_css_color(const SPColor& color) { + float rgb[3]; + color.get_rgb_floatv(rgb); + return rgba_to_css_color(rgb[0], rgb[1], rgb[2]); +} + +Glib::ustring double_to_css_value(double value) { + char buffer[32]; + // arbitrarily chosen precision + sprintf(buffer, "%.4f", value); + return Glib::ustring(buffer); +} + +std::shared_ptr<SPDocument> load_document(const char* svg_file_path) { + auto file = Gio::File::create_for_path(svg_file_path); + return std::shared_ptr<SPDocument>(ink_file_open(file, nullptr)); +} + +svg_renderer::svg_renderer(const char* svg_file_path): svg_renderer(load_document(svg_file_path)) { +} + +svg_renderer::svg_renderer(std::shared_ptr<SPDocument> document) { + _document = document; + if (document) { + _root = _document->getRoot(); + } + + if (!_root) throw std::runtime_error("Cannot find root element in svg document"); +} + +size_t svg_renderer::set_style(const Glib::ustring& selector, const char* name, const Glib::ustring& value) { + auto objects = _document->getObjectsBySelector(selector); + for (auto el : objects) { + if (SPCSSAttr* css = sp_repr_css_attr(el->getRepr(), "style")) { + sp_repr_css_set_property(css, name, value.c_str()); + el->changeCSS(css, "style"); + sp_repr_css_attr_unref(css); + } + } + return objects.size(); +} + +double svg_renderer::get_width_px() const { + return _document->getWidth().value("px"); +} + +double svg_renderer::get_height_px() const { + return _document->getHeight().value("px"); +} + +Inkscape::Pixbuf *svg_renderer::do_render(double scale) +{ + auto dpi = 96 * scale; + auto area = *(_document->preferredBounds()); + + auto checkerboard_ptr = _checkerboard ? &*_checkerboard : nullptr; + return sp_generate_internal_bitmap(_document.get(), area, dpi, {}, false, checkerboard_ptr, scale); +} + +Glib::RefPtr<Gdk::Pixbuf> svg_renderer::render(double scale) { + auto pixbuf = do_render(scale); + if (!pixbuf) return Glib::RefPtr<Gdk::Pixbuf>(); + + // ref it + auto raw = Glib::wrap(pixbuf->getPixbufRaw(), true); + delete pixbuf; + return raw; +} + +Cairo::RefPtr<Cairo::Surface> svg_renderer::render_surface(double scale) { + auto pixbuf = do_render(scale); + if (!pixbuf) return Cairo::RefPtr<Cairo::Surface>(); + + // ref it by saying that we have no reference + auto surface = Cairo::RefPtr<Cairo::Surface>(new Cairo::Surface(pixbuf->getSurfaceRaw(), false)); + delete pixbuf; + return surface; +} + +void svg_renderer::set_checkerboard_color(unsigned int rgba) { + _checkerboard.emplace(rgba); +} + +} // namespace |