more layers extracted from webkit
git-svn-id: http://skia.googlecode.com/svn/trunk@503 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/core/SkRect.h b/include/core/SkRect.h
index c9f432a..4f78e65 100644
--- a/include/core/SkRect.h
+++ b/include/core/SkRect.h
@@ -40,12 +40,11 @@
*/
int height() const { return fBottom - fTop; }
- friend int operator==(const SkIRect& a, const SkIRect& b)
- {
+ friend int operator==(const SkIRect& a, const SkIRect& b) {
return !memcmp(&a, &b, sizeof(a));
}
- friend int operator!=(const SkIRect& a, const SkIRect& b)
- {
+
+ friend int operator!=(const SkIRect& a, const SkIRect& b) {
return memcmp(&a, &b, sizeof(a));
}
@@ -58,8 +57,7 @@
*/
void setEmpty() { memset(this, 0, sizeof(*this)); }
- void set(int32_t left, int32_t top, int32_t right, int32_t bottom)
- {
+ void set(int32_t left, int32_t top, int32_t right, int32_t bottom) {
fLeft = left;
fTop = top;
fRight = right;
@@ -69,32 +67,34 @@
/** Offset set the rectangle by adding dx to its left and right,
and adding dy to its top and bottom.
*/
- void offset(int32_t dx, int32_t dy)
- {
+ void offset(int32_t dx, int32_t dy) {
fLeft += dx;
fTop += dy;
fRight += dx;
fBottom += dy;
}
+ void offset(const SkIPoint& delta) {
+ this->offset(delta.fX, delta.fY);
+ }
+
/** Inset the rectangle by (dx,dy). If dx is positive, then the sides are moved inwards,
making the rectangle narrower. If dx is negative, then the sides are moved outwards,
making the rectangle wider. The same hods true for dy and the top and bottom.
*/
- void inset(int32_t dx, int32_t dy)
- {
+ void inset(int32_t dx, int32_t dy) {
fLeft += dx;
fTop += dy;
fRight -= dx;
fBottom -= dy;
}
+
/** Returns true if (x,y) is inside the rectangle and the rectangle is not
empty. The left and top are considered to be inside, while the right
and bottom are not. Thus for the rectangle (0, 0, 5, 10), the
points (0,0) and (0,9) are inside, while (-1,0) and (5,9) are not.
*/
- bool contains(int32_t x, int32_t y) const
- {
+ bool contains(int32_t x, int32_t y) const {
return (unsigned)(x - fLeft) < (unsigned)(fRight - fLeft) &&
(unsigned)(y - fTop) < (unsigned)(fBottom - fTop);
}
@@ -102,8 +102,7 @@
/** Returns true if the 4 specified sides of a rectangle are inside or equal to this rectangle.
If either rectangle is empty, contains() returns false.
*/
- bool contains(int32_t left, int32_t top, int32_t right, int32_t bottom) const
- {
+ bool contains(int32_t left, int32_t top, int32_t right, int32_t bottom) const {
return left < right && top < bottom && !this->isEmpty() && // check for empties
fLeft <= left && fTop <= top &&
fRight >= right && fBottom >= bottom;
@@ -111,8 +110,7 @@
/** Returns true if the specified rectangle r is inside or equal to this rectangle.
*/
- bool contains(const SkIRect& r) const
- {
+ bool contains(const SkIRect& r) const {
return !r.isEmpty() && !this->isEmpty() && // check for empties
fLeft <= r.fLeft && fTop <= r.fTop &&
fRight >= r.fRight && fBottom >= r.fBottom;
@@ -125,8 +123,7 @@
specified rectangles are non-empty.
*/
bool containsNoEmptyCheck(int32_t left, int32_t top,
- int32_t right, int32_t bottom) const
- {
+ int32_t right, int32_t bottom) const {
SkASSERT(fLeft < fRight && fTop < fBottom);
SkASSERT(left < right && top < bottom);
@@ -138,8 +135,7 @@
intersection, otherwise return false and do not change this rectangle.
If either rectangle is empty, do nothing and return false.
*/
- bool intersect(const SkIRect& r)
- {
+ bool intersect(const SkIRect& r) {
SkASSERT(&r);
return this->intersect(r.fLeft, r.fTop, r.fRight, r.fBottom);
}
@@ -148,14 +144,12 @@
that intersection, otherwise return false and do not change this
rectangle. If either rectangle is empty, do nothing and return false.
*/
- bool intersect(const SkIRect& a, const SkIRect& b)
- {
+ bool intersect(const SkIRect& a, const SkIRect& b) {
SkASSERT(&a && &b);
if (!a.isEmpty() && !b.isEmpty() &&
- a.fLeft < b.fRight && b.fLeft < a.fRight &&
- a.fTop < b.fBottom && b.fTop < a.fBottom)
- {
+ a.fLeft < b.fRight && b.fLeft < a.fRight &&
+ a.fTop < b.fBottom && b.fTop < a.fBottom) {
fLeft = SkMax32(a.fLeft, b.fLeft);
fTop = SkMax32(a.fTop, b.fTop);
fRight = SkMin32(a.fRight, b.fRight);
@@ -171,14 +165,12 @@
If either is, then the return result is undefined. In the debug build,
we assert that both rectangles are non-empty.
*/
- bool intersectNoEmptyCheck(const SkIRect& a, const SkIRect& b)
- {
+ bool intersectNoEmptyCheck(const SkIRect& a, const SkIRect& b) {
SkASSERT(&a && &b);
SkASSERT(!a.isEmpty() && !b.isEmpty());
if (a.fLeft < b.fRight && b.fLeft < a.fRight &&
- a.fTop < b.fBottom && b.fTop < a.fBottom)
- {
+ a.fTop < b.fBottom && b.fTop < a.fBottom) {
fLeft = SkMax32(a.fLeft, b.fLeft);
fTop = SkMax32(a.fTop, b.fTop);
fRight = SkMin32(a.fRight, b.fRight);
@@ -193,11 +185,9 @@
otherwise return false and do not change this rectangle.
If either rectangle is empty, do nothing and return false.
*/
- bool intersect(int32_t left, int32_t top, int32_t right, int32_t bottom)
- {
+ bool intersect(int32_t left, int32_t top, int32_t right, int32_t bottom) {
if (left < right && top < bottom && !this->isEmpty() &&
- fLeft < right && left < fRight && fTop < bottom && top < fBottom)
- {
+ fLeft < right && left < fRight && fTop < bottom && top < fBottom) {
if (fLeft < left) fLeft = left;
if (fTop < top) fTop = top;
if (fRight > right) fRight = right;
@@ -209,8 +199,7 @@
/** Returns true if a and b are not empty, and they intersect
*/
- static bool Intersects(const SkIRect& a, const SkIRect& b)
- {
+ static bool Intersects(const SkIRect& a, const SkIRect& b) {
return !a.isEmpty() && !b.isEmpty() && // check for empties
a.fLeft < b.fRight && b.fLeft < a.fRight &&
a.fTop < b.fBottom && b.fTop < a.fBottom;
@@ -226,8 +215,7 @@
If this rectangle is empty, just set it to the specified rectangle. If the specified
rectangle is empty, do nothing.
*/
- void join(const SkIRect& r)
- {
+ void join(const SkIRect& r) {
this->join(r.fLeft, r.fTop, r.fRight, r.fBottom);
}
@@ -252,12 +240,11 @@
SkScalar centerX() const { return SkScalarHalf(fLeft + fRight); }
SkScalar centerY() const { return SkScalarHalf(fTop + fBottom); }
- friend int operator==(const SkRect& a, const SkRect& b)
- {
+ friend int operator==(const SkRect& a, const SkRect& b) {
return !memcmp(&a, &b, sizeof(a));
}
- friend int operator!=(const SkRect& a, const SkRect& b)
- {
+
+ friend int operator!=(const SkRect& a, const SkRect& b) {
return memcmp(&a, &b, sizeof(a));
}
@@ -269,16 +256,14 @@
*/
void setEmpty() { memset(this, 0, sizeof(*this)); }
- void set(const SkIRect& src)
- {
+ void set(const SkIRect& src) {
fLeft = SkIntToScalar(src.fLeft);
fTop = SkIntToScalar(src.fTop);
fRight = SkIntToScalar(src.fRight);
fBottom = SkIntToScalar(src.fBottom);
}
- void set(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom)
- {
+ void set(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) {
fLeft = left;
fTop = top;
fRight = right;
@@ -304,20 +289,22 @@
/** Offset set the rectangle by adding dx to its left and right,
and adding dy to its top and bottom.
*/
- void offset(SkScalar dx, SkScalar dy)
- {
+ void offset(SkScalar dx, SkScalar dy) {
fLeft += dx;
fTop += dy;
fRight += dx;
fBottom += dy;
}
+ void offset(const SkPoint& delta) {
+ this->offset(delta.fX, delta.fY);
+ }
+
/** Inset the rectangle by (dx,dy). If dx is positive, then the sides are moved inwards,
making the rectangle narrower. If dx is negative, then the sides are moved outwards,
making the rectangle wider. The same hods true for dy and the top and bottom.
*/
- void inset(SkScalar dx, SkScalar dy)
- {
+ void inset(SkScalar dx, SkScalar dy) {
fLeft += dx;
fTop += dy;
fRight -= dx;
@@ -340,8 +327,7 @@
/** Return true if this rectangle is not empty, and the specified sides of
a rectangle are not empty, and they intersect.
*/
- bool intersects(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) const
- {
+ bool intersects(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) const {
return // first check that both are not empty
left < right && top < bottom &&
fLeft < fRight && fTop < fBottom &&
@@ -352,8 +338,7 @@
/** Return true if rectangles a and b are not empty and intersect.
*/
- static bool Intersects(const SkRect& a, const SkRect& b)
- {
+ static bool Intersects(const SkRect& a, const SkRect& b) {
return !a.isEmpty() && !b.isEmpty() && // check for empties
a.fLeft < b.fRight && b.fLeft < a.fRight &&
a.fTop < b.fBottom && b.fTop < a.fBottom;
@@ -369,8 +354,7 @@
If this rectangle is empty, just set it to the specified rectangle. If the specified
rectangle is empty, do nothing.
*/
- void join(const SkRect& r)
- {
+ void join(const SkRect& r) {
this->join(r.fLeft, r.fTop, r.fRight, r.fBottom);
}
@@ -380,8 +364,7 @@
while (-1,0) and (5,9) are not.
If this rectangle is empty, return false.
*/
- bool contains(const SkPoint& p) const
- {
+ bool contains(const SkPoint& p) const {
return !this->isEmpty() &&
fLeft <= p.fX && p.fX < fRight &&
fTop <= p.fY && p.fY < fBottom;
@@ -393,8 +376,7 @@
while (-1,0) and (5,9) are not.
If this rectangle is empty, return false.
*/
- bool contains(SkScalar x, SkScalar y) const
- {
+ bool contains(SkScalar x, SkScalar y) const {
return !this->isEmpty() &&
fLeft <= x && x < fRight &&
fTop <= y && y < fBottom;
@@ -403,8 +385,7 @@
/** Return true if this rectangle contains r.
If either rectangle is empty, return false.
*/
- bool contains(const SkRect& r) const
- {
+ bool contains(const SkRect& r) const {
return !r.isEmpty() && !this->isEmpty() && // check for empties
fLeft <= r.fLeft && fTop <= r.fTop &&
fRight >= r.fRight && fBottom >= r.fBottom;
@@ -413,8 +394,7 @@
/** Set the dst integer rectangle by rounding this rectangle's coordinates
to their nearest integer values.
*/
- void round(SkIRect* dst) const
- {
+ void round(SkIRect* dst) const {
SkASSERT(dst);
dst->set(SkScalarRound(fLeft), SkScalarRound(fTop), SkScalarRound(fRight), SkScalarRound(fBottom));
}
@@ -422,8 +402,7 @@
/** Set the dst integer rectangle by rounding "out" this rectangle, choosing the floor of top and left,
and the ceiling of right and bototm.
*/
- void roundOut(SkIRect* dst) const
- {
+ void roundOut(SkIRect* dst) const {
SkASSERT(dst);
dst->set(SkScalarFloor(fLeft), SkScalarFloor(fTop), SkScalarCeil(fRight), SkScalarCeil(fBottom));
}
diff --git a/include/utils/SkLayer.h b/include/utils/SkLayer.h
index 36eccc7..c97bf72 100644
--- a/include/utils/SkLayer.h
+++ b/include/utils/SkLayer.h
@@ -26,33 +26,6 @@
#include "SkSize.h"
class SkCanvas;
-class SkPicture;
-
-
-struct SkLength {
- enum SkLengthType { Undefined, Auto, Relative, Percent, Fixed, Static, Intrinsic, MinIntrinsic };
- SkLengthType type;
- SkScalar value;
- SkLength() {
- type = Undefined;
- value = 0;
- }
- bool defined() const {
- if (type == Undefined)
- return false;
- return true;
- }
- float calcFloatValue(float max) const {
- switch (type) {
- case Percent:
- return (max * value) / 100.0f;
- case Fixed:
- return value;
- default:
- return value;
- }
- }
-};
class SkLayer : public SkRefCnt {
@@ -61,48 +34,21 @@
SkLayer(const SkLayer&);
virtual ~SkLayer();
- // deprecated
- void setTranslation(SkScalar x, SkScalar y) { m_translation.set(x, y); }
- void setRotation(SkScalar a) { m_angleTransform = a; m_doRotation = true; }
- void setScale(SkScalar x, SkScalar y) { m_scale.set(x, y); }
- SkPoint position() const { return m_position; }
- SkPoint translation() const { return m_translation; }
- SkSize size() const { return m_size; }
- SkRect bounds() const {
- SkRect rect;
- rect.set(m_position.fX, m_position.fY,
- m_position.fX + m_size.width(),
- m_position.fY + m_size.height());
- rect.offset(m_translation.fX, m_translation.fY);
- return rect;
- }
-
- const SkSize& getSize() const { return m_size; }
- void setSize(SkScalar w, SkScalar h) { m_size.set(w, h); }
-
SkScalar getOpacity() const { return m_opacity; }
- void setOpacity(SkScalar opacity) { m_opacity = opacity; }
-
+ const SkSize& getSize() const { return m_size; }
const SkPoint& getPosition() const { return m_position; }
- void setPosition(SkScalar x, SkScalar y) { m_position.set(x, y); }
-
const SkPoint& getAnchorPoint() const { return m_anchorPoint; }
- void setAnchorPoint(SkScalar x, SkScalar y) { m_anchorPoint.set(x, y); }
-
- virtual void setBackgroundColor(SkColor color) { m_backgroundColor = color; m_backgroundColorSet = true; }
-
- void setFixedPosition(SkLength left, SkLength top, SkLength right, SkLength bottom) {
- m_fixedLeft = left;
- m_fixedTop = top;
- m_fixedRight = right;
- m_fixedBottom = bottom;
- m_isFixed = true;
- }
-
const SkMatrix& getMatrix() const { return fMatrix; }
- void setMatrix(const SkMatrix&);
-
const SkMatrix& getChildrenMatrix() const { return fChildrenMatrix; }
+
+ SkScalar getWidth() const { return m_size.width(); }
+ SkScalar getHeight() const { return m_size.height(); }
+
+ void setOpacity(SkScalar opacity) { m_opacity = opacity; }
+ void setSize(SkScalar w, SkScalar h) { m_size.set(w, h); }
+ void setPosition(SkScalar x, SkScalar y) { m_position.set(x, y); }
+ void setAnchorPoint(SkScalar x, SkScalar y) { m_anchorPoint.set(x, y); }
+ void setMatrix(const SkMatrix&);
void setChildrenMatrix(const SkMatrix&);
// children
@@ -114,40 +60,22 @@
// paint method
- virtual void draw(SkCanvas*, SkScalar opacity, const SkRect* viewPort);
+ void draw(SkCanvas*, SkScalar opacity);
+ void draw(SkCanvas* canvas) {
+ this->draw(canvas, SK_Scalar1);
+ }
protected:
- virtual void onSetupCanvas(SkCanvas*, SkScalar opacity, const SkRect*);
- virtual void onDraw(SkCanvas*, SkScalar opacity, const SkRect* viewPort);
+ virtual void onDraw(SkCanvas*, SkScalar opacity);
private:
+ SkScalar m_opacity;
+ SkSize m_size;
+ SkPoint m_position;
+ SkPoint m_anchorPoint;
SkMatrix fMatrix;
SkMatrix fChildrenMatrix;
-public:
-
- bool m_doRotation;
- bool m_isFixed;
- bool m_backgroundColorSet;
-
- // layers properties
-
- SkScalar m_angleTransform;
- SkScalar m_opacity;
-
- SkSize m_size;
- SkPoint m_position;
- SkPoint m_translation;
- SkPoint m_anchorPoint;
- SkPoint m_scale;
-
- SkLength m_fixedLeft;
- SkLength m_fixedTop;
- SkLength m_fixedRight;
- SkLength m_fixedBottom;
-
- SkColor m_backgroundColor;
-
SkTDArray<SkLayer*> m_children;
};
diff --git a/samplecode/SampleSkLayer.cpp b/samplecode/SampleSkLayer.cpp
new file mode 100644
index 0000000..42f0a60
--- /dev/null
+++ b/samplecode/SampleSkLayer.cpp
@@ -0,0 +1,92 @@
+#include "SampleCode.h"
+#include "SkCanvas.h"
+#include "SkPaint.h"
+#include "SkView.h"
+#include "SkLayer.h"
+
+///////////////////////////////////////////////////////////////////////////////
+
+class TestLayer : public SkLayer {
+public:
+ TestLayer(SkColor c) : fColor(c) {}
+
+protected:
+ virtual void onDraw(SkCanvas* canvas, SkScalar opacity) {
+ SkRect r;
+ r.set(0, 0, this->getWidth(), this->getHeight());
+
+ SkPaint paint;
+ paint.setColor(fColor);
+ paint.setAlpha(SkScalarRound(opacity * 255));
+
+ canvas->drawRect(r, paint);
+ }
+
+private:
+ SkColor fColor;
+};
+
+class SkLayerView : public SkView {
+private:
+ SkLayer* fRootLayer;
+
+public:
+ SkLayerView() {
+ static const int W = 640;
+ static const int H = 480;
+ static const struct {
+ int fWidth;
+ int fHeight;
+ SkColor fColor;
+ int fPosX;
+ int fPosY;
+ } gData[] = {
+ { 120, 80, SK_ColorRED, 0, 0 },
+ { 120, 80, SK_ColorGREEN, W - 120, 0 },
+ { 120, 80, SK_ColorBLUE, 0, H - 80 },
+ { 120, 80, SK_ColorMAGENTA, W - 120, H - 80 },
+ };
+
+ fRootLayer = new SkLayer;
+ fRootLayer->setSize(W, H);
+ for (size_t i = 0; i < SK_ARRAY_COUNT(gData); i++) {
+ SkLayer* child = new TestLayer(gData[i].fColor);
+ child->setSize(gData[i].fWidth, gData[i].fHeight);
+ child->setPosition(gData[i].fPosX, gData[i].fPosY);
+ fRootLayer->addChild(child)->unref();
+ }
+ }
+
+ virtual ~SkLayerView() {
+ SkSafeUnref(fRootLayer);
+ }
+
+protected:
+ // overrides from SkEventSink
+ virtual bool onQuery(SkEvent* evt) {
+ if (SampleCode::TitleQ(*evt)) {
+ SampleCode::TitleR(evt, "SkLayer");
+ return true;
+ }
+ return this->INHERITED::onQuery(evt);
+ }
+
+ void drawBG(SkCanvas* canvas) {
+ canvas->drawColor(0xFFDDDDDD);
+
+ fRootLayer->draw(canvas);
+ }
+
+ virtual void onDraw(SkCanvas* canvas) {
+ this->drawBG(canvas);
+}
+
+private:
+ typedef SkView INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+static SkView* MyFactory() { return new SkLayerView; }
+static SkViewRegister reg(MyFactory);
+
diff --git a/src/utils/SkLayer.cpp b/src/utils/SkLayer.cpp
index fc1f5e5..603cdd1 100644
--- a/src/utils/SkLayer.cpp
+++ b/src/utils/SkLayer.cpp
@@ -2,44 +2,20 @@
#include "SkCanvas.h"
SkLayer::SkLayer() {
- m_doRotation = false;
- m_isFixed = false;
- m_backgroundColorSet = false;
-
- m_angleTransform = 0;
m_opacity = 1;
-
m_size.set(0, 0);
m_position.set(0, 0);
- m_translation.set(0, 0);
m_anchorPoint.set(0.5, 0.5);
- m_scale.set(1, 1);
-
- m_backgroundColor = 0;
fMatrix.reset();
fChildrenMatrix.reset();
}
SkLayer::SkLayer(const SkLayer& src) {
- m_doRotation = src.m_doRotation;
- m_isFixed = src.m_isFixed;
- m_backgroundColorSet = src.m_backgroundColorSet;
-
- m_angleTransform = src.m_angleTransform;
m_opacity = src.m_opacity;
m_size = src.m_size;
m_position = src.m_position;
- m_translation = src.m_translation;
m_anchorPoint = src.m_anchorPoint;
- m_scale = src.m_scale;
-
- m_fixedLeft = src.m_fixedLeft;
- m_fixedTop = src.m_fixedTop;
- m_fixedRight = src.m_fixedRight;
- m_fixedBottom = src.m_fixedBottom;
-
- m_backgroundColor = src.m_backgroundColor;
fMatrix = src.fMatrix;
fChildrenMatrix = src.fChildrenMatrix;
@@ -83,43 +59,54 @@
///////////////////////////////////////////////////////////////////////////////
-void SkLayer::onSetupCanvas(SkCanvas* canvas, SkScalar, const SkRect*) {
- SkScalar tx = m_position.fX;
- SkScalar ty = m_position.fY;
- canvas->translate(tx, ty);
-
- // now apply our matrix about the anchorPoint
- tx = SkScalarMul(m_anchorPoint.fX, m_size.width());
- ty = SkScalarMul(m_anchorPoint.fY, m_size.height());
- canvas->translate(tx, ty);
- canvas->concat(this->getMatrix());
- canvas->translate(-tx, -ty);
+void SkLayer::onDraw(SkCanvas*, SkScalar opacity) {
+// SkDebugf("----- no onDraw for %p\n", this);
}
-void SkLayer::onDraw(SkCanvas*, SkScalar opacity, const SkRect* viewport) {}
+#include "SkString.h"
-void SkLayer::draw(SkCanvas* canvas, SkScalar opacity, const SkRect* viewport) {
+void SkLayer::draw(SkCanvas* canvas, SkScalar opacity) {
#if 0
- SkDebugf("--- drawlayer %p anchor [%g %g] scale [%g %g]\n", this, m_anchorPoint.fX, m_anchorPoint.fY,
- m_scale.fX, m_scale.fY);
+ SkString str1, str2;
+ // this->getMatrix().toDumpString(&str1);
+ // this->getChildrenMatrix().toDumpString(&str2);
+ SkDebugf("--- drawlayer %p opacity %g size [%g %g] pos [%g %g] matrix %s children %s\n",
+ this, opacity * this->getOpacity(), m_size.width(), m_size.height(),
+ m_position.fX, m_position.fY, str1.c_str(), str2.c_str());
#endif
opacity = SkScalarMul(opacity, this->getOpacity());
if (opacity <= 0 || this->getSize().isEmpty()) {
+#if 0
+ SkDebugf("---- abort drawing %p opacity %g size [%g %g]\n",
+ this, opacity, m_size.width(), m_size.height());
+#endif
return;
}
- SkAutoCanvasRestore acr(canvas, false);
- canvas->save(SkCanvas::kMatrix_SaveFlag);
+ SkAutoCanvasRestore acr(canvas, true);
- this->onSetupCanvas(canvas, opacity, viewport);
- this->onDraw(canvas, opacity, viewport);
+ // update the matrix
+ {
+ SkScalar tx = m_position.fX;
+ SkScalar ty = m_position.fY;
+ canvas->translate(tx, ty);
+
+ // now apply our matrix about the anchorPoint
+ tx = SkScalarMul(m_anchorPoint.fX, m_size.width());
+ ty = SkScalarMul(m_anchorPoint.fY, m_size.height());
+ canvas->translate(tx, ty);
+ canvas->concat(this->getMatrix());
+ canvas->translate(-tx, -ty);
+ }
+
+ this->onDraw(canvas, opacity);
int count = this->countChildren();
if (count > 0) {
canvas->concat(this->getChildrenMatrix());
for (int i = 0; i < count; i++) {
- this->getChild(i)->draw(canvas, opacity, viewport);
+ this->getChild(i)->draw(canvas, opacity);
}
}
}