common: code refactoring

use ARRAY_FOREACH() for neat code and
accessing the memory efficiently than normal indexing.
This commit is contained in:
Hermet Park 2025-01-15 17:03:49 +09:00 committed by Hermet Park
parent 096b834771
commit 07e73a9e6f
25 changed files with 251 additions and 304 deletions

View file

@ -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
{ {

View file

@ -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);

View file

@ -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;
} }
} }

View file

@ -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;
} }
} }

View file

@ -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);
}
} }

View file

@ -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;

View file

@ -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));

View file

@ -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);
} }

View file

@ -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;
} }

View file

@ -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);

View file

@ -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);

View file

@ -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);
} }
} }

View file

@ -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();
} }

View file

@ -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)

View file

@ -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();
} }

View file

@ -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;

View file

@ -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;

View file

@ -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

View file

@ -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;
} }

View file

@ -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);
} }
} }

View file

@ -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);

View file

@ -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);

View file

@ -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();

View file

@ -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();

View file

@ -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 {