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