mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 13:43:43 +00:00
Merge "SvgLoader: Support to linear, radial gradient" into tizen
This commit is contained in:
commit
22581040f3
5 changed files with 279 additions and 50 deletions
|
@ -1365,11 +1365,18 @@ static SvgNode* _findChildById(SvgNode* node, const char* id)
|
|||
}
|
||||
|
||||
|
||||
static vector<SvgGradientStop*> _cloneGradStops(vector<SvgGradientStop*> src)
|
||||
static void _cloneGradStops(vector<Fill::ColorStop*> *dst, vector<Fill::ColorStop*> src)
|
||||
{
|
||||
vector<SvgGradientStop*> dst;
|
||||
copy(src.begin(), src.end(), dst.begin());
|
||||
return dst;
|
||||
for(vector<Fill::ColorStop*>::iterator itrStop = src.begin(); itrStop != src.end(); itrStop++) {
|
||||
Fill::ColorStop *stop = (Fill::ColorStop *)malloc(sizeof(Fill::ColorStop));
|
||||
stop->r = (*itrStop)->r;
|
||||
stop->g = (*itrStop)->g;
|
||||
stop->b = (*itrStop)->b;
|
||||
stop->a = (*itrStop)->a;
|
||||
stop->offset = (*itrStop)->offset;
|
||||
dst->push_back(stop);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1381,8 +1388,8 @@ static SvgStyleGradient* _cloneGradient(SvgStyleGradient* from)
|
|||
|
||||
grad = (SvgStyleGradient*)calloc(1, sizeof(SvgStyleGradient));
|
||||
grad->type = from->type;
|
||||
grad->id = _copyId(from->id->c_str());
|
||||
grad->ref = _copyId(from->ref->c_str());
|
||||
grad->id = from->id ? _copyId(from->id->c_str()) : nullptr;
|
||||
grad->ref = from->ref ? _copyId(from->ref->c_str()) : nullptr;
|
||||
grad->spread = from->spread;
|
||||
grad->usePercentage = from->usePercentage;
|
||||
grad->userSpace = from->userSpace;
|
||||
|
@ -1390,7 +1397,6 @@ static SvgStyleGradient* _cloneGradient(SvgStyleGradient* from)
|
|||
grad->transform = (Matrix*)calloc(1, sizeof(Matrix));
|
||||
memcpy(grad->transform, from->transform, sizeof(Matrix));
|
||||
}
|
||||
grad->stops = _cloneGradStops(from->stops);
|
||||
if (grad->type == SvgGradientType::Linear) {
|
||||
grad->linear = (SvgLinearGradient*)calloc(1, sizeof(SvgLinearGradient));
|
||||
memcpy(grad->linear, from->linear, sizeof(SvgLinearGradient));
|
||||
|
@ -1399,6 +1405,7 @@ static SvgStyleGradient* _cloneGradient(SvgStyleGradient* from)
|
|||
memcpy(grad->radial, from->radial, sizeof(SvgRadialGradient));
|
||||
}
|
||||
|
||||
_cloneGradStops(&(grad->stops), from->stops);
|
||||
return grad;
|
||||
}
|
||||
|
||||
|
@ -1562,14 +1569,14 @@ FIND_FACTORY(Group, groupTags);
|
|||
FIND_FACTORY(Graphics, graphicsTags);
|
||||
|
||||
|
||||
SvgGradientSpread _parseSpreadValue(const char* value)
|
||||
FillSpread _parseSpreadValue(const char* value)
|
||||
{
|
||||
SvgGradientSpread spread = SvgGradientSpread::Pad;
|
||||
FillSpread spread = FillSpread::Pad;
|
||||
|
||||
if (!strcmp(value, "reflect")) {
|
||||
spread = SvgGradientSpread::Reflect;
|
||||
spread = FillSpread::Reflect;
|
||||
} else if (!strcmp(value, "repeat")) {
|
||||
spread = SvgGradientSpread::Repeat;
|
||||
spread = FillSpread::Repeat;
|
||||
}
|
||||
|
||||
return spread;
|
||||
|
@ -1730,7 +1737,7 @@ static SvgStyleGradient* _createRadialGradient(SvgLoaderData* loader, const char
|
|||
static bool _attrParseStops(void* data, const char* key, const char* value)
|
||||
{
|
||||
SvgLoaderData* loader = (SvgLoaderData*)data;
|
||||
SvgGradientStop* stop = loader->svgParse->gradStop;
|
||||
Fill::ColorStop* stop = loader->svgParse->gradStop;
|
||||
|
||||
if (!strcmp(key, "offset")) {
|
||||
stop->offset = _toOffset(value);
|
||||
|
@ -2008,7 +2015,7 @@ static void _svgLoaderParserXmlOpen(SvgLoaderData* loader, const char* content,
|
|||
}
|
||||
loader->latestGradient = gradient;
|
||||
} else if (!strcmp(tagName, "stop")) {
|
||||
SvgGradientStop* stop = (SvgGradientStop*)calloc(1, sizeof(SvgGradientStop));
|
||||
Fill::ColorStop* stop = (Fill::ColorStop*)calloc(1, sizeof(Fill::ColorStop));
|
||||
loader->svgParse->gradStop = stop;
|
||||
/* default value for opacity */
|
||||
stop->a = 255;
|
||||
|
@ -2067,7 +2074,7 @@ static void _styleInherit(SvgStyleProperty* child, SvgStyleProperty* parent)
|
|||
child->fill.paint.b = parent->fill.paint.b;
|
||||
child->fill.paint.none = parent->fill.paint.none;
|
||||
child->fill.paint.curColor = parent->fill.paint.curColor;
|
||||
child->fill.paint.url = parent->fill.paint.url ? _copyId(parent->fill.paint.url->c_str()) : nullptr;
|
||||
if (parent->fill.paint.url) child->fill.paint.url = _copyId(parent->fill.paint.url->c_str());
|
||||
}
|
||||
if (!((int)child->fill.flags & (int)SvgFillFlags::Opacity)) {
|
||||
child->fill.opacity = parent->fill.opacity;
|
||||
|
@ -2109,12 +2116,12 @@ static void _updateStyle(SvgNode* node, SvgStyleProperty* parentStyle)
|
|||
}
|
||||
|
||||
|
||||
static SvgStyleGradient* _gradientDup(vector<SvgStyleGradient*> gradList, const char* id)
|
||||
static SvgStyleGradient* _gradientDup(vector<SvgStyleGradient*> gradList, string* id)
|
||||
{
|
||||
SvgStyleGradient* result = nullptr;
|
||||
|
||||
for (vector<SvgStyleGradient*>::iterator itrGrad = gradList.begin(); itrGrad != gradList.end(); itrGrad++) {
|
||||
if ((*itrGrad)->id->compare(string(id))) {
|
||||
if (!((*itrGrad)->id->compare(*id))) {
|
||||
result = _cloneGradient(*itrGrad);
|
||||
break;
|
||||
}
|
||||
|
@ -2122,9 +2129,9 @@ static SvgStyleGradient* _gradientDup(vector<SvgStyleGradient*> gradList, const
|
|||
|
||||
if (result && result->ref) {
|
||||
for (vector<SvgStyleGradient*>::iterator itrGrad = gradList.begin(); itrGrad != gradList.end(); itrGrad++) {
|
||||
if ((*itrGrad)->id->compare(*result->ref)) {
|
||||
if (!((*itrGrad)->id->compare(*result->ref))) {
|
||||
if (!result->stops.empty()) {
|
||||
result->stops = _cloneGradStops((*itrGrad)->stops);
|
||||
_cloneGradStops(&(result->stops), (*itrGrad)->stops);
|
||||
}
|
||||
//TODO: Properly inherit other property
|
||||
break;
|
||||
|
@ -2138,15 +2145,15 @@ static SvgStyleGradient* _gradientDup(vector<SvgStyleGradient*> gradList, const
|
|||
|
||||
static void _updateGradient(SvgNode* node, vector<SvgStyleGradient*> gradList)
|
||||
{
|
||||
if (node->child.empty()) {
|
||||
if (!node->child.empty()) {
|
||||
for (vector<SvgNode*>::iterator itrChild = node->child.begin(); itrChild != node->child.end(); itrChild++) {
|
||||
_updateGradient(*itrChild, gradList);
|
||||
}
|
||||
} else {
|
||||
if (node->style->fill.paint.url) {
|
||||
node->style->fill.paint.gradient = _gradientDup(gradList, node->style->fill.paint.url->c_str());
|
||||
node->style->fill.paint.gradient = _gradientDup(gradList, node->style->fill.paint.url);
|
||||
} else if (node->style->stroke.paint.url) {
|
||||
node->style->stroke.paint.gradient = _gradientDup(gradList, node->style->stroke.paint.url->c_str());
|
||||
//node->style->stroke.paint.gradient = _gradientDup(gradList, node->style->stroke.paint.url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2161,7 +2168,7 @@ static void _freeGradientStyle(SvgStyleGradient* grad)
|
|||
free(grad->linear);
|
||||
if (grad->transform) free(grad->transform);
|
||||
|
||||
for(vector<SvgGradientStop*>::iterator itrStop = grad->stops.begin(); itrStop != grad->stops.end(); itrStop++) {
|
||||
for(vector<Fill::ColorStop*>::iterator itrStop = grad->stops.begin(); itrStop != grad->stops.end(); itrStop++) {
|
||||
free(*itrStop);
|
||||
}
|
||||
free(grad);
|
||||
|
@ -2284,7 +2291,9 @@ bool SvgLoader::read()
|
|||
else {
|
||||
if (!loader->loaderData.gradients.empty()) {
|
||||
vector<SvgStyleGradient*> gradientList;
|
||||
std::copy(loader->loaderData.gradients.begin(), loader->loaderData.gradients.end(), gradientList.begin());
|
||||
for(vector<SvgStyleGradient*>::iterator itrGrad = loader->loaderData.gradients.begin(); itrGrad != loader->loaderData.gradients.end(); itrGrad++) {
|
||||
gradientList.push_back(*itrGrad);
|
||||
}
|
||||
_updateGradient(loader->loaderData.doc, gradientList);
|
||||
gradientList.clear();
|
||||
}
|
||||
|
|
|
@ -97,14 +97,6 @@ enum class SvgStyleType
|
|||
CompOp
|
||||
};
|
||||
|
||||
enum class SvgGradientSpread
|
||||
{
|
||||
Pad = 0,
|
||||
Reflect,
|
||||
Repeat,
|
||||
Last
|
||||
};
|
||||
|
||||
enum class SvgFillRule
|
||||
{
|
||||
Winding = 0,
|
||||
|
@ -221,7 +213,7 @@ struct SvgGradientStop
|
|||
struct SvgPaint
|
||||
{
|
||||
SvgStyleGradient* gradient;
|
||||
string* url;
|
||||
string *url;
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
|
@ -238,13 +230,13 @@ struct SvgDash
|
|||
struct _SvgStyleGradient
|
||||
{
|
||||
SvgGradientType type;
|
||||
string* id;
|
||||
string* ref;
|
||||
SvgGradientSpread spread;
|
||||
vector<SvgGradientStop *> stops;
|
||||
string *id;
|
||||
string *ref;
|
||||
FillSpread spread;
|
||||
SvgRadialGradient* radial;
|
||||
SvgLinearGradient* linear;
|
||||
Matrix* transform;
|
||||
vector<Fill::ColorStop *> stops;
|
||||
bool userSpace;
|
||||
bool usePercentage;
|
||||
};
|
||||
|
@ -286,8 +278,8 @@ struct _SvgNode
|
|||
SvgNodeType type;
|
||||
SvgNode* parent;
|
||||
vector<SvgNode*> child;
|
||||
string* id;
|
||||
SvgStyleProperty* style;
|
||||
string *id;
|
||||
SvgStyleProperty *style;
|
||||
Matrix* transform;
|
||||
union {
|
||||
SvgGNode g;
|
||||
|
@ -309,7 +301,7 @@ struct SvgParser
|
|||
{
|
||||
SvgNode* node;
|
||||
SvgStyleGradient* styleGrad;
|
||||
SvgGradientStop* gradStop;
|
||||
Fill::ColorStop* gradStop;
|
||||
struct
|
||||
{
|
||||
int x, y;
|
||||
|
|
|
@ -40,7 +40,188 @@ static void _getTransformationData(Matrix* m, float* tx, float* ty, float* s, fl
|
|||
}
|
||||
|
||||
|
||||
unique_ptr<tvg::Shape> _applyProperty(SvgNode* node, unique_ptr<tvg::Shape> vg)
|
||||
unique_ptr<LinearGradient> _applyLinearGradientProperty(SvgStyleGradient* g, Shape* vg, float rx, float ry, float rw, float rh)
|
||||
{
|
||||
Fill::ColorStop* stops;
|
||||
int stopCount = 0;
|
||||
float fillOpacity = 255.0f;
|
||||
float gx, gy, gw, gh;
|
||||
|
||||
auto fillGrad = LinearGradient::gen();
|
||||
|
||||
if (g->usePercentage) {
|
||||
g->linear->x1 = g->linear->x1 * rw + rx;
|
||||
g->linear->y1 = g->linear->y1 * rh + ry;
|
||||
g->linear->x2 = g->linear->x2 * rw + rx;
|
||||
g->linear->y2 = g->linear->y2 * rh + ry;
|
||||
}
|
||||
|
||||
//In case of objectBoundingBox it need proper scaling
|
||||
if (!g->userSpace) {
|
||||
float scaleX = 1.0, scaleReversedX = 1.0;
|
||||
float scaleY = 1.0, scaleReversedY = 1.0;
|
||||
|
||||
//Check the smallest size, find the scale value
|
||||
if (rh > rw) {
|
||||
scaleY = ((float)rw) / rh;
|
||||
scaleReversedY = ((float)rh) / rw;
|
||||
} else {
|
||||
scaleX = ((float)rh) / rw;
|
||||
scaleReversedX = ((float)rw) / rh;
|
||||
}
|
||||
|
||||
vg->bounds(&gx, &gy, &gw, &gh);
|
||||
|
||||
float cy = ((float)gh) * 0.5 + gy;
|
||||
float cy_scaled = (((float)gh) * 0.5) * scaleReversedY;
|
||||
float cx = ((float)gw) * 0.5 + gx;
|
||||
float cx_scaled = (((float)gw) * 0.5) * scaleReversedX;
|
||||
|
||||
//= T(gx, gy) x S(scaleX, scaleY) x T(cx_scaled - cx, cy_scaled - cy) x (radial->x, radial->y)
|
||||
g->linear->x1 = g->linear->x1 * scaleX + scaleX * (cx_scaled - cx) + gx;
|
||||
g->linear->y1 = g->linear->y1 * scaleY + scaleY * (cy_scaled - cy) + gy;
|
||||
g->linear->x2 = g->linear->x2 * scaleX + scaleX * (cx_scaled - cx) + gx;
|
||||
g->linear->y2 = g->linear->y2 * scaleY + scaleY * (cy_scaled - cy) + gy;
|
||||
}
|
||||
|
||||
if (g->transform) {
|
||||
float cy = ((float) rh) * 0.5 + ry;
|
||||
float cx = ((float) rw) * 0.5 + rx;
|
||||
|
||||
//Calc start point
|
||||
//= T(x - cx, y - cy) x g->transform x T(cx, cy)
|
||||
g->linear->x1 = cx * (g->transform->e11 + g->transform->e31 * (g->linear->x1 - cx)) +
|
||||
cx * (g->transform->e12 + g->transform->e32 * (g->linear->x1 - cx)) +
|
||||
cx * (g->transform->e13 + g->transform->e33 * (g->linear->x1 - cx));
|
||||
|
||||
g->linear->y1 = cy * (g->transform->e21 + g->transform->e31 * (g->linear->y1 - cy)) +
|
||||
cy * (g->transform->e22 + g->transform->e32 * (g->linear->y1 - cy)) +
|
||||
cy * (g->transform->e23 + g->transform->e33 * (g->linear->y1 - cy));
|
||||
|
||||
//Calc end point
|
||||
g->linear->x2 = cx * (g->transform->e11 + g->transform->e31 * (g->linear->x2 - cx)) +
|
||||
cx * (g->transform->e12 + g->transform->e32 * (g->linear->x2 - cx)) +
|
||||
cx * (g->transform->e13 + g->transform->e33 * (g->linear->x2 - cx));
|
||||
|
||||
g->linear->y2 = cy * (g->transform->e21 + g->transform->e31 * (g->linear->y2 - cy)) +
|
||||
cy * (g->transform->e22 + g->transform->e32 * (g->linear->y2 - cy)) +
|
||||
cy * (g->transform->e23 + g->transform->e33 * (g->linear->y2 - cy));
|
||||
}
|
||||
|
||||
fillGrad->linear(g->linear->x1, g->linear->y1, g->linear->x2, g->linear->y2);
|
||||
fillGrad->spread(g->spread);
|
||||
|
||||
//Update the stops
|
||||
stopCount = g->stops.size();
|
||||
if (stopCount > 0) {
|
||||
float opacity;
|
||||
float fopacity = fillOpacity / 255.0f; //fill opacity if any exists.
|
||||
int i = 0;
|
||||
stops = (Fill::ColorStop*)calloc(stopCount, sizeof(Fill::ColorStop));
|
||||
for (vector<Fill::ColorStop*>::iterator itrStop = g->stops.begin(); itrStop != g->stops.end(); itrStop++) {
|
||||
//Use premultiplied color
|
||||
opacity = ((float)(*itrStop)->a / 255) * fopacity;
|
||||
stops[i].r = ((*itrStop)->r * opacity);
|
||||
stops[i].g = ((*itrStop)->g * opacity);
|
||||
stops[i].b = ((*itrStop)->b * opacity);
|
||||
stops[i].a = ((*itrStop)->a * fopacity);
|
||||
stops[i].offset = (*itrStop)->offset;
|
||||
i++;
|
||||
}
|
||||
fillGrad->colorStops(stops, stopCount);
|
||||
free(stops);
|
||||
}
|
||||
return move(fillGrad);
|
||||
}
|
||||
|
||||
|
||||
unique_ptr<RadialGradient> _applyRadialGradientProperty(SvgStyleGradient* g, Shape* vg, float rx, float ry, float rw, float rh)
|
||||
{
|
||||
Fill::ColorStop *stops;
|
||||
int stopCount = 0;
|
||||
float gx, gy, gw, gh;
|
||||
int radius;
|
||||
float fillOpacity = 255.0f;
|
||||
|
||||
auto fillGrad = RadialGradient::gen();
|
||||
|
||||
radius = sqrt(pow(rw, 2) + pow(rh, 2)) / sqrt(2.0);
|
||||
if (!g->userSpace) {
|
||||
//That is according to Units in here
|
||||
//https://www.w3.org/TR/2015/WD-SVG2-20150915/coords.html
|
||||
int min = (rh > rw) ? rw : rh;
|
||||
radius = sqrt(pow(min, 2) + pow(min, 2)) / sqrt(2.0);
|
||||
}
|
||||
|
||||
if (g->usePercentage) {
|
||||
g->radial->cx = g->radial->cx * rw + rx;
|
||||
g->radial->cy = g->radial->cy * rh + ry;
|
||||
g->radial->r = g->radial->r * radius;
|
||||
g->radial->fx = g->radial->fx * rw + rx;
|
||||
g->radial->fy = g->radial->fy * rh + ry;
|
||||
}
|
||||
|
||||
//In case of objectBoundingBox it need proper scaling
|
||||
if (!g->userSpace) {
|
||||
float scaleX = 1.0, scaleReversedX = 1.0;
|
||||
float scaleY = 1.0, scaleReversedY = 1.0;
|
||||
|
||||
//Check the smallest size, find the scale value
|
||||
if (rh > rw) {
|
||||
scaleY = ((float)rw) / rh;
|
||||
scaleReversedY = ((float)rh) / rw;
|
||||
} else {
|
||||
scaleX = ((float)rh) / rw;
|
||||
scaleReversedX = ((float)rw) / rh;
|
||||
}
|
||||
|
||||
vg->bounds(&gx, &gy, &gw, &gh);
|
||||
|
||||
float cy = ((float)gh) * 0.5 + gy;
|
||||
float cy_scaled = (((float)gh) * 0.5) * scaleReversedY;
|
||||
float cx = ((float)gw) * 0.5 + gx;
|
||||
float cx_scaled = (((float)gw) * 0.5) * scaleReversedX;
|
||||
|
||||
//= T(gx, gy) x S(scaleX, scaleY) x T(cx_scaled - cx, cy_scaled - cy) x (radial->x, radial->y)
|
||||
g->radial->cx = g->radial->cx * scaleX + scaleX * (cx_scaled - cx) + gx;
|
||||
g->radial->cy = g->radial->cy * scaleY + scaleY * (cy_scaled - cy) + gy;
|
||||
}
|
||||
|
||||
//TODO: Radial gradient transformation is not yet supported.
|
||||
//if (g->transform) {}
|
||||
|
||||
//TODO: Tvg is not support to focal
|
||||
//if (g->radial->fx != 0 && g->radial->fy != 0) {
|
||||
// fillGrad->radial(g->radial->fx, g->radial->fy, g->radial->r);
|
||||
//}
|
||||
fillGrad->radial(g->radial->cx, g->radial->cy, g->radial->r);
|
||||
fillGrad->spread(g->spread);
|
||||
|
||||
//Update the stops
|
||||
stopCount = g->stops.size();
|
||||
if (stopCount > 0) {
|
||||
float opacity;
|
||||
float fopacity = fillOpacity / 255.0f; //fill opacity if any exists.
|
||||
int i = 0;
|
||||
stops = (Fill::ColorStop*)calloc(stopCount, sizeof(Fill::ColorStop));
|
||||
for (vector<Fill::ColorStop*>::iterator itrStop = g->stops.begin(); itrStop != g->stops.end(); itrStop++) {
|
||||
//Use premultiplied color
|
||||
opacity = ((float)(*itrStop)->a / 255) * fopacity;
|
||||
stops[i].r = ((*itrStop)->r * opacity);
|
||||
stops[i].g = ((*itrStop)->g * opacity);
|
||||
stops[i].b = ((*itrStop)->b * opacity);
|
||||
stops[i].a = ((*itrStop)->a * fopacity);
|
||||
stops[i].offset = (*itrStop)->offset;
|
||||
i++;
|
||||
}
|
||||
fillGrad->colorStops(stops, stopCount);
|
||||
free(stops);
|
||||
}
|
||||
return move(fillGrad);
|
||||
}
|
||||
|
||||
|
||||
unique_ptr<Shape> _applyProperty(SvgNode* node, unique_ptr<Shape> vg, float vx, float vy, float vw, float vh)
|
||||
{
|
||||
SvgStyleProperty* style = node->style;
|
||||
|
||||
|
@ -59,7 +240,15 @@ unique_ptr<tvg::Shape> _applyProperty(SvgNode* node, unique_ptr<tvg::Shape> vg)
|
|||
if (style->fill.paint.none) {
|
||||
//Do nothing
|
||||
} else if (style->fill.paint.gradient) {
|
||||
//TODO: Support gradient style
|
||||
if (!style->fill.paint.gradient->userSpace) vg->bounds(&vx, &vy, &vw, &vh);
|
||||
|
||||
if (style->fill.paint.gradient->type == SvgGradientType::Linear) {
|
||||
auto linear = _applyLinearGradientProperty(style->fill.paint.gradient, vg.get(), vx, vy, vw, vh);
|
||||
vg->fill(move(linear));
|
||||
} else if (style->fill.paint.gradient->type == SvgGradientType::Radial) {
|
||||
auto radial = _applyRadialGradientProperty(style->fill.paint.gradient, vg.get(), vx, vy, vw, vh);
|
||||
vg->fill(move(radial));
|
||||
}
|
||||
} else if (style->fill.paint.curColor) {
|
||||
//Apply the current style color
|
||||
float fa = ((float)style->fill.opacity / 255.0);
|
||||
|
@ -113,9 +302,9 @@ unique_ptr<tvg::Shape> _applyProperty(SvgNode* node, unique_ptr<tvg::Shape> vg)
|
|||
}
|
||||
|
||||
|
||||
unique_ptr<tvg::Shape> _shapeBuildHelper(SvgNode* node)
|
||||
unique_ptr<Shape> _shapeBuildHelper(SvgNode* node, float vx, float vy, float vw, float vh)
|
||||
{
|
||||
auto shape = tvg::Shape::gen();
|
||||
auto shape = Shape::gen();
|
||||
switch (node->type) {
|
||||
case SvgNodeType::Path: {
|
||||
if (node->node.path.path) {
|
||||
|
@ -162,15 +351,15 @@ unique_ptr<tvg::Shape> _shapeBuildHelper(SvgNode* node)
|
|||
break;
|
||||
}
|
||||
}
|
||||
shape = move(_applyProperty(node, move(shape)));
|
||||
shape = move(_applyProperty(node, move(shape), vx, vy, vw, vh));
|
||||
return shape;
|
||||
}
|
||||
|
||||
|
||||
unique_ptr<tvg::Scene> _sceneBuildHelper(SvgNode* node)
|
||||
unique_ptr<Scene> _sceneBuildHelper(SvgNode* node, float vx, float vy, float vw, float vh)
|
||||
{
|
||||
if (node->type == SvgNodeType::Doc || node->type == SvgNodeType::G) {
|
||||
auto scene = tvg::Scene::gen();
|
||||
auto scene = Scene::gen();
|
||||
if (node->transform) {
|
||||
float tx = 0, ty = 0, s = 0, z = 0;
|
||||
_getTransformationData(node->transform, &tx, &ty, &s, &z);
|
||||
|
@ -180,8 +369,8 @@ unique_ptr<tvg::Scene> _sceneBuildHelper(SvgNode* node)
|
|||
}
|
||||
for (vector<SvgNode*>::iterator itrChild = node->child.begin(); itrChild != node->child.end(); itrChild++) {
|
||||
SvgNode* child = *itrChild;
|
||||
if (child->type == SvgNodeType::Doc || child->type == SvgNodeType::G) scene->push(_sceneBuildHelper(*itrChild));
|
||||
else scene->push(_shapeBuildHelper(*itrChild));
|
||||
if (child->type == SvgNodeType::Doc || child->type == SvgNodeType::G) scene->push(_sceneBuildHelper(*itrChild, vx, vy, vw, vh));
|
||||
else scene->push(_shapeBuildHelper(*itrChild, vx, vy, vw, vh));
|
||||
}
|
||||
return move(scene);
|
||||
}
|
||||
|
@ -209,7 +398,7 @@ unique_ptr<Scene> SvgSceneBuilder::build(SvgNode* node)
|
|||
viewBox.h = node->node.doc.vh;
|
||||
preserveAspect = node->node.doc.preserveAspect;
|
||||
staticViewBox = true;
|
||||
return _sceneBuildHelper(node);
|
||||
return _sceneBuildHelper(node, viewBox.x, viewBox.y, viewBox.w, viewBox.h);
|
||||
}
|
||||
|
||||
|
||||
|
|
20
test/svgs/lineargrad1.svg
Normal file
20
test/svgs/lineargrad1.svg
Normal file
|
@ -0,0 +1,20 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
id="linearGradient1"
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="0.2"
|
||||
y2="0.2"
|
||||
spreadMethod="reflect">
|
||||
<stop
|
||||
style="stop-color:#ff0000;stop-opacity:1;"
|
||||
offset="0"/>
|
||||
<stop
|
||||
style="stop-color:#0000ff;stop-opacity:1;"
|
||||
offset="1"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="100" height="100" fill="url(#linearGradient1)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 514 B |
19
test/svgs/radialgrad1.svg
Normal file
19
test/svgs/radialgrad1.svg
Normal file
|
@ -0,0 +1,19 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<defs
|
||||
id="defs4">
|
||||
<radialGradient
|
||||
id="radialGradient1"
|
||||
r="0.2"
|
||||
cx="0.3"
|
||||
cy="0.3"
|
||||
spreadMethod="reflect">
|
||||
<stop
|
||||
style="stop-color:#ff0000;stop-opacity:1;"
|
||||
offset="0"/>
|
||||
<stop
|
||||
style="stop-color:#0000ff;stop-opacity:1;"
|
||||
offset="1"/>
|
||||
</radialGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="100" height="100" fill="url(#radialGradient1)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 501 B |
Loading…
Add table
Reference in a new issue