コード例 #1
0
ファイル: mgpath.cpp プロジェクト: Vito2015/vgcore
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
ファイル: gigraph.cpp プロジェクト: Vito2015/vgcore
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
ファイル: mgpath.cpp プロジェクト: Vito2015/vgcore
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();
}
コード例 #4
0
ファイル: mgpath.cpp プロジェクト: Vito2015/vgcore
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;
}