}
-void* GlRenderer::prepare(const Shape& shape, void* data, const RenderMatrix* transform, RenderUpdateFlag flags)
+void* GlRenderer::prepare(const Shape& shape, void* data, const RenderTransform* transform, RenderUpdateFlag flags)
{
//prepare shape data
GlShape* sdata = static_cast<GlShape*>(data);
class GlRenderer : public RenderMethod
{
public:
- void* prepare(const Shape& shape, void* data, const RenderMatrix* transform, RenderUpdateFlag flags) override;
+ void* prepare(const Shape& shape, void* data, const RenderTransform* transform, RenderUpdateFlag flags) override;
bool dispose(const Shape& shape, void *data) override;
bool render(const Shape& shape, void *data) override;
bool clear() override;
bool shapeGenOutline(const Shape& shape, SwShape& sdata);
void shapeDelOutline(SwShape& sdata);
bool shapeGenRle(const Shape& shape, SwShape& sdata, const SwSize& clip);
-void shapeTransformOutline(const Shape& shape, SwShape& sdata, const RenderMatrix& transform);
+void shapeTransformOutline(const Shape& shape, SwShape& sdata, const RenderTransform& transform);
SwRleData* rleRender(const SwShape& sdata, const SwSize& clip);
bool rasterShape(Surface& surface, SwShape& sdata, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
return true;
}
-void* SwRenderer::prepare(const Shape& shape, void* data, const RenderMatrix* transform, RenderUpdateFlag flags)
+void* SwRenderer::prepare(const Shape& shape, void* data, const RenderTransform* transform, RenderUpdateFlag flags)
{
//prepare shape data
SwShape* sdata = static_cast<SwShape*>(data);
public:
Surface surface;
- void* prepare(const Shape& shape, void* data, const RenderMatrix* transform, RenderUpdateFlag flags) override;
+ void* prepare(const Shape& shape, void* data, const RenderTransform* transform, RenderUpdateFlag flags) override;
bool dispose(const Shape& shape, void *data) override;
bool render(const Shape& shape, void *data) override;
bool target(uint32_t* buffer, size_t stride, size_t w, size_t h);
/* External Class Implementation */
/************************************************************************/
-void shapeTransformOutline(const Shape& shape, SwShape& sdata, const RenderMatrix& transform)
+void shapeTransformOutline(const Shape& shape, SwShape& sdata, const RenderTransform& transform)
{
auto outline = sdata.outline;
assert(outline);
enum RenderUpdateFlag {None = 0, Path = 1, Fill = 2, Transform = 4, All = 8};
-struct RenderMatrix
+struct RenderTransform
{
//3x3 Matrix Elements
float e11, e12, e13;
float e21, e22, e23;
float e31, e32, e33;
- static void rotate(RenderMatrix* out, float degree)
- {
- constexpr auto PI = 3.141592f;
-
- if (fabsf(degree) < FLT_EPSILON) return;
-
- auto radian = degree / 180.0f * PI;
- auto cosVal = cosf(radian);
- auto sinVal = sinf(radian);
-
- auto t11 = out->e11 * cosVal + out->e12 * sinVal;
- auto t12 = out->e11 * -sinVal + out->e12 * cosVal;
- auto t21 = out->e21 * cosVal + out->e22 * sinVal;
- auto t22 = out->e21 * -sinVal + out->e22 * cosVal;
- auto t31 = out->e31 * cosVal + out->e32 * sinVal;
- auto t32 = out->e31 * -sinVal + out->e32 * cosVal;
-
- out->e11 = t11;
- out->e12 = t12;
- out->e21 = t21;
- out->e22 = t22;
- out->e31 = t31;
- out->e32 = t32;
- }
-
- static void scale(RenderMatrix* out, float factor)
- {
- out->e11 *= factor;
- out->e22 *= factor;
- out->e33 *= factor;
- }
-
- static void identity(RenderMatrix* out)
- {
- out->e11 = 1.0f;
- out->e12 = 0.0f;
- out->e13 = 0.0f;
- out->e21 = 0.0f;
- out->e22 = 1.0f;
- out->e23 = 0.0f;
- out->e31 = 0.0f;
- out->e32 = 0.0f;
- out->e33 = 1.0f;
- }
-
- static void translate(RenderMatrix* out, float x, float y)
- {
- out->e31 += x;
- out->e32 += y;
- }
-
- static void multiply(const RenderMatrix* lhs, const RenderMatrix* rhs, RenderMatrix* out)
- {
- assert(lhs && rhs && out);
-
- out->e11 = lhs->e11 * rhs->e11 + lhs->e12 * rhs->e21 + lhs->e13 * rhs->e31;
- out->e12 = lhs->e11 * rhs->e12 + lhs->e12 * rhs->e22 + lhs->e13 * rhs->e32;
- out->e13 = lhs->e11 * rhs->e13 + lhs->e12 * rhs->e23 + lhs->e13 * rhs->e33;
-
- out->e21 = lhs->e21 * rhs->e11 + lhs->e22 * rhs->e21 + lhs->e23 * rhs->e31;
- out->e22 = lhs->e21 * rhs->e12 + lhs->e22 * rhs->e22 + lhs->e23 * rhs->e32;
- out->e23 = lhs->e21 * rhs->e13 + lhs->e22 * rhs->e23 + lhs->e23 * rhs->e33;
-
- out->e31 = lhs->e31 * rhs->e11 + lhs->e32 * rhs->e21 + lhs->e33 * rhs->e31;
- out->e32 = lhs->e31 * rhs->e12 + lhs->e32 * rhs->e22 + lhs->e33 * rhs->e32;
- out->e33 = lhs->e31 * rhs->e13 + lhs->e32 * rhs->e23 + lhs->e33 * rhs->e33;
- }
-};
-
-struct RenderTransform
-{
- RenderMatrix m;
float x = 0.0f;
float y = 0.0f;
float degree = 0.0f; //rotation degree
bool update()
{
+ constexpr auto PI = 3.141592f;
+
//Init Status
if (fabsf(x) <= FLT_EPSILON && fabsf(y) <= FLT_EPSILON &&
fabsf(degree) <= FLT_EPSILON && fabsf(factor - 1) <= FLT_EPSILON) {
return false;
}
- RenderMatrix::identity(&m);
- RenderMatrix::scale(&m, factor);
- RenderMatrix::rotate(&m, degree);
- RenderMatrix::translate(&m, x, y);
+ //identity
+ e11 = 1.0f;
+ e12 = 0.0f;
+ e13 = 0.0f;
+ e21 = 0.0f;
+ e22 = 1.0f;
+ e23 = 0.0f;
+ e31 = 0.0f;
+ e32 = 0.0f;
+ e33 = 1.0f;
+
+ //scale
+ e11 *= factor;
+ e22 *= factor;
+ e33 *= factor;
+
+ //rotation
+ if (fabsf(degree) > FLT_EPSILON) {
+ auto radian = degree / 180.0f * PI;
+ auto cosVal = cosf(radian);
+ auto sinVal = sinf(radian);
+
+ auto t11 = e11 * cosVal + e12 * sinVal;
+ auto t12 = e11 * -sinVal + e12 * cosVal;
+ auto t21 = e21 * cosVal + e22 * sinVal;
+ auto t22 = e21 * -sinVal + e22 * cosVal;
+ auto t31 = e31 * cosVal + e32 * sinVal;
+ auto t32 = e31 * -sinVal + e32 * cosVal;
+
+ e11 = t11;
+ e12 = t12;
+ e21 = t21;
+ e22 = t22;
+ e31 = t31;
+ e32 = t32;
+ }
+
+ e31 += x;
+ e32 += y;
return true;
}
+
+ RenderTransform()
+ {
+ }
+
+ RenderTransform(const RenderTransform* lhs, const RenderTransform* rhs)
+ {
+ assert(lhs && rhs);
+
+ auto dx = rhs->x * lhs->factor;
+ auto dy = rhs->y * lhs->factor;
+ auto tx = dx * lhs->e11 + dy * lhs->e12 + lhs->e13;
+ auto ty = dx * lhs->e21 + dy * lhs->e22 + lhs->e23;
+
+ x = lhs->x + tx;
+ y = lhs->y + ty;
+ degree = lhs->degree + rhs->degree;
+ factor = lhs->factor * rhs->factor;
+
+ update();
+ }
};
{
public:
virtual ~RenderMethod() {}
- virtual void* prepare(const Shape& shape, void* data, const RenderMatrix* transform, RenderUpdateFlag flags) = 0;
+ virtual void* prepare(const Shape& shape, void* data, const RenderTransform* transform, RenderUpdateFlag flags) = 0;
virtual bool dispose(const Shape& shape, void *data) = 0;
virtual bool render(const Shape& shape, void *data) = 0;
virtual bool clear() = 0;
return true;
}
- bool updateInternal(RenderMethod &renderer, const RenderMatrix* transform, size_t flag)
+ bool updateInternal(RenderMethod &renderer, const RenderTransform* transform, size_t flag)
{
for(auto paint: paints) {
if (auto scene = dynamic_cast<Scene*>(paint)) {
return true;
}
- bool update(RenderMethod &renderer, const RenderMatrix* pTransform = nullptr, size_t pFlag = 0)
+ bool update(RenderMethod &renderer, const RenderTransform* pTransform = nullptr, size_t pFlag = 0)
{
if (flag & RenderUpdateFlag::Transform) {
assert(transform);
auto ret = true;
if (transform && pTransform) {
- RenderMatrix outTransform;
- RenderMatrix::multiply(pTransform, &transform->m, &outTransform);
+ RenderTransform outTransform(pTransform, transform);
ret = updateInternal(renderer, &outTransform, pFlag | flag);
} else {
- auto outTransform = pTransform ? pTransform : &transform->m;
+ auto outTransform = pTransform ? pTransform : transform;
ret = updateInternal(renderer, outTransform, pFlag | flag);
}
return renderer.render(shape, edata);
}
- bool update(Shape& shape, RenderMethod& renderer, const RenderMatrix* pTransform = nullptr, size_t pFlag = 0)
+ bool update(Shape& shape, RenderMethod& renderer, const RenderTransform* pTransform = nullptr, size_t pFlag = 0)
{
if (flag & RenderUpdateFlag::Transform) {
assert(transform);
}
if (transform && pTransform) {
- RenderMatrix outTransform;
- RenderMatrix::multiply(pTransform, &transform->m, &outTransform);
+ RenderTransform outTransform(pTransform, transform);
edata = renderer.prepare(shape, edata, &outTransform, static_cast<RenderUpdateFlag>(pFlag | flag));
} else {
- auto outTransform = pTransform ? pTransform : &transform->m;
+ auto outTransform = pTransform ? pTransform : transform;
edata = renderer.prepare(shape, edata, outTransform, static_cast<RenderUpdateFlag>(pFlag | flag));
}
canvas = tvg::SwCanvas::gen();
canvas->target(buffer, WIDTH, WIDTH, HEIGHT);
- //Create a Scene
+ //Create a Scene1
auto scene = tvg::Scene::gen();
pScene1 = scene.get();
scene->reserve(3); //reserve 3 shape nodes (optional)
- //Prepare Round Rectangle
+ //Prepare Round Rectangle (Scene1)
auto shape1 = tvg::Shape::gen();
shape1->appendRect(-235, -250, 400, 400, 50); //x, y, w, h, cornerRadius
shape1->fill(0, 255, 0, 255); //r, g, b, a
scene->push(move(shape1));
- //Prepare Circle
+ //Prepare Circle (Scene1)
auto shape2 = tvg::Shape::gen();
shape2->appendCircle(-165, -150, 200, 200); //cx, cy, radiusW, radiusH
shape2->fill(255, 255, 0, 255); //r, g, b, a
scene->push(move(shape2));
- //Prepare Ellipse
+ //Prepare Ellipse (Scene1)
auto shape3 = tvg::Shape::gen();
shape3->appendCircle(265, 250, 150, 100); //cx, cy, radiusW, radiusH
shape3->fill(0, 255, 255, 255); //r, g, b, a
scene->push(move(shape3));
scene->translate(350, 350);
- scene->scale(0.7);
+ scene->scale(0.5);
- //Create another Scene
+ //Create Scene2
auto scene2 = tvg::Scene::gen();
pScene2 = scene2.get();
scene2->reserve(2); //reserve 2 shape nodes (optional)
-#if 0
- //Star
+ //Star (Scene2)
auto shape4 = tvg::Shape::gen();
//Appends Paths
shape4->lineTo(-53, -5.5);
shape4->close();
shape4->fill(0, 0, 127, 127);
-
- float x, y, w, h;
- shape4->bounds(x, y, w, h);
scene2->push(move(shape4));
- //Circle
+ //Circle (Scene2)
auto shape5 = tvg::Shape::gen();
auto cx = -150.0f;
auto cy = -150.0f;
- auto radius = 125.0f;
+ auto radius = 100.0f;
auto halfRadius = radius * 0.552284f;
//Append Paths
shape5->fill(127, 0, 0, 127);
scene2->push(move(shape5));
- scene2->translate(300, 300);
+ scene2->translate(500, 350);
//Push scene2 onto the scene
scene->push(move(scene2));
-#endif
+
//Draw the Scene onto the Canvas
canvas->push(move(scene));
while retaining other properties. */
pScene1->rotate(360 * progress);
+ pScene2->rotate(360 * progress);
//Update shape for drawing (this may work asynchronously)
canvas->update(pScene1);