mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-14 12:04:29 +00:00
sw_engine: fix dash offset bug.
The latest offset feature has a missing starting point of the cubic bezier. This fix addresses the issue.
This commit is contained in:
parent
68f4193378
commit
f2e755cdd5
2 changed files with 17 additions and 22 deletions
|
@ -194,14 +194,14 @@ struct SwStroke
|
||||||
|
|
||||||
struct SwDashStroke
|
struct SwDashStroke
|
||||||
{
|
{
|
||||||
SwOutline* outline;
|
SwOutline* outline = nullptr;
|
||||||
float curLen;
|
float curLen = 0;
|
||||||
int32_t curIdx;
|
int32_t curIdx = 0;
|
||||||
Point ptStart;
|
Point ptStart = {0, 0};
|
||||||
Point ptCur;
|
Point ptCur = {0, 0};
|
||||||
float* pattern;
|
float* pattern = nullptr;
|
||||||
uint32_t cnt;
|
uint32_t cnt = 0;
|
||||||
bool curOpGap;
|
bool curOpGap = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SwShape
|
struct SwShape
|
||||||
|
|
|
@ -169,14 +169,16 @@ static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ct
|
||||||
_outlineCubicTo(*dash.outline, ctrl1, ctrl2, to, transform);
|
_outlineCubicTo(*dash.outline, ctrl1, ctrl2, to, transform);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
bool begin = true; //starting with move_to
|
||||||
while (len > dash.curLen) {
|
while (len > dash.curLen) {
|
||||||
Bezier left, right;
|
Bezier left, right;
|
||||||
len -= dash.curLen;
|
len -= dash.curLen;
|
||||||
bezSplitAt(cur, dash.curLen, left, right);
|
bezSplitAt(cur, dash.curLen, left, right);
|
||||||
if (!dash.curOpGap) {
|
if (!dash.curOpGap) {
|
||||||
// leftovers from a previous command don't require moveTo
|
// leftovers from a previous command don't require moveTo
|
||||||
if (dash.pattern[dash.curIdx] - dash.curLen < FLT_EPSILON) {
|
if (begin || dash.pattern[dash.curIdx] - dash.curLen < FLT_EPSILON) {
|
||||||
_outlineMoveTo(*dash.outline, &left.start, transform);
|
_outlineMoveTo(*dash.outline, &left.start, transform);
|
||||||
|
begin = false;
|
||||||
}
|
}
|
||||||
_outlineCubicTo(*dash.outline, &left.ctrl1, &left.ctrl2, &left.end, transform);
|
_outlineCubicTo(*dash.outline, &left.ctrl1, &left.ctrl2, &left.end, transform);
|
||||||
}
|
}
|
||||||
|
@ -215,36 +217,29 @@ static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* trans
|
||||||
if (cmdCnt == 0 || ptsCnt == 0) return nullptr;
|
if (cmdCnt == 0 || ptsCnt == 0) return nullptr;
|
||||||
|
|
||||||
SwDashStroke dash;
|
SwDashStroke dash;
|
||||||
dash.curIdx = 0;
|
|
||||||
dash.curLen = 0;
|
|
||||||
dash.ptStart = {0, 0};
|
|
||||||
dash.ptCur = {0, 0};
|
|
||||||
dash.curOpGap = false;
|
|
||||||
|
|
||||||
const float* pattern;
|
|
||||||
float offset;
|
float offset;
|
||||||
dash.cnt = rshape->strokeDash(&pattern, &offset);
|
dash.cnt = rshape->strokeDash((const float**)&dash.pattern, &offset);
|
||||||
if (dash.cnt == 0) return nullptr;
|
if (dash.cnt == 0) return nullptr;
|
||||||
|
|
||||||
auto patternLength = 0.0f;
|
auto patternLength = 0.0f;
|
||||||
uint32_t offIdx = 0;
|
uint32_t offIdx = 0;
|
||||||
if (fabsf(offset) > FLT_EPSILON) {
|
if (fabsf(offset) > FLT_EPSILON) {
|
||||||
for (size_t i = 0; i < dash.cnt; ++i) patternLength += pattern[i];
|
for (size_t i = 0; i < dash.cnt; ++i) patternLength += dash.pattern[i];
|
||||||
bool isOdd = dash.cnt % 2;
|
bool isOdd = dash.cnt % 2;
|
||||||
if (isOdd) patternLength *= 2;
|
if (isOdd) patternLength *= 2;
|
||||||
|
|
||||||
if (offset < 0) offset = patternLength + fmod(offset, patternLength);
|
offset = fmod(offset, patternLength);
|
||||||
else offset = fmod(offset, patternLength);
|
if (offset < 0) offset += patternLength;
|
||||||
|
|
||||||
for (size_t i = 0; i < dash.cnt * (1 + isOdd); ++i, ++offIdx) {
|
for (size_t i = 0; i < dash.cnt * (1 + (size_t)isOdd); ++i, ++offIdx) {
|
||||||
auto curPattern = pattern[i % dash.cnt];
|
auto curPattern = dash.pattern[i % dash.cnt];
|
||||||
if (offset < curPattern) break;
|
if (offset < curPattern) break;
|
||||||
offset -= curPattern;
|
offset -= curPattern;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//OPTMIZE ME: Use mempool???
|
//OPTMIZE ME: Use mempool???
|
||||||
dash.pattern = const_cast<float*>(pattern);
|
|
||||||
dash.outline = static_cast<SwOutline*>(calloc(1, sizeof(SwOutline)));
|
dash.outline = static_cast<SwOutline*>(calloc(1, sizeof(SwOutline)));
|
||||||
|
|
||||||
//smart reservation
|
//smart reservation
|
||||||
|
|
Loading…
Add table
Reference in a new issue