mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 05:33:36 +00:00
common: neat code++
introduced common BBox structure
This commit is contained in:
parent
857f1404e1
commit
0dd0a3b45c
10 changed files with 53 additions and 72 deletions
|
@ -346,6 +346,17 @@ struct Bezier
|
|||
};
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Geometry functions */
|
||||
/************************************************************************/
|
||||
|
||||
struct BBox
|
||||
{
|
||||
Point min, max;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Interpolation functions */
|
||||
/************************************************************************/
|
||||
|
|
|
@ -908,20 +908,20 @@ static bool _attrParseSvgNode(void* data, const char* key, const char* value)
|
|||
doc->viewFlag = (doc->viewFlag | SvgViewFlag::Height);
|
||||
}
|
||||
} else if (STR_AS(key, "viewBox")) {
|
||||
if (_parseNumber(&value, nullptr, &doc->vx)) {
|
||||
if (_parseNumber(&value, nullptr, &doc->vy)) {
|
||||
if (_parseNumber(&value, nullptr, &doc->vw)) {
|
||||
if (_parseNumber(&value, nullptr, &doc->vh)) {
|
||||
if (_parseNumber(&value, nullptr, &doc->vbox.x)) {
|
||||
if (_parseNumber(&value, nullptr, &doc->vbox.y)) {
|
||||
if (_parseNumber(&value, nullptr, &doc->vbox.w)) {
|
||||
if (_parseNumber(&value, nullptr, &doc->vbox.h)) {
|
||||
doc->viewFlag = (doc->viewFlag | SvgViewFlag::Viewbox);
|
||||
loader->svgParse->global.h = doc->vh;
|
||||
loader->svgParse->global.h = doc->vbox.h;
|
||||
}
|
||||
loader->svgParse->global.w = doc->vw;
|
||||
loader->svgParse->global.w = doc->vbox.w;
|
||||
}
|
||||
loader->svgParse->global.y = doc->vy;
|
||||
loader->svgParse->global.y = doc->vbox.y;
|
||||
}
|
||||
loader->svgParse->global.x = doc->vx;
|
||||
loader->svgParse->global.x = doc->vbox.x;
|
||||
}
|
||||
if ((doc->viewFlag & SvgViewFlag::Viewbox) && (doc->vw < 0.0f || doc->vh < 0.0f)) {
|
||||
if ((doc->viewFlag & SvgViewFlag::Viewbox) && (doc->vbox.w < 0.0f || doc->vbox.h < 0.0f)) {
|
||||
doc->viewFlag = (SvgViewFlag)((uint32_t)doc->viewFlag & ~(uint32_t)SvgViewFlag::Viewbox);
|
||||
TVGLOG("SVG", "Negative values of the <viewBox> width and/or height - the attribute invalidated.");
|
||||
}
|
||||
|
@ -3900,7 +3900,7 @@ SvgLoader::~SvgLoader()
|
|||
void SvgLoader::run(unsigned tid)
|
||||
{
|
||||
//According to the SVG standard the value of the width/height of the viewbox set to 0 disables rendering
|
||||
if ((viewFlag & SvgViewFlag::Viewbox) && (fabsf(vw) <= FLOAT_EPSILON || fabsf(vh) <= FLOAT_EPSILON)) {
|
||||
if ((viewFlag & SvgViewFlag::Viewbox) && (fabsf(vbox.w) <= FLOAT_EPSILON || fabsf(vbox.h) <= FLOAT_EPSILON)) {
|
||||
TVGLOG("SVG", "The <viewBox> width and/or height set to 0 - rendering disabled.");
|
||||
root = Scene::gen();
|
||||
return;
|
||||
|
@ -3928,16 +3928,13 @@ void SvgLoader::run(unsigned tid)
|
|||
if (loaderData.gradients.count > 0) _updateGradient(&loaderData, loaderData.doc, &loaderData.gradients);
|
||||
if (defs) _updateGradient(&loaderData, loaderData.doc, &defs->node.defs.gradients);
|
||||
}
|
||||
root = svgSceneBuild(loaderData, {vx, vy, vw, vh}, w, h, align, meetOrSlice, svgPath, viewFlag);
|
||||
root = svgSceneBuild(loaderData, vbox, w, h, align, meetOrSlice, svgPath, viewFlag);
|
||||
|
||||
//In case no viewbox and width/height data is provided the completion of loading
|
||||
//has to be forced, in order to establish this data based on the whole picture.
|
||||
if (!(viewFlag & SvgViewFlag::Viewbox)) {
|
||||
//Override viewbox & size again after svg loading.
|
||||
vx = loaderData.doc->node.doc.vx;
|
||||
vy = loaderData.doc->node.doc.vy;
|
||||
vw = loaderData.doc->node.doc.vw;
|
||||
vh = loaderData.doc->node.doc.vh;
|
||||
vbox = loaderData.doc->node.doc.vbox;
|
||||
w = loaderData.doc->node.doc.w;
|
||||
h = loaderData.doc->node.doc.h;
|
||||
}
|
||||
|
@ -3965,14 +3962,11 @@ bool SvgLoader::header()
|
|||
meetOrSlice = loaderData.doc->node.doc.meetOrSlice;
|
||||
|
||||
if (viewFlag & SvgViewFlag::Viewbox) {
|
||||
vx = loaderData.doc->node.doc.vx;
|
||||
vy = loaderData.doc->node.doc.vy;
|
||||
vw = loaderData.doc->node.doc.vw;
|
||||
vh = loaderData.doc->node.doc.vh;
|
||||
vbox = loaderData.doc->node.doc.vbox;
|
||||
|
||||
if (viewFlag & SvgViewFlag::Width) w = loaderData.doc->node.doc.w;
|
||||
else {
|
||||
w = loaderData.doc->node.doc.vw;
|
||||
w = loaderData.doc->node.doc.vbox.w;
|
||||
if (viewFlag & SvgViewFlag::WidthInPercent) {
|
||||
w *= loaderData.doc->node.doc.w;
|
||||
viewFlag = (viewFlag ^ SvgViewFlag::WidthInPercent);
|
||||
|
@ -3981,7 +3975,7 @@ bool SvgLoader::header()
|
|||
}
|
||||
if (viewFlag & SvgViewFlag::Height) h = loaderData.doc->node.doc.h;
|
||||
else {
|
||||
h = loaderData.doc->node.doc.vh;
|
||||
h = loaderData.doc->node.doc.vbox.h;
|
||||
if (viewFlag & SvgViewFlag::HeightInPercent) {
|
||||
h *= loaderData.doc->node.doc.h;
|
||||
viewFlag = (viewFlag ^ SvgViewFlag::HeightInPercent);
|
||||
|
@ -3992,20 +3986,20 @@ bool SvgLoader::header()
|
|||
//has to be forced, in order to establish this data based on the whole picture.
|
||||
} else {
|
||||
//Before loading, set default viewbox & size if they are empty
|
||||
vx = vy = 0.0f;
|
||||
vbox.x = vbox.y = 0.0f;
|
||||
if (viewFlag & SvgViewFlag::Width) {
|
||||
vw = w = loaderData.doc->node.doc.w;
|
||||
vbox.w = w = loaderData.doc->node.doc.w;
|
||||
} else {
|
||||
vw = 1.0f;
|
||||
vbox.w = 1.0f;
|
||||
if (viewFlag & SvgViewFlag::WidthInPercent) {
|
||||
w = loaderData.doc->node.doc.w;
|
||||
} else w = 1.0f;
|
||||
}
|
||||
|
||||
if (viewFlag & SvgViewFlag::Height) {
|
||||
vh = h = loaderData.doc->node.doc.h;
|
||||
vbox.h = h = loaderData.doc->node.doc.h;
|
||||
} else {
|
||||
vh = 1.0f;
|
||||
vbox.h = 1.0f;
|
||||
if (viewFlag & SvgViewFlag::HeightInPercent) {
|
||||
h = loaderData.doc->node.doc.h;
|
||||
} else h = 1.0f;
|
||||
|
|
|
@ -54,10 +54,7 @@ private:
|
|||
SvgViewFlag viewFlag = SvgViewFlag::None;
|
||||
AspectRatioAlign align = AspectRatioAlign::XMidYMid;
|
||||
AspectRatioMeetOrSlice meetOrSlice = AspectRatioMeetOrSlice::Meet;
|
||||
float vx = 0;
|
||||
float vy = 0;
|
||||
float vw = 0;
|
||||
float vh = 0;
|
||||
Box vbox{};
|
||||
|
||||
bool header();
|
||||
void clear(bool all = true);
|
||||
|
|
|
@ -285,12 +285,8 @@ enum class AspectRatioMeetOrSlice
|
|||
|
||||
struct SvgDocNode
|
||||
{
|
||||
float w; //unit: point or in percentage see: SvgViewFlag
|
||||
float h; //unit: point or in percentage see: SvgViewFlag
|
||||
float vx;
|
||||
float vy;
|
||||
float vw;
|
||||
float vh;
|
||||
float w, h; //unit: point or in percentage see: SvgViewFlag
|
||||
Box vbox;
|
||||
SvgViewFlag viewFlag;
|
||||
SvgNode* defs;
|
||||
SvgNode* style;
|
||||
|
@ -558,10 +554,7 @@ struct SvgParser
|
|||
SvgStyleGradient* styleGrad;
|
||||
Fill::ColorStop gradStop;
|
||||
SvgStopStyleFlags flags;
|
||||
struct
|
||||
{
|
||||
float x, y, w, h;
|
||||
} global;
|
||||
Box global;
|
||||
struct
|
||||
{
|
||||
bool parsedFx;
|
||||
|
|
|
@ -940,10 +940,7 @@ Scene* svgSceneBuild(SvgLoaderData& loaderData, Box vBox, float w, float h, Aspe
|
|||
clippingLayer->clip(viewBoxClip);
|
||||
clippingLayer->push(docNode);
|
||||
|
||||
loaderData.doc->node.doc.vx = vBox.x;
|
||||
loaderData.doc->node.doc.vy = vBox.y;
|
||||
loaderData.doc->node.doc.vw = vBox.w;
|
||||
loaderData.doc->node.doc.vh = vBox.h;
|
||||
loaderData.doc->node.doc.vbox = vBox;
|
||||
loaderData.doc->node.doc.w = w;
|
||||
loaderData.doc->node.doc.h = h;
|
||||
|
||||
|
|
|
@ -2502,10 +2502,10 @@ void BWTessellator::tessellate(const RenderShape *rshape, const Matrix& matrix)
|
|||
RenderRegion BWTessellator::bounds() const
|
||||
{
|
||||
return RenderRegion {
|
||||
static_cast<int32_t>(floor(mLeftTop.x)),
|
||||
static_cast<int32_t>(floor(mLeftTop.y)),
|
||||
static_cast<int32_t>(ceil(mRightBottom.x - floor(mLeftTop.x))),
|
||||
static_cast<int32_t>(ceil(mRightBottom.y - floor(mLeftTop.y))),
|
||||
static_cast<int32_t>(floor(bbox.min.x)),
|
||||
static_cast<int32_t>(floor(bbox.min.y)),
|
||||
static_cast<int32_t>(ceil(bbox.max.x - floor(bbox.min.x))),
|
||||
static_cast<int32_t>(ceil(bbox.max.y - floor(bbox.min.y))),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -2515,13 +2515,10 @@ uint32_t BWTessellator::pushVertex(float x, float y)
|
|||
auto index = _pushVertex(mResPoints, x, y);
|
||||
|
||||
if (index == 0) {
|
||||
mRightBottom.x = mLeftTop.x = x;
|
||||
mRightBottom.y = mLeftTop.y = y;
|
||||
bbox.max = bbox.min = {x, y};
|
||||
} else {
|
||||
mLeftTop.x = std::min(mLeftTop.x, x);
|
||||
mLeftTop.y = std::min(mLeftTop.y, y);
|
||||
mRightBottom.x = std::max(mRightBottom.x, x);
|
||||
mRightBottom.y = std::max(mRightBottom.y , y);
|
||||
bbox.min = {std::min(bbox.min.x, x), std::min(bbox.min.y, y)};
|
||||
bbox.max = {std::max(bbox.max.x, x), std::max(bbox.max.y, y)};
|
||||
}
|
||||
|
||||
return index;
|
||||
|
|
|
@ -176,8 +176,7 @@ private:
|
|||
|
||||
Array<float>* mResPoints;
|
||||
Array<uint32_t>* mResIndices;
|
||||
Point mLeftTop = {0.0f, 0.0f};
|
||||
Point mRightBottom = {0.0f, 0.0f};
|
||||
BBox bbox = {{}, {}};
|
||||
};
|
||||
|
||||
} // namespace tvg
|
||||
|
|
|
@ -365,14 +365,12 @@ void WgRenderDataShape::updateBBox(Point pmin, Point pmax)
|
|||
|
||||
|
||||
void WgRenderDataShape::updateAABB(const Matrix& tr) {
|
||||
Point p0 = Point{pMin.x, pMin.y} * tr;
|
||||
Point p1 = Point{pMax.x, pMin.y} * tr;
|
||||
Point p2 = Point{pMin.x, pMax.y} * tr;
|
||||
Point p3 = Point{pMax.x, pMax.y} * tr;
|
||||
aabb.pMin.x = std::min({p0.x, p1.x, p2.x, p3.x});
|
||||
aabb.pMin.y = std::min({p0.y, p1.y, p2.y, p3.y});
|
||||
aabb.pMax.x = std::max({p0.x, p1.x, p2.x, p3.x});
|
||||
aabb.pMax.y = std::max({p0.y, p1.y, p2.y, p3.y});
|
||||
auto p0 = Point{pMin.x, pMin.y} * tr;
|
||||
auto p1 = Point{pMax.x, pMin.y} * tr;
|
||||
auto p2 = Point{pMin.x, pMax.y} * tr;
|
||||
auto p3 = Point{pMax.x, pMax.y} * tr;
|
||||
aabb.min = {std::min({p0.x, p1.x, p2.x, p3.x}), std::min({p0.y, p1.y, p2.y, p3.y})};
|
||||
aabb.max = {std::max({p0.x, p1.x, p2.x, p3.x}), std::max({p0.y, p1.y, p2.y, p3.y})};
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -26,11 +26,6 @@
|
|||
#include "tvgWgPipelines.h"
|
||||
#include "tvgWgGeometry.h"
|
||||
|
||||
struct WgAabb {
|
||||
Point pMin{};
|
||||
Point pMax{};
|
||||
};
|
||||
|
||||
struct WgMeshData {
|
||||
WGPUBuffer bufferPosition{};
|
||||
WGPUBuffer bufferTexCoord{};
|
||||
|
@ -104,7 +99,7 @@ struct WgRenderDataPaint
|
|||
WGPUBuffer bufferBlendSettings{};
|
||||
WGPUBindGroup bindGroupPaint{};
|
||||
RenderRegion viewport{};
|
||||
WgAabb aabb{};
|
||||
BBox aabb{{},{}};
|
||||
float opacity{};
|
||||
Array<WgRenderDataPaint*> clips;
|
||||
|
||||
|
|
|
@ -203,8 +203,8 @@ RenderRegion WgRenderer::region(RenderData data)
|
|||
{
|
||||
auto renderData = (WgRenderDataPaint*)data;
|
||||
if (renderData->type() == Type::Shape) {
|
||||
Point v1 = renderData->aabb.pMin;
|
||||
Point v2 = renderData->aabb.pMax;
|
||||
auto& v1 = renderData->aabb.min;
|
||||
auto& v2 = renderData->aabb.max;
|
||||
RenderRegion renderRegion;
|
||||
renderRegion.x = static_cast<int32_t>(nearbyint(v1.x));
|
||||
renderRegion.y = static_cast<int32_t>(nearbyint(v1.y));
|
||||
|
|
Loading…
Add table
Reference in a new issue