mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 05:33:36 +00:00
common: support Scene Transform
this contains testSceneTransform example Change-Id: I460b05dc8bc4a842e26e950c800c5c35f8d3da7f
This commit is contained in:
parent
2f2efb73dd
commit
fdbf42f478
14 changed files with 358 additions and 78 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -11,3 +11,4 @@ testUpdate
|
||||||
testDirectUpdate
|
testDirectUpdate
|
||||||
testScene
|
testScene
|
||||||
testTransform
|
testTransform
|
||||||
|
testSceneTransform
|
||||||
|
|
|
@ -65,7 +65,7 @@ bool GlRenderer::dispose(const Shape& shape, void *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void* GlRenderer::prepare(const Shape& shape, void* data, const RenderTransform* transform, RenderUpdateFlag flags)
|
void* GlRenderer::prepare(const Shape& shape, void* data, const RenderMatrix* transform, RenderUpdateFlag flags)
|
||||||
{
|
{
|
||||||
//prepare shape data
|
//prepare shape data
|
||||||
GlShape* sdata = static_cast<GlShape*>(data);
|
GlShape* sdata = static_cast<GlShape*>(data);
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace tvg
|
||||||
class GlRenderer : public RenderMethod
|
class GlRenderer : public RenderMethod
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void* prepare(const Shape& shape, void* data, const RenderTransform* transform, RenderUpdateFlag flags) override;
|
void* prepare(const Shape& shape, void* data, const RenderMatrix* transform, RenderUpdateFlag flags) override;
|
||||||
bool dispose(const Shape& shape, void *data) override;
|
bool dispose(const Shape& shape, void *data) override;
|
||||||
bool render(const Shape& shape, void *data) override;
|
bool render(const Shape& shape, void *data) override;
|
||||||
bool clear() override;
|
bool clear() override;
|
||||||
|
|
|
@ -96,7 +96,7 @@ void shapeReset(SwShape& sdata);
|
||||||
bool shapeGenOutline(const Shape& shape, SwShape& sdata);
|
bool shapeGenOutline(const Shape& shape, SwShape& sdata);
|
||||||
void shapeDelOutline(SwShape& sdata);
|
void shapeDelOutline(SwShape& sdata);
|
||||||
bool shapeGenRle(const Shape& shape, SwShape& sdata, const SwSize& clip);
|
bool shapeGenRle(const Shape& shape, SwShape& sdata, const SwSize& clip);
|
||||||
void shapeTransformOutline(const Shape& shape, SwShape& sdata, const RenderTransform& transform);
|
void shapeTransformOutline(const Shape& shape, SwShape& sdata, const RenderMatrix& transform);
|
||||||
SwRleData* rleRender(const SwShape& sdata, const SwSize& clip);
|
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);
|
bool rasterShape(Surface& surface, SwShape& sdata, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
|
||||||
|
|
|
@ -81,7 +81,7 @@ bool SwRenderer::dispose(const Shape& shape, void *data)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* SwRenderer::prepare(const Shape& shape, void* data, const RenderTransform* transform, RenderUpdateFlag flags)
|
void* SwRenderer::prepare(const Shape& shape, void* data, const RenderMatrix* transform, RenderUpdateFlag flags)
|
||||||
{
|
{
|
||||||
//prepare shape data
|
//prepare shape data
|
||||||
SwShape* sdata = static_cast<SwShape*>(data);
|
SwShape* sdata = static_cast<SwShape*>(data);
|
||||||
|
|
|
@ -22,7 +22,7 @@ class SwRenderer : public RenderMethod
|
||||||
public:
|
public:
|
||||||
Surface surface;
|
Surface surface;
|
||||||
|
|
||||||
void* prepare(const Shape& shape, void* data, const RenderTransform* transform, RenderUpdateFlag flags) override;
|
void* prepare(const Shape& shape, void* data, const RenderMatrix* transform, RenderUpdateFlag flags) override;
|
||||||
bool dispose(const Shape& shape, void *data) override;
|
bool dispose(const Shape& shape, void *data) override;
|
||||||
bool render(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);
|
bool target(uint32_t* buffer, size_t stride, size_t w, size_t h);
|
||||||
|
|
|
@ -215,7 +215,7 @@ void _deleteRle(SwShape& sdata)
|
||||||
/* External Class Implementation */
|
/* External Class Implementation */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
void shapeTransformOutline(const Shape& shape, SwShape& sdata, const RenderTransform& transform)
|
void shapeTransformOutline(const Shape& shape, SwShape& sdata, const RenderMatrix& transform)
|
||||||
{
|
{
|
||||||
auto outline = sdata.outline;
|
auto outline = sdata.outline;
|
||||||
assert(outline);
|
assert(outline);
|
||||||
|
|
|
@ -71,9 +71,9 @@ struct Canvas::Impl
|
||||||
|
|
||||||
for(auto paint: paints) {
|
for(auto paint: paints) {
|
||||||
if (auto scene = dynamic_cast<Scene*>(paint)) {
|
if (auto scene = dynamic_cast<Scene*>(paint)) {
|
||||||
if (!SCENE_IMPL->update(*renderer)) return -1;
|
if (!SCENE_IMPL->update(*renderer, nullptr)) return -1;
|
||||||
} else if (auto shape = dynamic_cast<Shape*>(paint)) {
|
} else if (auto shape = dynamic_cast<Shape*>(paint)) {
|
||||||
if (!SHAPE_IMPL->update(*shape, *renderer)) return -1;
|
if (!SHAPE_IMPL->update(*shape, *renderer, nullptr)) return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -30,13 +30,85 @@ struct Surface
|
||||||
|
|
||||||
enum RenderUpdateFlag {None = 0, Path = 1, Fill = 2, Transform = 4, All = 8};
|
enum RenderUpdateFlag {None = 0, Path = 1, Fill = 2, Transform = 4, All = 8};
|
||||||
|
|
||||||
struct RenderTransform
|
struct RenderMatrix
|
||||||
{
|
{
|
||||||
//3x3 Matrix Elements
|
//3x3 Matrix Elements
|
||||||
float e11, e12, e13;
|
float e11, e12, e13;
|
||||||
float e21, e22, e23;
|
float e21, e22, e23;
|
||||||
float e31, e32, e33;
|
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 x = 0.0f;
|
||||||
float y = 0.0f;
|
float y = 0.0f;
|
||||||
float degree = 0.0f; //rotation degree
|
float degree = 0.0f; //rotation degree
|
||||||
|
@ -44,74 +116,19 @@ struct RenderTransform
|
||||||
|
|
||||||
bool update()
|
bool update()
|
||||||
{
|
{
|
||||||
constexpr auto PI = 3.141592f;
|
|
||||||
|
|
||||||
//Init Status
|
//Init Status
|
||||||
if (fabsf(x) <= FLT_EPSILON && fabsf(y) <= FLT_EPSILON &&
|
if (fabsf(x) <= FLT_EPSILON && fabsf(y) <= FLT_EPSILON &&
|
||||||
fabsf(degree) <= FLT_EPSILON && fabsf(factor - 1) <= FLT_EPSILON) {
|
fabsf(degree) <= FLT_EPSILON && fabsf(factor - 1) <= FLT_EPSILON) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//identity
|
RenderMatrix::identity(&m);
|
||||||
e11 = 1.0f;
|
RenderMatrix::scale(&m, factor);
|
||||||
e12 = 0.0f;
|
RenderMatrix::rotate(&m, degree);
|
||||||
e13 = 0.0f;
|
RenderMatrix::translate(&m, x, y);
|
||||||
e21 = 0.0f;
|
|
||||||
e22 = 1.0f;
|
|
||||||
e23 = 0.0f;
|
|
||||||
e31 = 0.0f;
|
|
||||||
e32 = 0.0f;
|
|
||||||
e33 = 1.0f;
|
|
||||||
|
|
||||||
//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;
|
|
||||||
}
|
|
||||||
|
|
||||||
//scale
|
|
||||||
e11 *= factor;
|
|
||||||
e22 *= factor;
|
|
||||||
e33 *= factor;
|
|
||||||
|
|
||||||
//translate
|
|
||||||
e31 += x;
|
|
||||||
e32 += y;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderTransform& operator*=(const RenderTransform rhs)
|
|
||||||
{
|
|
||||||
e11 = e11 * rhs.e11 + e12 * rhs.e21 + e13 * rhs.e31;
|
|
||||||
e12 = e11 * rhs.e12 + e12 * rhs.e22 + e13 * rhs.e32;
|
|
||||||
e13 = e11 * rhs.e13 + e12 * rhs.e23 + e13 * rhs.e33;
|
|
||||||
|
|
||||||
e21 = e21 * rhs.e11 + e22 * rhs.e21 + e23 * rhs.e31;
|
|
||||||
e22 = e21 * rhs.e12 + e22 * rhs.e22 + e23 * rhs.e32;
|
|
||||||
e23 = e21 * rhs.e13 + e22 * rhs.e23 + e23 * rhs.e33;
|
|
||||||
|
|
||||||
e31 = e31 * rhs.e11 + e32 * rhs.e21 + e33 * rhs.e31;
|
|
||||||
e32 = e31 * rhs.e12 + e32 * rhs.e22 + e33 * rhs.e32;
|
|
||||||
e33 = e31 * rhs.e13 + e32 * rhs.e23 + e33 * rhs.e33;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -119,7 +136,7 @@ class RenderMethod
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~RenderMethod() {}
|
virtual ~RenderMethod() {}
|
||||||
virtual void* prepare(const Shape& shape, void* data, const RenderTransform* transform, RenderUpdateFlag flags) = 0;
|
virtual void* prepare(const Shape& shape, void* data, const RenderMatrix* transform, RenderUpdateFlag flags) = 0;
|
||||||
virtual bool dispose(const Shape& shape, void *data) = 0;
|
virtual bool dispose(const Shape& shape, void *data) = 0;
|
||||||
virtual bool render(const Shape& shape, void *data) = 0;
|
virtual bool render(const Shape& shape, void *data) = 0;
|
||||||
virtual bool clear() = 0;
|
virtual bool clear() = 0;
|
||||||
|
|
|
@ -64,21 +64,30 @@ int Scene::reserve(size_t size) noexcept
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Scene::scale(float scaleFacator) noexcept
|
int Scene::scale(float factor) noexcept
|
||||||
{
|
{
|
||||||
return 0;
|
auto impl = pImpl.get();
|
||||||
|
assert(impl);
|
||||||
|
|
||||||
|
return impl->scale(factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Scene::rotate(float degree) noexcept
|
int Scene::rotate(float degree) noexcept
|
||||||
{
|
{
|
||||||
return 0;
|
auto impl = pImpl.get();
|
||||||
|
assert(impl);
|
||||||
|
|
||||||
|
return impl->rotate(degree);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Scene::translate(float x, float y) noexcept
|
int Scene::translate(float x, float y) noexcept
|
||||||
{
|
{
|
||||||
return 0;
|
auto impl = pImpl.get();
|
||||||
|
assert(impl);
|
||||||
|
|
||||||
|
return impl->translate(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,11 +26,14 @@
|
||||||
struct Scene::Impl
|
struct Scene::Impl
|
||||||
{
|
{
|
||||||
vector<Paint*> paints;
|
vector<Paint*> paints;
|
||||||
|
RenderTransform *transform = nullptr;
|
||||||
|
size_t flag = RenderUpdateFlag::None;
|
||||||
|
|
||||||
~Impl()
|
~Impl()
|
||||||
{
|
{
|
||||||
//Are you sure clear() prior to this?
|
//Are you sure clear() prior to this?
|
||||||
assert(paints.empty());
|
assert(paints.empty());
|
||||||
|
if (transform) delete(transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool clear(RenderMethod& renderer)
|
bool clear(RenderMethod& renderer)
|
||||||
|
@ -48,18 +51,44 @@ struct Scene::Impl
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool update(RenderMethod &renderer)
|
bool updateInternal(RenderMethod &renderer, const RenderMatrix* transform, size_t flag)
|
||||||
{
|
{
|
||||||
for(auto paint: paints) {
|
for(auto paint: paints) {
|
||||||
if (auto scene = dynamic_cast<Scene*>(paint)) {
|
if (auto scene = dynamic_cast<Scene*>(paint)) {
|
||||||
if (!SCENE_IMPL->update(renderer)) return false;
|
if (!SCENE_IMPL->update(renderer, transform, flag)) return false;
|
||||||
} else if (auto shape = dynamic_cast<Shape*>(paint)) {
|
} else if (auto shape = dynamic_cast<Shape*>(paint)) {
|
||||||
if (!SHAPE_IMPL->update(*shape, renderer)) return false;
|
if (!SHAPE_IMPL->update(*shape, renderer, transform, flag)) return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool update(RenderMethod &renderer, const RenderMatrix* pTransform = nullptr, size_t pFlag = 0)
|
||||||
|
{
|
||||||
|
if (flag & RenderUpdateFlag::Transform) {
|
||||||
|
assert(transform);
|
||||||
|
if (!transform->update()) {
|
||||||
|
delete(transform);
|
||||||
|
transform = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ret = true;
|
||||||
|
|
||||||
|
if (transform && pTransform) {
|
||||||
|
RenderMatrix outTransform;
|
||||||
|
RenderMatrix::multiply(pTransform, &transform->m, &outTransform);
|
||||||
|
ret = updateInternal(renderer, &outTransform, pFlag | flag);
|
||||||
|
} else {
|
||||||
|
auto outTransform = pTransform ? pTransform : &transform->m;
|
||||||
|
ret = updateInternal(renderer, outTransform, pFlag | flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
flag = RenderUpdateFlag::None;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
bool render(RenderMethod &renderer)
|
bool render(RenderMethod &renderer)
|
||||||
{
|
{
|
||||||
for(auto paint: paints) {
|
for(auto paint: paints) {
|
||||||
|
@ -94,6 +123,52 @@ struct Scene::Impl
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool scale(float factor)
|
||||||
|
{
|
||||||
|
if (transform) {
|
||||||
|
if (fabsf(factor - transform->factor) <= FLT_EPSILON) return -1;
|
||||||
|
} else {
|
||||||
|
if (fabsf(factor) <= FLT_EPSILON) return -1;
|
||||||
|
transform = new RenderTransform();
|
||||||
|
assert(transform);
|
||||||
|
}
|
||||||
|
transform->factor = factor;
|
||||||
|
flag |= RenderUpdateFlag::Transform;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool rotate(float degree)
|
||||||
|
{
|
||||||
|
if (transform) {
|
||||||
|
if (fabsf(degree - transform->degree) <= FLT_EPSILON) return -1;
|
||||||
|
} else {
|
||||||
|
if (fabsf(degree) <= FLT_EPSILON) return -1;
|
||||||
|
transform = new RenderTransform();
|
||||||
|
assert(transform);
|
||||||
|
}
|
||||||
|
transform->degree = degree;
|
||||||
|
flag |= RenderUpdateFlag::Transform;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool translate(float x, float y)
|
||||||
|
{
|
||||||
|
if (transform) {
|
||||||
|
if (fabsf(x - transform->x) <= FLT_EPSILON && fabsf(y - transform->y) <= FLT_EPSILON) return -1;
|
||||||
|
} else {
|
||||||
|
if (fabsf(x) <= FLT_EPSILON && fabsf(y) <= FLT_EPSILON) return -1;
|
||||||
|
transform = new RenderTransform();
|
||||||
|
assert(transform);
|
||||||
|
}
|
||||||
|
transform->x = x;
|
||||||
|
transform->y = y;
|
||||||
|
flag |= RenderUpdateFlag::Transform;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //_TVG_SCENE_IMPL_H_
|
#endif //_TVG_SCENE_IMPL_H_
|
|
@ -66,7 +66,7 @@ struct Shape::Impl
|
||||||
return renderer.render(shape, edata);
|
return renderer.render(shape, edata);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool update(Shape& shape, RenderMethod& renderer)
|
bool update(Shape& shape, RenderMethod& renderer, const RenderMatrix* pTransform = nullptr, size_t pFlag = 0)
|
||||||
{
|
{
|
||||||
if (flag & RenderUpdateFlag::Transform) {
|
if (flag & RenderUpdateFlag::Transform) {
|
||||||
assert(transform);
|
assert(transform);
|
||||||
|
@ -75,7 +75,16 @@ struct Shape::Impl
|
||||||
transform = nullptr;
|
transform = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
edata = renderer.prepare(shape, edata, transform, static_cast<RenderUpdateFlag>(flag));
|
|
||||||
|
if (transform && pTransform) {
|
||||||
|
RenderMatrix outTransform;
|
||||||
|
RenderMatrix::multiply(pTransform, &transform->m, &outTransform);
|
||||||
|
edata = renderer.prepare(shape, edata, &outTransform, static_cast<RenderUpdateFlag>(pFlag | flag));
|
||||||
|
} else {
|
||||||
|
auto outTransform = pTransform ? pTransform : &transform->m;
|
||||||
|
edata = renderer.prepare(shape, edata, outTransform, static_cast<RenderUpdateFlag>(pFlag | flag));
|
||||||
|
}
|
||||||
|
|
||||||
flag = RenderUpdateFlag::None;
|
flag = RenderUpdateFlag::None;
|
||||||
|
|
||||||
if (edata) return true;
|
if (edata) return true;
|
||||||
|
|
|
@ -9,3 +9,4 @@ all:
|
||||||
gcc -o testDirectUpdate testDirectUpdate.cpp -g -lstdc++ `pkg-config --cflags --libs elementary tizenvg`
|
gcc -o testDirectUpdate testDirectUpdate.cpp -g -lstdc++ `pkg-config --cflags --libs elementary tizenvg`
|
||||||
gcc -o testScene testScene.cpp -g -lstdc++ `pkg-config --cflags --libs elementary tizenvg`
|
gcc -o testScene testScene.cpp -g -lstdc++ `pkg-config --cflags --libs elementary tizenvg`
|
||||||
gcc -o testTransform testTransform.cpp -g -lstdc++ `pkg-config --cflags --libs elementary tizenvg`
|
gcc -o testTransform testTransform.cpp -g -lstdc++ `pkg-config --cflags --libs elementary tizenvg`
|
||||||
|
gcc -o testSceneTransform testSceneTransform.cpp -g -lstdc++ `pkg-config --cflags --libs elementary tizenvg`
|
||||||
|
|
168
test/testSceneTransform.cpp
Normal file
168
test/testSceneTransform.cpp
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
#include <tizenvg.h>
|
||||||
|
#include <Elementary.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#define WIDTH 800
|
||||||
|
#define HEIGHT 800
|
||||||
|
|
||||||
|
static uint32_t buffer[WIDTH * HEIGHT];
|
||||||
|
unique_ptr<tvg::SwCanvas> canvas = nullptr;
|
||||||
|
tvg::Scene* pScene1 = nullptr;
|
||||||
|
tvg::Scene* pScene2 = nullptr;
|
||||||
|
|
||||||
|
void tvgtest()
|
||||||
|
{
|
||||||
|
//Initialize TizenVG Engine
|
||||||
|
tvg::Engine::init();
|
||||||
|
|
||||||
|
//Create a Canvas
|
||||||
|
canvas = tvg::SwCanvas::gen();
|
||||||
|
canvas->target(buffer, WIDTH, WIDTH, HEIGHT);
|
||||||
|
|
||||||
|
//Create a Scene
|
||||||
|
auto scene = tvg::Scene::gen();
|
||||||
|
pScene1 = scene.get();
|
||||||
|
scene->reserve(3); //reserve 3 shape nodes (optional)
|
||||||
|
|
||||||
|
//Prepare Round Rectangle
|
||||||
|
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
|
||||||
|
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
|
||||||
|
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);
|
||||||
|
|
||||||
|
//Create another Scene
|
||||||
|
auto scene2 = tvg::Scene::gen();
|
||||||
|
pScene2 = scene2.get();
|
||||||
|
scene2->reserve(2); //reserve 2 shape nodes (optional)
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
//Star
|
||||||
|
auto shape4 = tvg::Shape::gen();
|
||||||
|
|
||||||
|
//Appends Paths
|
||||||
|
shape4->moveTo(0, -114.5);
|
||||||
|
shape4->lineTo(54, -5.5);
|
||||||
|
shape4->lineTo(175, 11.5);
|
||||||
|
shape4->lineTo(88, 95.5);
|
||||||
|
shape4->lineTo(108, 216.5);
|
||||||
|
shape4->lineTo(0, 160.5);
|
||||||
|
shape4->lineTo(-102, 216.5);
|
||||||
|
shape4->lineTo(-87, 96.5);
|
||||||
|
shape4->lineTo(-173, 12.5);
|
||||||
|
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
|
||||||
|
auto shape5 = tvg::Shape::gen();
|
||||||
|
|
||||||
|
auto cx = -150.0f;
|
||||||
|
auto cy = -150.0f;
|
||||||
|
auto radius = 125.0f;
|
||||||
|
auto halfRadius = radius * 0.552284f;
|
||||||
|
|
||||||
|
//Append Paths
|
||||||
|
shape5->moveTo(cx, cy - radius);
|
||||||
|
shape5->cubicTo(cx + halfRadius, cy - radius, cx + radius, cy - halfRadius, cx + radius, cy);
|
||||||
|
shape5->cubicTo(cx + radius, cy + halfRadius, cx + halfRadius, cy + radius, cx, cy+ radius);
|
||||||
|
shape5->cubicTo(cx - halfRadius, cy + radius, cx - radius, cy + halfRadius, cx - radius, cy);
|
||||||
|
shape5->cubicTo(cx - radius, cy - halfRadius, cx - halfRadius, cy - radius, cx, cy - radius);
|
||||||
|
shape5->fill(127, 0, 0, 127);
|
||||||
|
scene2->push(move(shape5));
|
||||||
|
|
||||||
|
scene2->translate(300, 300);
|
||||||
|
|
||||||
|
//Push scene2 onto the scene
|
||||||
|
scene->push(move(scene2));
|
||||||
|
#endif
|
||||||
|
//Draw the Scene onto the Canvas
|
||||||
|
canvas->push(move(scene));
|
||||||
|
|
||||||
|
canvas->draw();
|
||||||
|
canvas->sync();
|
||||||
|
|
||||||
|
//Terminate TizenVG Engine
|
||||||
|
tvg::Engine::term();
|
||||||
|
}
|
||||||
|
|
||||||
|
void transit_cb(Elm_Transit_Effect *effect, Elm_Transit* transit, double progress)
|
||||||
|
{
|
||||||
|
/* Update scene directly.
|
||||||
|
You can update only necessary properties of this scene,
|
||||||
|
while retaining other properties. */
|
||||||
|
|
||||||
|
pScene1->rotate(360 * progress);
|
||||||
|
|
||||||
|
//Update shape for drawing (this may work asynchronously)
|
||||||
|
canvas->update(pScene1);
|
||||||
|
|
||||||
|
//Draw Next frames
|
||||||
|
canvas->draw();
|
||||||
|
canvas->sync();
|
||||||
|
|
||||||
|
//Update Efl Canvas
|
||||||
|
Eo* img = (Eo*) effect;
|
||||||
|
evas_object_image_data_update_add(img, 0, 0, WIDTH, HEIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
win_del(void *data, Evas_Object *o, void *ev)
|
||||||
|
{
|
||||||
|
elm_exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
//Initialize TizenVG Engine
|
||||||
|
tvg::Engine::init();
|
||||||
|
|
||||||
|
tvgtest();
|
||||||
|
|
||||||
|
//Show the result using EFL...
|
||||||
|
elm_init(argc, argv);
|
||||||
|
|
||||||
|
Eo* win = elm_win_util_standard_add(NULL, "TizenVG Test");
|
||||||
|
evas_object_smart_callback_add(win, "delete,request", win_del, 0);
|
||||||
|
|
||||||
|
Eo* img = evas_object_image_filled_add(evas_object_evas_get(win));
|
||||||
|
evas_object_image_size_set(img, WIDTH, HEIGHT);
|
||||||
|
evas_object_image_data_set(img, buffer);
|
||||||
|
evas_object_size_hint_weight_set(img, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||||
|
evas_object_show(img);
|
||||||
|
|
||||||
|
elm_win_resize_object_add(win, img);
|
||||||
|
evas_object_geometry_set(win, 0, 0, WIDTH, HEIGHT);
|
||||||
|
evas_object_show(win);
|
||||||
|
|
||||||
|
Elm_Transit *transit = elm_transit_add();
|
||||||
|
elm_transit_effect_add(transit, transit_cb, img, nullptr);
|
||||||
|
elm_transit_duration_set(transit, 2);
|
||||||
|
elm_transit_repeat_times_set(transit, -1);
|
||||||
|
elm_transit_go(transit);
|
||||||
|
|
||||||
|
elm_run();
|
||||||
|
elm_shutdown();
|
||||||
|
|
||||||
|
//Terminate TizenVG Engine
|
||||||
|
tvg::Engine::term();
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue