common shape: revise RenderTransform for Scene Transformation

This RenderTransform takes over all transform information.

Change-Id: I21b6a55de05feca56c40f3ff402d18445417463c
This commit is contained in:
Hermet Park 2020-05-17 14:54:55 +09:00
parent 40ef2f1575
commit 2f2efb73dd
3 changed files with 100 additions and 65 deletions

View file

@ -32,12 +32,27 @@ enum RenderUpdateFlag {None = 0, Path = 1, Fill = 2, Transform = 4, All = 8};
struct RenderTransform
{
//3x3 Matrix Elements
float e11, e12, e13;
float e21, e22, e23;
float e31, e32, e33;
void identity()
float x = 0.0f;
float y = 0.0f;
float degree = 0.0f; //rotation degree
float factor = 1.0f; //scale factor
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;
}
//identity
e11 = 1.0f;
e12 = 0.0f;
e13 = 0.0f;
@ -47,14 +62,9 @@ struct RenderTransform
e31 = 0.0f;
e32 = 0.0f;
e33 = 1.0f;
}
void rotate(float degree)
{
constexpr auto PI = 3.141592f;
if (fabsf(degree) <= FLT_EPSILON) return;
//rotation
if (fabsf(degree) > FLT_EPSILON) {
auto radian = degree / 180.0f * PI;
auto cosVal = cosf(radian);
auto sinVal = sinf(radian);
@ -74,17 +84,16 @@ struct RenderTransform
e32 = t32;
}
void translate(float x, float y)
{
e31 += x;
e32 += y;
}
void scale(float factor)
{
//scale
e11 *= factor;
e22 *= factor;
e33 *= factor;
//translate
e31 += x;
e32 += y;
return true;
}
RenderTransform& operator*=(const RenderTransform rhs)

View file

@ -247,12 +247,7 @@ int Shape::scale(float factor) noexcept
auto impl = pImpl.get();
assert(impl);
if (fabsf(factor - impl->scale) <= FLT_EPSILON) return -1;
impl->scale = factor;
impl->flag |= RenderUpdateFlag::Transform;
return 0;
return impl->scale(factor);
}
@ -261,12 +256,7 @@ int Shape::rotate(float degree) noexcept
auto impl = pImpl.get();
assert(impl);
if (fabsf(degree - impl->rotate) <= FLT_EPSILON) return -1;
impl->rotate = degree;
impl->flag |= RenderUpdateFlag::Transform;
return 0;
return impl->rotate(degree);
}
@ -275,13 +265,7 @@ int Shape::translate(float x, float y) noexcept
auto impl = pImpl.get();
assert(impl);
if (fabsf(x - impl->x) <= FLT_EPSILON && fabsf(y - impl->y) <= FLT_EPSILON) return -1;
impl->x = x;
impl->y = y;
impl->flag |= RenderUpdateFlag::Transform;
return 0;
return impl->translate(x, y);
}

View file

@ -38,13 +38,11 @@ struct Shape::Impl
ShapeFill *fill = nullptr;
ShapeStroke *stroke = nullptr;
ShapePath *path = nullptr;
RenderTransform *transform = nullptr;
uint8_t color[4] = {0, 0, 0, 0}; //r, g, b, a
float scale = 1;
float rotate = 0;
float x = 0;
float y = 0;
void *edata = nullptr; //engine data
size_t flag = RenderUpdateFlag::None;
void *edata = nullptr; //engine data
Impl() : path(new ShapePath)
{
@ -55,6 +53,7 @@ struct Shape::Impl
if (path) delete(path);
if (stroke) delete(stroke);
if (fill) delete(fill);
if (transform) delete(transform);
}
bool dispose(Shape& shape, RenderMethod& renderer)
@ -70,16 +69,13 @@ struct Shape::Impl
bool update(Shape& shape, RenderMethod& renderer)
{
if (flag & RenderUpdateFlag::Transform) {
RenderTransform transform;
transform.identity();
transform.rotate(rotate);
transform.scale(scale);
transform.translate(x, y);
edata = renderer.prepare(shape, edata, &transform, static_cast<RenderUpdateFlag>(flag));
} else {
edata = renderer.prepare(shape, edata, nullptr, static_cast<RenderUpdateFlag>(flag));
assert(transform);
if (!transform->update()) {
delete(transform);
transform = nullptr;
}
}
edata = renderer.prepare(shape, edata, transform, static_cast<RenderUpdateFlag>(flag));
flag = RenderUpdateFlag::None;
if (edata) return true;
@ -91,6 +87,52 @@ struct Shape::Impl
assert(path);
return path->bounds(x, y, w, h);
}
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_SHAPE_IMPL_H_