mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-07 21:23:32 +00:00
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:
parent
6a45e6e494
commit
630cbc48ae
7 changed files with 37 additions and 91 deletions
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue