Example #1
0
bool GiGraphics::drawRoundRect(const GiContext* ctx, 
                               const Box2d& rect, float rx, float ry, 
                               bool modelUnit)
{
    if (m_impl->drawRefcnt == 0 || rect.isEmpty())
        return false;
    GiLock lock (&m_impl->drawRefcnt);
    bool ret = false;

    if (ry < _MGZERO)
        ry = rx;

    if (!DRAW_RECT(m_impl, modelUnit).isIntersect(rect))  // 全部在显示区域外
        return false;

    if (rx < _MGZERO)
    {
        Point2d points[4] = {
            rect.leftBottom(), rect.rightBottom(), 
            rect.rightTop(), rect.leftTop()
        };
        return drawPolygon(ctx, 4, points);
    }
    else
    {
        Point2d points[16];

        mgRoundRectToBeziers(points, rect, rx, ry);
        S2D(xf(), modelUnit).TransformPoints(16, points);

        ret = rawBeginPath();
        if (ret)
        {
            ret = rawMoveTo(points[0].x, points[0].y);
            ret = rawBezierTo(&points[1], 3);

            ret = rawLineTo(points[4].x, points[4].y);
            ret = rawBezierTo(&points[5], 3);

            ret = rawLineTo(points[8].x, points[8].y);
            ret = rawBezierTo(&points[9], 3);

            ret = rawLineTo(points[12].x, points[12].y);
            ret = rawBezierTo(&points[13], 3);

            ret = rawClosePath();
            ret = rawEndPath(ctx, true);
        }
    }

    return ret;
}
Example #2
0
bool GiGraphics::drawRoundRect(const GiContext* ctx, 
                               const Box2d& rect, float rx, float ry, 
                               bool modelUnit)
{
    if (rect.isEmpty() || isStopping())
        return false;
    bool ret = false;

    if (ry < _MGZERO)
        ry = rx;

    if (!DRAW_RECT(m_impl, modelUnit).isIntersect(rect))  // 全部在显示区域外
        return false;

    if (rx < _MGZERO) {
        Point2d points[4] = {
            rect.leftBottom(), rect.rightBottom(), 
            rect.rightTop(), rect.leftTop()
        };
        return drawPolygon(ctx, 4, points);
    } else {
        Point2d pxs[16];

        mgcurv::roundRectToBeziers(pxs, rect, rx, ry);
        S2D(xf(), modelUnit).transformPoints(16, pxs);

        ret = rawBeginPath();
        if (ret) {
            rawMoveTo(pxs[0].x, pxs[0].y);
            rawBezierTo(pxs[1].x, pxs[1].y, pxs[2].x, pxs[2].y, pxs[3].x, pxs[3].y);

            rawLineTo(pxs[4].x, pxs[4].y);
            rawBezierTo(pxs[5].x, pxs[5].y, pxs[6].x, pxs[6].y, pxs[7].x, pxs[7].y);

            rawLineTo(pxs[8].x, pxs[8].y);
            rawBezierTo(pxs[9].x, pxs[9].y, pxs[10].x, pxs[10].y, pxs[11].x, pxs[11].y);

            rawLineTo(pxs[12].x, pxs[12].y);
            rawBezierTo(pxs[13].x, pxs[13].y, pxs[14].x, pxs[14].y, pxs[15].x, pxs[15].y);

            rawClosePath();
            ret = rawEndPath(ctx, true);
        }
    }

    return ret;
}
Example #3
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);
}
Example #4
0
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);
}
Example #5
0
bool GiGraphics::drawPath(const GiContext* ctx, const GiPath& path, 
                          bool fill, bool modelUnit)
{
    int n = path.getCount();
    if (n == 0)
        return false;

    Matrix2d matD(S2D(xf(), modelUnit));
    const Point2d* pts = path.getPoints();
    const char* types = path.getTypes();
    Point2d a, b, c;

    rawBeginPath();

    for (int i = 0; i < n; i++) {
        switch (types[i] & ~kGiCloseFigure) {
        case kGiMoveTo:
            a = pts[i] * matD;
            rawMoveTo(a.x, a.y);
            break;

        case kGiLineTo:
            a = pts[i] * matD;
            rawLineTo(a.x, a.y);
            break;

        case kGiBeziersTo:
            if (i + 2 >= n)
                return false;
            a = pts[i] * matD;
            b = pts[i+1] * matD;
            c = pts[i+2] * matD;
            rawBezierTo(a.x, a.y, b.x, b.y, c.x, c.y);
            i += 2;
            break;

        default:
            return false;
        }
        if (types[i] & kGiCloseFigure)
            rawClosePath();
    }

    return rawEndPath(ctx, fill);
}
Example #6
0
bool GiGraphics::drawPie(const GiContext* ctx, 
                         const Point2d& center, float rx, float ry, 
                         float startAngle, float sweepAngle, 
                         bool modelUnit)
{
    if (m_impl->drawRefcnt == 0 || rx < _MGZERO || fabsf(sweepAngle) < 1e-5f)
        return false;
    GiLock lock (&m_impl->drawRefcnt);

    if (ry < _MGZERO)
        ry = rx;

    const Box2d extent (center, rx*2.f, ry*2.f);            // 模型坐标范围
    if (!DRAW_RECT(m_impl, modelUnit).isIntersect(extent))  // 全部在显示区域外
        return false;

    Point2d pxs[16];
    int count = mgcurv::arcToBezier(pxs, center,
        rx, ry, startAngle, sweepAngle);
    if (count < 4)
        return false;
    S2D(xf(), modelUnit).TransformPoints(count, pxs);
    Point2d cen(center * S2D(xf(), modelUnit));

    bool ret = rawBeginPath();
    if (ret)
    {
        rawMoveTo(cen.x, cen.y);
        rawLineTo(pxs[0].x, pxs[0].y);
        for (int i = 1; i + 2 < count; i += 3) {
            rawBezierTo(pxs[i].x, pxs[i].y,
                pxs[i+1].x, pxs[i+1].y, pxs[i+2].x, pxs[i+2].y);
        }
        rawClosePath();
        ret = rawEndPath(ctx, true);
    }

    return ret;
}