diff --git a/src/lib/sw_engine/tvgSwCommon.h b/src/lib/sw_engine/tvgSwCommon.h index 3d68b56f..58f40d22 100644 --- a/src/lib/sw_engine/tvgSwCommon.h +++ b/src/lib/sw_engine/tvgSwCommon.h @@ -194,14 +194,14 @@ struct SwStroke struct SwDashStroke { - SwOutline* outline; - float curLen; - int32_t curIdx; - Point ptStart; - Point ptCur; - float* pattern; - uint32_t cnt; - bool curOpGap; + SwOutline* outline = nullptr; + float curLen = 0; + int32_t curIdx = 0; + Point ptStart = {0, 0}; + Point ptCur = {0, 0}; + float* pattern = nullptr; + uint32_t cnt = 0; + bool curOpGap = false; }; struct SwShape diff --git a/src/lib/sw_engine/tvgSwShape.cpp b/src/lib/sw_engine/tvgSwShape.cpp index f4bcd4a6..cbdf92a7 100644 --- a/src/lib/sw_engine/tvgSwShape.cpp +++ b/src/lib/sw_engine/tvgSwShape.cpp @@ -169,14 +169,16 @@ static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ct _outlineCubicTo(*dash.outline, ctrl1, ctrl2, to, transform); } } else { + bool begin = true; //starting with move_to while (len > dash.curLen) { Bezier left, right; len -= dash.curLen; bezSplitAt(cur, dash.curLen, left, right); if (!dash.curOpGap) { // 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); + begin = false; } _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; SwDashStroke dash; - dash.curIdx = 0; - dash.curLen = 0; - dash.ptStart = {0, 0}; - dash.ptCur = {0, 0}; - dash.curOpGap = false; - const float* pattern; float offset; - dash.cnt = rshape->strokeDash(&pattern, &offset); + dash.cnt = rshape->strokeDash((const float**)&dash.pattern, &offset); if (dash.cnt == 0) return nullptr; auto patternLength = 0.0f; uint32_t offIdx = 0; 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; if (isOdd) patternLength *= 2; - if (offset < 0) offset = patternLength + fmod(offset, patternLength); - else offset = fmod(offset, patternLength); + offset = fmod(offset, patternLength); + if (offset < 0) offset += patternLength; - for (size_t i = 0; i < dash.cnt * (1 + isOdd); ++i, ++offIdx) { - auto curPattern = pattern[i % dash.cnt]; + for (size_t i = 0; i < dash.cnt * (1 + (size_t)isOdd); ++i, ++offIdx) { + auto curPattern = dash.pattern[i % dash.cnt]; if (offset < curPattern) break; offset -= curPattern; } } //OPTMIZE ME: Use mempool??? - dash.pattern = const_cast(pattern); dash.outline = static_cast(calloc(1, sizeof(SwOutline))); //smart reservation