mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 13:43:43 +00:00
common shape: revise RenderTransform for Scene Transformation
This RenderTransform takes over all transform information. Change-Id: I21b6a55de05feca56c40f3ff402d18445417463c
This commit is contained in:
parent
40ef2f1575
commit
2f2efb73dd
3 changed files with 100 additions and 65 deletions
|
@ -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,44 +62,38 @@ struct RenderTransform
|
|||
e31 = 0.0f;
|
||||
e32 = 0.0f;
|
||||
e33 = 1.0f;
|
||||
}
|
||||
|
||||
void rotate(float degree)
|
||||
{
|
||||
constexpr auto PI = 3.141592f;
|
||||
//rotation
|
||||
if (fabsf(degree) > FLT_EPSILON) {
|
||||
auto radian = degree / 180.0f * PI;
|
||||
auto cosVal = cosf(radian);
|
||||
auto sinVal = sinf(radian);
|
||||
|
||||
if (fabsf(degree) <= FLT_EPSILON) return;
|
||||
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;
|
||||
|
||||
auto radian = degree / 180.0f * PI;
|
||||
auto cosVal = cosf(radian);
|
||||
auto sinVal = sinf(radian);
|
||||
e11 = t11;
|
||||
e12 = t12;
|
||||
e21 = t21;
|
||||
e22 = t22;
|
||||
e31 = t31;
|
||||
e32 = t32;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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_
|
Loading…
Add table
Reference in a new issue