示例#1
0
MgPath& MgPath::reverse()
{
    if (getSubPathCount() > 1) {
        MgPath subpath;
        std::list<MgPath> paths;
        
        for (size_t i = 0; i < m_data->types.size(); i++) {
            if (m_data->types[i] == kMgMoveTo && subpath.getCount() > 0) {
                paths.push_back(subpath);
                subpath.clear();
            }
            subpath.m_data->types.push_back(m_data->types[i]);
            subpath.m_data->points.push_back(m_data->points[i]);
        }
        if (subpath.getCount() > 0) {
            paths.push_back(subpath);
        }
        
        clear();
        for (std::list<MgPath>::reverse_iterator it = paths.rbegin(); it != paths.rend(); ++it) {
            append(it->reverse());
        }
    } else {
        for (int i = 0, j = getCount() - 1; i < j; i++, j--) {
            if (i > 0) {
                mgSwap(m_data->types[i], m_data->types[j]);
            }
            mgSwap(m_data->points[i], m_data->points[j]);
        }
    }
    
    return *this;
}
示例#2
0
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);
}
示例#3
0
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());
}
示例#4
0
bool GiGraphics::drawPath(const GiContext* ctx, const MgPath& path, bool fill, bool modelUnit)
{
    if (ctx && ctx->hasArrayHead() && path.getSubPathCount() == 1 && !path.isClosed()) {
        MgPath pathw(path);
        GiContext ctx2(*ctx);
        
        pathw.transform(S2D(xf(), modelUnit));
        
        ctx2.setNoFillColor();
        ctx2.setStartArrayHead(0);
        ctx2.setEndArrayHead(0);
        
        return drawPathWithArrayHead(ctx2, pathw, ctx->getStartArrayHead(), ctx->getEndArrayHead());
    }
    
    return drawPath_(ctx, path, fill, S2D(xf(), modelUnit));
}
示例#5
0
void GiGraphics::drawArrayHead(const GiContext& ctx, MgPath& path, int type, float px, float scale)
{
    float xoffset = _arrayHeads[type - 1].xoffset * scale;
    Point2d startpt(path.getStartPoint());
    path.trimStart(startpt, xoffset + px / 2);
    
    Matrix2d mat(Matrix2d::translation(startpt.asVector()));
    Vector2d vec(mgIsZero(xoffset) ? path.getStartTangent() : path.getStartPoint() - startpt);
    mat *= Matrix2d::rotation(vec.angle2(), startpt);
    mat *= Matrix2d::scaling(scale, startpt);
    
    MgPath headPath(_arrayHeads[type - 1].types);
    headPath.transform(mat);
    
    GiContext ctxhead(ctx);
    if (_arrayHeads[type - 1].fill) {
        ctxhead.setFillColor(ctxhead.getLineColor());
        ctxhead.setNullLine();
    }
    drawPath_(&ctxhead, headPath, ctxhead.hasFillColor(), Matrix2d::kIdentity());
}
示例#6
0
文件: mgarc.cpp 项目: Vito2015/vgcore
void MgArc::_output(MgPath& path) const
{
    float r = getRadius();
    float sweepAngle = getSweepAngle();
    Point2d points[16];
    
    if (r < _MGZERO || fabsf(sweepAngle) < _MGZERO)
        return;
    
    int count = mgcurv::arcToBezier(points, getCenter(), r, r,
                                    getStartAngle(), sweepAngle);
    
    if (_subtype > 0) {
        path.moveTo(getCenter());
        path.lineTo(points[0]);
        path.beziersTo(count - 1, points + 1);
        path.closeFigure();
    } else {
        path.moveTo(points[0]);
        path.beziersTo(count - 1, points + 1);
    }
}
示例#7
0
void MgEllipse::_output(MgPath& path) const
{
    path.moveTo(_bzpts[0]);
    path.beziersTo(12, _bzpts + 1);
    path.closeFigure();
}
示例#8
0
void MgBaseRect::_output(MgPath& path) const
{
    path.moveTo(_points[0]);
    path.linesTo(3, _points + 1);
    path.closeFigure();
}
示例#9
0
bool MgPath::crossWithPath(const MgPath& p, const Box2d& box, Point2d& ptCross) const
{
    MgPathCrossCallback cc(box, ptCross);
    
    if (isLine() && p.isLine()) {
        return (mglnrel::cross2Line(getPoint(0), getPoint(1),
                                    p.getPoint(0), p.getPoint(1), ptCross)
                && box.contains(ptCross));
    }
    if (isLines() && p.isLines()) {
        for (int m = getCount() - (isClosed() ? 0 : 1), i = 0; i < m; i++) {
            Point2d a(getPoint(i)), b(getPoint(i + 1));
            
            for (int n = p.getCount() - (p.isClosed() ? 0 : 1), j = 0; j < n; j++) {
                Point2d c(p.getPoint(j)), d(p.getPoint(j + 1));
                
                if (mglnrel::cross2Line(a, b, c, d, cc.tmpcross)
                    && box.contains(cc.tmpcross)) {
                    float dist = cc.tmpcross.distanceTo(box.center());
                    if (cc.mindist > dist) {
                        cc.mindist = dist;
                        ptCross = cc.tmpcross;
                    }
                }
            }
        }
    }
    else if (isLine() && p.getSubPathCount() == 1) {
        cc.a = getPoint(0);
        cc.b = getPoint(1);
        p.scanSegments(cc);
    }
    else if (p.isLine() && getSubPathCount() == 1) {
        cc.a = p.getPoint(0);
        cc.b = p.getPoint(1);
        scanSegments(cc);
    }
    
    return cc.mindist < box.width();
}
示例#10
0
bool MgPath::scanSegments(MgSegmentCallback& c) const
{
    bool ret = true;
    
    if (getSubPathCount() > 1) {
        MgPath subpath;
        std::list<MgPath> paths;
        
        for (size_t i = 0; i < m_data->types.size(); i++) {
            if (m_data->types[i] == kMgMoveTo && subpath.getCount() > 0) {
                paths.push_back(subpath);
                subpath.clear();
            }
            subpath.m_data->types.push_back(m_data->types[i]);
            subpath.m_data->points.push_back(m_data->points[i]);
        }
        if (subpath.getCount() > 0) {
            paths.push_back(subpath);
        }
        
        for (std::list<MgPath>::reverse_iterator it = paths.rbegin(); ret && it != paths.rend(); ++it) {
            ret = it->scanSegments(c);
        }
    } else {
        Point2d pts[4];
        int i, startIndex = 0, type = 0;
        
        for (i = 0; i < getCount() && ret; startIndex = ++i - 1) {
            type = m_data->types[i] & ~kMgCloseFigure;
            switch (type) {
                case kMgMoveTo:
                    pts[0] = m_data->points[i];
                    c.beginSubPath();
                    break;
                    
                case kMgLineTo:
                    pts[1] = m_data->points[i];
                    ret = c.processLine(startIndex, i, pts[0], pts[1]);
                    pts[0] = pts[1];
                    break;
                    
                case kMgBezierTo:
                    if (i + 2 >= getCount())
                        return false;
                    pts[1] = m_data->points[i++];
                    pts[2] = m_data->points[i++];
                    pts[3] = m_data->points[i];
                    ret = c.processBezier(startIndex, i, pts);
                    pts[0] = pts[3];
                    break;
                    
                case kMgQuadTo:
                    if (i + 1 >= getCount())
                        return false;
                    pts[2] = m_data->points[i++];
                    pts[3] = m_data->points[i];
                    pts[1] = (pts[0] + pts[2] * 2) / 3;
                    pts[2] = (pts[3] + pts[2] * 2) / 3;
                    ret = c.processBezier(startIndex, i, pts);
                    pts[0] = pts[3];
                    break;
                    
                default:
                    return false;
            }
        }
        if (isClosed()) {
            i = 0;
            switch (type) {
                case kMgLineTo:
                    ret = c.processLine(startIndex, i, pts[0], m_data->points[0]);
                    break;
                    
                case kMgBezierTo:
                    pts[1] = 2 * pts[0] + (- m_data->points[getCount() - 2]);
                    pts[3] = m_data->points[0];
                    pts[2] = 2 * pts[3] + (- m_data->points[1]);
                    ret = c.processBezier(startIndex, i, pts);
                    break;
                    
                case kMgQuadTo:
                    pts[3] = m_data->points[0];
                    pts[2] = 2 * pts[3] + (- m_data->points[1]);
                    pts[1] = (pts[0] + pts[2] * 2) / 3;
                    pts[2] = (pts[3] + pts[2] * 2) / 3;
                    ret = c.processBezier(startIndex, i, pts);
                    break;
                    
                default:
                    break;
            }
        }
        c.endSubPath(isClosed());
    }
    
    return ret;
}