mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 21:53:41 +00:00
common: code refactoring
use ARRAY_FOREACH() for neat code and accessing the memory efficiently than normal indexing.
This commit is contained in:
parent
096b834771
commit
07e73a9e6f
25 changed files with 251 additions and 304 deletions
|
@ -27,6 +27,9 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#define ARRAY_FOREACH(A, B) \
|
||||||
|
for (auto A = (B).begin(); A < (B).end(); ++A)
|
||||||
|
|
||||||
namespace tvg
|
namespace tvg
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -336,8 +336,8 @@ static void _repeat(LottieGroup* parent, Shape* path, RenderContext* ctx)
|
||||||
for (int i = 0; i < repeater->cnt; ++i) {
|
for (int i = 0; i < repeater->cnt; ++i) {
|
||||||
auto multiplier = repeater->offset + static_cast<float>(i);
|
auto multiplier = repeater->offset + static_cast<float>(i);
|
||||||
|
|
||||||
for (auto propagator = propagators.begin(); propagator < propagators.end(); ++propagator) {
|
ARRAY_FOREACH(p, propagators) {
|
||||||
auto shape = static_cast<Shape*>((*propagator)->duplicate());
|
auto shape = static_cast<Shape*>((*p)->duplicate());
|
||||||
SHAPE(shape)->rs.path = SHAPE(path)->rs.path;
|
SHAPE(shape)->rs.path = SHAPE(path)->rs.path;
|
||||||
|
|
||||||
auto opacity = repeater->interpOpacity ? lerp<uint8_t>(repeater->startOpacity, repeater->endOpacity, static_cast<float>(i + 1) / repeater->cnt) : repeater->startOpacity;
|
auto opacity = repeater->interpOpacity ? lerp<uint8_t>(repeater->startOpacity, repeater->endOpacity, static_cast<float>(i + 1) / repeater->cnt) : repeater->startOpacity;
|
||||||
|
@ -363,9 +363,9 @@ static void _repeat(LottieGroup* parent, Shape* path, RenderContext* ctx)
|
||||||
|
|
||||||
//push repeat shapes in order.
|
//push repeat shapes in order.
|
||||||
if (repeater->inorder) {
|
if (repeater->inorder) {
|
||||||
for (auto shape = shapes.begin(); shape < shapes.end(); ++shape) {
|
ARRAY_FOREACH(p, shapes) {
|
||||||
parent->scene->push(*shape);
|
parent->scene->push(*p);
|
||||||
propagators.push(*shape);
|
propagators.push(*p);
|
||||||
}
|
}
|
||||||
} else if (!shapes.empty()) {
|
} else if (!shapes.empty()) {
|
||||||
for (auto shape = shapes.end() - 1; shape >= shapes.begin(); --shape) {
|
for (auto shape = shapes.end() - 1; shape >= shapes.begin(); --shape) {
|
||||||
|
@ -1066,7 +1066,7 @@ void LottieBuilder::updateText(LottieLayer* layer, float frameNo)
|
||||||
|
|
||||||
//find the glyph
|
//find the glyph
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (auto g = text->font->chars.begin(); g < text->font->chars.end(); ++g) {
|
ARRAY_FOREACH(g, text->font->chars) {
|
||||||
auto glyph = *g;
|
auto glyph = *g;
|
||||||
//draw matched glyphs
|
//draw matched glyphs
|
||||||
if (!strncmp(glyph->code, code, glyph->len)) {
|
if (!strncmp(glyph->code, code, glyph->len)) {
|
||||||
|
@ -1080,9 +1080,9 @@ void LottieBuilder::updateText(LottieLayer* layer, float frameNo)
|
||||||
auto& textGroupMatrix = textGroup->transform();
|
auto& textGroupMatrix = textGroup->transform();
|
||||||
auto shape = text->pooling();
|
auto shape = text->pooling();
|
||||||
shape->reset();
|
shape->reset();
|
||||||
for (auto g = glyph->children.begin(); g < glyph->children.end(); ++g) {
|
ARRAY_FOREACH(p, glyph->children) {
|
||||||
auto group = static_cast<LottieGroup*>(*g);
|
auto group = static_cast<LottieGroup*>(*p);
|
||||||
for (auto p = group->children.begin(); p < group->children.end(); ++p) {
|
ARRAY_FOREACH(p, group->children) {
|
||||||
if (static_cast<LottiePath*>(*p)->pathset(frameNo, SHAPE(shape)->rs.path.cmds, SHAPE(shape)->rs.path.pts, nullptr, nullptr, nullptr)) {
|
if (static_cast<LottiePath*>(*p)->pathset(frameNo, SHAPE(shape)->rs.path.cmds, SHAPE(shape)->rs.path.pts, nullptr, nullptr, nullptr)) {
|
||||||
PAINT(shape)->update(RenderUpdateFlag::Path);
|
PAINT(shape)->update(RenderUpdateFlag::Path);
|
||||||
}
|
}
|
||||||
|
@ -1111,50 +1111,51 @@ void LottieBuilder::updateText(LottieLayer* layer, float frameNo)
|
||||||
uint8_t fillOpacity = 255;
|
uint8_t fillOpacity = 255;
|
||||||
uint8_t strokeOpacity = 255;
|
uint8_t strokeOpacity = 255;
|
||||||
|
|
||||||
for (auto s = text->ranges.begin(); s < text->ranges.end(); ++s) {
|
ARRAY_FOREACH(p, text->ranges) {
|
||||||
|
auto range = *p;
|
||||||
auto basedIdx = idx;
|
auto basedIdx = idx;
|
||||||
if ((*s)->based == LottieTextRange::Based::CharsExcludingSpaces) basedIdx = idx - space;
|
if (range->based == LottieTextRange::Based::CharsExcludingSpaces) basedIdx = idx - space;
|
||||||
else if ((*s)->based == LottieTextRange::Based::Words) basedIdx = line + space;
|
else if (range->based == LottieTextRange::Based::Words) basedIdx = line + space;
|
||||||
else if ((*s)->based == LottieTextRange::Based::Lines) basedIdx = line;
|
else if (range->based == LottieTextRange::Based::Lines) basedIdx = line;
|
||||||
|
|
||||||
auto f = (*s)->factor(frameNo, float(totalChars), (float)basedIdx);
|
auto f = range->factor(frameNo, float(totalChars), (float)basedIdx);
|
||||||
if (tvg::zero(f)) continue;
|
if (tvg::zero(f)) continue;
|
||||||
needGroup = true;
|
needGroup = true;
|
||||||
|
|
||||||
translation = translation + f * (*s)->style.position(frameNo);
|
translation = translation + f * range->style.position(frameNo);
|
||||||
scaling = scaling * (f * ((*s)->style.scale(frameNo) * 0.01f - Point{1.0f, 1.0f}) + Point{1.0f, 1.0f});
|
scaling = scaling * (f * (range->style.scale(frameNo) * 0.01f - Point{1.0f, 1.0f}) + Point{1.0f, 1.0f});
|
||||||
rotation += f * (*s)->style.rotation(frameNo);
|
rotation += f * range->style.rotation(frameNo);
|
||||||
|
|
||||||
opacity = (uint8_t)(opacity - f * (opacity - (*s)->style.opacity(frameNo)));
|
opacity = (uint8_t)(opacity - f * (opacity - range->style.opacity(frameNo)));
|
||||||
shape->opacity(opacity);
|
shape->opacity(opacity);
|
||||||
|
|
||||||
auto rangeColor = (*s)->style.fillColor(frameNo); //TODO: use flag to check whether it was really set
|
auto rangeColor = range->style.fillColor(frameNo); //TODO: use flag to check whether it was really set
|
||||||
if (tvg::equal(f, 1.0f)) color = rangeColor;
|
if (tvg::equal(f, 1.0f)) color = rangeColor;
|
||||||
else {
|
else {
|
||||||
color.rgb[0] = lerp<uint8_t>(color.rgb[0], rangeColor.rgb[0], f);
|
color.rgb[0] = lerp<uint8_t>(color.rgb[0], rangeColor.rgb[0], f);
|
||||||
color.rgb[1] = lerp<uint8_t>(color.rgb[1], rangeColor.rgb[1], f);
|
color.rgb[1] = lerp<uint8_t>(color.rgb[1], rangeColor.rgb[1], f);
|
||||||
color.rgb[2] = lerp<uint8_t>(color.rgb[2], rangeColor.rgb[2], f);
|
color.rgb[2] = lerp<uint8_t>(color.rgb[2], rangeColor.rgb[2], f);
|
||||||
}
|
}
|
||||||
fillOpacity = (uint8_t)(fillOpacity - f * (fillOpacity - (*s)->style.fillOpacity(frameNo)));
|
fillOpacity = (uint8_t)(fillOpacity - f * (fillOpacity - range->style.fillOpacity(frameNo)));
|
||||||
shape->fill(color.rgb[0], color.rgb[1], color.rgb[2], fillOpacity);
|
shape->fill(color.rgb[0], color.rgb[1], color.rgb[2], fillOpacity);
|
||||||
|
|
||||||
shape->strokeWidth(f * (*s)->style.strokeWidth(frameNo) / scale);
|
shape->strokeWidth(f * range->style.strokeWidth(frameNo) / scale);
|
||||||
if (shape->strokeWidth() > 0.0f) {
|
if (shape->strokeWidth() > 0.0f) {
|
||||||
auto rangeColor = (*s)->style.strokeColor(frameNo); //TODO: use flag to check whether it was really set
|
auto rangeColor = range->style.strokeColor(frameNo); //TODO: use flag to check whether it was really set
|
||||||
if (tvg::equal(f, 1.0f)) strokeColor = rangeColor;
|
if (tvg::equal(f, 1.0f)) strokeColor = rangeColor;
|
||||||
else {
|
else {
|
||||||
strokeColor.rgb[0] = lerp<uint8_t>(strokeColor.rgb[0], rangeColor.rgb[0], f);
|
strokeColor.rgb[0] = lerp<uint8_t>(strokeColor.rgb[0], rangeColor.rgb[0], f);
|
||||||
strokeColor.rgb[1] = lerp<uint8_t>(strokeColor.rgb[1], rangeColor.rgb[1], f);
|
strokeColor.rgb[1] = lerp<uint8_t>(strokeColor.rgb[1], rangeColor.rgb[1], f);
|
||||||
strokeColor.rgb[2] = lerp<uint8_t>(strokeColor.rgb[2], rangeColor.rgb[2], f);
|
strokeColor.rgb[2] = lerp<uint8_t>(strokeColor.rgb[2], rangeColor.rgb[2], f);
|
||||||
}
|
}
|
||||||
strokeOpacity = (uint8_t)(strokeOpacity - f * (strokeOpacity - (*s)->style.strokeOpacity(frameNo)));
|
strokeOpacity = (uint8_t)(strokeOpacity - f * (strokeOpacity - range->style.strokeOpacity(frameNo)));
|
||||||
shape->strokeFill(strokeColor.rgb[0], strokeColor.rgb[1], strokeColor.rgb[2], strokeOpacity);
|
shape->strokeFill(strokeColor.rgb[0], strokeColor.rgb[1], strokeColor.rgb[2], strokeOpacity);
|
||||||
shape->order(doc.stroke.below);
|
shape->order(doc.stroke.below);
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor.x += f * (*s)->style.letterSpacing(frameNo);
|
cursor.x += f * range->style.letterSpacing(frameNo);
|
||||||
|
|
||||||
auto spacing = f * (*s)->style.lineSpacing(frameNo);
|
auto spacing = f * range->style.lineSpacing(frameNo);
|
||||||
if (spacing > lineSpacing) lineSpacing = spacing;
|
if (spacing > lineSpacing) lineSpacing = spacing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1237,8 +1238,8 @@ void LottieBuilder::updateMasks(LottieLayer* layer, float frameNo)
|
||||||
MaskMethod pMethod;
|
MaskMethod pMethod;
|
||||||
uint8_t pOpacity;
|
uint8_t pOpacity;
|
||||||
|
|
||||||
for (auto m = layer->masks.begin(); m < layer->masks.end(); ++m) {
|
ARRAY_FOREACH(p, layer->masks) {
|
||||||
auto mask = *m;
|
auto mask = *p;
|
||||||
if (mask->method == MaskMethod::None) continue;
|
if (mask->method == MaskMethod::None) continue;
|
||||||
|
|
||||||
auto method = mask->method;
|
auto method = mask->method;
|
||||||
|
@ -1318,8 +1319,8 @@ void LottieBuilder::updateStrokeEffect(LottieLayer* layer, LottieFxStroke* effec
|
||||||
|
|
||||||
//FIXME: all mask
|
//FIXME: all mask
|
||||||
if (effect->allMask(frameNo)) {
|
if (effect->allMask(frameNo)) {
|
||||||
for (auto m = layer->masks.begin(); m < layer->masks.end(); ++m) {
|
ARRAY_FOREACH(p, layer->masks) {
|
||||||
auto mask = *m;
|
auto mask = *p;
|
||||||
mask->pathset(frameNo, SHAPE(shape)->rs.path.cmds, SHAPE(shape)->rs.path.pts, nullptr, nullptr, nullptr, exps);
|
mask->pathset(frameNo, SHAPE(shape)->rs.path.cmds, SHAPE(shape)->rs.path.pts, nullptr, nullptr, nullptr, exps);
|
||||||
}
|
}
|
||||||
//A specific mask
|
//A specific mask
|
||||||
|
@ -1370,29 +1371,29 @@ void LottieBuilder::updateEffect(LottieLayer* layer, float frameNo)
|
||||||
|
|
||||||
if (layer->effects.count == 0) return;
|
if (layer->effects.count == 0) return;
|
||||||
|
|
||||||
for (auto ef = layer->effects.begin(); ef < layer->effects.end(); ++ef) {
|
ARRAY_FOREACH(p, layer->effects) {
|
||||||
if (!(*ef)->enable) continue;
|
if (!(*p)->enable) continue;
|
||||||
switch ((*ef)->type) {
|
switch ((*p)->type) {
|
||||||
case LottieEffect::Tint: {
|
case LottieEffect::Tint: {
|
||||||
auto effect = static_cast<LottieFxTint*>(*ef);
|
auto effect = static_cast<LottieFxTint*>(*p);
|
||||||
auto black = effect->black(frameNo);
|
auto black = effect->black(frameNo);
|
||||||
auto white = effect->white(frameNo);
|
auto white = effect->white(frameNo);
|
||||||
layer->scene->push(SceneEffect::Tint, black.rgb[0], black.rgb[1], black.rgb[2], white.rgb[0], white.rgb[1], white.rgb[2], (double)effect->intensity(frameNo));
|
layer->scene->push(SceneEffect::Tint, black.rgb[0], black.rgb[1], black.rgb[2], white.rgb[0], white.rgb[1], white.rgb[2], (double)effect->intensity(frameNo));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LottieEffect::Fill: {
|
case LottieEffect::Fill: {
|
||||||
auto effect = static_cast<LottieFxFill*>(*ef);
|
auto effect = static_cast<LottieFxFill*>(*p);
|
||||||
auto color = effect->color(frameNo);
|
auto color = effect->color(frameNo);
|
||||||
layer->scene->push(SceneEffect::Fill, color.rgb[0], color.rgb[1], color.rgb[2], (int)(255.0f * effect->opacity(frameNo)));
|
layer->scene->push(SceneEffect::Fill, color.rgb[0], color.rgb[1], color.rgb[2], (int)(255.0f * effect->opacity(frameNo)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LottieEffect::Stroke: {
|
case LottieEffect::Stroke: {
|
||||||
auto effect = static_cast<LottieFxStroke*>(*ef);
|
auto effect = static_cast<LottieFxStroke*>(*p);
|
||||||
updateStrokeEffect(layer, effect, frameNo);
|
updateStrokeEffect(layer, effect, frameNo);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LottieEffect::Tritone: {
|
case LottieEffect::Tritone: {
|
||||||
auto effect = static_cast<LottieFxTritone*>(*ef);
|
auto effect = static_cast<LottieFxTritone*>(*p);
|
||||||
auto dark = effect->dark(frameNo);
|
auto dark = effect->dark(frameNo);
|
||||||
auto midtone = effect->midtone(frameNo);
|
auto midtone = effect->midtone(frameNo);
|
||||||
auto bright = effect->bright(frameNo);
|
auto bright = effect->bright(frameNo);
|
||||||
|
@ -1400,14 +1401,14 @@ void LottieBuilder::updateEffect(LottieLayer* layer, float frameNo)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LottieEffect::DropShadow: {
|
case LottieEffect::DropShadow: {
|
||||||
auto effect = static_cast<LottieFxDropShadow*>(*ef);
|
auto effect = static_cast<LottieFxDropShadow*>(*p);
|
||||||
auto color = effect->color(frameNo);
|
auto color = effect->color(frameNo);
|
||||||
//seems the opacity range in dropshadow is 0 ~ 256
|
//seems the opacity range in dropshadow is 0 ~ 256
|
||||||
layer->scene->push(SceneEffect::DropShadow, color.rgb[0], color.rgb[1], color.rgb[2], std::min(255, (int)effect->opacity(frameNo)), (double)effect->angle(frameNo), (double)effect->distance(frameNo), (double)effect->blurness(frameNo) * BLUR_TO_SIGMA, QUALITY);
|
layer->scene->push(SceneEffect::DropShadow, color.rgb[0], color.rgb[1], color.rgb[2], std::min(255, (int)effect->opacity(frameNo)), (double)effect->angle(frameNo), (double)effect->distance(frameNo), (double)effect->blurness(frameNo) * BLUR_TO_SIGMA, QUALITY);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LottieEffect::GaussianBlur: {
|
case LottieEffect::GaussianBlur: {
|
||||||
auto effect = static_cast<LottieFxGaussianBlur*>(*ef);
|
auto effect = static_cast<LottieFxGaussianBlur*>(*p);
|
||||||
layer->scene->push(SceneEffect::GaussianBlur, (double)effect->blurness(frameNo) * BLUR_TO_SIGMA, effect->direction(frameNo) - 1, effect->wrap(frameNo), QUALITY);
|
layer->scene->push(SceneEffect::GaussianBlur, (double)effect->blurness(frameNo) * BLUR_TO_SIGMA, effect->direction(frameNo) - 1, effect->wrap(frameNo), QUALITY);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1481,16 +1482,16 @@ void LottieBuilder::updateLayer(LottieComposition* comp, Scene* scene, LottieLay
|
||||||
|
|
||||||
static void _buildReference(LottieComposition* comp, LottieLayer* layer)
|
static void _buildReference(LottieComposition* comp, LottieLayer* layer)
|
||||||
{
|
{
|
||||||
for (auto asset = comp->assets.begin(); asset < comp->assets.end(); ++asset) {
|
ARRAY_FOREACH(p, comp->assets) {
|
||||||
if (layer->rid != (*asset)->id) continue;
|
if (layer->rid != (*p)->id) continue;
|
||||||
if (layer->type == LottieLayer::Precomp) {
|
if (layer->type == LottieLayer::Precomp) {
|
||||||
auto assetLayer = static_cast<LottieLayer*>(*asset);
|
auto assetLayer = static_cast<LottieLayer*>(*p);
|
||||||
if (_buildComposition(comp, assetLayer)) {
|
if (_buildComposition(comp, assetLayer)) {
|
||||||
layer->children = assetLayer->children;
|
layer->children = assetLayer->children;
|
||||||
layer->reqFragment = assetLayer->reqFragment;
|
layer->reqFragment = assetLayer->reqFragment;
|
||||||
}
|
}
|
||||||
} else if (layer->type == LottieLayer::Image) {
|
} else if (layer->type == LottieLayer::Image) {
|
||||||
layer->children.push(*asset);
|
layer->children.push(*p);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1506,7 +1507,7 @@ static void _buildHierarchy(LottieGroup* parent, LottieLayer* child)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto p = parent->children.begin(); p < parent->children.end(); ++p) {
|
ARRAY_FOREACH(p, parent->children) {
|
||||||
auto parent = static_cast<LottieLayer*>(*p);
|
auto parent = static_cast<LottieLayer*>(*p);
|
||||||
if (child == parent) continue;
|
if (child == parent) continue;
|
||||||
if (child->pidx == parent->idx) {
|
if (child->pidx == parent->idx) {
|
||||||
|
@ -1524,8 +1525,8 @@ static void _buildHierarchy(LottieGroup* parent, LottieLayer* child)
|
||||||
static void _attachFont(LottieComposition* comp, LottieLayer* parent)
|
static void _attachFont(LottieComposition* comp, LottieLayer* parent)
|
||||||
{
|
{
|
||||||
//TODO: Consider to migrate this attachment to the frame update time.
|
//TODO: Consider to migrate this attachment to the frame update time.
|
||||||
for (auto c = parent->children.begin(); c < parent->children.end(); ++c) {
|
ARRAY_FOREACH(p, parent->children) {
|
||||||
auto text = static_cast<LottieText*>(*c);
|
auto text = static_cast<LottieText*>(*p);
|
||||||
auto& doc = text->doc(0);
|
auto& doc = text->doc(0);
|
||||||
if (!doc.name) continue;
|
if (!doc.name) continue;
|
||||||
auto len = strlen(doc.name);
|
auto len = strlen(doc.name);
|
||||||
|
@ -1547,8 +1548,8 @@ static bool _buildComposition(LottieComposition* comp, LottieLayer* parent)
|
||||||
if (parent->buildDone) return true;
|
if (parent->buildDone) return true;
|
||||||
parent->buildDone = true;
|
parent->buildDone = true;
|
||||||
|
|
||||||
for (auto c = parent->children.begin(); c < parent->children.end(); ++c) {
|
ARRAY_FOREACH(p, parent->children) {
|
||||||
auto child = static_cast<LottieLayer*>(*c);
|
auto child = static_cast<LottieLayer*>(*p);
|
||||||
|
|
||||||
//attach the precomp layer.
|
//attach the precomp layer.
|
||||||
if (child->rid) _buildReference(comp, child);
|
if (child->rid) _buildReference(comp, child);
|
||||||
|
@ -1556,8 +1557,8 @@ static bool _buildComposition(LottieComposition* comp, LottieLayer* parent)
|
||||||
if (child->matteType != MaskMethod::None) {
|
if (child->matteType != MaskMethod::None) {
|
||||||
//no index of the matte layer is provided: the layer above is used as the matte source
|
//no index of the matte layer is provided: the layer above is used as the matte source
|
||||||
if (child->mid == -1) {
|
if (child->mid == -1) {
|
||||||
if (c > parent->children.begin()) {
|
if (p > parent->children.begin()) {
|
||||||
child->matteTarget = static_cast<LottieLayer*>(*(c - 1));
|
child->matteTarget = static_cast<LottieLayer*>(*(p - 1));
|
||||||
}
|
}
|
||||||
//matte layer is specified by an index.
|
//matte layer is specified by an index.
|
||||||
} else child->matteTarget = parent->layerByIdx(child->mid);
|
} else child->matteTarget = parent->layerByIdx(child->mid);
|
||||||
|
|
|
@ -186,9 +186,9 @@ static jerry_value_t _buildGroup(LottieGroup* group, float frameNo)
|
||||||
auto obj = jerry_function_external(_content);
|
auto obj = jerry_function_external(_content);
|
||||||
|
|
||||||
//attach a transform
|
//attach a transform
|
||||||
for (auto c = group->children.begin(); c < group->children.end(); ++c) {
|
ARRAY_FOREACH(p, group->children) {
|
||||||
if ((*c)->type == LottieObject::Type::Transform) {
|
if ((*p)->type == LottieObject::Type::Transform) {
|
||||||
_buildTransform(obj, frameNo, static_cast<LottieTransform*>(*c));
|
_buildTransform(obj, frameNo, static_cast<LottieTransform*>(*p));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -307,9 +307,9 @@ bool LottieLoader::override(const char* slots, bool byDefault)
|
||||||
auto succeed = false;
|
auto succeed = false;
|
||||||
while (auto sid = parser.sid(idx == 0)) {
|
while (auto sid = parser.sid(idx == 0)) {
|
||||||
auto applied = false;
|
auto applied = false;
|
||||||
for (auto s = comp->slots.begin(); s < comp->slots.end(); ++s) {
|
ARRAY_FOREACH(p, comp->slots) {
|
||||||
if (strcmp((*s)->sid, sid)) continue;
|
if (strcmp((*p)->sid, sid)) continue;
|
||||||
if (parser.apply(*s, byDefault)) succeed = applied = true;
|
if (parser.apply(*p, byDefault)) succeed = applied = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!applied) parser.skip();
|
if (!applied) parser.skip();
|
||||||
|
@ -321,8 +321,8 @@ bool LottieLoader::override(const char* slots, bool byDefault)
|
||||||
return rebuild;
|
return rebuild;
|
||||||
//reset slots
|
//reset slots
|
||||||
} else if (overridden) {
|
} else if (overridden) {
|
||||||
for (auto s = comp->slots.begin(); s < comp->slots.end(); ++s) {
|
ARRAY_FOREACH(p, comp->slots) {
|
||||||
(*s)->reset();
|
(*p)->reset();
|
||||||
}
|
}
|
||||||
overridden = false;
|
overridden = false;
|
||||||
rebuild = true;
|
rebuild = true;
|
||||||
|
@ -404,10 +404,10 @@ bool LottieLoader::segment(const char* marker, float& begin, float& end)
|
||||||
{
|
{
|
||||||
if (!ready() || comp->markers.count == 0) return false;
|
if (!ready() || comp->markers.count == 0) return false;
|
||||||
|
|
||||||
for (auto m = comp->markers.begin(); m < comp->markers.end(); ++m) {
|
ARRAY_FOREACH(p, comp->markers) {
|
||||||
if (!strcmp(marker, (*m)->name)) {
|
if (!strcmp(marker, (*p)->name)) {
|
||||||
begin = (*m)->time / frameCnt;
|
begin = (*p)->time / frameCnt;
|
||||||
end = ((*m)->time + (*m)->duration) / frameCnt;
|
end = ((*p)->time + (*p)->duration) / frameCnt;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ void LottieSlot::reset()
|
||||||
|
|
||||||
auto shallow = pairs.count == 1 ? true : false;
|
auto shallow = pairs.count == 1 ? true : false;
|
||||||
|
|
||||||
for (auto pair = pairs.begin(); pair < pairs.end(); ++pair) {
|
ARRAY_FOREACH(pair, pairs) {
|
||||||
pair->obj->override(pair->prop, shallow, true);
|
pair->obj->override(pair->prop, shallow, true);
|
||||||
delete(pair->prop);
|
delete(pair->prop);
|
||||||
pair->prop = nullptr;
|
pair->prop = nullptr;
|
||||||
|
@ -56,7 +56,7 @@ void LottieSlot::assign(LottieObject* target, bool byDefault)
|
||||||
auto shallow = pairs.count == 1 ? true : false;
|
auto shallow = pairs.count == 1 ? true : false;
|
||||||
|
|
||||||
//apply slot object to all targets
|
//apply slot object to all targets
|
||||||
for (auto pair = pairs.begin(); pair < pairs.end(); ++pair) {
|
ARRAY_FOREACH(pair, pairs) {
|
||||||
//backup the original properties before overwriting
|
//backup the original properties before overwriting
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case LottieProperty::Type::Position: {
|
case LottieProperty::Type::Position: {
|
||||||
|
@ -216,7 +216,7 @@ void LottieImage::update()
|
||||||
{
|
{
|
||||||
//Update the picture data
|
//Update the picture data
|
||||||
TaskScheduler::async(false);
|
TaskScheduler::async(false);
|
||||||
for (auto p = pooler.begin(); p < pooler.end(); ++p) {
|
ARRAY_FOREACH(p, pooler) {
|
||||||
if (data.size > 0) (*p)->load((const char*)data.b64Data, data.size, data.mimeType);
|
if (data.size > 0) (*p)->load((const char*)data.b64Data, data.size, data.mimeType);
|
||||||
else (*p)->load(data.path);
|
else (*p)->load(data.path);
|
||||||
(*p)->size(data.width, data.height);
|
(*p)->size(data.width, data.height);
|
||||||
|
@ -478,13 +478,8 @@ LottieLayer::~LottieLayer()
|
||||||
//No need to free assets children because the Composition owns them.
|
//No need to free assets children because the Composition owns them.
|
||||||
if (rid) children.clear();
|
if (rid) children.clear();
|
||||||
|
|
||||||
for (auto m = masks.begin(); m < masks.end(); ++m) {
|
ARRAY_FOREACH(p, masks) delete(*p);
|
||||||
delete(*m);
|
ARRAY_FOREACH(p, effects) delete(*p);
|
||||||
}
|
|
||||||
|
|
||||||
for (auto e = effects.begin(); e < effects.end(); ++e) {
|
|
||||||
delete(*e);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete(transform);
|
delete(transform);
|
||||||
free(name);
|
free(name);
|
||||||
|
@ -497,7 +492,7 @@ void LottieLayer::prepare(RGB24* color)
|
||||||
so force it to be a Null Layer and release all resource. */
|
so force it to be a Null Layer and release all resource. */
|
||||||
if (hidden) {
|
if (hidden) {
|
||||||
type = LottieLayer::Null;
|
type = LottieLayer::Null;
|
||||||
for (auto p = children.begin(); p < children.end(); ++p) delete(*p);
|
ARRAY_FOREACH(p, children) delete(*p);
|
||||||
children.reset();
|
children.reset();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -540,28 +535,13 @@ LottieComposition::~LottieComposition()
|
||||||
free(version);
|
free(version);
|
||||||
free(name);
|
free(name);
|
||||||
|
|
||||||
//delete interpolators
|
ARRAY_FOREACH(p, interpolators) {
|
||||||
for (auto i = interpolators.begin(); i < interpolators.end(); ++i) {
|
free((*p)->key);
|
||||||
free((*i)->key);
|
free(*p);
|
||||||
free(*i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//delete assets
|
ARRAY_FOREACH(p, assets) delete(*p);
|
||||||
for (auto a = assets.begin(); a < assets.end(); ++a) {
|
ARRAY_FOREACH(p, fonts) delete(*p);
|
||||||
delete(*a);
|
ARRAY_FOREACH(p, slots) delete(*p);
|
||||||
}
|
ARRAY_FOREACH(p, markers) delete(*p);
|
||||||
|
|
||||||
//delete fonts
|
|
||||||
for (auto f = fonts.begin(); f < fonts.end(); ++f) {
|
|
||||||
delete(*f);
|
|
||||||
}
|
|
||||||
|
|
||||||
//delete slots
|
|
||||||
for (auto s = slots.begin(); s < slots.end(); ++s) {
|
|
||||||
delete(*s);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto m = markers.begin(); m < markers.end(); ++m) {
|
|
||||||
delete(*m);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -241,7 +241,7 @@ struct LottieGlyph
|
||||||
|
|
||||||
~LottieGlyph()
|
~LottieGlyph()
|
||||||
{
|
{
|
||||||
for (auto p = children.begin(); p < children.end(); ++p) delete(*p);
|
ARRAY_FOREACH(p, children) delete(*p);
|
||||||
free(code);
|
free(code);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -296,7 +296,7 @@ struct LottieFont
|
||||||
|
|
||||||
~LottieFont()
|
~LottieFont()
|
||||||
{
|
{
|
||||||
for (auto c = chars.begin(); c < chars.end(); ++c) delete(*c);
|
ARRAY_FOREACH(p, chars) delete(*p);
|
||||||
free(style);
|
free(style);
|
||||||
free(family);
|
free(family);
|
||||||
free(name);
|
free(name);
|
||||||
|
@ -354,7 +354,7 @@ struct LottieText : LottieObject, LottieRenderPooler<tvg::Shape>
|
||||||
|
|
||||||
~LottieText()
|
~LottieText()
|
||||||
{
|
{
|
||||||
for (auto r = ranges.begin(); r < ranges.end(); ++r) delete(*r);
|
ARRAY_FOREACH(p, ranges) delete(*p);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -659,7 +659,7 @@ struct LottieGradient : LottieObject
|
||||||
if (!colorStops.populated) {
|
if (!colorStops.populated) {
|
||||||
auto count = colorStops.count; //colorstop count can be modified after population
|
auto count = colorStops.count; //colorstop count can be modified after population
|
||||||
if (colorStops.frames) {
|
if (colorStops.frames) {
|
||||||
for (auto v = colorStops.frames->begin(); v < colorStops.frames->end(); ++v) {
|
ARRAY_FOREACH(v, *colorStops.frames) {
|
||||||
colorStops.count = populate(v->value, count);
|
colorStops.count = populate(v->value, count);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -802,7 +802,7 @@ struct LottieGroup : LottieObject, LottieRenderPooler<tvg::Shape>
|
||||||
|
|
||||||
virtual ~LottieGroup()
|
virtual ~LottieGroup()
|
||||||
{
|
{
|
||||||
for (auto p = children.begin(); p < children.end(); ++p) delete(*p);
|
ARRAY_FOREACH(p, children) delete(*p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void prepare(LottieObject::Type type = LottieObject::Group);
|
void prepare(LottieObject::Type type = LottieObject::Group);
|
||||||
|
@ -813,8 +813,8 @@ struct LottieGroup : LottieObject, LottieRenderPooler<tvg::Shape>
|
||||||
if (this->id == id) return this;
|
if (this->id == id) return this;
|
||||||
|
|
||||||
//source has children, find recursively.
|
//source has children, find recursively.
|
||||||
for (auto c = children.begin(); c < children.end(); ++c) {
|
ARRAY_FOREACH(p, children) {
|
||||||
auto child = *c;
|
auto child = *p;
|
||||||
if (child->type == LottieObject::Type::Group || child->type == LottieObject::Type::Layer) {
|
if (child->type == LottieObject::Type::Group || child->type == LottieObject::Type::Layer) {
|
||||||
if (auto ret = static_cast<LottieGroup*>(child)->content(id)) return ret;
|
if (auto ret = static_cast<LottieGroup*>(child)->content(id)) return ret;
|
||||||
} else if (child->id == id) return child;
|
} else if (child->id == id) return child;
|
||||||
|
@ -878,9 +878,9 @@ struct LottieLayer : LottieGroup
|
||||||
|
|
||||||
LottieLayer* layerById(unsigned long id)
|
LottieLayer* layerById(unsigned long id)
|
||||||
{
|
{
|
||||||
for (auto child = children.begin(); child < children.end(); ++child) {
|
ARRAY_FOREACH(p, children) {
|
||||||
if ((*child)->type != LottieObject::Type::Layer) continue;
|
if ((*p)->type != LottieObject::Type::Layer) continue;
|
||||||
auto layer = static_cast<LottieLayer*>(*child);
|
auto layer = static_cast<LottieLayer*>(*p);
|
||||||
if (layer->id == id) return layer;
|
if (layer->id == id) return layer;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -888,9 +888,9 @@ struct LottieLayer : LottieGroup
|
||||||
|
|
||||||
LottieLayer* layerByIdx(int16_t idx)
|
LottieLayer* layerByIdx(int16_t idx)
|
||||||
{
|
{
|
||||||
for (auto child = children.begin(); child < children.end(); ++child) {
|
ARRAY_FOREACH(p, children) {
|
||||||
if ((*child)->type != LottieObject::Type::Layer) continue;
|
if ((*p)->type != LottieObject::Type::Layer) continue;
|
||||||
auto layer = static_cast<LottieLayer*>(*child);
|
auto layer = static_cast<LottieLayer*>(*p);
|
||||||
if (layer->idx == idx) return layer;
|
if (layer->idx == idx) return layer;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -917,9 +917,7 @@ struct LottieSlot
|
||||||
{
|
{
|
||||||
free(sid);
|
free(sid);
|
||||||
if (!overridden) return;
|
if (!overridden) return;
|
||||||
for (auto pair = pairs.begin(); pair < pairs.end(); ++pair) {
|
ARRAY_FOREACH(pair, pairs) delete(pair->prop);
|
||||||
delete(pair->prop);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char* sid;
|
char* sid;
|
||||||
|
@ -957,8 +955,8 @@ struct LottieComposition
|
||||||
|
|
||||||
LottieLayer* asset(unsigned long id)
|
LottieLayer* asset(unsigned long id)
|
||||||
{
|
{
|
||||||
for (auto asset = assets.begin(); asset < assets.end(); ++asset) {
|
ARRAY_FOREACH(p, assets) {
|
||||||
auto layer = static_cast<LottieLayer*>(*asset);
|
auto layer = static_cast<LottieLayer*>(*p);
|
||||||
if (layer->id == id) return layer;
|
if (layer->id == id) return layer;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -377,8 +377,8 @@ LottieInterpolator* LottieParser::getInterpolator(const char* key, Point& in, Po
|
||||||
LottieInterpolator* interpolator = nullptr;
|
LottieInterpolator* interpolator = nullptr;
|
||||||
|
|
||||||
//get a cached interpolator if it has any.
|
//get a cached interpolator if it has any.
|
||||||
for (auto i = comp->interpolators.begin(); i < comp->interpolators.end(); ++i) {
|
ARRAY_FOREACH(p, comp->interpolators) {
|
||||||
if (!strncmp((*i)->key, key, sizeof(buf))) interpolator = *i;
|
if (!strncmp((*p)->key, key, sizeof(buf))) interpolator = *p;
|
||||||
}
|
}
|
||||||
|
|
||||||
//new interpolator
|
//new interpolator
|
||||||
|
@ -461,9 +461,9 @@ template<LottieProperty::Type type>
|
||||||
void LottieParser::registerSlot(LottieObject* obj, const char* sid)
|
void LottieParser::registerSlot(LottieObject* obj, const char* sid)
|
||||||
{
|
{
|
||||||
//append object if the slot already exists.
|
//append object if the slot already exists.
|
||||||
for (auto slot = comp->slots.begin(); slot < comp->slots.end(); ++slot) {
|
ARRAY_FOREACH(p, comp->slots) {
|
||||||
if (strcmp((*slot)->sid, sid)) continue;
|
if (strcmp((*p)->sid, sid)) continue;
|
||||||
(*slot)->pairs.push({obj});
|
(*p)->pairs.push({obj});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
comp->slots.push(new LottieSlot(strdup(sid), obj, type));
|
comp->slots.push(new LottieSlot(strdup(sid), obj, type));
|
||||||
|
|
|
@ -377,7 +377,7 @@ struct LottiePathSet : LottieProperty
|
||||||
|
|
||||||
if (!frames) return;
|
if (!frames) return;
|
||||||
|
|
||||||
for (auto p = frames->begin(); p < frames->end(); ++p) {
|
ARRAY_FOREACH(p, *frames) {
|
||||||
free((*p).value.cmds);
|
free((*p).value.cmds);
|
||||||
free((*p).value.pts);
|
free((*p).value.pts);
|
||||||
}
|
}
|
||||||
|
@ -542,7 +542,7 @@ struct LottieColorStop : LottieProperty
|
||||||
|
|
||||||
if (!frames) return;
|
if (!frames) return;
|
||||||
|
|
||||||
for (auto p = frames->begin(); p < frames->end(); ++p) {
|
ARRAY_FOREACH(p, *frames) {
|
||||||
free((*p).value.data);
|
free((*p).value.data);
|
||||||
}
|
}
|
||||||
free(frames->data);
|
free(frames->data);
|
||||||
|
@ -800,7 +800,7 @@ struct LottieTextDoc : LottieProperty
|
||||||
|
|
||||||
if (!frames) return;
|
if (!frames) return;
|
||||||
|
|
||||||
for (auto p = frames->begin(); p < frames->end(); ++p) {
|
ARRAY_FOREACH(p, *frames) {
|
||||||
free((*p).value.text);
|
free((*p).value.text);
|
||||||
free((*p).value.name);
|
free((*p).value.name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ struct LottieRenderPooler
|
||||||
|
|
||||||
~LottieRenderPooler()
|
~LottieRenderPooler()
|
||||||
{
|
{
|
||||||
for (auto p = pooler.begin(); p < pooler.end(); ++p) {
|
ARRAY_FOREACH(p, pooler) {
|
||||||
(*p)->unref();
|
(*p)->unref();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ struct LottieRenderPooler
|
||||||
T* pooling(bool copy = false)
|
T* pooling(bool copy = false)
|
||||||
{
|
{
|
||||||
//return available one.
|
//return available one.
|
||||||
for (auto p = pooler.begin(); p < pooler.end(); ++p) {
|
ARRAY_FOREACH(p, pooler) {
|
||||||
if ((*p)->refCnt() == 1) return *p;
|
if ((*p)->refCnt() == 1) return *p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -138,8 +138,8 @@ static void _copyStyle(SvgStyleProperty* to, const SvgStyleProperty* from)
|
||||||
if (from->stroke.dash.array.count > 0) {
|
if (from->stroke.dash.array.count > 0) {
|
||||||
to->stroke.dash.array.clear();
|
to->stroke.dash.array.clear();
|
||||||
to->stroke.dash.array.reserve(from->stroke.dash.array.count);
|
to->stroke.dash.array.reserve(from->stroke.dash.array.count);
|
||||||
for (uint32_t i = 0; i < from->stroke.dash.array.count; ++i) {
|
ARRAY_FOREACH(p, from->stroke.dash.array) {
|
||||||
to->stroke.dash.array.push(from->stroke.dash.array[i]);
|
to->stroke.dash.array.push(*p);
|
||||||
}
|
}
|
||||||
to->stroke.flags = (to->stroke.flags | SvgStrokeFlags::Dash);
|
to->stroke.flags = (to->stroke.flags | SvgStrokeFlags::Dash);
|
||||||
to->flags = (to->flags | SvgStyleFlags::StrokeDashArray);
|
to->flags = (to->flags | SvgStyleFlags::StrokeDashArray);
|
||||||
|
@ -211,10 +211,9 @@ SvgNode* cssFindStyleNode(const SvgNode* style, const char* title, SvgNodeType t
|
||||||
{
|
{
|
||||||
if (!style) return nullptr;
|
if (!style) return nullptr;
|
||||||
|
|
||||||
auto child = style->child.data;
|
ARRAY_FOREACH(p, style->child) {
|
||||||
for (uint32_t i = 0; i < style->child.count; ++i, ++child) {
|
if ((*p)->type == type) {
|
||||||
if ((*child)->type == type) {
|
if ((!title && !(*p)->id) || (title && (*p)->id && !strcmp((*p)->id, title))) return *p;
|
||||||
if ((!title && !(*child)->id) || (title && (*child)->id && !strcmp((*child)->id, title))) return (*child);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -225,10 +224,9 @@ SvgNode* cssFindStyleNode(const SvgNode* style, const char* title)
|
||||||
{
|
{
|
||||||
if (!style || !title) return nullptr;
|
if (!style || !title) return nullptr;
|
||||||
|
|
||||||
auto child = style->child.data;
|
ARRAY_FOREACH(p, style->child) {
|
||||||
for (uint32_t i = 0; i < style->child.count; ++i, ++child) {
|
if ((*p)->type == SvgNodeType::CssStyle) {
|
||||||
if ((*child)->type == SvgNodeType::CssStyle) {
|
if ((*p)->id && !strcmp((*p)->id, title)) return *p;
|
||||||
if ((*child)->id && !strcmp((*child)->id, title)) return (*child);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -238,12 +236,11 @@ SvgNode* cssFindStyleNode(const SvgNode* style, const char* title)
|
||||||
void cssUpdateStyle(SvgNode* doc, SvgNode* style)
|
void cssUpdateStyle(SvgNode* doc, SvgNode* style)
|
||||||
{
|
{
|
||||||
if (doc->child.count > 0) {
|
if (doc->child.count > 0) {
|
||||||
auto child = doc->child.data;
|
ARRAY_FOREACH(p, doc->child) {
|
||||||
for (uint32_t i = 0; i < doc->child.count; ++i, ++child) {
|
if (auto cssNode = cssFindStyleNode(style, nullptr, (*p)->type)) {
|
||||||
if (auto cssNode = cssFindStyleNode(style, nullptr, (*child)->type)) {
|
cssCopyStyleAttr(*p, cssNode);
|
||||||
cssCopyStyleAttr(*child, cssNode);
|
|
||||||
}
|
}
|
||||||
cssUpdateStyle(*child, style);
|
cssUpdateStyle(*p, style);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -251,9 +248,8 @@ void cssUpdateStyle(SvgNode* doc, SvgNode* style)
|
||||||
|
|
||||||
void cssApplyStyleToPostponeds(Array<SvgNodeIdPair>& postponeds, SvgNode* style)
|
void cssApplyStyleToPostponeds(Array<SvgNodeIdPair>& postponeds, SvgNode* style)
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < postponeds.count; ++i) {
|
ARRAY_FOREACH(p, postponeds) {
|
||||||
auto nodeIdPair = postponeds[i];
|
auto nodeIdPair = *p;
|
||||||
|
|
||||||
//css styling: tag.name has higher priority than .name
|
//css styling: tag.name has higher priority than .name
|
||||||
if (auto cssNode = cssFindStyleNode(style, nodeIdPair.id, nodeIdPair.node->type)) {
|
if (auto cssNode = cssFindStyleNode(style, nodeIdPair.id, nodeIdPair.node->type)) {
|
||||||
cssCopyStyleAttr(nodeIdPair.node, cssNode);
|
cssCopyStyleAttr(nodeIdPair.node, cssNode);
|
||||||
|
|
|
@ -1966,9 +1966,8 @@ static SvgNode* _findNodeById(SvgNode *node, const char* id)
|
||||||
if (node->id && !strcmp(node->id, id)) return node;
|
if (node->id && !strcmp(node->id, id)) return node;
|
||||||
|
|
||||||
if (node->child.count > 0) {
|
if (node->child.count > 0) {
|
||||||
auto child = node->child.data;
|
ARRAY_FOREACH(p, node->child) {
|
||||||
for (uint32_t i = 0; i < node->child.count; ++i, ++child) {
|
result = _findNodeById(*p, id);
|
||||||
result = _findNodeById(*child, id);
|
|
||||||
if (result) break;
|
if (result) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2812,8 +2811,8 @@ static GradientFactoryMethod _findGradientFactory(const char* name)
|
||||||
|
|
||||||
static void _cloneGradStops(Array<Fill::ColorStop>& dst, const Array<Fill::ColorStop>& src)
|
static void _cloneGradStops(Array<Fill::ColorStop>& dst, const Array<Fill::ColorStop>& src)
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < src.count; ++i) {
|
ARRAY_FOREACH(p, src) {
|
||||||
dst.push(src[i]);
|
dst.push(*p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2972,8 +2971,8 @@ static void _styleInherit(SvgStyleProperty* child, const SvgStyleProperty* paren
|
||||||
if (parent->stroke.dash.array.count > 0) {
|
if (parent->stroke.dash.array.count > 0) {
|
||||||
child->stroke.dash.array.clear();
|
child->stroke.dash.array.clear();
|
||||||
child->stroke.dash.array.reserve(parent->stroke.dash.array.count);
|
child->stroke.dash.array.reserve(parent->stroke.dash.array.count);
|
||||||
for (uint32_t i = 0; i < parent->stroke.dash.array.count; ++i) {
|
ARRAY_FOREACH(p, parent->stroke.dash.array) {
|
||||||
child->stroke.dash.array.push(parent->stroke.dash.array[i]);
|
child->stroke.dash.array.push(*p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3047,8 +3046,8 @@ static void _styleCopy(SvgStyleProperty* to, const SvgStyleProperty* from)
|
||||||
if (from->stroke.dash.array.count > 0) {
|
if (from->stroke.dash.array.count > 0) {
|
||||||
to->stroke.dash.array.clear();
|
to->stroke.dash.array.clear();
|
||||||
to->stroke.dash.array.reserve(from->stroke.dash.array.count);
|
to->stroke.dash.array.reserve(from->stroke.dash.array.count);
|
||||||
for (uint32_t i = 0; i < from->stroke.dash.array.count; ++i) {
|
ARRAY_FOREACH(p, from->stroke.dash.array) {
|
||||||
to->stroke.dash.array.push(from->stroke.dash.array[i]);
|
to->stroke.dash.array.push(*p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3183,17 +3182,16 @@ static void _cloneNode(SvgNode* from, SvgNode* parent, int depth)
|
||||||
_styleInherit(newNode->style, parent->style);
|
_styleInherit(newNode->style, parent->style);
|
||||||
_copyAttr(newNode, from);
|
_copyAttr(newNode, from);
|
||||||
|
|
||||||
auto child = from->child.data;
|
ARRAY_FOREACH(p, from->child) {
|
||||||
for (uint32_t i = 0; i < from->child.count; ++i, ++child) {
|
_cloneNode(*p, newNode, depth + 1);
|
||||||
_cloneNode(*child, newNode, depth + 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void _clonePostponedNodes(Array<SvgNodeIdPair>* cloneNodes, SvgNode* doc)
|
static void _clonePostponedNodes(Array<SvgNodeIdPair>* cloneNodes, SvgNode* doc)
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < cloneNodes->count; ++i) {
|
ARRAY_FOREACH(p, *cloneNodes) {
|
||||||
auto nodeIdPair = (*cloneNodes)[i];
|
auto nodeIdPair = *p;
|
||||||
auto defs = _getDefsNode(nodeIdPair.node);
|
auto defs = _getDefsNode(nodeIdPair.node);
|
||||||
auto nodeFrom = _findNodeById(defs, nodeIdPair.id);
|
auto nodeFrom = _findNodeById(defs, nodeIdPair.id);
|
||||||
if (!nodeFrom) nodeFrom = _findNodeById(doc, nodeIdPair.id);
|
if (!nodeFrom) nodeFrom = _findNodeById(doc, nodeIdPair.id);
|
||||||
|
@ -3477,9 +3475,8 @@ static void _updateStyle(SvgNode* node, SvgStyleProperty* parentStyle)
|
||||||
_styleInherit(node->style, parentStyle);
|
_styleInherit(node->style, parentStyle);
|
||||||
_inefficientNodeCheck(node);
|
_inefficientNodeCheck(node);
|
||||||
|
|
||||||
auto child = node->child.data;
|
ARRAY_FOREACH(p, node->child) {
|
||||||
for (uint32_t i = 0; i < node->child.count; ++i, ++child) {
|
_updateStyle(*p, node->style);
|
||||||
_updateStyle(*child, node->style);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3488,24 +3485,19 @@ static SvgStyleGradient* _gradientDup(SvgLoaderData* loader, Array<SvgStyleGradi
|
||||||
{
|
{
|
||||||
SvgStyleGradient* result = nullptr;
|
SvgStyleGradient* result = nullptr;
|
||||||
|
|
||||||
auto gradList = gradients->data;
|
ARRAY_FOREACH(p, *gradients) {
|
||||||
|
if ((*p)->id && !strcmp((*p)->id, id)) {
|
||||||
for (uint32_t i = 0; i < gradients->count; ++i) {
|
result = _cloneGradient(*p);
|
||||||
if ((*gradList)->id && !strcmp((*gradList)->id, id)) {
|
|
||||||
result = _cloneGradient(*gradList);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
++gradList;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result && result->ref) {
|
if (result && result->ref) {
|
||||||
gradList = gradients->data;
|
ARRAY_FOREACH(p, *gradients) {
|
||||||
for (uint32_t i = 0; i < gradients->count; ++i) {
|
if ((*p)->id && !strcmp((*p)->id, result->ref)) {
|
||||||
if ((*gradList)->id && !strcmp((*gradList)->id, result->ref)) {
|
_inheritGradient(loader, result, *p);
|
||||||
_inheritGradient(loader, result, *gradList);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
++gradList;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3516,9 +3508,8 @@ static SvgStyleGradient* _gradientDup(SvgLoaderData* loader, Array<SvgStyleGradi
|
||||||
static void _updateGradient(SvgLoaderData* loader, SvgNode* node, Array<SvgStyleGradient*>* gradients)
|
static void _updateGradient(SvgLoaderData* loader, SvgNode* node, Array<SvgStyleGradient*>* gradients)
|
||||||
{
|
{
|
||||||
if (node->child.count > 0) {
|
if (node->child.count > 0) {
|
||||||
auto child = node->child.data;
|
ARRAY_FOREACH(p, node->child) {
|
||||||
for (uint32_t i = 0; i < node->child.count; ++i, ++child) {
|
_updateGradient(loader, *p, gradients);
|
||||||
_updateGradient(loader, *child, gradients);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (node->style->fill.paint.url) {
|
if (node->style->fill.paint.url) {
|
||||||
|
@ -3556,9 +3547,8 @@ static void _updateComposite(SvgNode* node, SvgNode* root)
|
||||||
if (findResult) node->style->mask.node = findResult;
|
if (findResult) node->style->mask.node = findResult;
|
||||||
}
|
}
|
||||||
if (node->child.count > 0) {
|
if (node->child.count > 0) {
|
||||||
auto child = node->child.data;
|
ARRAY_FOREACH(p, node->child) {
|
||||||
for (uint32_t i = 0; i < node->child.count; ++i, ++child) {
|
_updateComposite(*p, root);
|
||||||
_updateComposite(*child, root);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3592,10 +3582,7 @@ static void _freeNode(SvgNode* node)
|
||||||
{
|
{
|
||||||
if (!node) return;
|
if (!node) return;
|
||||||
|
|
||||||
auto child = node->child.data;
|
ARRAY_FOREACH(p, node->child) _freeNode(*p);
|
||||||
for (uint32_t i = 0; i < node->child.count; ++i, ++child) {
|
|
||||||
_freeNode(*child);
|
|
||||||
}
|
|
||||||
node->child.reset();
|
node->child.reset();
|
||||||
|
|
||||||
free(node->id);
|
free(node->id);
|
||||||
|
@ -3620,11 +3607,9 @@ static void _freeNode(SvgNode* node)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SvgNodeType::Defs: {
|
case SvgNodeType::Defs: {
|
||||||
auto gradients = node->node.defs.gradients.data;
|
ARRAY_FOREACH(p, node->node.defs.gradients) {
|
||||||
for (size_t i = 0; i < node->node.defs.gradients.count; ++i) {
|
(*p)->clear();
|
||||||
(*gradients)->clear();
|
free(*p);
|
||||||
free(*gradients);
|
|
||||||
++gradients;
|
|
||||||
}
|
}
|
||||||
node->node.defs.gradients.reset();
|
node->node.defs.gradients.reset();
|
||||||
break;
|
break;
|
||||||
|
@ -3712,9 +3697,9 @@ void SvgLoader::clear(bool all)
|
||||||
free(loaderData.svgParse);
|
free(loaderData.svgParse);
|
||||||
loaderData.svgParse = nullptr;
|
loaderData.svgParse = nullptr;
|
||||||
|
|
||||||
for (auto gradient = loaderData.gradients.begin(); gradient < loaderData.gradients.end(); ++gradient) {
|
ARRAY_FOREACH(p, loaderData.gradients) {
|
||||||
(*gradient)->clear();
|
(*p)->clear();
|
||||||
free(*gradient);
|
free(*p);
|
||||||
}
|
}
|
||||||
loaderData.gradients.reset();
|
loaderData.gradients.reset();
|
||||||
|
|
||||||
|
@ -3724,9 +3709,7 @@ void SvgLoader::clear(bool all)
|
||||||
|
|
||||||
if (!all) return;
|
if (!all) return;
|
||||||
|
|
||||||
for (auto p = loaderData.images.begin(); p < loaderData.images.end(); ++p) {
|
ARRAY_FOREACH(p, loaderData.images) free(*p);
|
||||||
free(*p);
|
|
||||||
}
|
|
||||||
loaderData.images.reset();
|
loaderData.images.reset();
|
||||||
|
|
||||||
if (copy) free((char*)content);
|
if (copy) free((char*)content);
|
||||||
|
|
|
@ -222,11 +222,10 @@ static bool _applyClip(SvgLoaderData& loaderData, Paint* paint, const SvgNode* n
|
||||||
node->style->clipPath.applying = true;
|
node->style->clipPath.applying = true;
|
||||||
|
|
||||||
auto clipper = Shape::gen();
|
auto clipper = Shape::gen();
|
||||||
auto child = clipNode->child.data;
|
|
||||||
auto valid = false; //Composite only when valid shapes exist
|
auto valid = false; //Composite only when valid shapes exist
|
||||||
|
|
||||||
for (uint32_t i = 0; i < clipNode->child.count; ++i, ++child) {
|
ARRAY_FOREACH(p, clipNode->child) {
|
||||||
if (_appendClipChild(loaderData, *child, clipper, vBox, svgPath)) valid = true;
|
if (_appendClipChild(loaderData, *p, clipper, vBox, svgPath)) valid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valid) {
|
if (valid) {
|
||||||
|
@ -804,21 +803,21 @@ static Scene* _sceneBuildHelper(SvgLoaderData& loaderData, const SvgNode* node,
|
||||||
|
|
||||||
if (!node->style->display || node->style->opacity == 0) return scene;
|
if (!node->style->display || node->style->opacity == 0) return scene;
|
||||||
|
|
||||||
auto child = node->child.data;
|
ARRAY_FOREACH(p, node->child) {
|
||||||
for (uint32_t i = 0; i < node->child.count; ++i, ++child) {
|
auto child = *p;
|
||||||
if (_isGroupType((*child)->type)) {
|
if (_isGroupType(child->type)) {
|
||||||
if ((*child)->type == SvgNodeType::Use)
|
if (child->type == SvgNodeType::Use)
|
||||||
scene->push(_useBuildHelper(loaderData, *child, vBox, svgPath, depth + 1));
|
scene->push(_useBuildHelper(loaderData, child, vBox, svgPath, depth + 1));
|
||||||
else if (!((*child)->type == SvgNodeType::Symbol && node->type != SvgNodeType::Use))
|
else if (!(child->type == SvgNodeType::Symbol && node->type != SvgNodeType::Use))
|
||||||
scene->push(_sceneBuildHelper(loaderData, *child, vBox, svgPath, false, depth + 1));
|
scene->push(_sceneBuildHelper(loaderData, child, vBox, svgPath, false, depth + 1));
|
||||||
if ((*child)->id) scene->id = djb2Encode((*child)->id);
|
if (child->id) scene->id = djb2Encode(child->id);
|
||||||
} else {
|
} else {
|
||||||
Paint* paint = nullptr;
|
Paint* paint = nullptr;
|
||||||
if ((*child)->type == SvgNodeType::Image) paint = _imageBuildHelper(loaderData, *child, vBox, svgPath);
|
if (child->type == SvgNodeType::Image) paint = _imageBuildHelper(loaderData, child, vBox, svgPath);
|
||||||
else if ((*child)->type == SvgNodeType::Text) paint = _textBuildHelper(loaderData, *child, vBox, svgPath);
|
else if (child->type == SvgNodeType::Text) paint = _textBuildHelper(loaderData, child, vBox, svgPath);
|
||||||
else if ((*child)->type != SvgNodeType::Mask) paint = _shapeBuildHelper(loaderData, *child, vBox, svgPath);
|
else if (child->type != SvgNodeType::Mask) paint = _shapeBuildHelper(loaderData, child, vBox, svgPath);
|
||||||
if (paint) {
|
if (paint) {
|
||||||
if ((*child)->id) paint->id = djb2Encode((*child)->id);
|
if (child->id) paint->id = djb2Encode(child->id);
|
||||||
scene->push(paint);
|
scene->push(paint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,9 +40,7 @@ GlRenderPass::~GlRenderPass()
|
||||||
{
|
{
|
||||||
if (mTasks.empty()) return;
|
if (mTasks.empty()) return;
|
||||||
|
|
||||||
for(uint32_t i = 0; i < mTasks.count; i++) {
|
ARRAY_FOREACH(p, mTasks) delete(*p);
|
||||||
delete mTasks[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
mTasks.clear();
|
mTasks.clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,10 +166,7 @@ GlComposeTask::GlComposeTask(GlProgram* program, GLuint target, GlRenderTarget*
|
||||||
|
|
||||||
GlComposeTask::~GlComposeTask()
|
GlComposeTask::~GlComposeTask()
|
||||||
{
|
{
|
||||||
for(uint32_t i = 0; i < mTasks.count; i++) {
|
ARRAY_FOREACH(p, mTasks) delete(*p);
|
||||||
delete mTasks[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
mTasks.clear();
|
mTasks.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,8 +188,8 @@ void GlComposeTask::run()
|
||||||
GL_CHECK(glDepthMask(0));
|
GL_CHECK(glDepthMask(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
for(uint32_t i = 0; i < mTasks.count; i++) {
|
ARRAY_FOREACH(p, mTasks) {
|
||||||
mTasks[i]->run();
|
(*p)->run();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(THORVG_GL_TARGET_GLES)
|
#if defined(THORVG_GL_TARGET_GLES)
|
||||||
|
|
|
@ -52,24 +52,20 @@ void GlRenderer::flush()
|
||||||
mDisposed.textures.clear();
|
mDisposed.textures.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto p = mRenderPassStack.begin(); p < mRenderPassStack.end(); ++p) {
|
ARRAY_FOREACH(p, mRenderPassStack) delete(*p);
|
||||||
delete(*p);
|
|
||||||
}
|
|
||||||
mRenderPassStack.clear();
|
mRenderPassStack.clear();
|
||||||
|
|
||||||
for (auto p = mComposePool.begin(); p < mComposePool.end(); p++) {
|
ARRAY_FOREACH(p, mComposePool) delete(*p);
|
||||||
delete(*p);
|
|
||||||
}
|
|
||||||
mComposePool.clear();
|
mComposePool.clear();
|
||||||
|
|
||||||
for (auto p = mBlendPool.begin(); p < mBlendPool.end(); p++) {
|
ARRAY_FOREACH(p, mBlendPool) delete(*p);
|
||||||
delete(*p);
|
|
||||||
}
|
|
||||||
mBlendPool.clear();
|
mBlendPool.clear();
|
||||||
|
|
||||||
for (auto p = mComposeStack.begin(); p < mComposeStack.end(); p++) {
|
ARRAY_FOREACH(p, mComposeStack) delete(*p);
|
||||||
delete(*p);
|
|
||||||
}
|
|
||||||
mComposeStack.clear();
|
mComposeStack.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,9 +94,7 @@ GlRenderer::~GlRenderer()
|
||||||
|
|
||||||
flush();
|
flush();
|
||||||
|
|
||||||
for (auto p = mPrograms.begin(); p < mPrograms.end(); ++p) {
|
ARRAY_FOREACH(p, mPrograms) delete(*p);
|
||||||
delete(*p);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rendererCnt == 0 && initEngineCnt == 0) _termEngine();
|
if (rendererCnt == 0 && initEngineCnt == 0) _termEngine();
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,8 +170,8 @@ struct SwShapeTask : SwTask
|
||||||
shapeDelOutline(&shape, mpool, tid);
|
shapeDelOutline(&shape, mpool, tid);
|
||||||
|
|
||||||
//Clip Path
|
//Clip Path
|
||||||
for (auto clip = clips.begin(); clip < clips.end(); ++clip) {
|
ARRAY_FOREACH(p, clips) {
|
||||||
auto clipper = static_cast<SwTask*>(*clip);
|
auto clipper = static_cast<SwTask*>(*p);
|
||||||
auto clipShapeRle = shape.rle ? clipper->clip(shape.rle) : true;
|
auto clipShapeRle = shape.rle ? clipper->clip(shape.rle) : true;
|
||||||
auto clipStrokeRle = shape.strokeRle ? clipper->clip(shape.strokeRle) : true;
|
auto clipStrokeRle = shape.strokeRle ? clipper->clip(shape.strokeRle) : true;
|
||||||
if (!clipShapeRle && !clipStrokeRle) goto err;
|
if (!clipShapeRle && !clipStrokeRle) goto err;
|
||||||
|
@ -231,8 +231,8 @@ struct SwImageTask : SwTask
|
||||||
if (image.rle) {
|
if (image.rle) {
|
||||||
//Clear current task memorypool here if the clippers would use the same memory pool
|
//Clear current task memorypool here if the clippers would use the same memory pool
|
||||||
imageDelOutline(&image, mpool, tid);
|
imageDelOutline(&image, mpool, tid);
|
||||||
for (auto clip = clips.begin(); clip < clips.end(); ++clip) {
|
ARRAY_FOREACH(p, clips) {
|
||||||
auto clipper = static_cast<SwTask*>(*clip);
|
auto clipper = static_cast<SwTask*>(*p);
|
||||||
if (!clipper->clip(image.rle)) goto err;
|
if (!clipper->clip(image.rle)) goto err;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -314,12 +314,12 @@ bool SwRenderer::clear()
|
||||||
|
|
||||||
bool SwRenderer::sync()
|
bool SwRenderer::sync()
|
||||||
{
|
{
|
||||||
for (auto task = tasks.begin(); task < tasks.end(); ++task) {
|
ARRAY_FOREACH(p, tasks) {
|
||||||
if ((*task)->disposed) {
|
if ((*p)->disposed) {
|
||||||
delete(*task);
|
delete(*p);
|
||||||
} else {
|
} else {
|
||||||
(*task)->done();
|
(*p)->done();
|
||||||
(*task)->pushed = false;
|
(*p)->pushed = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tasks.clear();
|
tasks.clear();
|
||||||
|
@ -384,10 +384,10 @@ bool SwRenderer::preRender()
|
||||||
void SwRenderer::clearCompositors()
|
void SwRenderer::clearCompositors()
|
||||||
{
|
{
|
||||||
//Free Composite Caches
|
//Free Composite Caches
|
||||||
for (auto comp = compositors.begin(); comp < compositors.end(); ++comp) {
|
ARRAY_FOREACH(p, compositors) {
|
||||||
free((*comp)->compositor->image.data);
|
free((*p)->compositor->image.data);
|
||||||
delete((*comp)->compositor);
|
delete((*p)->compositor);
|
||||||
delete(*comp);
|
delete(*p);
|
||||||
}
|
}
|
||||||
compositors.reset();
|
compositors.reset();
|
||||||
}
|
}
|
||||||
|
@ -400,9 +400,9 @@ bool SwRenderer::postRender()
|
||||||
rasterUnpremultiply(surface);
|
rasterUnpremultiply(surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto task = tasks.begin(); task < tasks.end(); ++task) {
|
ARRAY_FOREACH(p, tasks) {
|
||||||
if ((*task)->disposed) delete(*task);
|
if ((*p)->disposed) delete(*p);
|
||||||
else (*task)->pushed = false;
|
else (*p)->pushed = false;
|
||||||
}
|
}
|
||||||
tasks.clear();
|
tasks.clear();
|
||||||
|
|
||||||
|
@ -561,7 +561,7 @@ SwSurface* SwRenderer::request(int channelSize, bool square)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Use cached data
|
//Use cached data
|
||||||
for (auto p = compositors.begin(); p < compositors.end(); ++p) {
|
ARRAY_FOREACH(p, compositors) {
|
||||||
auto cur = *p;
|
auto cur = *p;
|
||||||
if (cur->compositor->valid && cur->compositor->image.channelSize == channelSize) {
|
if (cur->compositor->valid && cur->compositor->image.channelSize == channelSize) {
|
||||||
if (w == cur->w && h == cur->h) {
|
if (w == cur->w && h == cur->h) {
|
||||||
|
@ -737,8 +737,8 @@ void* SwRenderer::prepareCommon(SwTask* task, const Matrix& transform, const Arr
|
||||||
//TODO: Failed threading them. It would be better if it's possible.
|
//TODO: Failed threading them. It would be better if it's possible.
|
||||||
//See: https://github.com/thorvg/thorvg/issues/1409
|
//See: https://github.com/thorvg/thorvg/issues/1409
|
||||||
//Guarantee composition targets get ready.
|
//Guarantee composition targets get ready.
|
||||||
for (auto clip = clips.begin(); clip < clips.end(); ++clip) {
|
ARRAY_FOREACH(p, clips) {
|
||||||
static_cast<SwTask*>(*clip)->done();
|
static_cast<SwTask*>(*p)->done();
|
||||||
}
|
}
|
||||||
|
|
||||||
task->clips = clips;
|
task->clips = clips;
|
||||||
|
|
|
@ -692,8 +692,8 @@ static bool _decomposeOutline(RleWorker& rw)
|
||||||
auto outline = rw.outline;
|
auto outline = rw.outline;
|
||||||
auto first = 0; //index of first point in contour
|
auto first = 0; //index of first point in contour
|
||||||
|
|
||||||
for (auto cntr = outline->cntrs.begin(); cntr < outline->cntrs.end(); ++cntr) {
|
ARRAY_FOREACH(p, outline->cntrs) {
|
||||||
auto last = *cntr;
|
auto last = *p;
|
||||||
auto limit = outline->pts.data + last;
|
auto limit = outline->pts.data + last;
|
||||||
auto start = UPSCALE(outline->pts[first]);
|
auto start = UPSCALE(outline->pts[first]);
|
||||||
auto pt = outline->pts.data + first;
|
auto pt = outline->pts.data + first;
|
||||||
|
|
|
@ -841,8 +841,8 @@ bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline)
|
||||||
uint32_t first = 0;
|
uint32_t first = 0;
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
|
|
||||||
for (auto cntr = outline.cntrs.begin(); cntr < outline.cntrs.end(); ++cntr, ++i) {
|
ARRAY_FOREACH(p, outline.cntrs) {
|
||||||
auto last = *cntr; //index of last point in contour
|
auto last = *p; //index of last point in contour
|
||||||
auto limit = outline.pts.data + last;
|
auto limit = outline.pts.data + last;
|
||||||
|
|
||||||
//Skip empty points
|
//Skip empty points
|
||||||
|
|
|
@ -140,8 +140,8 @@ struct Scene::Impl : Paint::Impl
|
||||||
if (effects) {
|
if (effects) {
|
||||||
//Notify the possiblity of the direct composition of the effect result to the origin surface.
|
//Notify the possiblity of the direct composition of the effect result to the origin surface.
|
||||||
auto direct = (effects->count == 1) & (compFlag == CompositionFlag::PostProcessing);
|
auto direct = (effects->count == 1) & (compFlag == CompositionFlag::PostProcessing);
|
||||||
for (auto e = effects->begin(); e < effects->end(); ++e) {
|
ARRAY_FOREACH(p, *effects) {
|
||||||
renderer->effect(cmp, *e, direct);
|
renderer->effect(cmp, *p, direct);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
renderer->endComposite(cmp);
|
renderer->endComposite(cmp);
|
||||||
|
@ -172,8 +172,8 @@ struct Scene::Impl : Paint::Impl
|
||||||
//Extends the render region if post effects require
|
//Extends the render region if post effects require
|
||||||
int32_t ex = 0, ey = 0, ew = 0, eh = 0;
|
int32_t ex = 0, ey = 0, ew = 0, eh = 0;
|
||||||
if (effects) {
|
if (effects) {
|
||||||
for (auto e = effects->begin(); e < effects->end(); ++e) {
|
ARRAY_FOREACH(p, *effects) {
|
||||||
auto effect = *e;
|
auto effect = *p;
|
||||||
if (effect->valid || renderer->prepare(effect)) {
|
if (effect->valid || renderer->prepare(effect)) {
|
||||||
ex = std::min(ex, effect->extend.x);
|
ex = std::min(ex, effect->extend.x);
|
||||||
ey = std::min(ey, effect->extend.y);
|
ey = std::min(ey, effect->extend.y);
|
||||||
|
@ -293,9 +293,7 @@ struct Scene::Impl : Paint::Impl
|
||||||
Result resetEffects()
|
Result resetEffects()
|
||||||
{
|
{
|
||||||
if (effects) {
|
if (effects) {
|
||||||
for (auto e = effects->begin(); e < effects->end(); ++e) {
|
ARRAY_FOREACH(p, *effects) delete(*p);
|
||||||
delete(*e);
|
|
||||||
}
|
|
||||||
delete(effects);
|
delete(effects);
|
||||||
effects = nullptr;
|
effects = nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,15 +123,15 @@ struct TaskSchedulerImpl
|
||||||
|
|
||||||
~TaskSchedulerImpl()
|
~TaskSchedulerImpl()
|
||||||
{
|
{
|
||||||
for (auto tq = taskQueues.begin(); tq < taskQueues.end(); ++tq) {
|
ARRAY_FOREACH(p, taskQueues) {
|
||||||
(*tq)->complete();
|
(*p)->complete();
|
||||||
}
|
}
|
||||||
for (auto thread = threads.begin(); thread < threads.end(); ++thread) {
|
ARRAY_FOREACH(p, threads) {
|
||||||
(*thread)->join();
|
(*p)->join();
|
||||||
delete(*thread);
|
delete(*p);
|
||||||
}
|
}
|
||||||
for (auto tq = taskQueues.begin(); tq < taskQueues.end(); ++tq) {
|
ARRAY_FOREACH(p, taskQueues) {
|
||||||
delete(*tq);
|
delete(*p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -277,8 +277,8 @@ void WgCompositor::drawShape(WgContext& context, WgRenderDataShape* renderData)
|
||||||
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr);
|
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr);
|
||||||
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, stencilPipeline);
|
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, stencilPipeline);
|
||||||
// draw to stencil (first pass)
|
// draw to stencil (first pass)
|
||||||
for (uint32_t i = 0; i < renderData->meshGroupShapes.meshes.count; i++)
|
ARRAY_FOREACH(p, renderData->meshGroupShapes.meshes)
|
||||||
renderData->meshGroupShapes.meshes[i]->drawFan(context, renderPassEncoder);
|
(*p)->drawFan(context, renderPassEncoder);
|
||||||
// setup fill rules
|
// setup fill rules
|
||||||
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
|
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
|
||||||
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr);
|
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr);
|
||||||
|
@ -324,8 +324,8 @@ void WgCompositor::blendShape(WgContext& context, WgRenderDataShape* renderData,
|
||||||
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr);
|
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr);
|
||||||
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, stencilPipeline);
|
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, stencilPipeline);
|
||||||
// draw to stencil (first pass)
|
// draw to stencil (first pass)
|
||||||
for (uint32_t i = 0; i < renderData->meshGroupShapes.meshes.count; i++)
|
ARRAY_FOREACH(p, renderData->meshGroupShapes.meshes)
|
||||||
renderData->meshGroupShapes.meshes[i]->drawFan(context, renderPassEncoder);
|
(*p)->drawFan(context, renderPassEncoder);
|
||||||
// setup fill rules
|
// setup fill rules
|
||||||
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
|
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
|
||||||
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr);
|
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr);
|
||||||
|
@ -364,8 +364,8 @@ void WgCompositor::clipShape(WgContext& context, WgRenderDataShape* renderData)
|
||||||
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr);
|
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr);
|
||||||
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, stencilPipeline);
|
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, stencilPipeline);
|
||||||
// draw to stencil (first pass)
|
// draw to stencil (first pass)
|
||||||
for (uint32_t i = 0; i < renderData->meshGroupShapes.meshes.count; i++)
|
ARRAY_FOREACH(p, renderData->meshGroupShapes.meshes)
|
||||||
renderData->meshGroupShapes.meshes[i]->drawFan(context, renderPassEncoder);
|
(*p)->drawFan(context, renderPassEncoder);
|
||||||
// merge depth and stencil buffer
|
// merge depth and stencil buffer
|
||||||
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
|
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
|
||||||
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, bindGroupOpacities[128], 0, nullptr);
|
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, bindGroupOpacities[128], 0, nullptr);
|
||||||
|
@ -662,25 +662,25 @@ void WgCompositor::renderClipPath(WgContext& context, WgRenderDataPaint* paint)
|
||||||
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
|
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
|
||||||
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData0->bindGroupPaint, 0, nullptr);
|
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData0->bindGroupPaint, 0, nullptr);
|
||||||
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, stencilPipeline);
|
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, stencilPipeline);
|
||||||
for (uint32_t i = 0; i < renderData0->meshGroupShapes.meshes.count; i++)
|
ARRAY_FOREACH(p, renderData0->meshGroupShapes.meshes)
|
||||||
renderData0->meshGroupShapes.meshes[i]->drawFan(context, renderPassEncoder);
|
(*p)->drawFan(context, renderPassEncoder);
|
||||||
// copy stencil to depth
|
// copy stencil to depth
|
||||||
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
|
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
|
||||||
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData0->bindGroupPaint, 0, nullptr);
|
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData0->bindGroupPaint, 0, nullptr);
|
||||||
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, bindGroupOpacities[128], 0, nullptr);
|
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, bindGroupOpacities[128], 0, nullptr);
|
||||||
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.copy_stencil_to_depth);
|
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.copy_stencil_to_depth);
|
||||||
renderData0->meshDataBBox.drawFan(context, renderPassEncoder);
|
renderData0->meshDataBBox.drawFan(context, renderPassEncoder);
|
||||||
// merge clip pathes with AND logic
|
// merge clip pathes with AND logic
|
||||||
for (uint32_t clipIndex = 1; clipIndex < paint->clips.count; clipIndex++) {
|
for (auto p = paint->clips.begin() + 1; paint->clips.end(); ++p) {
|
||||||
// get render data
|
// get render data
|
||||||
WgRenderDataShape* renderData = (WgRenderDataShape*)paint->clips[clipIndex];
|
WgRenderDataShape* renderData = (WgRenderDataShape*)(*p);
|
||||||
// markup stencil
|
// markup stencil
|
||||||
WGPURenderPipeline stencilPipeline = (renderData->fillRule == FillRule::NonZero) ? pipelines.nonzero : pipelines.evenodd;
|
WGPURenderPipeline stencilPipeline = (renderData->fillRule == FillRule::NonZero) ? pipelines.nonzero : pipelines.evenodd;
|
||||||
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
|
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
|
||||||
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr);
|
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr);
|
||||||
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, stencilPipeline);
|
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, stencilPipeline);
|
||||||
for (uint32_t i = 0; i < renderData->meshGroupShapes.meshes.count; i++)
|
ARRAY_FOREACH(p, renderData->meshGroupShapes.meshes)
|
||||||
renderData->meshGroupShapes.meshes[i]->drawFan(context, renderPassEncoder);
|
(*p)->drawFan(context, renderPassEncoder);
|
||||||
// copy stencil to depth (clear stencil)
|
// copy stencil to depth (clear stencil)
|
||||||
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
|
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
|
||||||
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr);
|
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr);
|
||||||
|
@ -723,8 +723,8 @@ void WgCompositor::clearClipPath(WgContext& context, WgRenderDataPaint* paint)
|
||||||
// reset scissor recr to full screen
|
// reset scissor recr to full screen
|
||||||
wgpuRenderPassEncoderSetScissorRect(renderPassEncoder, 0, 0, width, height);
|
wgpuRenderPassEncoderSetScissorRect(renderPassEncoder, 0, 0, width, height);
|
||||||
// get render data
|
// get render data
|
||||||
for (uint32_t clipIndex = 0; clipIndex < paint->clips.count; clipIndex++) {
|
ARRAY_FOREACH(p, paint->clips) {
|
||||||
WgRenderDataShape* renderData = (WgRenderDataShape*)paint->clips[clipIndex];
|
WgRenderDataShape* renderData = (WgRenderDataShape*)(*p);
|
||||||
// set transformations
|
// set transformations
|
||||||
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
|
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
|
||||||
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr);
|
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr);
|
||||||
|
|
|
@ -193,8 +193,8 @@ struct WgVertexBuffer
|
||||||
// decode path
|
// decode path
|
||||||
reset(tscale);
|
reset(tscale);
|
||||||
size_t pntIndex = 0;
|
size_t pntIndex = 0;
|
||||||
for (uint32_t cmdIndex = 0; cmdIndex < rshape.path.cmds.count; cmdIndex++) {
|
ARRAY_FOREACH(p, rshape.path.cmds) {
|
||||||
PathCommand cmd = rshape.path.cmds[cmdIndex];
|
auto cmd = *p;
|
||||||
if (cmd == PathCommand::MoveTo) {
|
if (cmd == PathCommand::MoveTo) {
|
||||||
// after path decoding we need to update distances and total length
|
// after path decoding we need to update distances and total length
|
||||||
if (update_dist) updateDistances();
|
if (update_dist) updateDistances();
|
||||||
|
@ -208,9 +208,9 @@ struct WgVertexBuffer
|
||||||
} else if (cmd == PathCommand::Close) {
|
} else if (cmd == PathCommand::Close) {
|
||||||
close();
|
close();
|
||||||
// proceed path if close command is not the last command and next command is LineTo or CubicTo
|
// proceed path if close command is not the last command and next command is LineTo or CubicTo
|
||||||
if ((cmdIndex + 1 < rshape.path.cmds.count) &&
|
if (((p + 1) < rshape.path.cmds.end()) &&
|
||||||
((rshape.path.cmds[cmdIndex + 1] == PathCommand::LineTo) ||
|
((*(p + 1) == PathCommand::LineTo) ||
|
||||||
(rshape.path.cmds[cmdIndex + 1] == PathCommand::CubicTo))) {
|
(*(p + 1) == PathCommand::CubicTo))) {
|
||||||
// proceed current path
|
// proceed current path
|
||||||
if (update_dist) updateDistances();
|
if (update_dist) updateDistances();
|
||||||
if ((vcount > 0) && (onPolyline)) onPolyline(*this);
|
if ((vcount > 0) && (onPolyline)) onPolyline(*this);
|
||||||
|
|
|
@ -157,9 +157,9 @@ void WgMeshDataPool::free(WgContext& context, WgMeshData* meshData)
|
||||||
|
|
||||||
void WgMeshDataPool::release(WgContext& context)
|
void WgMeshDataPool::release(WgContext& context)
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < mList.count; i++) {
|
ARRAY_FOREACH(p, mList) {
|
||||||
mList[i]->release(context);
|
(*p)->release(context);
|
||||||
delete mList[i];
|
delete(*p);
|
||||||
}
|
}
|
||||||
mPool.clear();
|
mPool.clear();
|
||||||
mList.clear();
|
mList.clear();
|
||||||
|
@ -197,8 +197,8 @@ void WgMeshDataGroup::append(WgContext& context, const Point pmin, const Point p
|
||||||
|
|
||||||
void WgMeshDataGroup::release(WgContext& context)
|
void WgMeshDataGroup::release(WgContext& context)
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < meshes.count; i++)
|
ARRAY_FOREACH(p, meshes)
|
||||||
WgMeshDataPool::gMeshDataPool->free(context, meshes[i]);
|
WgMeshDataPool::gMeshDataPool->free(context, *p);
|
||||||
meshes.clear();
|
meshes.clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -324,9 +324,9 @@ void WgRenderDataPaint::update(WgContext& context, const tvg::Matrix& transform,
|
||||||
|
|
||||||
void WgRenderDataPaint::updateClips(tvg::Array<tvg::RenderData> &clips) {
|
void WgRenderDataPaint::updateClips(tvg::Array<tvg::RenderData> &clips) {
|
||||||
this->clips.clear();
|
this->clips.clear();
|
||||||
for (uint32_t i = 0; i < clips.count; i++)
|
ARRAY_FOREACH(p, clips) {
|
||||||
if (clips[i])
|
this->clips.push((WgRenderDataPaint*)(*p));
|
||||||
this->clips.push((WgRenderDataPaint*)clips[i]);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//***********************************************************************
|
//***********************************************************************
|
||||||
|
@ -532,9 +532,9 @@ void WgRenderDataShapePool::free(WgContext& context, WgRenderDataShape* renderDa
|
||||||
|
|
||||||
void WgRenderDataShapePool::release(WgContext& context)
|
void WgRenderDataShapePool::release(WgContext& context)
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < mList.count; i++) {
|
ARRAY_FOREACH(p, mList) {
|
||||||
mList[i]->release(context);
|
(*p)->release(context);
|
||||||
delete mList[i];
|
delete(*p);
|
||||||
}
|
}
|
||||||
mPool.clear();
|
mPool.clear();
|
||||||
mList.clear();
|
mList.clear();
|
||||||
|
@ -593,9 +593,9 @@ void WgRenderDataPicturePool::free(WgContext& context, WgRenderDataPicture* rend
|
||||||
|
|
||||||
void WgRenderDataPicturePool::release(WgContext& context)
|
void WgRenderDataPicturePool::release(WgContext& context)
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < mList.count; i++) {
|
ARRAY_FOREACH(p, mList) {
|
||||||
mList[i]->release(context);
|
(*p)->release(context);
|
||||||
delete mList[i];
|
delete(*p);
|
||||||
}
|
}
|
||||||
mPool.clear();
|
mPool.clear();
|
||||||
mList.clear();
|
mList.clear();
|
||||||
|
|
|
@ -83,9 +83,9 @@ void WgRenderStoragePool::initialize(WgContext& context, uint32_t width, uint32_
|
||||||
|
|
||||||
void WgRenderStoragePool::release(WgContext& context)
|
void WgRenderStoragePool::release(WgContext& context)
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < list.count; i++) {
|
ARRAY_FOREACH(p, list) {
|
||||||
list[i]->release(context);
|
(*p)->release(context);
|
||||||
delete list[i];
|
delete(*p);
|
||||||
}
|
}
|
||||||
list.clear();
|
list.clear();
|
||||||
pool.clear();
|
pool.clear();
|
||||||
|
|
|
@ -70,8 +70,8 @@ void WgRenderer::release()
|
||||||
|
|
||||||
void WgRenderer::disposeObjects()
|
void WgRenderer::disposeObjects()
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < mDisposeRenderDatas.count; i++) {
|
ARRAY_FOREACH(p, mDisposeRenderDatas) {
|
||||||
WgRenderDataPaint* renderData = (WgRenderDataPaint*)mDisposeRenderDatas[i];
|
auto renderData = (WgRenderDataPaint*)(*p);
|
||||||
if (renderData->type() == Type::Shape) {
|
if (renderData->type() == Type::Shape) {
|
||||||
mRenderDataShapePool.free(mContext, (WgRenderDataShape*)renderData);
|
mRenderDataShapePool.free(mContext, (WgRenderDataShape*)renderData);
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Add table
Reference in a new issue