common transformation: fix transformation multiply

Change-Id: Ibc95fab0abfc07aa7f0c4ff6c74785d4f73d02c7
This commit is contained in:
Hermet Park 2020-07-16 20:42:42 +09:00
parent a5d1542e44
commit 2ba529c8fb
6 changed files with 56 additions and 66 deletions

View file

@ -100,12 +100,12 @@ bool _prepareLinear(SwFill* fill, const LinearGradient* linear, const Matrix* tr
auto cy = (y2 - y1) * 0.5f + y1;
auto dx = x1 - cx;
auto dy = y1 - cy;
x1 = dx * transform->e11 + dy * transform->e12 + transform->e31 + cx;
y1 = dx * transform->e21 + dy * transform->e22 + transform->e32 + cy;
x1 = dx * transform->e11 + dy * transform->e12 + transform->e13 + cx;
y1 = dx * transform->e21 + dy * transform->e22 + transform->e23 + cy;
dx = x2 - cx;
dy = y2 - cy;
x2 = dx * transform->e11 + dy * transform->e12 + transform->e31 + cx;
y2 = dx * transform->e21 + dy * transform->e22 + transform->e32 + cy;
x2 = dx * transform->e11 + dy * transform->e12 + transform->e13 + cx;
y2 = dx * transform->e21 + dy * transform->e22 + transform->e23 + cy;
}
fill->linear.dx = x2 - x1;
@ -131,8 +131,8 @@ bool _prepareRadial(SwFill* fill, const RadialGradient* radial, const Matrix* tr
if (radius < FLT_EPSILON) return true;
if (transform) {
auto tx = fill->radial.cx * transform->e11 + fill->radial.cy * transform->e12 + transform->e31;
auto ty = fill->radial.cx * transform->e21 + fill->radial.cy * transform->e22 + transform->e32;
auto tx = fill->radial.cx * transform->e11 + fill->radial.cy * transform->e12 + transform->e13;
auto ty = fill->radial.cx * transform->e21 + fill->radial.cy * transform->e22 + transform->e23;
fill->radial.cx = tx;
fill->radial.cy = ty;
radius *= transform->e33;

View file

@ -239,8 +239,8 @@ static void _transformOutline(SwOutline* outline, const Matrix* transform)
for(uint32_t i = 0; i < outline->ptsCnt; ++i) {
auto dx = static_cast<float>(outline->pts[i].x >> 6);
auto dy = static_cast<float>(outline->pts[i].y >> 6);
auto tx = dx * transform->e11 + dy * transform->e12 + transform->e31;
auto ty = dx * transform->e21 + dy * transform->e22 + transform->e32;
auto tx = dx * transform->e11 + dy * transform->e12 + transform->e13;
auto ty = dx * transform->e21 + dy * transform->e22 + transform->e23;
auto pt = Point{round(tx), round(ty)};
outline->pts[i] = TO_SWPOINT(&pt);
}

View file

@ -66,7 +66,6 @@ bool RenderTransform::update()
//scale
m.e11 *= factor;
m.e22 *= factor;
m.e33 *= factor;
//rotation
if (fabsf(degree) > FLT_EPSILON) {
@ -78,19 +77,19 @@ bool RenderTransform::update()
auto t12 = m.e11 * -sinVal + m.e12 * cosVal;
auto t21 = m.e21 * cosVal + m.e22 * sinVal;
auto t22 = m.e21 * -sinVal + m.e22 * cosVal;
auto t31 = m.e31 * cosVal + m.e32 * sinVal;
auto t32 = m.e31 * -sinVal + m.e32 * cosVal;
auto t13 = m.e13 * cosVal + m.e23 * sinVal;
auto t23 = m.e13 * -sinVal + m.e23 * cosVal;
m.e11 = t11;
m.e12 = t12;
m.e21 = t21;
m.e22 = t22;
m.e31 = t31;
m.e32 = t32;
m.e13 = t13;
m.e23 = t23;
}
m.e31 += x;
m.e32 += y;
m.e13 += x;
m.e23 += y;
return true;
}
@ -105,17 +104,17 @@ RenderTransform::RenderTransform(const RenderTransform* lhs, const RenderTransfo
{
assert(lhs && rhs);
auto dx = rhs->x * lhs->factor;
auto dy = rhs->y * lhs->factor;
auto tx = dx * lhs->m.e11 + dy * lhs->m.e12 + lhs->m.e13;
auto ty = dx * lhs->m.e21 + dy * lhs->m.e22 + lhs->m.e23;
m.e11 = lhs->m.e11 * rhs->m.e11 + lhs->m.e12 * rhs->m.e21 + lhs->m.e13 * rhs->m.e31;
m.e12 = lhs->m.e11 * rhs->m.e12 + lhs->m.e12 * rhs->m.e22 + lhs->m.e13 * rhs->m.e32;
m.e13 = lhs->m.e11 * rhs->m.e13 + lhs->m.e12 * rhs->m.e23 + lhs->m.e13 * rhs->m.e33;
x = lhs->x + tx;
y = lhs->y + ty;
degree = lhs->degree + rhs->degree;
factor = lhs->factor * rhs->factor;
m.e21 = lhs->m.e21 * rhs->m.e11 + lhs->m.e22 * rhs->m.e21 + lhs->m.e23 * rhs->m.e31;
m.e22 = lhs->m.e21 * rhs->m.e12 + lhs->m.e22 * rhs->m.e22 + lhs->m.e23 * rhs->m.e32;
m.e23 = lhs->m.e21 * rhs->m.e13 + lhs->m.e22 * rhs->m.e23 + lhs->m.e23 * rhs->m.e33;
update();
m.e31 = lhs->m.e31 * rhs->m.e11 + lhs->m.e32 * rhs->m.e21 + lhs->m.e33 * rhs->m.e31;
m.e32 = lhs->m.e31 * rhs->m.e12 + lhs->m.e32 * rhs->m.e22 + lhs->m.e33 * rhs->m.e32;
m.e33 = lhs->m.e31 * rhs->m.e13 + lhs->m.e32 * rhs->m.e23 + lhs->m.e33 * rhs->m.e33;
}
#endif //_TVG_RENDER_CPP_

View file

@ -20,26 +20,6 @@
#include "tvgSvgSceneBuilder.h"
static void _getTransformationData(Matrix* m, float* tx, float* ty, float* s, float* z)
{
float rz, si, cs, zcs, zsi;
*tx = m->e13;
*ty = m->e23;
cs = m->e11;
si = m->e21;
rz = atan2(si, cs);
*z = rz * (180.0f / M_PI);
zcs = cosf(-1.0f * rz);
zsi = sinf(-1.0f * rz);
m->e11 = m->e11 * zcs + m->e12 * zsi;
m->e22 = m->e21 * (-1 * zsi) + m->e22 * zcs;
*s = m->e11 > m->e22 ? m->e11 : m->e22;
}
unique_ptr<LinearGradient> _applyLinearGradientProperty(SvgStyleGradient* g, Shape* vg, float rx, float ry, float rw, float rh)
{
Fill::ColorStop* stops;
@ -225,15 +205,7 @@ void _applyProperty(SvgNode* node, Shape* vg, float vx, float vy, float vw, floa
{
SvgStyleProperty* style = node->style;
//Apply the transformation
if (node->transform) {
float tx = 0, ty = 0, s = 0, z = 0;
_getTransformationData(node->transform, &tx, &ty, &s, &z);
vg->scale(s);
vg->rotate(z);
vg->translate(tx, ty);
}
if (node->transform) vg->transform(*node->transform);
if (node->type == SvgNodeType::Doc) return;
//If fill property is nullptr then do nothing
@ -359,13 +331,7 @@ unique_ptr<Scene> _sceneBuildHelper(SvgNode* node, float vx, float vy, float vw,
{
if (node->type == SvgNodeType::Doc || node->type == SvgNodeType::G) {
auto scene = Scene::gen();
if (node->transform) {
float tx = 0, ty = 0, s = 0, z = 0;
_getTransformationData(node->transform, &tx, &ty, &s, &z);
scene->scale(s);
scene->rotate(z);
scene->translate(tx, ty);
}
if (node->transform) scene->transform(*node->transform);
node->style->opacity = (node->style->opacity * parentOpacity) / 255.0f;
for (auto child : node->child) {
child->style->opacity = (child->style->opacity * node->style->opacity) / 255.0f;

25
test/svgs/duke.svg Normal file
View file

@ -0,0 +1,25 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 75 136">
<path d="M1190 2982 c-38-31-31-179 17-347 14-49-50 34-89 115-59 126
-75 138-139 104-89-45-31-286 106-438 37-41 37-56 2-56-64-1-147
-63-147-111 0-68 36-95 107-78 72 17 110 12 162-18 59-36 99-53 121
-53 70 0 98-274 36-339-77-80-124-64-211 69-235 363-871 1021-794
823 6-16 15-109 21-208 8-154 7-237-7-510-1-22-5-71-9-110-3
-38-8-99-11-135-16-193-59-311-172-463-89-120-103-199-62-333
46-147 32-217-65-342-86-110-34-240 74-182 15 8 16-2 16-118-1
-208 99-262 252-137 459 378 583 383 820 37 106-155 165-182 267-123 179
103 150 755-55 1272-72 180-71 272 6 419 l38 71-1 147 c0 177 4 192 76
262 82 80 99 158 65 300-25 105-22 166 16 269 47 130 23 186-68 161-65
-17-142-154-142-253 0-42-37 30-49 96-23 120-43 186-61 202-30 27
-91 31-120 7z m-342-1094 c74-22 122-90 122-170 0-77-7-87-54-86-83
2-183-78-173-139 14-82-172-40-237 54-127 183 105 413 342 341z m315
-214 c237-426 341-786 342-1179 0-460-61-531-239-277-251 358-453
367-824 35-124-110-190-136-208-80-7 22-7 235 0 272 2 11 7 45 10 75
4 30 8 66 11 80 2 14 9 52 14 85 109 661 160 849 214 789 199-228 612 2 545
303-6 28-4 32 15 36 38 7 40 4 120-139z m-900-522 c3-4-5-61-18-127
-13-66-25-131-27-145-6-36-39 38-46 101-7 76 66 213 91 171z"
transform="translate(0,136) scale(0.045181,-0.045181)"/>
<ellipse rx="12" ry="10" transform="rotate(-24) translate(5.4,68.3)"
fill="#F00" opacity="0.7"/>
<ellipse rx="3.5" ry="2" transform="rotate(-33) translate(-9,61)" fill="#FFF"
opacity="0.7"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -61,19 +61,19 @@ void tvgUpdateCmds(tvg::Canvas* canvas, float progress)
auto t12 = m.e11 * -sinVal + m.e12 * cosVal;
auto t21 = m.e21 * cosVal + m.e22 * sinVal;
auto t22 = m.e21 * -sinVal + m.e22 * cosVal;
auto t31 = m.e31 * cosVal + m.e32 * sinVal;
auto t32 = m.e31 * -sinVal + m.e32 * cosVal;
auto t13 = m.e31 * cosVal + m.e32 * sinVal;
auto t23 = m.e31 * -sinVal + m.e32 * cosVal;
m.e11 = t11;
m.e12 = t12;
m.e21 = t21;
m.e22 = t22;
m.e31 = t31;
m.e32 = t32;
m.e13 = t13;
m.e23 = t23;
//translate
m.e31 = progress * 300.0f + 300.0f;
m.e32 = progress * -100.0f + 300.0f;
m.e13 = progress * 300.0f + 300.0f;
m.e23 = progress * -100.0f + 300.0f;
pShape->transform(m);