common: neat code++

introduced common BBox structure
This commit is contained in:
Hermet Park 2025-02-06 15:03:31 +09:00 committed by Hermet Park
parent 857f1404e1
commit 0dd0a3b45c
10 changed files with 53 additions and 72 deletions

View file

@ -346,6 +346,17 @@ struct Bezier
}; };
/************************************************************************/
/* Geometry functions */
/************************************************************************/
struct BBox
{
Point min, max;
};
/************************************************************************/ /************************************************************************/
/* Interpolation functions */ /* Interpolation functions */
/************************************************************************/ /************************************************************************/

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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