bool GiGraphics::drawBeziers(const GiContext* ctx, int count, const Point2d* points, bool modelUnit) { if (m_impl->drawRefcnt == 0 || count < 4 || points == NULL) return false; GiLock lock (&m_impl->drawRefcnt); if (count > 0x2000) count = 0x2000; count = 1 + (count - 1) / 3 * 3; bool ret = false; vector<Point2d> pxpoints; vector<Point2d> pointBuf; int i, j, n, si, ei; Point2d * pxs; Matrix2d matD(S2D(xf(), modelUnit)); const Box2d extent (count, points); // 模型坐标范围 if (!DRAW_RECT(m_impl, modelUnit).isIntersect(extent)) // 全部在显示区域外 return false; if (DRAW_MAXR(m_impl, modelUnit).contains(extent)) // 全部在显示区域内 { pxpoints.resize(count); pxs = &pxpoints.front(); for (i = 0; i < count; i++) pxs[i] = points[i] * matD; ret = rawBeziers(ctx, pxs, count); } else { pointBuf.resize(count); for (i = 0; i < count; i++) // 转换到像素坐标 pointBuf[i] = points[i] * matD; Point2d* pts = &pointBuf.front(); si = ei = 0; for (i = 3; i < count; i += 3) { for ( ; i < count && m_impl->rectDraw.isIntersect(Box2d(4, &pts[ei])); i += 3) ei = i; n = ei - si + 1; if (n > 1) { pxpoints.resize(n); pxs = &pxpoints.front(); for (j=0; j<n; j++) pxs[j] = pts[si + j]; ret = rawBeziers(ctx, pxs, n); } si = ei = i; } } return ret; }
bool GiGraphics::drawBeziers(const GiContext* ctx, int count, const Point2d* points, bool closed, bool modelUnit) { if (count < 4 || !points || isStopping()) return false; if (count > 0x2000) count = 0x2000; count = 1 + (count - 1) / 3 * 3; bool ret = false; vector<Point2d> pxpoints; vector<Point2d> pointBuf; int i, j, n, si, ei; Point2d * pxs; Matrix2d matD(S2D(xf(), modelUnit)); const Box2d extent (count, points); // 模型坐标范围 if (!DRAW_RECT(m_impl, modelUnit).isIntersect(extent)) // 全部在显示区域外 return false; if (closed) { pxpoints.resize(count); pxs = &pxpoints.front(); for (i = 0; i < count; i++) pxs[i] = points[i] * matD; ret = rawBeziers(ctx, pxs, count, closed); } else if (DRAW_MAXR(m_impl, modelUnit).contains(extent)) { // 全部在显示区域内 pxpoints.resize(count); pxs = &pxpoints.front(); for (i = 0; i < count; i++) pxs[i] = points[i] * matD; ret = rawBeziers(ctx, pxs, count); } else { pointBuf.resize(count); for (i = 0; i < count; i++) // 转换到像素坐标 pointBuf[i] = points[i] * matD; Point2d* pts = &pointBuf.front(); for (i = 0; i + 3 < count;) { for (; i + 3 < count && !m_impl->rectDraw.isIntersect(Box2d(4, &pts[i])); i += 3) ; si = ei = i; for (; i + 3 < count && m_impl->rectDraw.isIntersect(Box2d(4, &pts[i])); i += 3) ei = i + 3; if (ei > si) { n = ei - si + 1; pxpoints.resize(n); pxs = &pxpoints.front(); for (j=0; j<n; j++) pxs[j] = pts[si + j]; ret = rawBeziers(ctx, pxs, n); } } } return ret; }
bool GiGraphics::drawLines(const GiContext* ctx, int count, const Point2d* points, bool modelUnit) { if (m_impl->drawRefcnt == 0 || count < 2 || points == NULL) return false; if (count > 0x2000) count = 0x2000; GiLock lock (&m_impl->drawRefcnt); int i; Point2d pt1, pt2, ptLast; vector<Point2d> pxpoints; vector<Point2d> pointBuf; bool ret = false; Matrix2d matD(S2D(xf(), modelUnit)); const Box2d extent (count, points); // 模型坐标范围 if (!DRAW_RECT(m_impl, modelUnit).isIntersect(extent)) // 全部在显示区域外 return false; if (DRAW_MAXR(m_impl, modelUnit).contains(extent)) // 全部在显示区域内 { pxpoints.resize(count); Point2d* pxs = &pxpoints.front(); int n = 0; for (i = 0; i < count; i++) { pt2 = points[i] * matD; if (i == 0 || fabs(pt1.x - pt2.x) > 2 || fabs(pt1.y - pt2.y) > 2) { pt1 = pt2; pxs[n++] = pt2; } } ret = rawLines(ctx, pxs, n); } else // 部分在显示区域内 { pointBuf.resize(count); for (i = 0; i < count; i++) // 转换到像素坐标 pointBuf[i] = points[i] * matD; Point2d* pts = &pointBuf.front(); ptLast = pts[0]; PolylineAux aux(this, ctx); for (i = 0; i < count - 1; i++) { ret = DrawEdge(count, i, pts, ptLast, aux, m_impl->rectDraw) || ret; } } return ret; }
bool GiGraphics::drawPolygon(const GiContext* ctx, int count, const Point2d* points, bool modelUnit) { if (m_impl->drawRefcnt == 0 || count < 2 || points == NULL) return false; GiLock lock (&m_impl->drawRefcnt); if (count > 0x2000) count = 0x2000; bool ret = false; const Box2d extent (count, points); // 模型坐标范围 if (!DRAW_RECT(m_impl, modelUnit).isIntersect(extent)) // 全部在显示区域外 return false; if (DRAW_MAXR(m_impl, modelUnit).contains(extent)) // 全部在显示区域内 { ret = _DrawPolygon(m_impl->canvas, ctx, count, points, true, true, true, modelUnit); } else // 部分在显示区域内 { PolygonClip clip (m_impl->rectDraw); if (!clip.clip(count, points, &S2D(xf(), modelUnit))) // 多边形剪裁 return false; count = clip.getCount(); points = clip.getPoints(); ret = _DrawPolygon(m_impl->canvas, ctx, count, points, false, true, false, modelUnit); int ienter = findInvisibleEdge(clip); if (ienter == count) { ret = _DrawPolygon(m_impl->canvas, ctx, count, points, false, false, true, modelUnit) || ret; } else { ret = drawPolygonEdge(PolylineAux(this, ctx), count, clip, ienter) || ret; } } return ret; }
bool GiGraphics::drawPolygon(const GiContext* ctx, int count, const Point2d* points, bool modelUnit) { if (count < 2 || !points || isStopping()) return false; count = count > 0x2000 ? 0x2000 : count; ctx = ctx ? ctx : &(m_impl->ctx); bool ret = false; const Box2d extent (count, points); // 模型坐标范围 if (!DRAW_RECT(m_impl, modelUnit).isIntersect(extent)) // 全部在显示区域外 return false; if (DRAW_MAXR(m_impl, modelUnit).contains(extent)) { // 全部在显示区域内 ret = _drawPolygon(ctx, count, points, true, true, true, modelUnit); } else { // 部分在显示区域内 PolygonClip clip (m_impl->rectDraw); if (!clip.clip(count, points, &S2D(xf(), modelUnit))) // 多边形剪裁 return false; count = clip.getCount(); points = clip.getPoints(); ret = _drawPolygon(ctx, count, points, false, true, false, modelUnit); int ienter = findInvisibleEdge(clip); if (ienter == count) { ret = _drawPolygon(ctx, count, points, false, false, true, modelUnit) || ret; } else { ret = drawPolygonEdge(PolylineAux(this, ctx), count, clip, ienter) || ret; } } return ret; }
bool GiGraphics::drawBeziers(const GiContext* ctx, int count, const Point2d* knot, const Vector2d* knotvs, bool closed, bool modelUnit) { if (count < 2 || !knot || !knotvs || isStopping()) return false; if (count > 0x1000) count = 0x1000; bool ret = false; vector<Point2d> pxpoints; vector<Point2d> pointBuf; int i, j, n, si, ei; Point2d * pxs; Matrix2d matD(S2D(xf(), modelUnit)); const Box2d extent (count, knot); // 模型坐标范围 if (!DRAW_RECT(m_impl, modelUnit).isIntersect(extent)) // 全部在显示区域外 return false; pointBuf.resize(1 + (count - 1) * 3); pxs = &pointBuf.front(); if (closed) { pxs[0] = knot[0] * matD; for (i = 0, j = 1; i + 1 < count; i++) { pxs[j++] = (knot[i] + knotvs[i]) * matD; pxs[j++] = (knot[i+1] - knotvs[i+1]) * matD; pxs[j++] = knot[i+1] * matD; } ret = rawBeziers(ctx, pxs, j, closed); } else if (DRAW_MAXR(m_impl, modelUnit).contains(extent)) { // 全部在显示区域内 pxs[0] = knot[0] * matD; for (i = 0, j = 1; i + 1 < count; i++) { pxs[j++] = (knot[i] + knotvs[i]) * matD; pxs[j++] = (knot[i+1] - knotvs[i+1]) * matD; pxs[j++] = knot[i+1] * matD; } ret = rawBeziers(ctx, pxs, j); } else { pxs[0] = knot[0] * matD; for (i = 0, j = 1; i + 1 < count; i++) { pxs[j++] = (knot[i] + knotvs[i]) * matD; pxs[j++] = (knot[i+1] - knotvs[i+1]) * matD; pxs[j++] = knot[i+1] * matD; } Point2d* pts = pxs; count = 1 + (count - 1) * 3; for (i = 0; i + 3 < count;) { for (; i + 3 < count && !m_impl->rectDraw.isIntersect(Box2d(4, &pts[i])); i += 3) ; si = ei = i; for (; i + 3 < count && m_impl->rectDraw.isIntersect(Box2d(4, &pts[i])); i += 3) ei = i + 3; if (ei > si) { n = ei - si + 1; pxpoints.resize(n); pxs = &pxpoints.front(); for (j=0; j<n; j++) pxs[j] = pts[si + j]; ret = rawBeziers(ctx, pxs, n); } } } return ret; }