bool GiGraphics::drawQuadSplines(const GiContext* ctx, int count, const Point2d* ctlpts, bool closed, bool modelUnit) { if (count < 3 || !ctlpts || isStopping()) return false; const Box2d wndrect (DRAW_RECT(m_impl, modelUnit)); const Matrix2d matD(S2D(xf(), modelUnit)); Point2d mid, pt; rawBeginPath(); for (int i = 0; i < (closed ? count : count - 2); i++) { if (i == 0) { pt = (closed ? (ctlpts[0] + ctlpts[1]) / 2 : ctlpts[0]) * matD; rawMoveTo(pt.x, pt.y); } pt = ctlpts[(i+1) % count] * matD; if (closed || i + 3 < count) mid = (ctlpts[(i+1) % count] + ctlpts[(i+2) % count]) / 2 * matD; else mid = ctlpts[i+2] * matD; rawQuadTo(pt.x, pt.y, mid.x, mid.y); } if (closed) { rawClosePath(); } return rawEndPath(ctx, closed); }
bool GiGraphics::drawPath_(const GiContext* ctx, const MgPath& path, bool fill, const Matrix2d& matD) { int n = path.getCount(); if (n == 0 || isStopping()) return false; const Point2d* pts = path.getPoints(); const char* types = path.getTypes(); Point2d ends, cp1, cp2; bool matsame = matD.isIdentity(); rawBeginPath(); for (int i = 0; i < n; i++) { switch (types[i] & ~kMgCloseFigure) { case kMgMoveTo: ends = matsame ? pts[i] : (pts[i] * matD); rawMoveTo(ends.x, ends.y); break; case kMgLineTo: ends = matsame ? pts[i] : (pts[i] * matD); rawLineTo(ends.x, ends.y); break; case kMgBezierTo: if (i + 2 >= n) return false; cp1 = matsame ? pts[i] : (pts[i] * matD); cp2 = matsame ? pts[i+1] : (pts[i+1] * matD); ends = matsame ? pts[i+2] : (pts[i+2] * matD); rawBezierTo(cp1.x, cp1.y, cp2.x, cp2.y, ends.x, ends.y); i += 2; break; case kMgQuadTo: if (i + 1 >= n) return false; cp1 = matsame ? pts[i] : (pts[i] * matD); ends = matsame ? pts[i+1] : (pts[i+1] * matD); rawQuadTo(cp1.x, cp1.y, ends.x, ends.y); i++; break; default: return false; } if (types[i] & kMgCloseFigure) rawClosePath(); } return rawEndPath(ctx, fill); }
bool GiGraphics::drawQuadSplines(const GiContext* ctx, int count, const Point2d* ctlpts, bool modelUnit) { if (m_impl->drawRefcnt == 0 || count < 3 || ctlpts == NULL) return false; GiLock lock (&m_impl->drawRefcnt); const Box2d wndrect (DRAW_RECT(m_impl, modelUnit)); const Matrix2d matD(S2D(xf(), modelUnit)); Point2d mid1, mid2, pt, pt2; int n = 0; rawBeginPath(); for (int i = 0; i + 2 < count; i++) { if (Box2d(3, ctlpts + i).isIntersect(wndrect)) { pt2 = ctlpts[i+2]; mid1 = (ctlpts[i] + ctlpts[i+1]) / 2 * matD; mid2 = (ctlpts[i+1] + pt2) / 2 * matD; if (n++ == 0) { pt = ctlpts[i] * matD; rawMoveTo(pt.x, pt.y); rawLineTo(mid1.x, mid1.y); } pt = ctlpts[i+1] * matD; rawQuadTo(pt.x, pt.y, mid2.x, mid2.y); } else if (n > 0) { pt = pt2 * matD; rawLineTo(pt.x, pt.y); n = 0; } } if (n > 0) { pt = pt2 * matD; rawLineTo(pt.x, pt.y); } return rawEndPath(ctx, false); }