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. * @return The augmented transformation matrix.
*/ */
Matrix transform() const noexcept; Matrix& transform() const noexcept;
/** /**
* @brief Creates a copy of the Fill object. * @brief Creates a copy of the Fill object.

View file

@ -92,9 +92,8 @@ static unique_ptr<LinearGradient> _applyLinearGradientProperty(SvgStyleGradient*
Fill::ColorStop* stops; Fill::ColorStop* stops;
int stopCount = 0; int stopCount = 0;
auto fillGrad = LinearGradient::gen(); auto fillGrad = LinearGradient::gen();
auto isTransform = (g->transform ? true : false);
bool isTransform = (g->transform ? true : false); auto& finalTransform = fillGrad->transform();
Matrix finalTransform = {1, 0, 0, 0, 1, 0, 0, 0, 1};
if (isTransform) finalTransform = *g->transform; if (isTransform) finalTransform = *g->transform;
if (g->userSpace) { if (g->userSpace) {
@ -105,13 +104,8 @@ static unique_ptr<LinearGradient> _applyLinearGradientProperty(SvgStyleGradient*
} else { } else {
Matrix m = {vBox.w, 0, vBox.x, 0, vBox.h, vBox.y, 0, 0, 1}; Matrix m = {vBox.w, 0, vBox.x, 0, vBox.h, vBox.y, 0, 0, 1};
if (isTransform) _transformMultiply(&m, &finalTransform); if (isTransform) _transformMultiply(&m, &finalTransform);
else { else finalTransform = m;
finalTransform = m;
isTransform = true;
} }
}
if (isTransform) fillGrad->transform(finalTransform);
fillGrad->linear(g->linear->x1, g->linear->y1, g->linear->x2, g->linear->y2); fillGrad->linear(g->linear->x1, g->linear->y1, g->linear->x2, g->linear->y2);
fillGrad->spread(g->spread); fillGrad->spread(g->spread);
@ -147,9 +141,8 @@ static unique_ptr<RadialGradient> _applyRadialGradientProperty(SvgStyleGradient*
Fill::ColorStop *stops; Fill::ColorStop *stops;
int stopCount = 0; int stopCount = 0;
auto fillGrad = RadialGradient::gen(); auto fillGrad = RadialGradient::gen();
auto isTransform = (g->transform ? true : false);
bool isTransform = (g->transform ? true : false); auto& finalTransform = fillGrad->transform();
Matrix finalTransform = {1, 0, 0, 0, 1, 0, 0, 0, 1};
if (isTransform) finalTransform = *g->transform; if (isTransform) finalTransform = *g->transform;
if (g->userSpace) { if (g->userSpace) {
@ -164,13 +157,8 @@ static unique_ptr<RadialGradient> _applyRadialGradientProperty(SvgStyleGradient*
} else { } else {
Matrix m = {vBox.w, 0, vBox.x, 0, vBox.h, vBox.y, 0, 0, 1}; Matrix m = {vBox.w, 0, vBox.x, 0, vBox.h, vBox.y, 0, 0, 1};
if (isTransform) _transformMultiply(&m, &finalTransform); if (isTransform) _transformMultiply(&m, &finalTransform);
else { else finalTransform = m;
finalTransform = m;
isTransform = true;
} }
}
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); 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); 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(); const auto& matrix = sdata.geometry->getTransformMatrix();
auto gradientTransform = fill->transform();
float invMat4[16]; float invMat4[16];
if (!identity(const_cast<const Matrix*>(&gradientTransform))) { Matrix inv;
Matrix inv{}; inverse(&fill->transform(), &inv);
inverse(&gradientTransform , &inv);
GET_MATRIX44(inv, invMat4); 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]; float matrix44[16];
currentPass()->getMatrix(matrix44, matrix); currentPass()->getMatrix(matrix44, matrix);
uint32_t loc = task->getProgram()->getUniformBlockIndex("Matrix"); uint32_t loc = task->getProgram()->getUniformBlockIndex("Matrix");
uint32_t viewOffset = mGpuBuffer->push(matrix44, 16 * sizeof(float), true); uint32_t viewOffset = mGpuBuffer->push(matrix44, 16 * sizeof(float), true);
task->addBindResource(GlBindingResource{ 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; float x1, x2, y1, y2;
if (linear->linear(&x1, &y1, &x2, &y2) != Result::Success) return false; 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.dy /= len;
fill->linear.offset = -fill->linear.dx * x1 - fill->linear.dy * y1; fill->linear.offset = -fill->linear.dx * x1 - fill->linear.dy * y1;
auto gradTransform = linear->transform(); auto transform = pTransform * linear->transform();
bool isTransformation = !identity((const Matrix*)(&gradTransform));
if (isTransformation) { Matrix itransform;
gradTransform = transform * gradTransform; if (!inverse(&transform, &itransform)) return false;
} else {
gradTransform = transform;
isTransformation = true;
}
if (isTransformation) { fill->linear.offset += fill->linear.dx * itransform.e13 + fill->linear.dy * itransform.e23;
Matrix invTransform;
if (!inverse(&gradTransform, &invTransform)) return false;
fill->linear.offset += fill->linear.dx * invTransform.e13 + fill->linear.dy * invTransform.e23;
auto dx = fill->linear.dx; auto dx = fill->linear.dx;
fill->linear.dx = dx * invTransform.e11 + fill->linear.dy * invTransform.e21; fill->linear.dx = dx * itransform.e11 + fill->linear.dy * itransform.e21;
fill->linear.dy = dx * invTransform.e12 + fill->linear.dy * invTransform.e22; fill->linear.dy = dx * itransform.e12 + fill->linear.dy * itransform.e22;
}
return true; 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 cx = P(radial)->cx;
auto cy = P(radial)->cy; 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; if (fill->radial.a > 0) fill->radial.invA = 1.0f / fill->radial.a;
auto gradTransform = radial->transform(); auto transform = pTransform * radial->transform();
bool isTransformation = !identity((const Matrix*)(&gradTransform));
if (isTransformation) gradTransform = transform * gradTransform; Matrix itransform;
else { if (!inverse(&transform, &itransform)) return false;
gradTransform = transform;
isTransformation = true; 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; return true;
} }

View file

@ -134,18 +134,14 @@ FillSpread Fill::spread() const noexcept
Result Fill::transform(const Matrix& m) noexcept Result Fill::transform(const Matrix& m) noexcept
{ {
if (!pImpl->transform) { pImpl->transform = m;
pImpl->transform = static_cast<Matrix*>(malloc(sizeof(Matrix)));
}
*pImpl->transform = m;
return Result::Success; return Result::Success;
} }
Matrix Fill::transform() const noexcept Matrix& Fill::transform() const noexcept
{ {
if (pImpl->transform) return *pImpl->transform; return pImpl->transform;
return {1, 0, 0, 0, 1, 0, 0, 0, 1};
} }

View file

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

View file

@ -213,10 +213,9 @@ void WgRenderSettings::update(WgContext& context, const Fill* fill, const uint8_
if ((flags & (RenderUpdateFlag::Gradient)) && fill) { if ((flags & (RenderUpdateFlag::Gradient)) && fill) {
rasterType = WgRenderRasterType::Gradient; rasterType = WgRenderRasterType::Gradient;
// get gradient transfrom matrix // get gradient transfrom matrix
Matrix fillTransform = fill->transform();
Matrix invFillTransform; Matrix invFillTransform;
WgShaderTypeMat4x4f gradientTrans; // identity by default WgShaderTypeMat4x4f gradientTrans; // identity by default
if (inverse(&fillTransform, &invFillTransform)) if (inverse(&fill->transform(), &invFillTransform))
gradientTrans.update(invFillTransform); gradientTrans.update(invFillTransform);
// get gradient rasterisation settings // get gradient rasterisation settings
WgShaderTypeGradient gradient; WgShaderTypeGradient gradient;