mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 13:43:43 +00:00
common: move&fix trimming wrapping logic
The logic of interpretation of trimming start and end values has been moved to the sw_engine, so the values provided by the user are not modified. No logical changes in the interpretation alg. For pairs of trim's start/end values where the distance between begin and end is >= 1, the entire stroke should be drawn, but instead, nothing or only part is drawn. Fixed. Stroke trim docs fixed.
This commit is contained in:
parent
c9ad7289a6
commit
d29a3d754b
5 changed files with 37 additions and 25 deletions
|
@ -1040,7 +1040,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* @brief Sets the trim of the stroke along the defined path segment, allowing control over which part of the stroke is visible.
|
* @brief Sets the trim of the stroke along the defined path segment, allowing control over which part of the stroke is visible.
|
||||||
*
|
*
|
||||||
* The values of the arguments @p begin, @p end, and @p offset are in the range of 0.0 to 1.0, representing the beginning of the path and the end, respectively.
|
* If the values of the arguments @p begin and @p end exceed the 0-1 range, they are wrapped around in a manner similar to angle wrapping, effectively treating the range as circular.
|
||||||
*
|
*
|
||||||
* @param[in] begin Specifies the start of the segment to display along the path.
|
* @param[in] begin Specifies the start of the segment to display along the path.
|
||||||
* @param[in] end Specifies the end of the segment to display along the path.
|
* @param[in] end Specifies the end of the segment to display along the path.
|
||||||
|
|
|
@ -1511,7 +1511,7 @@ TVG_API Tvg_Result tvg_shape_get_stroke_miterlimit(const Tvg_Paint* paint, float
|
||||||
/*!
|
/*!
|
||||||
* \brief Sets the trim of the stroke along the defined path segment, allowing control over which part of the stroke is visible.
|
* \brief Sets the trim of the stroke along the defined path segment, allowing control over which part of the stroke is visible.
|
||||||
*
|
*
|
||||||
* The values of the arguments @p begin, @p end, and @p offset are in the range of 0.0 to 1.0, representing the beginning of the path and the end, respectively.
|
* If the values of the arguments @p begin and @p end exceed the 0-1 range, they are wrapped around in a manner similar to angle wrapping, effectively treating the range as circular.
|
||||||
*
|
*
|
||||||
* \param[in] paint A Tvg_Paint pointer to the shape object.
|
* \param[in] paint A Tvg_Paint pointer to the shape object.
|
||||||
* \param[in] begin Specifies the start of the segment to display along the path.
|
* \param[in] begin Specifies the start of the segment to display along the path.
|
||||||
|
|
|
@ -244,10 +244,10 @@ static void _dashMoveTo(SwDashStroke& dash, uint32_t offIdx, float offset, const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void _trimPattern(SwDashStroke* dash, const RenderShape* rshape, float length)
|
static void _trimPattern(SwDashStroke* dash, const RenderShape* rshape, float length, float trimBegin, float trimEnd)
|
||||||
{
|
{
|
||||||
auto begin = length * rshape->stroke->trim.begin;
|
auto begin = length * trimBegin;
|
||||||
auto end = length * rshape->stroke->trim.end;
|
auto end = length * trimEnd;
|
||||||
|
|
||||||
//default
|
//default
|
||||||
if (end > begin) {
|
if (end > begin) {
|
||||||
|
@ -340,6 +340,8 @@ static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix& trans
|
||||||
auto offset = 0.0f;
|
auto offset = 0.0f;
|
||||||
dash.cnt = rshape->strokeDash((const float**)&dash.pattern, &offset);
|
dash.cnt = rshape->strokeDash((const float**)&dash.pattern, &offset);
|
||||||
auto simultaneous = rshape->stroke->trim.simultaneous;
|
auto simultaneous = rshape->stroke->trim.simultaneous;
|
||||||
|
float trimBegin = 0.0f, trimEnd = 1.0f;
|
||||||
|
if (trimmed) rshape->stroke->strokeTrim(trimBegin, trimEnd);
|
||||||
|
|
||||||
if (dash.cnt == 0) {
|
if (dash.cnt == 0) {
|
||||||
if (trimmed) dash.pattern = (float*)malloc(sizeof(float) * 4);
|
if (trimmed) dash.pattern = (float*)malloc(sizeof(float) * 4);
|
||||||
|
@ -371,7 +373,7 @@ static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix& trans
|
||||||
|
|
||||||
//must begin with moveTo
|
//must begin with moveTo
|
||||||
if (cmds[0] == PathCommand::MoveTo) {
|
if (cmds[0] == PathCommand::MoveTo) {
|
||||||
if (trimmed) _trimPattern(&dash, rshape, _outlineLength(rshape, 0, 0, simultaneous));
|
if (trimmed) _trimPattern(&dash, rshape, _outlineLength(rshape, 0, 0, simultaneous), trimBegin, trimEnd);
|
||||||
_dashMoveTo(dash, offIdx, offset, pts);
|
_dashMoveTo(dash, offIdx, offset, pts);
|
||||||
cmds++;
|
cmds++;
|
||||||
pts++;
|
pts++;
|
||||||
|
@ -386,7 +388,7 @@ static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix& trans
|
||||||
case PathCommand::MoveTo: {
|
case PathCommand::MoveTo: {
|
||||||
if (trimmed) {
|
if (trimmed) {
|
||||||
if (simultaneous) {
|
if (simultaneous) {
|
||||||
_trimPattern(&dash, rshape, _outlineLength(rshape, pts - startPts, cmds - startCmds, true));
|
_trimPattern(&dash, rshape, _outlineLength(rshape, pts - startPts, cmds - startCmds, true), trimBegin, trimEnd);
|
||||||
_dashMoveTo(dash, offIdx, offset, pts);
|
_dashMoveTo(dash, offIdx, offset, pts);
|
||||||
} else _dashMoveTo(dash, pts);
|
} else _dashMoveTo(dash, pts);
|
||||||
} else _dashMoveTo(dash, offIdx, offset, pts);
|
} else _dashMoveTo(dash, offIdx, offset, pts);
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#ifndef _TVG_RENDER_H_
|
#ifndef _TVG_RENDER_H_
|
||||||
#define _TVG_RENDER_H_
|
#define _TVG_RENDER_H_
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
#include "tvgCommon.h"
|
#include "tvgCommon.h"
|
||||||
#include "tvgArray.h"
|
#include "tvgArray.h"
|
||||||
#include "tvgLock.h"
|
#include "tvgLock.h"
|
||||||
|
@ -155,6 +156,32 @@ struct RenderStroke
|
||||||
trim = rhs.trim;
|
trim = rhs.trim;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool strokeTrim(float& begin, float& end) const
|
||||||
|
{
|
||||||
|
begin = trim.begin;
|
||||||
|
end = trim.end;
|
||||||
|
|
||||||
|
if (fabsf(end - begin) > 1.0f) {
|
||||||
|
begin = 0.0f;
|
||||||
|
end = 1.0f;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto loop = true;
|
||||||
|
|
||||||
|
if (begin > 1.0f && end > 1.0f) loop = false;
|
||||||
|
if (begin < 0.0f && end < 0.0f) loop = false;
|
||||||
|
if (begin >= 0.0f && begin <= 1.0f && end >= 0.0f && end <= 1.0f) loop = false;
|
||||||
|
|
||||||
|
if (begin > 1.0f) begin -= 1.0f;
|
||||||
|
if (begin < 0.0f) begin += 1.0f;
|
||||||
|
if (end > 1.0f) end -= 1.0f;
|
||||||
|
if (end < 0.0f) end += 1.0f;
|
||||||
|
|
||||||
|
if ((loop && begin < end) || (!loop && begin > end)) std::swap(begin, end);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
~RenderStroke()
|
~RenderStroke()
|
||||||
{
|
{
|
||||||
free(dashPattern);
|
free(dashPattern);
|
||||||
|
@ -199,7 +226,7 @@ struct RenderShape
|
||||||
{
|
{
|
||||||
if (!stroke) return false;
|
if (!stroke) return false;
|
||||||
if (stroke->trim.begin == 0.0f && stroke->trim.end == 1.0f) return false;
|
if (stroke->trim.begin == 0.0f && stroke->trim.end == 1.0f) return false;
|
||||||
if (stroke->trim.begin == 1.0f && stroke->trim.end == 0.0f) return false;
|
if (fabsf(stroke->trim.end - stroke->trim.begin) > 1.0f) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -217,23 +217,6 @@ struct Shape::Impl
|
||||||
if (tvg::equal(rs.stroke->trim.begin, begin) && tvg::equal(rs.stroke->trim.end, end) &&
|
if (tvg::equal(rs.stroke->trim.begin, begin) && tvg::equal(rs.stroke->trim.end, end) &&
|
||||||
rs.stroke->trim.simultaneous == simultaneous) return;
|
rs.stroke->trim.simultaneous == simultaneous) return;
|
||||||
|
|
||||||
auto loop = true;
|
|
||||||
|
|
||||||
if (begin > 1.0f && end > 1.0f) loop = false;
|
|
||||||
if (begin < 0.0f && end < 0.0f) loop = false;
|
|
||||||
if (begin >= 0.0f && begin <= 1.0f && end >= 0.0f && end <= 1.0f) loop = false;
|
|
||||||
|
|
||||||
if (begin > 1.0f) begin -= 1.0f;
|
|
||||||
if (begin < 0.0f) begin += 1.0f;
|
|
||||||
if (end > 1.0f) end -= 1.0f;
|
|
||||||
if (end < 0.0f) end += 1.0f;
|
|
||||||
|
|
||||||
if ((loop && begin < end) || (!loop && begin > end)) {
|
|
||||||
auto tmp = begin;
|
|
||||||
begin = end;
|
|
||||||
end = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
rs.stroke->trim.begin = begin;
|
rs.stroke->trim.begin = begin;
|
||||||
rs.stroke->trim.end = end;
|
rs.stroke->trim.end = end;
|
||||||
rs.stroke->trim.simultaneous = simultaneous;
|
rs.stroke->trim.simultaneous = simultaneous;
|
||||||
|
|
Loading…
Add table
Reference in a new issue