HGDIOBJ createBrush(const GiContext* ctx) { if (ctx == NULL) ctx = &m_context; if (m_brush == NULL || m_context.getFillColor() != ctx->getFillColor() || m_context.getFillAlpha() != ctx->getFillAlpha()) { m_context.setFillColor(ctx->getFillColor()); m_context.setFillAlpha(ctx->getFillAlpha()); if (m_brush != NULL) ::DeleteObject(m_brush); if (!ctx->hasFillColor() || ctx->getFillAlpha() < 127) m_brush = ::GetStockObject(NULL_BRUSH); else { GiColor color = m_this->gs()->calcPenColor(ctx->getFillColor()); m_brush = ::CreateSolidBrush(RGB(color.r, color.g, color.b)); } } return m_brush; }
bool setBrush(const GiContext* ctx) { bool changed = !_ctxused[1]; if (ctx && ctx->hasFillColor()) { if (_gictx.getFillColor() != ctx->getFillColor()) { _gictx.setFillColor(ctx->getFillColor()); changed = true; } } if (!ctx) ctx = &_gictx; if (ctx->hasFillColor() && changed) { _ctxused[1] = true; GiColor color = ctx->getFillColor(); if (gs()) color = gs()->calcPenColor(color); CGContextSetRGBFillColor(getContext(), toFloat(color.r), toFloat(color.g), toFloat(color.b), toFloat(color.a)); } return ctx->hasFillColor(); }
G::SolidBrush* createBrush(const GiContext* ctx) { G::SolidBrush* pBrush = NULL; if (ctx == NULL) ctx = &m_context; m_brushNull = !ctx->hasFillColor(); if (!m_brushNull) { if (m_brush == NULL || m_context.getFillColor() != ctx->getFillColor() || m_context.getFillAlpha() != ctx->getFillAlpha()) { m_context.setFillColor(ctx->getFillColor()); m_context.setFillAlpha(ctx->getFillAlpha()); if (m_brush != NULL) { delete m_brush; m_brush = NULL; } GiColor color = gs()->calcPenColor(ctx->getFillColor()); m_brush = new G::SolidBrush( G::Color(ctx->getFillAlpha(), color.r, color.g, color.b)); } pBrush = m_brush; } return pBrush; }
bool MgDot::_draw(int mode, GiGraphics& gs, const GiContext& ctx, int segment) const { GiContext ctx2(0, GiColor::Invalid(), GiContext::kNullLine, ctx.hasFillColor() ? ctx.getFillColor() : ctx.getLineColor()); float w = gs.calcPenWidth(ctx.getLineWidth(), false); bool ret = gs.drawCircle(&ctx2, _point, gs.xf().displayToModel(w)); return __super::_draw(mode, gs, ctx, segment) || ret; }
bool GiGraphics::drawPathWithArrayHead(const GiContext& ctx, MgPath& path, int startArray, int endArray) { float px = calcPenWidth(ctx.getLineWidth(), ctx.isAutoScale()); float scale = 0.5f * xf().getWorldToDisplayX() * (1 + mgMax(0.f, (px - 4.f) / 5)); if (startArray > 0 && startArray <= GiContext::kArrowOpenedCircle) { drawArrayHead(ctx, path, startArray, px, scale); } if (endArray > 0 && endArray <= GiContext::kArrowOpenedCircle) { path.reverse(); drawArrayHead(ctx, path, endArray, px, scale); path.reverse(); } return drawPath_(&ctx, path, false, Matrix2d::kIdentity()); }
bool MgGroup::_draw(int mode, GiGraphics& gs, const GiContext& ctx, int segment) const { MgShape* sp = _shapes->findShape(segment); if (sp) { return sp->draw(mode, gs, ctx.isNullLine() ? NULL : &ctx, -1); } return __super::_draw(mode, gs, ctx, segment); }
bool MgComposite::_draw(int mode, GiGraphics& gs, const GiContext& ctx, int) const { MgShapeIterator it(_shapes); int n = 0; while (MgShape* sp = it.getNext()) { n += sp->draw(mode, gs, ctx.isNullLine() ? NULL : &ctx, -1) ? 1 : 0; } return n > 0; }
bool GiGraphics::_drawPolygon(const GiContext* ctx, int count, const Point2d* points, bool m2d, bool fill, bool edge, bool modelUnit) { GiContext context (ctx ? *ctx : m_impl->ctx); if (!edge) context.setNullLine(); if (!fill) context.setNoFillColor(); if (context.isNullLine() && !context.hasFillColor()) return false; vector<Point2d> pxpoints; Point2d pt1, pt2; Matrix2d matD(S2D(xf(), modelUnit)); pxpoints.resize(count); Point2d *pxs = &pxpoints.front(); int n = 0; for (int i = 0; i < count; i++) { pt2 = points[i]; if (m2d) pt2 *= matD; if (i == 0 || count <= 4 || fabsf(pt1.x - pt2.x) > 2 || fabsf(pt1.y - pt2.y) > 2) { pt1 = pt2; pxs[n++] = pt1; } } if (n == 4 && m2d && mgEquals(pxs[0].x, pxs[3].x) && mgEquals(pxs[1].x, pxs[2].x) && mgEquals(pxs[0].y, pxs[1].y) && mgEquals(pxs[2].y, pxs[3].y)) { Box2d rc(pxs[0].x, pxs[0].y, pxs[2].x, pxs[2].y, true); return rawRect(&context, rc.xmin, rc.ymin, rc.width(), rc.height()); } return rawPolygon(&context, pxs, n); }
static bool _DrawPolygon(GiCanvas* cv, const GiContext* ctx, int count, const Point2d* points, bool bM2D, bool bFill, bool bEdge, bool modelUnit) { if (!ctx && cv) ctx = cv->getCurrentContext(); if (!ctx || !cv) return false; GiContext context (*ctx); if (!bEdge) context.setNullLine(); if (!bFill) context.setNoFillColor(); if (context.isNullLine() && !context.hasFillColor()) return false; vector<Point2d> pxpoints; Point2d pt1, pt2; Matrix2d matD(S2D(cv->owner()->xf(), modelUnit)); pxpoints.resize(count); Point2d *pxs = &pxpoints.front(); int n = 0; for (int i = 0; i < count; i++) { pt2 = points[i]; if (bM2D) pt2 *= matD; if (i == 0 || fabs(pt1.x - pt2.x) > 2 || fabs(pt1.y - pt2.y) > 2) { pt1 = pt2; pxs[n++] = pt1; } } return cv->rawPolygon(&context, pxs, n); }
bool MgComposite::_draw(int mode, GiGraphics& gs, const GiContext& ctx, int) const { void* it; int n = 0; for (MgShape* sp = _shapes->getFirstShape(it); sp; sp = _shapes->getNextShape(it)) { n += sp->draw(mode, gs, ctx.isNullLine() ? NULL : &ctx, -1) ? 1 : 0; } _shapes->freeIterator(it); return n > 0; }
G::Pen* createPen(const GiContext* ctx, bool* pNotSmoothing = NULL) { G::Pen* pPen = NULL; if (ctx == NULL) ctx = &m_context; m_penNull = ctx->isNullLine(); if (!m_penNull) { if (m_pen == NULL || m_context.getLineStyle() != ctx->getLineStyle() || m_context.getLineWidth() != ctx->getLineWidth() || m_context.getLineColor() != ctx->getLineColor() || m_context.getLineAlpha() != ctx->getLineAlpha()) { m_context.setLineStyle(ctx->getLineStyle()); m_context.setLineWidth(ctx->getLineWidth()); m_context.setLineColor(ctx->getLineColor()); m_context.setLineAlpha(ctx->getLineAlpha()); if (m_pen != NULL) { delete m_pen; m_pen = NULL; } float width = gs()->calcPenWidth(ctx->getLineWidth()); GiColor color = gs()->calcPenColor(ctx->getLineColor()); m_pen = new G::Pen(G::Color(ctx->getLineAlpha(), color.r, color.g, color.b), width); if (m_pen != NULL) { m_pen->SetDashStyle((G::DashStyle)ctx->getLineStyle()); if (pNotSmoothing != NULL) { *pNotSmoothing = (width <= 1 && ctx->getLineStyle() != kGiLineSolid); } } } pPen = m_pen; } return pPen; }
float GiGraphics::drawTextAt(GiTextWidthCallback* c, int argb, const char* text, const Point2d& pnt, float h, int align, float angle) { float ret = 0; if (m_impl->canvas && text && h > 0 && !m_impl->stopping && !pnt.isDegenerate()) { Point2d ptd(pnt * xf().modelToDisplay()); float w2d = xf().getWorldToDisplayY(h < 0); h = fabsf(h) * w2d; if (!mgIsZero(angle)) { angle = (Vector2d::angledVector(angle, 1) * xf().modelToWorld()).angle2(); } GiContext ctx; ctx.setFillARGB(argb ? argb : 0xFF000000); if (setBrush(&ctx)) { TextWidthCallback1 *cw = c ? new TextWidthCallback1(c, w2d) : (TextWidthCallback1 *)0; ret = m_impl->canvas->drawTextAt(cw, text, ptd.x, ptd.y, h, align, angle) / w2d; } } return ret; }
HGDIOBJ createPen(const GiContext* ctx, bool rectJoin = false) { if (ctx == NULL) ctx = &m_context; if (m_pen == NULL || m_context.getLineStyle() != ctx->getLineStyle() || m_context.getLineWidth() != ctx->getLineWidth() || m_context.getLineColor() != ctx->getLineColor() || m_context.getLineAlpha() != ctx->getLineAlpha()) { m_context.setLineStyle(ctx->getLineStyle()); m_context.setLineWidth(ctx->getLineWidth(), ctx->isAutoScale()); m_context.setLineColor(ctx->getLineColor()); m_context.setLineAlpha(ctx->getLineAlpha()); if (m_pen != NULL) ::DeleteObject(m_pen); if (ctx->isNullLine() || ctx->getLineAlpha() < 127) m_pen = ::GetStockObject(NULL_PEN); else { int width = mgRound(m_this->gs()->calcPenWidth( ctx->getLineWidth(), ctx->isAutoScale())); GiColor color = m_this->gs()->calcPenColor(ctx->getLineColor()); COLORREF cr = RGB(color.r, color.g, color.b); int lineStyle = ctx->getLineStyle(); if (width > 1) { LOGBRUSH logBrush = { BS_SOLID, cr }; m_pen = ::ExtCreatePen( (rectJoin ? PS_JOIN_MITER : 0) | PS_GEOMETRIC | PS_ENDCAP_FLAT | lineStyle, width, &logBrush, 0, NULL); } else { m_pen = ::CreatePen(lineStyle, width, cr); } } } return m_pen; }
bool MgGrid::_draw(int mode, GiGraphics& gs, const GiContext& ctx) const { Vector2d cell(m_cell / 2); if (cell.x < _MGZERO || cell.y < _MGZERO) { GiContext ctxedge(ctx); ctxedge.setNoFillColor(); gs.drawRect(&ctxedge, getRect()); return __super::_draw(mode, gs, ctx); } int nx = (int)(getWidth() / cell.x + _MGZERO); int ny = (int)(getHeight() / cell.y + _MGZERO); Box2d rect(getPoint(3), getPoint(3) + Vector2d((float)(cell.x * nx), (float)(cell.y * ny))); float w = gs.calcPenWidth(ctx.getLineWidth(), ctx.isAutoScale()) / -2.f; GiContext ctxgrid(w, ctx.getLineColor()); bool antiAlias = gs.setAntiAliasMode(false); int ret = gs.drawRect(&ctxgrid, rect) ? 1 : 0; bool switchx = (nx >= 10 && cell.x < gs.xf().displayToModel(20, true)); bool switchy = (ny >= 10 && cell.y < gs.xf().displayToModel(20, true)); Point2d pts[2] = { rect.leftTop(), rect.leftBottom() }; for (int i = 1; i < nx; i++) { pts[0].x += cell.x; pts[1].x += cell.x; ctxgrid.setLineWidth(!switchx || i%5 > 0 ? w/2 : w, false); ctxgrid.setLineAlpha(-w < 0.9f && (!switchx || i%5 > 0) ? ctx.getLineAlpha() / 2 : ctx.getLineAlpha()); ret += gs.drawLine(&ctxgrid, pts[0], pts[1]) ? 1 : 0; } pts[0] = rect.leftBottom(); pts[1] = rect.rightBottom(); for (int j = 1; j < ny; j++) { pts[0].y += cell.y; pts[1].y += cell.y; ctxgrid.setLineWidth(!switchy || j%5 > 0 ? w/2 : w, false); ctxgrid.setLineAlpha(-w < 0.9f && (!switchy || j%5 > 0) ? ctx.getLineAlpha() / 2 : ctx.getLineAlpha()); ret += gs.drawLine(&ctxgrid, pts[0], pts[1]) ? 1 : 0; } gs.setAntiAliasMode(antiAlias); return __super::_draw(mode, gs, ctx) || ret > 0; }
bool setPen(const GiContext* ctx) { bool changed = !_ctxused[0]; if (ctx && !ctx->isNullLine()) { if (_gictx.getLineColor() != ctx->getLineColor()) { _gictx.setLineColor(ctx->getLineColor()); changed = true; } if (_gictx.getLineWidth() != ctx->getLineWidth()) { _gictx.setLineWidth(ctx->getLineWidth(), ctx->isAutoScale()); changed = true; } if (_gictx.getLineStyle() != ctx->getLineStyle()) { _gictx.setLineStyle(ctx->getLineStyle()); changed = true; } } if (!ctx) ctx = &_gictx; if (!ctx->isNullLine() && changed) { _ctxused[0] = true; GiColor color = ctx->getLineColor(); if (gs()) color = gs()->calcPenColor(color); CGContextSetRGBStrokeColor(getContext(), toFloat(color.r), toFloat(color.g), toFloat(color.b), toFloat(color.a)); float w = ctx->getLineWidth(); w = gs() ? gs()->calcPenWidth(w, ctx->isAutoScale()) : (w < 0 ? -w : 1); CGContextSetLineWidth(getContext(), _fast && w > 1 ? w - 1 : w); // 不是反走样就细一点 int style = ctx->getLineStyle(); CGFloat pattern[6]; if (style >= 0 && style < sizeof(lpats)/sizeof(lpats[0])) { if (lpats[style].arr && !_fast) { // 快速画时不要线型 makeLinePattern(pattern, lpats[style].arr, lpats[style].n, w); CGContextSetLineDash(getContext(), 0, pattern, lpats[style].n); } else { CGContextSetLineDash(getContext(), 0, NULL, 0); } CGContextSetLineCap(getContext(), style > 0 ? kCGLineCapButt : kCGLineCapRound); } } return !ctx->isNullLine(); }
bool MgShape::load(MgShapeFactory* factory, MgStorage* s) { setTag(s->readInt("tag", getTag())); GiContext ctx; ctx.setLineStyle(s->readInt("lineStyle", 0)); ctx.setLineWidth(s->readFloat("lineWidth", 0), true); ctx.setLineColor(GiColor(s->readInt("lineColor", 0xFF000000), true)); ctx.setFillColor(GiColor(s->readInt("fillColor", 0), true)); ctx.setStartArrayHead(s->readInt("startArrayHead", 0)); ctx.setEndArrayHead(s->readInt("endArrayHead", 0)); setContext(ctx); bool ret = shape()->load(factory, s); if (ret) { shape()->update(); } return ret; }