예제 #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
bool GiCanvasGdi::drawImage(long hmWidth, long hmHeight, HBITMAP hbitmap, 
                            const Box2d& rectW, bool fast)
{
    BOOL ret = FALSE;
    HDC hdc = m_draw->getDrawDC();

    if (hdc != NULL && hmWidth > 0 && hmHeight > 0 && hbitmap != NULL
        && m_owner->getClipWorld().isIntersect(Box2d(rectW, true)))
    {
        RECT_2D clipBox;
        RECT rc, rcDraw, rcFrom;

        // rc: 整个图像对应的显示坐标区域
        (rectW * xf().worldToDisplay()).get(rc);

        // rcDraw: 图像经剪裁后的可显示部分
        Box2d(gs()->getClipBox(clipBox)).get(rcFrom);
        if (!IntersectRect(&rcDraw, &rc, &rcFrom))
            return false;

        long width, height;       // pixel units
        width = MulDiv(hmWidth, GetDeviceCaps(hdc, LOGPIXELSX), 2540);
        height = MulDiv(hmHeight, GetDeviceCaps(hdc, LOGPIXELSY), 2540);

        // rcFrom: rcDraw在原始图像上对应的图像范围
        rcFrom.left = MulDiv(rcDraw.left - rc.left, width, rc.right - rc.left);
        rcFrom.top = MulDiv(rcDraw.top - rc.top, height, rc.bottom - rc.top);
        rcFrom.right = MulDiv(rcDraw.right - rc.left, width, rc.right - rc.left);
        rcFrom.bottom = MulDiv(rcDraw.bottom - rc.top, height, rc.bottom - rc.top);

        // 根据rectW正负决定是否颠倒显示图像
        if (rectW.xmin > rectW.xmax)
            mgSwap(rcDraw.left, rcDraw.right);
        if (rectW.ymin > rectW.ymax)
            mgSwap(rcDraw.top, rcDraw.bottom);

        GiCompatibleDC memDC (hdc);
        if (memDC == NULL)
            return false;
        KGDIObject bmp (memDC, hbitmap, false);
        KGDIObject brush (hdc, ::GetStockObject(NULL_BRUSH), false);

        int nBltMode = (!fast || m_owner->isPrint()) ? HALFTONE : COLORONCOLOR;
        int nOldMode = ::SetStretchBltMode(hdc, nBltMode);
        ::SetBrushOrgEx(hdc, rcDraw.left % 8, rcDraw.top % 8, NULL);
        ret = ::StretchBlt(hdc, 
            rcDraw.left, rcDraw.top, 
            rcDraw.right - rcDraw.left, 
            rcDraw.bottom - rcDraw.top, 
            memDC, 
            rcFrom.left, rcFrom.top, 
            rcFrom.right - rcFrom.left, 
            rcFrom.bottom - rcFrom.top, 
            SRCCOPY);
        ::SetStretchBltMode(hdc, nOldMode);
    }

    return ret ? true : false;
}
예제 #3
0
bool GiCanvasGdipImpl::drawImage(G::Bitmap* pBmp, const Box2d& rectW, bool fast)
{
    RECT_2D rc, rcDraw, rcFrom;
    Box2d rect;
    float width = (float)pBmp->GetWidth();
    float height = (float)pBmp->GetHeight();

    // rc: 整个图像对应的显示坐标区域
    (rectW * gs()->xf().worldToDisplay()).get(rc);

    // rcDraw: 图像经剪裁后的可显示部分
    gs()->getClipBox(rcDraw);
    if (rect.intersectWith(Box2d(rc), Box2d(rcDraw)).isEmpty())
        return false;
    rect.get(rcDraw);

    // rcFrom: rcDraw在原始图像上对应的图像范围
    rcFrom.left = (rcDraw.left - rc.left) * width / (rc.right - rc.left);
    rcFrom.top  = (rcDraw.top - rc.top) * height / (rc.bottom - rc.top);
    rcFrom.right = (rcDraw.right - rc.left) * width / (rc.right - rc.left);
    rcFrom.bottom = (rcDraw.bottom - rc.top) * height / (rc.bottom - rc.top);

    // 根据rectW正负决定是否颠倒显示图像
    if (rectW.xmin > rectW.xmax)
        mgSwap(rcDraw.left, rcDraw.right);
    if (rectW.ymin > rectW.ymax)
        mgSwap(rcDraw.top, rcDraw.bottom);

    G::InterpolationMode nOldMode = getDrawGs()->GetInterpolationMode();
    getDrawGs()->SetInterpolationMode( (!fast || gs()->isPrint())
        ? G::InterpolationModeBilinear : G::InterpolationModeLowQuality);

    G::Status ret = getDrawGs()->DrawImage(pBmp, 
        G::RectF(rcDraw.left, rcDraw.top, 
        rcDraw.right - rcDraw.left, 
        rcDraw.bottom - rcDraw.top), 
        rcFrom.left, rcFrom.top, 
        rcFrom.right - rcFrom.left, 
        rcFrom.bottom - rcFrom.top, 
        G::UnitPixel);
    getDrawGs()->SetInterpolationMode(nOldMode);

    return G::Ok == ret;
}
예제 #4
0
void GiTransform::setViewScaleRange(float minScale, float maxScale)
{
    if (minScale > maxScale)
        mgSwap(minScale, maxScale);

    minScale = mgMax(minScale, 1e-5f);
    minScale = mgMin(minScale, 0.5f);

    maxScale = mgMax(maxScale, 1.f);
    maxScale = mgMin(maxScale, 50.f);

    m_impl->minViewScale = minScale;
    m_impl->maxViewScale = maxScale;
}
예제 #5
0
int mgcurv::arcToBezier(
    Point2d points[16], const Point2d& center, float rx, float ry,
    float startAngle, float sweepAngle)
{
    if (mgIsZero(rx) || fabsf(sweepAngle) < 1e-5)
        return 0;
    if (mgIsZero(ry))
        ry = rx;
    if (sweepAngle > _M_2PI)
        sweepAngle = _M_2PI;
    else if (sweepAngle < -_M_2PI)
        sweepAngle = -_M_2PI;
    
    int n = 0;
    
    if (fabsf(sweepAngle) < _M_PI_2 + 1e-5)
    {
        _arcToBezier(points, center, rx, ry, startAngle, sweepAngle);
        n = 4;
    }
    else if (sweepAngle > 0)
    {
        startAngle = mgbase::to0_2PI(startAngle);
        n = _arcToBezierPlusSweep(
            points, center, rx, ry, startAngle, sweepAngle);
    }
    else // sweepAngle < 0
    {
        float endAngle = startAngle + sweepAngle;
        sweepAngle = -sweepAngle;
        startAngle = mgbase::to0_2PI(endAngle);
        n = _arcToBezierPlusSweep(
            points, center, rx, ry, startAngle, sweepAngle);

        for (int i = 0; i < n / 2; i++)
            mgSwap(points[i], points[n - 1 - i]);
    }
    
    return n;
}
예제 #6
0
bool MgArc::_reverse()
{
    mgSwap(_points[1], _points[2]);
    return true;
}