api: revise the api for v1.0

- refactored the Fill matrix to hold internal data statically.
- refactored for clean & neat the raster engine / svg loader logic.

API Modification:
 - Matrix Fill::transform() const -> Matrix& Fill::transform() const

issue: https://github.com/thorvg/thorvg/issues/1372
This commit is contained in:
Hermet Park 2024-10-14 17:12:04 +09:00 committed by Hermet Park
parent 6a45e6e494
commit 630cbc48ae
7 changed files with 37 additions and 91 deletions

View file

@ -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.

View file

@ -92,9 +92,8 @@ static unique_ptr<LinearGradient> _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,13 +104,8 @@ static unique_ptr<LinearGradient> _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<RadialGradient> _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,13 +157,8 @@ static unique_ptr<RadialGradient> _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);

View file

@ -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<const Matrix*>(&gradientTransform))) {
Matrix inv{};
inverse(&gradientTransform , &inv);
Matrix inv;
inverse(&fill->transform(), &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;
}
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{

View file

@ -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 * invTransform.e13 + fill->linear.dy * invTransform.e23;
fill->linear.offset += fill->linear.dx * itransform.e13 + fill->linear.dy * itransform.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;
}
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;
}

View file

@ -134,18 +134,14 @@ FillSpread Fill::spread() const noexcept
Result Fill::transform(const Matrix& m) noexcept
{
if (!pImpl->transform) {
pImpl->transform = static_cast<Matrix*>(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;
}

View file

@ -51,16 +51,15 @@ struct FillDup : DuplicateMethod<Fill>
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<Fill>* dup = nullptr;
FillSpread spread;
~Impl()
{
delete(dup);
free(colorStops);
free(transform);
}
void method(DuplicateMethod<Fill>* 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<ColorStop*>(malloc(sizeof(ColorStop) * cnt));
memcpy(ret->pImpl->colorStops, colorStops, sizeof(ColorStop) * cnt);
if (transform) {
ret->pImpl->transform = static_cast<Matrix*>(malloc(sizeof(Matrix)));
*ret->pImpl->transform = *transform;
}
ret->pImpl->transform = transform;
return ret;
}
};

View file

@ -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;