mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-09 06:04:03 +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
|
struct RenderTransform
|
||||||
{
|
{
|
||||||
|
//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;
|
||||||
|
|
||||||
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;
|
e11 = 1.0f;
|
||||||
e12 = 0.0f;
|
e12 = 0.0f;
|
||||||
e13 = 0.0f;
|
e13 = 0.0f;
|
||||||
|
@ -47,44 +62,38 @@ struct RenderTransform
|
||||||
e31 = 0.0f;
|
e31 = 0.0f;
|
||||||
e32 = 0.0f;
|
e32 = 0.0f;
|
||||||
e33 = 1.0f;
|
e33 = 1.0f;
|
||||||
}
|
|
||||||
|
|
||||||
void rotate(float degree)
|
//rotation
|
||||||
{
|
if (fabsf(degree) > FLT_EPSILON) {
|
||||||
constexpr auto PI = 3.141592f;
|
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;
|
e11 = t11;
|
||||||
auto cosVal = cosf(radian);
|
e12 = t12;
|
||||||
auto sinVal = sinf(radian);
|
e21 = t21;
|
||||||
|
e22 = t22;
|
||||||
|
e31 = t31;
|
||||||
|
e32 = t32;
|
||||||
|
}
|
||||||
|
|
||||||
auto t11 = e11 * cosVal + e12 * sinVal;
|
//scale
|
||||||
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)
|
|
||||||
{
|
|
||||||
e11 *= factor;
|
e11 *= factor;
|
||||||
e22 *= factor;
|
e22 *= factor;
|
||||||
e33 *= factor;
|
e33 *= factor;
|
||||||
|
|
||||||
|
//translate
|
||||||
|
e31 += x;
|
||||||
|
e32 += y;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderTransform& operator*=(const RenderTransform rhs)
|
RenderTransform& operator*=(const RenderTransform rhs)
|
||||||
|
|
|
@ -247,12 +247,7 @@ int Shape::scale(float factor) noexcept
|
||||||
auto impl = pImpl.get();
|
auto impl = pImpl.get();
|
||||||
assert(impl);
|
assert(impl);
|
||||||
|
|
||||||
if (fabsf(factor - impl->scale) <= FLT_EPSILON) return -1;
|
return impl->scale(factor);
|
||||||
|
|
||||||
impl->scale = factor;
|
|
||||||
impl->flag |= RenderUpdateFlag::Transform;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -261,12 +256,7 @@ int Shape::rotate(float degree) noexcept
|
||||||
auto impl = pImpl.get();
|
auto impl = pImpl.get();
|
||||||
assert(impl);
|
assert(impl);
|
||||||
|
|
||||||
if (fabsf(degree - impl->rotate) <= FLT_EPSILON) return -1;
|
return impl->rotate(degree);
|
||||||
|
|
||||||
impl->rotate = degree;
|
|
||||||
impl->flag |= RenderUpdateFlag::Transform;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -275,13 +265,7 @@ int Shape::translate(float x, float y) noexcept
|
||||||
auto impl = pImpl.get();
|
auto impl = pImpl.get();
|
||||||
assert(impl);
|
assert(impl);
|
||||||
|
|
||||||
if (fabsf(x - impl->x) <= FLT_EPSILON && fabsf(y - impl->y) <= FLT_EPSILON) return -1;
|
return impl->translate(x, y);
|
||||||
|
|
||||||
impl->x = x;
|
|
||||||
impl->y = y;
|
|
||||||
impl->flag |= RenderUpdateFlag::Transform;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,13 +38,11 @@ struct Shape::Impl
|
||||||
ShapeFill *fill = nullptr;
|
ShapeFill *fill = nullptr;
|
||||||
ShapeStroke *stroke = nullptr;
|
ShapeStroke *stroke = nullptr;
|
||||||
ShapePath *path = nullptr;
|
ShapePath *path = nullptr;
|
||||||
|
RenderTransform *transform = nullptr;
|
||||||
uint8_t color[4] = {0, 0, 0, 0}; //r, g, b, a
|
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;
|
size_t flag = RenderUpdateFlag::None;
|
||||||
|
void *edata = nullptr; //engine data
|
||||||
|
|
||||||
|
|
||||||
Impl() : path(new ShapePath)
|
Impl() : path(new ShapePath)
|
||||||
{
|
{
|
||||||
|
@ -55,6 +53,7 @@ struct Shape::Impl
|
||||||
if (path) delete(path);
|
if (path) delete(path);
|
||||||
if (stroke) delete(stroke);
|
if (stroke) delete(stroke);
|
||||||
if (fill) delete(fill);
|
if (fill) delete(fill);
|
||||||
|
if (transform) delete(transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dispose(Shape& shape, RenderMethod& renderer)
|
bool dispose(Shape& shape, RenderMethod& renderer)
|
||||||
|
@ -70,16 +69,13 @@ struct Shape::Impl
|
||||||
bool update(Shape& shape, RenderMethod& renderer)
|
bool update(Shape& shape, RenderMethod& renderer)
|
||||||
{
|
{
|
||||||
if (flag & RenderUpdateFlag::Transform) {
|
if (flag & RenderUpdateFlag::Transform) {
|
||||||
RenderTransform transform;
|
assert(transform);
|
||||||
transform.identity();
|
if (!transform->update()) {
|
||||||
transform.rotate(rotate);
|
delete(transform);
|
||||||
transform.scale(scale);
|
transform = nullptr;
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
edata = renderer.prepare(shape, edata, transform, static_cast<RenderUpdateFlag>(flag));
|
||||||
flag = RenderUpdateFlag::None;
|
flag = RenderUpdateFlag::None;
|
||||||
|
|
||||||
if (edata) return true;
|
if (edata) return true;
|
||||||
|
@ -91,6 +87,52 @@ struct Shape::Impl
|
||||||
assert(path);
|
assert(path);
|
||||||
return path->bounds(x, y, w, h);
|
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_
|
#endif //_TVG_SHAPE_IMPL_H_
|
Loading…
Add table
Reference in a new issue