NovaSVG 0.10.0
A header-only SVG library
Loading...
Searching...
No Matches
novasvg.h
Go to the documentation of this file.
1/*
2 * MIT License
3 *
4 * Copyright (c) 2023-present Mohammad Raziei
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23*/
24
25
26#ifndef NOVASVG_H
27#define NOVASVG_H
28#pragma once
29
30#include <cstdint>
31#include <memory>
32#include <string>
33#include <cctype>
34#include <vector>
35
36// True header-only linkage: every function/method defined in the detail/
37// implementation headers is marked NOVASVG_INLINE (plain `inline`), so
38// this whole library -- including its rendering backend -- can safely be
39// #included from any number of translation units with no separate
40// "#define NOVASVG_IMPLEMENTATION in exactly one .cpp" step required.
41#ifndef NOVASVG_INLINE
42#define NOVASVG_INLINE inline
43#endif
44
45// NovaSVG is header-only: every function is NOVASVG_INLINE, so the default
46// linkage must NOT be dllimport/dllexport. On MSVC, __declspec(dllimport) on
47// an inline-defined function suppresses the inline body and produces LNK2019
48// unresolved externals. Shared-library decoration is therefore opt-in via
49// NOVASVG_BUILD_SHARED.
50#if defined(NOVASVG_BUILD_STATIC) || !defined(NOVASVG_BUILD_SHARED)
51#define NOVASVG_EXPORT
52#define NOVASVG_IMPORT
53#elif (defined(_WIN32) || defined(__CYGWIN__))
54#define NOVASVG_EXPORT __declspec(dllexport)
55#define NOVASVG_IMPORT __declspec(dllimport)
56#elif defined(__GNUC__) && (__GNUC__ >= 4)
57#define NOVASVG_EXPORT __attribute__((__visibility__("default")))
58#define NOVASVG_IMPORT
59#else
60#define NOVASVG_EXPORT
61#define NOVASVG_IMPORT
62#endif
63
64#ifdef NOVASVG_BUILD
65#define NOVASVG_API NOVASVG_EXPORT
66#else
67#define NOVASVG_API NOVASVG_IMPORT
68#endif
69
70// Plain ternary macros instead of std::max/std::min. A uniquely-prefixed
71// macro can never collide with anything, which a bare `std::max`/
72// `std::min` call genuinely can: <windows.h> (pulled in transitively by
73// Python.h and friends on a Windows build) `#define`s `max`/`min` as
74// object-like macros unless NOMINMAX is defined first, and since that's
75// a build-system concern novasvg can't force on every consumer of a
76// header-only library, this codebase calls these instead of std::max/
77// std::min directly wherever it needs a two-argument max/min. Same
78// pattern the vendored FreeType rasterizer already uses for its own
79// internals (PVG_FT_MIN/PVG_FT_MAX in detail/render/vendor/), just
80// under this project's own prefix for general-purpose call sites.
81// ponytail: no protection against double-evaluating a/b if either has
82// side effects -- fine for every current call site (plain variable/
83// member reads), just don't reach for these with e.g. `x++` as an
84// argument.
85#ifndef NOVASVG_MAX
86#define NOVASVG_MAX(a, b) ((a) > (b) ? (a) : (b))
87#endif
88#ifndef NOVASVG_MIN
89#define NOVASVG_MIN(a, b) ((a) < (b) ? (a) : (b))
90#endif
91
92#define NOVASVG_VERSION_MAJOR 0
93#define NOVASVG_VERSION_MINOR 10
94#define NOVASVG_VERSION_PATCH 0
95
96#define NOVASVG_VERSION_ENCODE(major, minor, patch) (((major) * 10000) + ((minor) * 100) + ((patch) * 1))
97#define NOVASVG_VERSION NOVASVG_VERSION_ENCODE(NOVASVG_VERSION_MAJOR, NOVASVG_VERSION_MINOR, NOVASVG_VERSION_PATCH)
98
99#define NOVASVG_VERSION_XSTRINGIZE(major, minor, patch) #major"."#minor"."#patch
100#define NOVASVG_VERSION_STRINGIZE(major, minor, patch) NOVASVG_VERSION_XSTRINGIZE(major, minor, patch)
101#define NOVASVG_VERSION_STRING NOVASVG_VERSION_STRINGIZE(NOVASVG_VERSION_MAJOR, NOVASVG_VERSION_MINOR, NOVASVG_VERSION_PATCH)
102
103#include "detail/color.h"
104
105namespace novasvg {
106namespace render {
107struct surface;
108struct matrix;
109using surface_t = surface;
111} // namespace render
112} // namespace novasvg
113
121typedef void (*novasvg_destroy_func_t)(void* closure);
122
129typedef void (*novasvg_write_func_t)(void* closure, void* data, int size);
130
131
132namespace novasvg {
133using namespace render;
134
143int version();
144
153std::string versionString();
154
155} // namespace novasvg
156
157#include "detail/font.h"
158
159#include "detail/bitmap.h"
160
161namespace novasvg {
162using namespace render;
163
164class Rect;
165class Matrix;
166
171public:
175 Box() = default;
176
184 Box(float x, float y, float w, float h);
185
189 Box(const Rect& rect);
190
196 Box& transform(const Matrix& matrix);
197
203 Box transformed(const Matrix& matrix) const;
204
205 float x{0};
206 float y{0};
207 float w{0};
208 float h{0};
209};
210
211class Transform;
212
217public:
221 Matrix() = default;
222
232 Matrix(float a, float b, float c, float d, float e, float f);
233
237 Matrix(const matrix_t& matrix);
238
242 Matrix(const Transform& transform);
243
249 Matrix operator*(const Matrix& matrix) const;
250
256 Matrix& operator*=(const Matrix& matrix);
257
263 Matrix& multiply(const Matrix& matrix);
264
271 Matrix& translate(float tx, float ty);
272
279 Matrix& scale(float sx, float sy);
280
288 Matrix& rotate(float angle, float cx = 0.f, float cy = 0.f);
289
296 Matrix& shear(float shx, float shy);
297
302 Matrix& invert();
303
308 Matrix inverse() const;
309
313 void reset();
314
321 static Matrix translated(float tx, float ty);
322
329 static Matrix scaled(float sx, float sy);
330
338 static Matrix rotated(float angle, float cx = 0.f, float cy = 0.f);
339
346 static Matrix sheared(float shx, float shy);
347
348 float a{1};
349 float b{0};
350 float c{0};
351 float d{1};
352 float e{0};
353 float f{0};
354};
355
356class SVGNode;
357class SVGTextNode;
358class SVGElement;
359
360class Element;
361class TextNode;
362
364public:
368 Node() = default;
369
374 bool isTextNode() const;
375
380 bool isElement() const;
381
386 TextNode toTextNode() const;
387
392 Element toElement() const;
393
398 Element parentElement() const;
399
404 bool isNull() const { return m_node == nullptr; }
405
410 operator bool() const { return !isNull(); }
411
417 bool operator==(const Node& node) const { return m_node == node.m_node; }
418
424 bool operator!=(const Node& node) const { return m_node != node.m_node; }
425
426protected:
427 Node(SVGNode* node);
428 SVGNode* node() const { return m_node; }
429 SVGNode* m_node{nullptr};
430 friend class Element;
431};
432
433using NodeList = std::vector<Node>;
434
435class NOVASVG_API TextNode : public Node {
436public:
440 TextNode() = default;
441
446 const std::string& data() const;
447
452 void setData(const std::string& data);
453
454private:
456 SVGTextNode* text() const;
457 friend class Node;
458};
459
460class NOVASVG_API Element : public Node {
461public:
465 Element() = default;
466
472 bool hasAttribute(const std::string& name) const;
473
479 const std::string& getAttribute(const std::string& name) const;
480
486 void setAttribute(const std::string& name, const std::string& value);
487
493 void render(Bitmap& bitmap, const Matrix& matrix = Matrix()) const;
494
502 Bitmap renderToBitmap(int width = -1, int height = -1, const Color& backgroundColor = Color(0, 0, 0, 0)) const;
503
508 Matrix getLocalMatrix() const;
509
514 Matrix getGlobalMatrix() const;
515
520 Box getLocalBoundingBox() const;
521
526 Box getGlobalBoundingBox() const;
527
532 Box getBoundingBox() const;
533
538 NodeList children() const;
539
540private:
541 Element(SVGElement* element);
542 SVGElement* element(bool layoutIfNeeded = false) const;
543 friend class Node;
544 friend class Document;
545};
546
547using ElementList = std::vector<Element>;
548
549class SVGRootElement;
550
552public:
558 static std::unique_ptr<Document> loadFromFile(const std::string& filename);
559
565 static std::unique_ptr<Document> loadFromData(const std::string& string);
566
572 static std::unique_ptr<Document> loadFromData(const char* data);
573
580 static std::unique_ptr<Document> loadFromData(const char* data, size_t length);
581
586 void applyStyleSheet(const std::string& content);
587
593 ElementList querySelectorAll(const std::string& content) const;
594
599 float width() const;
600
605 float height() const;
606
611 Box boundingBox() const;
612
616 void updateLayout();
617
621 void forceLayout();
622
628 void render(Bitmap& bitmap, const Matrix& matrix = Matrix()) const;
629
637 Bitmap renderToBitmap(int width = -1, int height = -1, const Color& backgroundColor = Color(0, 0, 0, 0)) const;
638
645 Element elementFromPoint(float x, float y) const;
646
652 Element getElementById(const std::string& id) const;
653
658 Element documentElement() const;
659
663
664private:
665 Document();
666 Document(const Document&) = delete;
667 Document& operator=(const Document&) = delete;
668 SVGRootElement* rootElement(bool layoutIfNeeded = false) const;
669 bool parse(const char* data, size_t length);
670 std::unique_ptr<SVGRootElement> m_rootElement;
671 friend class SVGURIReference;
672 friend class SVGNode;
673};
674
675} // namespace novasvg
676
677// Always included -- see the NOVASVG_INLINE note above. Defining
678// NOVASVG_IMPLEMENTATION is no longer required and has no effect; it is
679// kept as a harmless no-op purely so existing code that still defines it
680// keeps compiling unchanged.
681//
682// This used to be a separate "detail/novasvg_impl.h" file, but that file
683// did nothing except forward this exact list of includes to the one
684// place (here) that used it, so it's inlined directly instead.
685//
686// The render/ layer's own extern "C" wrapper is gone too: it's pure,
687// header-only C++ (NOVASVG_INLINE / internal-linkage everywhere), nothing
688// in this project links against it from actual C code, and the vendored
689// STB headers already manage their own extern "C" internally when
690// compiled as C++.
691
692#include <cstring>
693#include <fstream>
694#include <cmath>
695
696#include "detail/canvas.h"
697#include "detail/svgelement.h"
698#include "detail/svgparser.hpp"
699
700namespace novasvg {
701using namespace render;
702
703// ---------------------------------------------------------------
704// Implementation (formerly detail/novasvg.hpp -- merged in since
705// this header is fully NOVASVG_INLINE now, there's no reason left
706// to keep the public declarations and their definitions apart).
707// ---------------------------------------------------------------
708
709using namespace render; // render/ layer (novasvg::render), the former plutovg
710
712{
713 return NOVASVG_VERSION;
714}
715
717{
719}
720
721
722NOVASVG_INLINE Box::Box(float x, float y, float w, float h)
723 : x(x), y(y), w(w), h(h)
724{
725}
726
728 : x(rect.x), y(rect.y), w(rect.w), h(rect.h)
729{
730}
731
733{
734 *this = transformed(matrix);
735 return *this;
736}
737
739{
740 return Transform(matrix).mapRect(*this);
741}
742
744 : x(box.x), y(box.y), w(box.w), h(box.h)
745{
746}
747
748NOVASVG_INLINE Matrix::Matrix(float a, float b, float c, float d, float e, float f)
749 : a(a), b(b), c(c), d(d), e(e), f(f)
750{
751}
752
754 : a(matrix.a), b(matrix.b), c(matrix.c), d(matrix.d), e(matrix.e), f(matrix.f)
755{
756}
757
759 : Matrix(transform.matrix())
760{
761}
762
764{
765 return Transform(*this) * Transform(matrix);
766}
767
772
774{
775 return (*this = *this * matrix);
776}
777
779{
780 return (*this *= matrix);
781}
782
784{
785 return multiply(scaled(sx, sy));
786}
787
789{
790 return multiply(translated(tx, ty));
791}
792
793NOVASVG_INLINE Matrix& Matrix::rotate(float angle, float cx, float cy)
794{
795 return multiply(rotated(angle, cx, cy));
796}
797
798NOVASVG_INLINE Matrix& Matrix::shear(float shx, float shy)
799{
800 return multiply(sheared(shx, shy));
801}
802
804{
805 return Transform(*this).inverse();
806}
807
809{
810 return (*this = inverse());
811}
812
814{
815 *this = Matrix(1, 0, 0, 1, 0, 0);
816}
817
819{
820 return Transform::translated(tx, ty);
821}
822
824{
825 return Transform::scaled(sx, sy);
826}
827
828NOVASVG_INLINE Matrix Matrix::rotated(float angle, float cx, float cy)
829{
830 return Transform::rotated(angle, cx, cy);
831}
832
834{
835 return Transform::sheared(shx, shy);
836}
837
839 : m_node(node)
840{
841}
842
844{
845 return m_node && m_node->isTextNode();
846}
847
849{
850 return m_node && m_node->isElement();
851}
852
854{
855 if(m_node && m_node->isTextNode())
856 return static_cast<SVGTextNode*>(m_node);
857 return TextNode();
858}
859
861{
862 if(m_node && m_node->isElement())
863 return static_cast<SVGElement*>(m_node);
864 return Element();
865}
866
868{
869 if(m_node)
870 return m_node->parentElement();
871 return Element();
872}
873
875 : Node(text)
876{
877}
878
879NOVASVG_INLINE const std::string& TextNode::data() const
880{
881 if(m_node)
882 return text()->data();
883 return emptyString;
884}
885
886NOVASVG_INLINE void TextNode::setData(const std::string& data)
887{
888 if(m_node) {
889 text()->setData(data);
890 }
891}
892
893NOVASVG_INLINE SVGTextNode* TextNode::text() const
894{
895 return static_cast<SVGTextNode*>(m_node);
896}
897
898NOVASVG_INLINE Element::Element(SVGElement* element)
899 : Node(element)
900{
901}
902
903NOVASVG_INLINE bool Element::hasAttribute(const std::string& name) const
904{
905 if(m_node)
906 return element()->hasAttribute(name);
907 return false;
908}
909
910NOVASVG_INLINE const std::string& Element::getAttribute(const std::string& name) const
911{
912 if(m_node)
913 return element()->getAttribute(name);
914 return emptyString;
915}
916
917NOVASVG_INLINE void Element::setAttribute(const std::string& name, const std::string& value)
918{
919 if(m_node) {
920 element()->setAttribute(name, value);
921 }
922}
923
925{
926 if(m_node == nullptr || bitmap.isNull())
927 return;
928 auto canvas = Canvas::create(bitmap);
930 element(true)->render(state);
931}
932
933NOVASVG_INLINE Bitmap Element::renderToBitmap(int width, int height, const Color& backgroundColor) const
934{
935 if(m_node == nullptr)
936 return Bitmap();
937 auto elementBounds = element(true)->localTransform().mapRect(element()->paintBoundingBox());
938 if(elementBounds.isEmpty())
939 return Bitmap();
940 if(width <= 0 && height <= 0) {
941 width = static_cast<int>(std::ceil(elementBounds.w));
942 height = static_cast<int>(std::ceil(elementBounds.h));
943 } else if(width > 0 && height <= 0) {
944 height = static_cast<int>(std::ceil(width * elementBounds.h / elementBounds.w));
945 } else if(height > 0 && width <= 0) {
946 width = static_cast<int>(std::ceil(height * elementBounds.w / elementBounds.h));
947 }
948
949 auto xScale = width / elementBounds.w;
950 auto yScale = height / elementBounds.h;
951
952 Matrix matrix(xScale, 0, 0, yScale, -elementBounds.x * xScale, -elementBounds.y * yScale);
953 Bitmap bitmap(width, height);
954 if(backgroundColor.value()) bitmap.clear(backgroundColor);
955 render(bitmap, matrix);
956 return bitmap;
957}
958
960{
961 if(m_node)
962 return element(true)->localTransform();
963 return Matrix();
964}
965
967{
968 if(m_node == nullptr)
969 return Matrix();
970 auto transform = element(true)->localTransform();
971 for(auto parent = element()->parentElement(); parent; parent = parent->parentElement())
972 transform.postMultiply(parent->localTransform());
973 return transform;
974}
975
980
985
987{
988 if(m_node)
989 return element(true)->paintBoundingBox();
990 return Box();
991}
992
994{
995 if(m_node == nullptr)
996 return NodeList();
998 for(const auto& child : element()->children())
999 children.push_back(child.get());
1000 return children;
1001}
1002
1003NOVASVG_INLINE SVGElement* Element::element(bool layoutIfNeeded) const
1004{
1005 auto element = static_cast<SVGElement*>(m_node);
1006 if(element && layoutIfNeeded)
1007 element->rootElement()->layoutIfNeeded();
1008 return element;
1009}
1010
1011NOVASVG_INLINE std::unique_ptr<Document> Document::loadFromFile(const std::string& filename)
1012{
1013 std::ifstream fs;
1014 fs.open(filename);
1015 if(!fs.is_open())
1016 return nullptr;
1017 std::string content;
1018 std::getline(fs, content, '\0');
1019 fs.close();
1020 return loadFromData(content);
1021}
1022
1023NOVASVG_INLINE std::unique_ptr<Document> Document::loadFromData(const std::string& string)
1024{
1025 return loadFromData(string.data(), string.size());
1026}
1027
1028NOVASVG_INLINE std::unique_ptr<Document> Document::loadFromData(const char* data)
1029{
1030 return loadFromData(data, std::strlen(data));
1031}
1032
1033NOVASVG_INLINE std::unique_ptr<Document> Document::loadFromData(const char* data, size_t length)
1034{
1035 std::unique_ptr<Document> document(new Document);
1036 if(!document->parse(data, length))
1037 return nullptr;
1038 return document;
1039}
1040
1042{
1043 return rootElement(true)->intrinsicWidth();
1044}
1045
1047{
1048 return rootElement(true)->intrinsicHeight();
1049}
1050
1052{
1053 return rootElement(true)->localTransform().mapRect(rootElement()->paintBoundingBox());
1054}
1055
1057{
1058 m_rootElement->layoutIfNeeded();
1059}
1060
1062{
1063 m_rootElement->forceLayout();
1064}
1065
1067{
1068 if(bitmap.isNull())
1069 return;
1070
1071 // A `background-color` in the root <svg>'s own inline style isn't a
1072 // real SVG presentation property -- it's a CSS box-model property
1073 // that only means something when an SVG is displayed as a standalone
1074 // document/replaced element (which is exactly how a browser navigated
1075 // straight to a .svg file treats it, painting that color behind
1076 // everything). Most pure-vector SVG renderers ignore it entirely, but
1077 // since generated SVGs (Mermaid in particular) rely on it for a
1078 // correct-looking standalone render, honor it here the same way:
1079 // clear the bitmap to it before any content paints, so it sits under
1080 // everything and behind any transparency in the content itself. Takes
1081 // priority over renderToBitmap()'s own `backgroundColor` argument
1082 // (this runs after that clear) since that argument means "what to
1083 // show through transparent content", and content here isn't actually
1084 // transparent -- it explicitly asked for this color.
1085 // A `background-color` in the root <svg>'s own style isn't a real SVG
1086 // presentation property -- it's a CSS box-model property that only
1087 // means something when an SVG is displayed as a standalone
1088 // document/replaced element (exactly how a browser navigated straight
1089 // to a .svg file treats it, painting that color behind everything).
1090 // Most pure-vector SVG renderers ignore it entirely, but since
1091 // generated SVGs (Mermaid in particular) rely on it for a
1092 // correct-looking standalone render, honor it here the same way:
1093 // clear the bitmap to it before any content paints, so it sits under
1094 // everything and behind any transparency in the content itself. Takes
1095 // priority over renderToBitmap()'s own `backgroundColor` argument
1096 // (this runs after that clear) since that argument means "what to
1097 // show through transparent content", and content here isn't actually
1098 // transparent -- it explicitly asked for this color.
1099 if(const auto& bg = rootElement(true)->getAttribute(PropertyID::Background_Color); !bg.empty()) {
1100 color_t color;
1101 if(color_parse(&color, bg.data(), static_cast<int>(bg.length())) > 0) {
1102 auto argb = color_to_argb32(&color);
1103 bitmap.clear(Color((argb >> 16) & 0xff, (argb >> 8) & 0xff, argb & 0xff, (argb >> 24) & 0xff));
1104 }
1105 }
1106
1107 auto canvas = Canvas::create(bitmap);
1109 rootElement(true)->render(state);
1110}
1111
1112NOVASVG_INLINE Bitmap Document::renderToBitmap(int width, int height, const Color& backgroundColor) const
1113{
1114 auto intrinsicWidth = rootElement(true)->intrinsicWidth();
1115 auto intrinsicHeight = rootElement()->intrinsicHeight();
1116 if(intrinsicWidth == 0.f || intrinsicHeight == 0.f)
1117 return Bitmap();
1118 if(width <= 0 && height <= 0) {
1119 width = static_cast<int>(std::ceil(intrinsicWidth));
1120 height = static_cast<int>(std::ceil(intrinsicHeight));
1121 } else if(width > 0 && height <= 0) {
1122 height = static_cast<int>(std::ceil(width * intrinsicHeight / intrinsicWidth));
1123 } else if(height > 0 && width <= 0) {
1124 width = static_cast<int>(std::ceil(height * intrinsicWidth / intrinsicHeight));
1125 }
1126
1127 auto xScale = width / intrinsicWidth;
1128 auto yScale = height / intrinsicHeight;
1129
1130 Matrix matrix(xScale, 0, 0, yScale, 0, 0);
1132 if(backgroundColor.value()) bitmap.clear(backgroundColor);
1134 return bitmap;
1135}
1136
1138{
1139 return rootElement(true)->elementFromPoint(x, y);
1140}
1141
1143{
1144 return m_rootElement->getElementById(id);
1145}
1146
1148{
1149 return m_rootElement.get();
1150}
1151
1152NOVASVG_INLINE SVGRootElement* Document::rootElement(bool layoutIfNeeded) const
1153{
1154 if(layoutIfNeeded)
1155 m_rootElement->layoutIfNeeded();
1156 return m_rootElement.get();
1157}
1158
1159NOVASVG_INLINE Document::Document(Document&&) = default;
1160NOVASVG_INLINE Document& Document::operator=(Document&&) = default;
1161
1162NOVASVG_INLINE Document::Document() = default;
1164
1165} // namespace novasvg
1166
1167#endif // NOVASVG_H
bool isNull() const
Checks if the bitmap is null.
Definition bitmap.h:132
void clear(const Color &value)
Clears the bitmap with the specified color.
Definition bitmap.h:1702
Represents a 2D axis-aligned bounding box.
Definition novasvg.h:170
Box & transform(const Matrix &matrix)
Transforms the box using the specified matrix.
Definition novasvg.h:732
Box()=default
Constructs a box with zero dimensions.
Box transformed(const Matrix &matrix) const
Returns a new box transformed by the specified matrix.
Definition novasvg.h:738
Represents a color in RGBA format (0xRRGGBBAA).
Definition color.h:85
uint32_t value() const
Convert the color to a 32-bit unsigned integer.
Definition color.h:308
Bitmap renderToBitmap(int width=-1, int height=-1, const Color &backgroundColor=Color(0, 0, 0, 0)) const
Renders the document to a bitmap with specified dimensions.
Definition novasvg.h:1112
Document & operator=(Document &&)
void forceLayout()
Forces an immediate layout update.
Definition novasvg.h:1061
float width() const
Returns the intrinsic width of the document in pixels.
Definition novasvg.h:1041
void render(Bitmap &bitmap, const Matrix &matrix=Matrix()) const
Renders the document onto a bitmap using a transformation matrix.
Definition novasvg.h:1066
Element elementFromPoint(float x, float y) const
Returns the topmost element under the specified point.
Definition novasvg.h:1137
Document(Document &&)
Element getElementById(const std::string &id) const
Retrieves an element by its ID.
Definition novasvg.h:1142
static std::unique_ptr< Document > loadFromData(const std::string &string)
Load an SVG document from a string.
Definition novasvg.h:1023
Element documentElement() const
Retrieves the document element.
Definition novasvg.h:1147
float height() const
Returns the intrinsic height of the document in pixels.
Definition novasvg.h:1046
Box boundingBox() const
Returns the smallest rectangle that encloses the document content.
Definition novasvg.h:1051
static std::unique_ptr< Document > loadFromFile(const std::string &filename)
Load an SVG document from a file.
Definition novasvg.h:1011
void updateLayout()
Updates the layout of the document if needed.
Definition novasvg.h:1056
void setAttribute(const std::string &name, const std::string &value)
Sets the value of an attribute.
Definition novasvg.h:917
Box getBoundingBox() const
Retrieves the bounding box of the element without any transformations.
Definition novasvg.h:986
Matrix getGlobalMatrix() const
Retrieves the global transformation matrix of the element.
Definition novasvg.h:966
Bitmap renderToBitmap(int width=-1, int height=-1, const Color &backgroundColor=Color(0, 0, 0, 0)) const
Renders the element to a bitmap with specified dimensions.
Definition novasvg.h:933
void render(Bitmap &bitmap, const Matrix &matrix=Matrix()) const
Renders the element onto a bitmap using a transformation matrix.
Definition novasvg.h:924
Box getLocalBoundingBox() const
Retrieves the local bounding box of the element.
Definition novasvg.h:976
Matrix getLocalMatrix() const
Retrieves the local transformation matrix of the element.
Definition novasvg.h:959
Box getGlobalBoundingBox() const
Retrieves the global bounding box of the element.
Definition novasvg.h:981
NodeList children() const
Returns the child nodes of this node.
Definition novasvg.h:993
const std::string & getAttribute(const std::string &name) const
Retrieves the value of an attribute.
Definition novasvg.h:910
Element()=default
Constructs a null element.
bool hasAttribute(const std::string &name) const
Checks if the element has a specific attribute.
Definition novasvg.h:903
Represents a 2D transformation matrix.
Definition novasvg.h:216
void reset()
Resets this matrix to the identity matrix.
Definition novasvg.h:813
static Matrix sheared(float shx, float shy)
Creates a shearing matrix with the specified factors.
Definition novasvg.h:833
Matrix & multiply(const Matrix &matrix)
Multiplies this matrix with another matrix.
Definition novasvg.h:778
Matrix & rotate(float angle, float cx=0.f, float cy=0.f)
Rotates this matrix by the specified angle around a point.
Definition novasvg.h:793
static Matrix rotated(float angle, float cx=0.f, float cy=0.f)
Creates a rotation matrix with the specified angle around a point.
Definition novasvg.h:828
static Matrix translated(float tx, float ty)
Creates a translation matrix with the specified offsets.
Definition novasvg.h:818
Matrix & invert()
Inverts this matrix.
Definition novasvg.h:808
Matrix operator*(const Matrix &matrix) const
Multiplies this matrix with another matrix.
Definition novasvg.h:763
Matrix & shear(float shx, float shy)
Shears this matrix by the specified factors.
Definition novasvg.h:798
Matrix & translate(float tx, float ty)
Translates this matrix by the specified offsets.
Definition novasvg.h:788
Matrix()=default
Initializes the matrix to the identity matrix.
Matrix & operator*=(const Matrix &matrix)
Multiplies this matrix with another matrix in place.
Definition novasvg.h:773
Matrix & scale(float sx, float sy)
Scales this matrix by the specified factors.
Definition novasvg.h:783
Matrix inverse() const
Returns the inverse of this matrix.
Definition novasvg.h:803
static Matrix scaled(float sx, float sy)
Creates a scaling matrix with the specified factors.
Definition novasvg.h:823
friend class Element
Definition novasvg.h:430
Node()=default
Constructs a null node.
SVGNode * m_node
Definition novasvg.h:429
bool isNull() const
Checks if the node is null.
Definition novasvg.h:404
SVGNode * node() const
Definition novasvg.h:428
bool isElement() const
Checks if the node is an element node.
Definition novasvg.h:848
TextNode toTextNode() const
Converts the node to a TextNode.
Definition novasvg.h:853
Element toElement() const
Converts the node to an Element.
Definition novasvg.h:860
bool isTextNode() const
Checks if the node is a text node.
Definition novasvg.h:843
bool operator==(const Node &node) const
Checks if two nodes are equal.
Definition novasvg.h:417
bool operator!=(const Node &node) const
Checks if two nodes are not equal.
Definition novasvg.h:424
Element parentElement() const
Returns the parent element.
Definition novasvg.h:867
constexpr Rect()=default
const std::string & getAttribute(std::string_view name) const
virtual Rect paintBoundingBox() const
virtual Transform localTransform() const
Definition svgelement.h:852
bool hasAttribute(std::string_view name) const
const SVGNodeList & children() const
Definition svgelement.h:850
virtual void render(SVGRenderState &state) const
bool setAttribute(std::string_view name, const std::string &value)
SVGElement * elementFromPoint(float x, float y)
SVGElement * parentElement() const
Definition svgelement.h:702
SVGRootElement * rootElement() const
Definition svgelement.h:700
virtual bool isTextNode() const
Definition svgelement.h:692
virtual bool isElement() const
Definition svgelement.h:693
float intrinsicHeight() const
float intrinsicWidth() const
SVGRootElement * layoutIfNeeded()
Transform localTransform() const override
void render(SVGRenderState &state) const override
const std::string & data() const
Definition svgelement.h:722
void setData(const std::string &data)
const std::string & data() const
Returns the text content of the node.
Definition novasvg.h:879
void setData(const std::string &data)
Sets the text content of the node.
Definition novasvg.h:886
TextNode()=default
Constructs a null text node.
Transform inverse() const
Definition canvas.h:632
Transform & postMultiply(const Transform &transform)
Definition canvas.h:607
static Transform translated(float tx, float ty)
Definition canvas.h:715
static Transform sheared(float shx, float shy)
Definition canvas.h:708
static Transform scaled(float sx, float sy)
Definition canvas.h:701
Rect mapRect(const Rect &rect) const
Definition canvas.h:661
static Transform rotated(float angle, float cx, float cy)
Definition canvas.h:687
struct surface surface_t
Represents an image surface for drawing operations.
Definition render.h:1152
NOVASVG_INLINE unsigned int color_to_argb32(const color_t *color)
Converts a color to a 32-bit unsigned ARGB value.
Definition paint.h:84
NOVASVG_INLINE int color_parse(color_t *color, const char *data, int length)
Parses a color from a string using CSS color syntax.
Definition paint.h:144
Main namespace for the NovaSVG library.
Definition bitmap.h:23
std::vector< Node > NodeList
Definition novasvg.h:433
std::vector< Element > ElementList
Definition novasvg.h:547
constexpr float operator*(const Point &a, const Point &b)
Definition canvas.h:108
int version()
Returns the version of the novasvg library encoded in a single integer.
Definition novasvg.h:711
const std::string emptyString
std::string versionString()
Returns the novasvg library version as a human-readable string in "X.Y.Z" format.
Definition novasvg.h:716
void(* novasvg_destroy_func_t)(void *closure)
Callback for cleaning up resources.
Definition novasvg.h:121
void(* novasvg_write_func_t)(void *closure, void *data, int size)
A function pointer type for a write callback.
Definition novasvg.h:129
#define NOVASVG_VERSION_STRING
Definition novasvg.h:101
#define NOVASVG_INLINE
Definition novasvg.h:42
#define NOVASVG_VERSION
Definition novasvg.h:97
#define NOVASVG_API
Definition render.h:62
Represents a color with red, green, blue, and alpha components.
Definition render.h:1019
A structure representing a 2D transformation matrix.
Definition render.h:138
A structure representing a rectangle in 2D space.
Definition render.h:125
std::string text
UTF-8; ' ' marks a forced line break ( ,.