thorvg/src/loaders/svg/tvgSvgLoaderCommon.h
Mira Grudzinska a0490fd026 svg_loader: improved clarity, no logical changes
Unnecessary structure removed, typos corrected,
comment added, an unused function argument removed.
2024-06-14 10:50:48 +09:00

571 lines
10 KiB
C++

/*
* Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef _TVG_SVG_LOADER_COMMON_H_
#define _TVG_SVG_LOADER_COMMON_H_
#include "tvgCommon.h"
#include "tvgArray.h"
struct SvgNode;
struct SvgStyleGradient;
//NOTE: Please update simpleXmlNodeTypeToString() as well.
enum class SvgNodeType
{
Doc,
G,
Defs,
Animation,
Arc,
Circle,
Ellipse,
Image,
Line,
Path,
Polygon,
Polyline,
Rect,
Text,
TextArea,
Tspan,
Use,
Video,
ClipPath,
Mask,
CssStyle,
Symbol,
Unknown
};
/*
// TODO - remove?
enum class SvgLengthType
{
Percent,
Px,
Pc,
Pt,
Mm,
Cm,
In,
};
*/
enum class SvgFillFlags
{
Paint = 0x01,
Opacity = 0x02,
Gradient = 0x04,
FillRule = 0x08,
ClipPath = 0x16
};
constexpr bool operator &(SvgFillFlags a, SvgFillFlags b)
{
return int(a) & int(b);
}
constexpr SvgFillFlags operator |(SvgFillFlags a, SvgFillFlags b)
{
return SvgFillFlags(int(a) | int(b));
}
enum class SvgStrokeFlags
{
Paint = 0x1,
Opacity = 0x2,
Gradient = 0x4,
Scale = 0x8,
Width = 0x10,
Cap = 0x20,
Join = 0x40,
Dash = 0x80,
Miterlimit = 0x100,
DashOffset = 0x200
};
constexpr bool operator &(SvgStrokeFlags a, SvgStrokeFlags b)
{
return int(a) & int(b);
}
constexpr SvgStrokeFlags operator |(SvgStrokeFlags a, SvgStrokeFlags b)
{
return SvgStrokeFlags(int(a) | int(b));
}
enum class SvgGradientType
{
Linear,
Radial
};
enum class SvgStyleFlags
{
Color = 0x01,
Fill = 0x02,
FillRule = 0x04,
FillOpacity = 0x08,
Opacity = 0x010,
Stroke = 0x20,
StrokeWidth = 0x40,
StrokeLineJoin = 0x80,
StrokeLineCap = 0x100,
StrokeOpacity = 0x200,
StrokeDashArray = 0x400,
Transform = 0x800,
ClipPath = 0x1000,
Mask = 0x2000,
MaskType = 0x4000,
Display = 0x8000,
PaintOrder = 0x10000,
StrokeMiterlimit = 0x20000,
StrokeDashOffset = 0x40000,
};
constexpr bool operator &(SvgStyleFlags a, SvgStyleFlags b)
{
return int(a) & int(b);
}
constexpr SvgStyleFlags operator |(SvgStyleFlags a, SvgStyleFlags b)
{
return SvgStyleFlags(int(a) | int(b));
}
enum class SvgStopStyleFlags
{
StopDefault = 0x0,
StopOpacity = 0x01,
StopColor = 0x02
};
constexpr bool operator &(SvgStopStyleFlags a, SvgStopStyleFlags b)
{
return int(a) & int(b);
}
constexpr SvgStopStyleFlags operator |(SvgStopStyleFlags a, SvgStopStyleFlags b)
{
return SvgStopStyleFlags(int(a) | int(b));
}
enum class SvgGradientFlags
{
None = 0x0,
GradientUnits = 0x1,
SpreadMethod = 0x2,
X1 = 0x4,
X2 = 0x8,
Y1 = 0x10,
Y2 = 0x20,
Cx = 0x40,
Cy = 0x80,
R = 0x100,
Fx = 0x200,
Fy = 0x400,
Fr = 0x800
};
constexpr bool operator &(SvgGradientFlags a, SvgGradientFlags b)
{
return int(a) & int(b);
}
constexpr SvgGradientFlags operator |(SvgGradientFlags a, SvgGradientFlags b)
{
return SvgGradientFlags(int(a) | int(b));
}
enum class SvgFillRule
{
Winding = 0,
OddEven = 1
};
enum class SvgMaskType
{
Luminance = 0,
Alpha
};
//Length type to recalculate %, pt, pc, mm, cm etc
enum class SvgParserLengthType
{
Vertical,
Horizontal,
//In case of, for example, radius of radial gradient
Other
};
enum class SvgViewFlag
{
None = 0x0,
Width = 0x01, //viewPort width
Height = 0x02, //viewPort height
Viewbox = 0x04, //viewBox x,y,w,h - used only if all 4 are correctly set
WidthInPercent = 0x08,
HeightInPercent = 0x10
};
constexpr bool operator &(SvgViewFlag a, SvgViewFlag b)
{
return static_cast<int>(a) & static_cast<int>(b);
}
constexpr SvgViewFlag operator |(SvgViewFlag a, SvgViewFlag b)
{
return SvgViewFlag(int(a) | int(b));
}
constexpr SvgViewFlag operator ^(SvgViewFlag a, SvgViewFlag b)
{
return SvgViewFlag(int(a) ^ int(b));
}
enum class AspectRatioAlign
{
None,
XMinYMin,
XMidYMin,
XMaxYMin,
XMinYMid,
XMidYMid,
XMaxYMid,
XMinYMax,
XMidYMax,
XMaxYMax
};
enum class AspectRatioMeetOrSlice
{
Meet,
Slice
};
struct SvgDocNode
{
float w; //unit: point or in percentage see: SvgViewFlag
float h; //unit: point or in percentage see: SvgViewFlag
float vx;
float vy;
float vw;
float vh;
SvgViewFlag viewFlag;
SvgNode* defs;
SvgNode* style;
AspectRatioAlign align;
AspectRatioMeetOrSlice meetOrSlice;
};
struct SvgGNode
{
};
struct SvgDefsNode
{
Array<SvgStyleGradient*> gradients;
};
struct SvgSymbolNode
{
float w, h;
float vx, vy, vw, vh;
AspectRatioAlign align;
AspectRatioMeetOrSlice meetOrSlice;
bool overflowVisible;
bool hasViewBox;
bool hasWidth;
bool hasHeight;
};
struct SvgUseNode
{
float x, y, w, h;
bool isWidthSet;
bool isHeightSet;
SvgNode* symbol;
};
struct SvgEllipseNode
{
float cx;
float cy;
float rx;
float ry;
};
struct SvgCircleNode
{
float cx;
float cy;
float r;
};
struct SvgRectNode
{
float x;
float y;
float w;
float h;
float rx;
float ry;
bool hasRx;
bool hasRy;
};
struct SvgLineNode
{
float x1;
float y1;
float x2;
float y2;
};
struct SvgImageNode
{
float x, y, w, h;
char* href;
};
struct SvgPathNode
{
char* path;
};
struct SvgPolygonNode
{
Array<float> pts;
};
struct SvgClipNode
{
bool userSpace;
};
struct SvgMaskNode
{
SvgMaskType type;
bool userSpace;
};
struct SvgCssStyleNode
{
};
struct SvgLinearGradient
{
float x1;
float y1;
float x2;
float y2;
bool isX1Percentage;
bool isY1Percentage;
bool isX2Percentage;
bool isY2Percentage;
};
struct SvgRadialGradient
{
float cx;
float cy;
float fx;
float fy;
float r;
float fr;
bool isCxPercentage;
bool isCyPercentage;
bool isFxPercentage;
bool isFyPercentage;
bool isRPercentage;
bool isFrPercentage;
};
struct SvgComposite
{
char *url;
SvgNode* node;
bool applying; //flag for checking circular dependency.
};
struct SvgColor
{
uint8_t r;
uint8_t g;
uint8_t b;
};
struct SvgPaint
{
SvgStyleGradient* gradient;
char *url;
SvgColor color;
bool none;
bool curColor;
};
struct SvgDash
{
Array<float> array;
float offset;
};
struct SvgStyleGradient
{
SvgGradientType type;
char* id;
char* ref;
FillSpread spread;
SvgRadialGradient* radial;
SvgLinearGradient* linear;
Matrix* transform;
Array<Fill::ColorStop> stops;
SvgGradientFlags flags;
bool userSpace;
void clear()
{
stops.reset();
free(transform);
free(radial);
free(linear);
free(ref);
free(id);
}
};
struct SvgStyleFill
{
SvgFillFlags flags;
SvgPaint paint;
int opacity;
FillRule fillRule;
};
struct SvgStyleStroke
{
SvgStrokeFlags flags;
SvgPaint paint;
int opacity;
float scale;
float width;
float centered;
StrokeCap cap;
StrokeJoin join;
float miterlimit;
SvgDash dash;
};
struct SvgStyleProperty
{
SvgStyleFill fill;
SvgStyleStroke stroke;
SvgComposite clipPath;
SvgComposite mask;
int opacity;
SvgColor color;
char* cssClass;
SvgStyleFlags flags;
SvgStyleFlags flagsImportance; //indicates the importance of the flag - if set, higher priority is applied (https://drafts.csswg.org/css-cascade-4/#importance)
bool curColorSet;
bool paintOrder; //true if default (fill, stroke), false otherwise
bool display;
};
struct SvgNode
{
SvgNodeType type;
SvgNode* parent;
Array<SvgNode*> child;
char *id;
SvgStyleProperty *style;
Matrix* transform;
union {
SvgGNode g;
SvgDocNode doc;
SvgDefsNode defs;
SvgUseNode use;
SvgCircleNode circle;
SvgEllipseNode ellipse;
SvgPolygonNode polygon;
SvgPolygonNode polyline;
SvgRectNode rect;
SvgPathNode path;
SvgLineNode line;
SvgImageNode image;
SvgMaskNode mask;
SvgClipNode clip;
SvgCssStyleNode cssStyle;
SvgSymbolNode symbol;
} node;
~SvgNode();
};
struct SvgParser
{
SvgNode* node;
SvgStyleGradient* styleGrad;
Fill::ColorStop gradStop;
SvgStopStyleFlags flags;
struct
{
float x, y, w, h;
} global;
struct
{
bool parsedFx;
bool parsedFy;
} gradient;
};
struct SvgNodeIdPair
{
SvgNode* node;
char *id;
};
struct SvgLoaderData
{
Array<SvgNode*> stack;
SvgNode* doc = nullptr;
SvgNode* def = nullptr; //also used to store nested graphic nodes
SvgNode* cssStyle = nullptr;
Array<SvgStyleGradient*> gradients;
SvgStyleGradient* latestGradient = nullptr; //For stops
SvgParser* svgParse = nullptr;
Array<SvgNodeIdPair> cloneNodes;
Array<SvgNodeIdPair> nodesToStyle;
Array<char*> images; //embedded images
int level = 0;
bool result = false;
bool style = false;
SvgNode* currentGraphicsNode = nullptr;
};
struct Box
{
float x, y, w, h;
};
#endif