diff --git a/inc/thorvg.h b/inc/thorvg.h index 9bce0e57..6e29630d 100644 --- a/inc/thorvg.h +++ b/inc/thorvg.h @@ -546,7 +546,7 @@ public: * * @return The augmented transformation matrix. */ - Matrix transform() const noexcept; + Matrix& transform() const noexcept; /** * @brief Creates a copy of the Fill object. diff --git a/src/loaders/svg/tvgSvgSceneBuilder.cpp b/src/loaders/svg/tvgSvgSceneBuilder.cpp index e670d3cf..1c282161 100644 --- a/src/loaders/svg/tvgSvgSceneBuilder.cpp +++ b/src/loaders/svg/tvgSvgSceneBuilder.cpp @@ -92,9 +92,8 @@ static unique_ptr _applyLinearGradientProperty(SvgStyleGradient* Fill::ColorStop* stops; int stopCount = 0; auto fillGrad = LinearGradient::gen(); - - bool isTransform = (g->transform ? true : false); - Matrix finalTransform = {1, 0, 0, 0, 1, 0, 0, 0, 1}; + auto isTransform = (g->transform ? true : false); + auto& finalTransform = fillGrad->transform(); if (isTransform) finalTransform = *g->transform; if (g->userSpace) { @@ -105,14 +104,9 @@ static unique_ptr _applyLinearGradientProperty(SvgStyleGradient* } else { Matrix m = {vBox.w, 0, vBox.x, 0, vBox.h, vBox.y, 0, 0, 1}; if (isTransform) _transformMultiply(&m, &finalTransform); - else { - finalTransform = m; - isTransform = true; - } + else finalTransform = m; } - if (isTransform) fillGrad->transform(finalTransform); - fillGrad->linear(g->linear->x1, g->linear->y1, g->linear->x2, g->linear->y2); fillGrad->spread(g->spread); @@ -147,9 +141,8 @@ static unique_ptr _applyRadialGradientProperty(SvgStyleGradient* Fill::ColorStop *stops; int stopCount = 0; auto fillGrad = RadialGradient::gen(); - - bool isTransform = (g->transform ? true : false); - Matrix finalTransform = {1, 0, 0, 0, 1, 0, 0, 0, 1}; + auto isTransform = (g->transform ? true : false); + auto& finalTransform = fillGrad->transform(); if (isTransform) finalTransform = *g->transform; if (g->userSpace) { @@ -164,14 +157,9 @@ static unique_ptr _applyRadialGradientProperty(SvgStyleGradient* } else { Matrix m = {vBox.w, 0, vBox.x, 0, vBox.h, vBox.y, 0, 0, 1}; if (isTransform) _transformMultiply(&m, &finalTransform); - else { - finalTransform = m; - isTransform = true; - } + else finalTransform = m; } - if (isTransform) fillGrad->transform(finalTransform); - P(fillGrad)->radial(g->radial->cx, g->radial->cy, g->radial->r, g->radial->fx, g->radial->fy, g->radial->fr); fillGrad->spread(g->spread); diff --git a/src/renderer/gl_engine/tvgGlRenderer.cpp b/src/renderer/gl_engine/tvgGlRenderer.cpp index de8b07a6..12699e9b 100644 --- a/src/renderer/gl_engine/tvgGlRenderer.cpp +++ b/src/renderer/gl_engine/tvgGlRenderer.cpp @@ -288,27 +288,15 @@ void GlRenderer::drawPrimitive(GlShape& sdata, const Fill* fill, RenderUpdateFla { const auto& matrix = sdata.geometry->getTransformMatrix(); - auto gradientTransform = fill->transform(); float invMat4[16]; - if (!identity(const_cast(&gradientTransform))) { - Matrix inv{}; - inverse(&gradientTransform , &inv); - - GET_MATRIX44(inv, invMat4); - } else { - memset(invMat4, 0, 16 * sizeof(float)); - invMat4[0] = 1.f; - invMat4[5] = 1.f; - invMat4[10] = 1.f; - invMat4[15] = 1.f; - } + Matrix inv; + inverse(&fill->transform(), &inv); + GET_MATRIX44(inv, invMat4); float matrix44[16]; - currentPass()->getMatrix(matrix44, matrix); uint32_t loc = task->getProgram()->getUniformBlockIndex("Matrix"); - uint32_t viewOffset = mGpuBuffer->push(matrix44, 16 * sizeof(float), true); task->addBindResource(GlBindingResource{ diff --git a/src/renderer/sw_engine/tvgSwFill.cpp b/src/renderer/sw_engine/tvgSwFill.cpp index 8b77b797..d02986f9 100644 --- a/src/renderer/sw_engine/tvgSwFill.cpp +++ b/src/renderer/sw_engine/tvgSwFill.cpp @@ -207,7 +207,7 @@ static bool _updateColorTable(SwFill* fill, const Fill* fdata, const SwSurface* } -bool _prepareLinear(SwFill* fill, const LinearGradient* linear, const Matrix& transform) +bool _prepareLinear(SwFill* fill, const LinearGradient* linear, const Matrix& pTransform) { float x1, x2, y1, y2; if (linear->linear(&x1, &y1, &x2, &y2) != Result::Success) return false; @@ -227,32 +227,22 @@ bool _prepareLinear(SwFill* fill, const LinearGradient* linear, const Matrix& tr fill->linear.dy /= len; fill->linear.offset = -fill->linear.dx * x1 - fill->linear.dy * y1; - auto gradTransform = linear->transform(); - bool isTransformation = !identity((const Matrix*)(&gradTransform)); + auto transform = pTransform * linear->transform(); - if (isTransformation) { - gradTransform = transform * gradTransform; - } else { - gradTransform = transform; - isTransformation = true; - } + Matrix itransform; + if (!inverse(&transform, &itransform)) return false; - if (isTransformation) { - Matrix invTransform; - if (!inverse(&gradTransform, &invTransform)) return false; + fill->linear.offset += fill->linear.dx * itransform.e13 + fill->linear.dy * itransform.e23; - fill->linear.offset += fill->linear.dx * invTransform.e13 + fill->linear.dy * invTransform.e23; - - auto dx = fill->linear.dx; - fill->linear.dx = dx * invTransform.e11 + fill->linear.dy * invTransform.e21; - fill->linear.dy = dx * invTransform.e12 + fill->linear.dy * invTransform.e22; - } + auto dx = fill->linear.dx; + fill->linear.dx = dx * itransform.e11 + fill->linear.dy * itransform.e21; + fill->linear.dy = dx * itransform.e12 + fill->linear.dy * itransform.e22; return true; } -bool _prepareRadial(SwFill* fill, const RadialGradient* radial, const Matrix& transform) +bool _prepareRadial(SwFill* fill, const RadialGradient* radial, const Matrix& pTransform) { auto cx = P(radial)->cx; auto cy = P(radial)->cy; @@ -294,29 +284,18 @@ bool _prepareRadial(SwFill* fill, const RadialGradient* radial, const Matrix& tr if (fill->radial.a > 0) fill->radial.invA = 1.0f / fill->radial.a; - auto gradTransform = radial->transform(); - bool isTransformation = !identity((const Matrix*)(&gradTransform)); + auto transform = pTransform * radial->transform(); - if (isTransformation) gradTransform = transform * gradTransform; - else { - gradTransform = transform; - isTransformation = true; - } + Matrix itransform; + if (!inverse(&transform, &itransform)) return false; + + fill->radial.a11 = itransform.e11; + fill->radial.a12 = itransform.e12; + fill->radial.a13 = itransform.e13; + fill->radial.a21 = itransform.e21; + fill->radial.a22 = itransform.e22; + fill->radial.a23 = itransform.e23; - if (isTransformation) { - Matrix invTransform; - if (!inverse(&gradTransform, &invTransform)) return false; - fill->radial.a11 = invTransform.e11; - fill->radial.a12 = invTransform.e12; - fill->radial.a13 = invTransform.e13; - fill->radial.a21 = invTransform.e21; - fill->radial.a22 = invTransform.e22; - fill->radial.a23 = invTransform.e23; - } else { - fill->radial.a11 = fill->radial.a22 = 1.0f; - fill->radial.a12 = fill->radial.a13 = 0.0f; - fill->radial.a21 = fill->radial.a23 = 0.0f; - } return true; } diff --git a/src/renderer/tvgFill.cpp b/src/renderer/tvgFill.cpp index 98b9a737..fb7b3579 100644 --- a/src/renderer/tvgFill.cpp +++ b/src/renderer/tvgFill.cpp @@ -134,18 +134,14 @@ FillSpread Fill::spread() const noexcept Result Fill::transform(const Matrix& m) noexcept { - if (!pImpl->transform) { - pImpl->transform = static_cast(malloc(sizeof(Matrix))); - } - *pImpl->transform = m; + pImpl->transform = m; return Result::Success; } -Matrix Fill::transform() const noexcept +Matrix& Fill::transform() const noexcept { - if (pImpl->transform) return *pImpl->transform; - return {1, 0, 0, 0, 1, 0, 0, 0, 1}; + return pImpl->transform; } diff --git a/src/renderer/tvgFill.h b/src/renderer/tvgFill.h index f249356a..f7e4bb83 100644 --- a/src/renderer/tvgFill.h +++ b/src/renderer/tvgFill.h @@ -51,16 +51,15 @@ struct FillDup : DuplicateMethod struct Fill::Impl { ColorStop* colorStops = nullptr; - Matrix* transform = nullptr; + Matrix transform = {1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f}; uint32_t cnt = 0; - FillSpread spread; DuplicateMethod* dup = nullptr; + FillSpread spread; ~Impl() { delete(dup); free(colorStops); - free(transform); } void method(DuplicateMethod* dup) @@ -71,16 +70,13 @@ struct Fill::Impl Fill* duplicate() { auto ret = dup->duplicate(); - if (!ret) return nullptr; ret->pImpl->cnt = cnt; ret->pImpl->spread = spread; ret->pImpl->colorStops = static_cast(malloc(sizeof(ColorStop) * cnt)); memcpy(ret->pImpl->colorStops, colorStops, sizeof(ColorStop) * cnt); - if (transform) { - ret->pImpl->transform = static_cast(malloc(sizeof(Matrix))); - *ret->pImpl->transform = *transform; - } + ret->pImpl->transform = transform; + return ret; } }; diff --git a/src/renderer/wg_engine/tvgWgRenderData.cpp b/src/renderer/wg_engine/tvgWgRenderData.cpp index fedde25f..33b14ccb 100755 --- a/src/renderer/wg_engine/tvgWgRenderData.cpp +++ b/src/renderer/wg_engine/tvgWgRenderData.cpp @@ -213,10 +213,9 @@ void WgRenderSettings::update(WgContext& context, const Fill* fill, const uint8_ if ((flags & (RenderUpdateFlag::Gradient)) && fill) { rasterType = WgRenderRasterType::Gradient; // get gradient transfrom matrix - Matrix fillTransform = fill->transform(); Matrix invFillTransform; WgShaderTypeMat4x4f gradientTrans; // identity by default - if (inverse(&fillTransform, &invFillTransform)) + if (inverse(&fill->transform(), &invFillTransform)) gradientTrans.update(invFillTransform); // get gradient rasterisation settings WgShaderTypeGradient gradient;