ttf_loader: handling contours starting with OFF_CURVE

It might happen that the first point doesn't belong
to the contour - such cases were observed as artifacts
till now.

@Issue: https://github.com/thorvg/thorvg/issues/3268
This commit is contained in:
Mira Grudzinska 2025-02-24 17:36:40 +01:00 committed by Hermet Park
parent 2c73da0e20
commit 47130ea911

View file

@ -479,13 +479,13 @@ bool TtfReader::convert(Shape* shape, TtfGlyphMetrics& gmetrics, const Point& of
for (uint32_t i = 0; i < cntrsCnt; ++i) { for (uint32_t i = 0; i < cntrsCnt; ++i) {
//contour must start with move to //contour must start with move to
bool offCurve = !(flags[begin] & ON_CURVE);
Point ptsBegin = offCurve ? (pts[begin] + pts[endPts[i]]) * 0.5f : pts[begin];
pathCmds.push(PathCommand::MoveTo); pathCmds.push(PathCommand::MoveTo);
pathPts.push(pts[begin]); pathPts.push(ptsBegin);
bool offCurve = false; auto cnt = endPts[i] - begin + 1;
auto last = (endPts[i] - begin) + 1; for (uint32_t x = 1; x < cnt; ++x) {
for (uint32_t x = 1; x < last; ++x) {
if (flags[begin + x] & ON_CURVE) { if (flags[begin + x] & ON_CURVE) {
if (offCurve) { if (offCurve) {
pathCmds.push(PathCommand::CubicTo); pathCmds.push(PathCommand::CubicTo);
@ -511,9 +511,9 @@ bool TtfReader::convert(Shape* shape, TtfGlyphMetrics& gmetrics, const Point& of
} }
if (offCurve) { if (offCurve) {
pathCmds.push(PathCommand::CubicTo); pathCmds.push(PathCommand::CubicTo);
pathPts.push(pathPts.last() + (2.0f/3.0f) * (pts[begin + last - 1] - pathPts.last())); pathPts.push(pathPts.last() + (2.0f/3.0f) * (pts[begin + cnt - 1] - pathPts.last()));
pathPts.push(pts[begin] + (2.0f/3.0f) * (pts[begin + last - 1] - pts[begin])); pathPts.push(ptsBegin + (2.0f/3.0f) * (pts[begin + cnt - 1] - ptsBegin));
pathPts.push(pts[begin]); pathPts.push(ptsBegin);
} }
//contour must end with close //contour must end with close
pathCmds.push(PathCommand::Close); pathCmds.push(PathCommand::Close);