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