Example #1
0
float mgnear::quadSplinesHit(int n, const Point2d* knots, bool closed,
                             const Point2d& pt, float tol, Point2d& nearpt, int& segment)
{
    Point2d ptTemp;
    float dist, distMin = _FLT_MAX;
    Point2d pts[3 + 4];
    const Box2d rect (pt, 2 * tol, 2 * tol);
    
    segment = -1;
    for (int i = 0; i < (closed ? n : n - 2); i++, pts[0] = pts[2]) {
        if (i == 0) {
            pts[0] = closed ? (knots[0] + knots[1]) / 2 : knots[0];
        }
        pts[1] = knots[(i+1) % n];
        if (closed || i + 3 < n)
            pts[2] = (knots[(i+1) % n] + knots[(i+2) % n]) / 2;
        else
            pts[2] = knots[i+2];
        
        mgcurv::quadBezierToCubic(pts, pts + 3);
        if (rect.isIntersect(computeCubicBox(pts + 3))) {
            dist = mgnear::nearestOnBezier(pt, pts + 3, ptTemp);
            if (dist < distMin) {
                distMin = dist;
                nearpt = ptTemp;
                segment = i;
            }
        }
    }
    
    return distMin;
}
Example #2
0
void NormalFilter::render(const ITextureObject& texture, const ICamera<float>& renderedCamera)
{
	const Box2d<float> box(Vector2d<float>(-1.0, -1.0), Vector2d<float>(1.0, 1.0));
	const auto& positions = box.toArray();

	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


	glEnable(GL_DEPTH_TEST);
	//glDisable(GL_DEPTH_TEST);

	glUseProgram(shader.getId());

	texture.bind();
	
	//glGetUniformLocation( texture.getId()
	glUniform1i(shader.getUniformLocation("depthTex"), texture.getId());
	glUniform1f(shader.getUniformLocation("texelSizeW"), 1.0f / static_cast<float>(texture.getWidth()));
	glUniform1f(shader.getUniformLocation("texelSizeH"), 1.0f / static_cast<float>(texture.getHeight()));

	glUniformMatrix4fv(shader.getUniformLocation("projectionMatrix"), 1, GL_FALSE, renderedCamera.getProjectionMatrix().toArray().data());
	glVertexAttribPointer(shader.getAttribLocation("positions"), 2, GL_FLOAT, GL_FALSE, 0, positions.data());

	glEnableVertexAttribArray(0);
	glDrawArrays(GL_QUADS, 0, static_cast<GLsizei>( positions.size() / 2) );
	glDisableVertexAttribArray(0);

	glBindFragDataLocation(shader.getId(), 0, "fragColor");

	texture.unbind();
	glDisable(GL_DEPTH_TEST);

	glUseProgram(0);
}
Example #3
0
bool GiGraphics::setClipBox(const RECT_2D& rc)
{
    if (m_impl->drawRefcnt < 1)
        return false;

    bool ret = false;
    Box2d rect;

    if (!rect.intersectWith(Box2d(rc), Box2d(m_impl->clipBox0)).isEmpty())
    {
        if (rect != Box2d(m_impl->clipBox))
        {
            rect.get(m_impl->clipBox);
            m_impl->rectDraw.set(Box2d(rc));
            m_impl->rectDraw.inflate(GiGraphicsImpl::CLIP_INFLATE);
            m_impl->rectDrawM = m_impl->rectDraw * xf().displayToModel();
            m_impl->rectDrawW = m_impl->rectDrawM * xf().modelToWorld();
            SafeCall(m_impl->canvas, clipRect(m_impl->clipBox.left, m_impl->clipBox.top,
                                              m_impl->clipBox.width(),
                                              m_impl->clipBox.height()));
        }
        ret = true;
    }

    return ret;
}
Example #4
0
float mgnear::cubicSplinesHit(
    int n, const Point2d* knots, const Vector2d* knotvs, bool closed, 
    const Point2d& pt, float tol, Point2d& nearpt, int& segment, bool hermite)
{
    Point2d ptTemp;
    float dist, distMin = _FLT_MAX;
    Point2d pts[4];
    const Box2d rect (pt, 2 * tol, 2 * tol);
    int n2 = (closed && n > 1) ? n + 1 : n;

    segment = -1;
    for (int i = 0; i + 1 < n2; i++) {
        mgcurv::cubicSplineToBezier(n, knots, knotvs, i, pts, hermite);
        if (rect.isIntersect(computeCubicBox(pts))) {
            dist = mgnear::nearestOnBezier(pt, pts, ptTemp);
            if (dist < distMin) {
                distMin = dist;
                nearpt = ptTemp;
                segment = i;
            }
        }
    }

    return distMin;
}
Example #5
0
bool GiGraphics::setClipWorld(const Box2d& rectWorld)
{
    bool ret = false;

    if (isDrawing() && !rectWorld.isEmpty())
    {
        Box2d box (rectWorld * xf().worldToDisplay());

        box.intersectWith(Box2d(m_impl->clipBox0));
        if (!box.isEmpty(Tol(1, 0)))
        {
            if (box != Box2d(m_impl->clipBox))
            {
                box.get(m_impl->clipBox);
                m_impl->rectDraw = box;
                m_impl->rectDraw.inflate(GiGraphicsImpl::CLIP_INFLATE);
                m_impl->rectDrawM = m_impl->rectDraw * xf().displayToModel();
                m_impl->rectDrawW = m_impl->rectDrawM * xf().modelToWorld();
                SafeCall(m_impl->canvas, _clipBoxChanged(m_impl->clipBox));
            }

            ret = true;
        }
    }

    return ret;
}
Example #6
0
float MgEllipse::_hitTest(const Point2d& pt, float tol, MgHitResult& res) const
{
    if (isCircle()) {
        Point2d pt1(getCenter()), pt2(pt);
        crossCircle(pt1, pt2, this);
        float d1 = pt.distanceTo(pt1);
        float d2 = pt.distanceTo(pt2);
        res.nearpt = d1 < d2 ? pt1 : pt2;
        return mgMin(d1, d2);
    }
    
    float distMin = _FLT_MAX;
    const Box2d rect (pt, 2 * tol, 2 * tol);
    Point2d ptTemp;

    for (int i = 0; i < 4; i++) {
        if (rect.isIntersect(Box2d(4, _bzpts + 3 * i))) {
            mgnear::nearestOnBezier(pt, _bzpts + 3 * i, ptTemp);
            float dist = pt.distanceTo(ptTemp);
            if (dist <= tol && dist < distMin) {
                distMin = dist;
                res.nearpt = ptTemp;
                res.segment = i;
            }
        }
    }

    return distMin;
}
Example #7
0
float MgEllipse::_hitTest(const Point2d& pt, float tol, 
                          Point2d& nearpt, int& segment) const
{
    float distMin = _FLT_MAX;
    const Box2d rect (pt, 2 * tol, 2 * tol);
    Point2d ptTemp;

    segment = -1;
    for (int i = 0; i < 4; i++)
    {
        if (rect.isIntersect(Box2d(4, _bzpts + 3 * i)))
        {
            mgNearestOnBezier(pt, _bzpts + 3 * i, ptTemp);
            float dist = pt.distanceTo(ptTemp);
            if (dist <= tol && dist < distMin)
            {
                distMin = dist;
                nearpt = ptTemp;
                segment = i;
            }
        }
    }

    return distMin;
}
void OnScreenRenderer::render(const ITextureObject& texture)
{
	const Box2d<float> box(Vector2d<float>(-1.0, -1.0), Vector2d<float>(1.0, 1.0));
	const auto& positions = box.toArray();

	//glEnable(GL_DEPTH_TEST);

	glUseProgram(shader.getId());

	texture.bind();

	glUniform1i(shader.getUniformLocation("texture"), texture.getId());

	glVertexAttribPointer(shader.getAttribLocation("positions"), 2, GL_FLOAT, GL_FALSE, 0, positions.data());

	glEnableVertexAttribArray(0);
	glDrawArrays(GL_QUADS, 0,  static_cast<GLsizei>( positions.size() / 2) );
	glDisableVertexAttribArray(0);

	glBindFragDataLocation(shader.getId(), 0, "fragColor");

	texture.unbind();
	//glDisable(GL_DEPTH_TEST);

	glUseProgram(0);
}
Example #9
0
 inline Pt2dr  PQ2(const Box2d<Type> & b,INT c1,INT c2)
 {
       return Pt2dr
              (  
                  b.x(TAB_IND_Q2X[c1][c2]),
                  b.y(TAB_IND_Q2Y[c1][c2])
              );
 }
Example #10
0
bool mglnrel::clipLine(Point2d& pt1, Point2d& pt2, const Box2d& _box)
{
    Box2d box (_box);
    box.normalize();
    
    unsigned code1, code2;
    code1 = ClipCode(pt1, box);
    code2 = ClipCode(pt2, box);
    
    for ( ; ; )
    {
        if (!(code1 | code2))       // 完全在矩形内
            return true;
        if (code1 & code2)          // 完全在矩形外
            return false;
        
        float x = 0.f, y = 0.f;
        unsigned code;
        
        if (code1)                  // 起点不在矩形内
            code = code1;
        else                        // 终点不在矩形内
            code = code2;
        if (code & 0x1000)          // 上
        {
            x = pt1.x + (pt2.x - pt1.x) * (box.ymax - pt1.y) / (pt2.y - pt1.y);
            y = box.ymax;
        }
        else if (code & 0x0100)     // 下
        {
            x = pt1.x + (pt2.x - pt1.x) * (box.ymin - pt1.y) / (pt2.y - pt1.y);
            y = box.ymin;
        }
        else if (code & 0x0001)     // 左
        {
            y = pt1.y + (pt2.y - pt1.y) * (box.xmin - pt1.x) / (pt2.x - pt1.x);
            x = box.xmin;
        }
        else if (code & 0x0010)     // 右
        {
            y = pt1.y + (pt2.y - pt1.y) * (box.xmax - pt1.x) / (pt2.x - pt1.x);
            x = box.xmax;
        }
        
        if (code == code1)
        {
            pt1.x = x;
            pt1.y = y;
            code1 = ClipCode(pt1, box);
        }
        else
        {
            pt2.x = x;
            pt2.y = y;
            code2 = ClipCode(pt2, box);
        }
    }
}
Example #11
0
bool GiGraphics::drawRect(const GiContext* ctx, const Box2d& rect, 
                          bool modelUnit)
{
    Point2d points[4] = {
        rect.leftBottom(), rect.rightBottom(), 
        rect.rightTop(), rect.leftTop()
    };
    return drawPolygon(ctx, 4, points, modelUnit);
}
Example #12
0
void CScrollShapeView::OnZoomed()
{
    CRandomShapeView::OnZoomed();

    Box2d rect;

    // m_rcLimits: 极限范围对应的坐标范围, 像素
    rect = m_shapes->getExtent() * m_graph->xf.modelToDisplay();
    rect.inflate(1, 1);
    rect.get(m_rcLimits);

    // m_rcScrWnd: 当前窗口对应的坐标范围, 像素
    rect = Box2d(m_graph->xf.getCenterW(),
        m_graph->xf.getWidth() / m_graph->xf.getWorldToDisplayX(),
        m_graph->xf.getHeight() / m_graph->xf.getWorldToDisplayY());
    rect *= m_graph->xf.worldToDisplay();
    rect.get(m_rcScrWnd);

    // 以m_rcLimits左上角为原点调整m_rcScrWnd和m_rcLimits
    ::OffsetRect(&m_rcScrWnd, -m_rcLimits.left, -m_rcLimits.top);
    ::OffsetRect(&m_rcLimits, -m_rcLimits.left, -m_rcLimits.top);

    // 避免m_rcScrWnd部分超出m_rcLimits
    ::UnionRect(&m_rcLimits, &m_rcLimits, &m_rcScrWnd);

    SCROLLINFO si;
    si.cbSize = sizeof(si);
    si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
    si.nMin = 0;

    if (m_rcLimits.right - m_rcLimits.left > m_rcScrWnd.right - m_rcScrWnd.left)
    {
        si.nMax = max(1, m_rcLimits.right - m_rcLimits.left);
        si.nPage = m_rcScrWnd.right - m_rcScrWnd.left;
        si.nPos = m_rcScrWnd.left;
        ::EnableScrollBar(m_hWnd, SB_HORZ, ESB_ENABLE_BOTH);
        ::SetScrollInfo(m_hWnd, SB_HORZ, &si, TRUE);
    }
    else
    {
        ::EnableScrollBar(m_hWnd, SB_HORZ, ESB_DISABLE_BOTH);
    }

    if (m_rcLimits.bottom - m_rcLimits.top > m_rcScrWnd.bottom - m_rcScrWnd.top)
    {
        si.nMax = max(1, m_rcLimits.bottom - m_rcLimits.top);
        si.nPage = m_rcScrWnd.bottom - m_rcScrWnd.top;
        si.nPos = m_rcScrWnd.top;
        ::EnableScrollBar(m_hWnd, SB_VERT, ESB_ENABLE_BOTH);
        ::SetScrollInfo(m_hWnd, SB_VERT, &si, TRUE);
    }
    else
    {
        ::EnableScrollBar(m_hWnd, SB_VERT, ESB_DISABLE_BOTH);
    }
}
Example #13
0
Box2d MgShapeDoc::getExtent() const
{
    Box2d rect;

    for (unsigned i = 0; i < im->layers.size(); i++) {
        rect.unionWith(im->layers[i]->getExtent());
    }

    return rect;
}
Example #14
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 #15
0
void MgCmdManagerImpl::getBoundingBox(Box2d& box, const MgMotion* sender)
{
    MgCommand* cmd = sender->cmds()->getCommand();
    Box2d selbox;

    if (cmd && strcmp(cmd->getName(), MgCmdSelect::Name()) == 0) {
        MgCmdSelect* sel = (MgCmdSelect*)cmd;
        selbox = sel->getBoundingBox(sender);
    }

    box = selbox.isEmpty() ? Box2d(sender->pointM, 0, 0) : selbox;
    box *= sender->view->xform()->modelToDisplay();
    box.normalize();
}
Example #16
0
void mgnear::beziersBox(
    Box2d& box, int count, const Point2d* points, bool closed)
{
    box.empty();

    for (int i = 0; i + 3 < count; i += 3) {
        box.unionWith(computeCubicBox(points + i));
    }
    if (closed && count > 3) {
        box.unionWith(computeCubicBox(points[count - 1],
            points[count - 1] * 2 - points[count - 2].asVector(),
            points[0] * 2 - points[1].asVector(), points[0]));
    }
}
Example #17
0
void MgBaseRect::setRect(const Box2d& rect, float angle)
{
    _points[0] = rect.leftTop();
    _points[1] = rect.rightTop();
    _points[2] = rect.rightBottom();
    _points[3] = rect.leftBottom();

    if (!mgIsZero(angle))
    {
        Matrix2d mat(Matrix2d::rotation(angle, rect.center()));
        for (int i = 0; i < 4; i++)
            _points[i] *= mat;
    }
}
Example #18
0
float mgnear::linesHit(
    int n, const Point2d* points, bool closed, 
    const Point2d& pt, float tol, Point2d& nearpt, int& segment,
    bool* inside, int* hitType)
{
    Point2d ptTemp;
    float dist, distMin = _FLT_MAX;
    const Box2d rect (pt, 2 * tol, 2 * tol);
    int n2 = (closed && n > 1) ? n + 1 : n;
    
    int type = mglnrel::ptInArea(pt, n, points, segment, Tol(tol), closed);
    
    if (inside) {
        *inside = (closed && type == mglnrel::kPtInArea);
    }
    if (hitType) {
        *hitType = type;
    }
    if (type == mglnrel::kPtAtVertex) {
        nearpt = points[segment];
        distMin = nearpt.distanceTo(pt);
        return distMin;
    }
    if (type == mglnrel::kPtOnEdge) {
        distMin = mglnrel::ptToLine(points[segment], points[(segment+1)%n], pt, nearpt);
        return distMin;
    }
    if (!closed || type != mglnrel::kPtInArea) {
        return distMin;
    }
    
    for (int i = 0; i + 1 < n2; i++)
    {
        const Point2d& pt2 = points[(i + 1) % n];
        if (closed || rect.isIntersect(Box2d(points[i], pt2)))
        {
            dist = mglnrel::ptToLine(points[i], pt2, pt, ptTemp);
            if (distMin > 1e10f || (dist <= tol && dist < distMin))
            {
                distMin = dist;
                nearpt = ptTemp;
                if (dist <= tol)
                    segment = i;
            }
        }
    }

    return distMin;
}
Example #19
0
    bool showContextActions(int /*selState*/, const int* actions, 
        const Box2d& selbox, const MgShape*)
    {
        int n = 0;
        for (; actions && actions[n] > 0; n++) {}

        if (n > 0 && motion.pressDrag && isContextActionsVisible()) {
            return false;
        }
        mgvector<int> arr(actions, n);
        mgvector<float> pos(2 * n);
        calcContextButtonPosition(pos, n, selbox);
        return CALL_VIEW2(deviceView()->showContextActions(arr, pos,
            selbox.xmin, selbox.ymin, selbox.width(), selbox.height()), false);
    }
Example #20
0
static void _RoundRectHit(
    const Box2d& rect, float rx, float ry, 
    const Point2d& pt, float tol, const Box2d &rectTol, 
    Point2d* pts, float& distMin, 
    Point2d& nearpt, int& segment)
{
    Point2d ptsBezier[13], ptTemp;
    Vector2d vec;
    float dx = rect.width() * 0.5f - rx;
    float dy = rect.height() * 0.5f - ry;
    
    // 按逆时针方向从第一象限到第四象限连接的四段
    mgcurv::ellipseToBezier(ptsBezier, rect.center(), rx, ry);
    
    pts[3] = ptsBezier[0];
    for (int i = 0; i < 4; i++)
    {
        pts[0] = pts[3];
        pts[1] = ptsBezier[3 * i];
        pts[2] = ptsBezier[3 * i + 1];
        pts[3] = ptsBezier[3 * i + 2];
        
        switch (i)
        {
        case 0: vec.set(dx, dy); break;
        case 1: vec.set(-dx, dy); break;
        case 2: vec.set(-dx, -dy); break;
        case 3: vec.set(dx, -dy); break;
        }
        
        for (int j = 0; j < 4; j++)
            pts[j] += vec;
        
        if (rectTol.isIntersect(Box2d(4, pts)))
        {
            mgnear::nearestOnBezier(pt, pts, ptTemp);
            float dist = pt.distanceTo(ptTemp);
            if (dist <= tol && dist < distMin)
            {
                distMin = dist;
                nearpt = ptTemp;
                segment = (5 - i) % 4;
            }
        }
        
        pts[3] -= vec;
    }
}
Example #21
0
Box2d GiTransform::setWorldLimits(const Box2d& rect)
{
    Box2d ret = m_impl->rectLimitsW;
    m_impl->rectLimitsW = rect.isEmpty() ? Box2d(Point2d::kOrigin(), 2e5f, 2e5f) : rect;
    m_impl->rectLimitsW.normalize();
    return ret;
}
Example #22
0
void mgnear::cubicSplinesBox(
    Box2d& box, int n, const Point2d* knots, 
    const Vector2d* knotvs, bool closed, bool hermite)
{
    int n2 = (closed && n > 1) ? n + 1 : n;
    float d = hermite ? 1.f/3.f : 1.f;

    box.empty();
    for (int i = 0; i + 1 < n2; i++)
    {
        box.unionWith(computeCubicBox(knots[i], 
            knots[i] + knotvs[i] * d,
            knots[(i + 1) % n] - knotvs[(i + 1) % n] * d,
            knots[(i + 1) % n]));
    }
}
Example #23
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 #24
0
static void AdjustCenterW(Point2d &ptW, float halfw, float halfh, 
                          const Box2d& rectW)
{
    if (ptW.x - halfw < rectW.xmin)
        ptW.x += rectW.xmin - (ptW.x - halfw);
    if (ptW.x + halfw > rectW.xmax)
        ptW.x += rectW.xmax - (ptW.x + halfw);
    if (2 * halfw >= rectW.width())
        ptW.x = rectW.center().x;

    if (ptW.y - halfh < rectW.ymin)
        ptW.y += rectW.ymin - (ptW.y - halfh);
    if (ptW.y + halfh > rectW.ymax)
        ptW.y += rectW.ymax - (ptW.y + halfh);
    if (2 * halfh >= rectW.height())
        ptW.y = rectW.center().y;
}
Example #25
0
void mgcurv::roundRectToBeziers(
    Point2d points[16], const Box2d& rect, float rx, float ry)
{
    if (2 * rx > rect.width())
        rx = rect.width() / 2;
    if (2 * ry > rect.height())
        ry = rect.height() / 2;

    int i, j;
    float dx = rect.width() / 2 - rx;
    float dy = rect.height() / 2 - ry;

    mgcurv::ellipseToBezier(points, rect.center(), rx, ry);

    for (i = 3; i >= 1; i--)
    {
        for (j = 3; j >= 0; j--)
            points[4 * i + j] = points[3 * i + j];
    }
    for (i = 0; i < 4; i++)
    {
        float dx1 = (0 == i || 3 == i) ? dx : -dx;
        float dy1 = (0 == i || 1 == i) ? dy : -dy;
        for (j = 0; j < 4; j++)
            points[4 * i + j].offset(dx1, dy1);
    }
}
Example #26
0
void SplineGeometry::GetBoundingBox(Box2d& box) const
{
    if (!splines.size()) {
        Point2d auxp{0.0, 0.0};
        box.SetPoint(auxp);
        return;
    }

    std::vector<Point2d> points;
    for (size_t i = 0; i < splines.size(); i++) {
        splines[i]->GetPoints(20, points);

        if (i == 0) box.SetPoint(points[0]);
        for (size_t j = 0; j < points.size(); j++) {
            box.AddPoint(points[j]);
        }
    }
}
Example #27
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;
}
Example #28
0
void mgnear::getRectHandle(const Box2d& rect, int index, Point2d& pt)
{
    switch (index)
    {
    case 0: pt = rect.leftTop(); break;
    case 1: pt = rect.rightTop(); break;
    case 2: pt = rect.rightBottom(); break;
    case 3: pt = rect.leftBottom(); break;
    case 4: pt = Point2d(rect.center().x, rect.ymax); break;
    case 5: pt = Point2d(rect.xmax, rect.center().y); break;
    case 6: pt = Point2d(rect.center().x, rect.ymin); break;
    case 7: pt = Point2d(rect.xmin, rect.center().y); break;
    default: pt = rect.center(); break;
    }
}
Example #29
0
bool MgArc::_hitTestBox(const Box2d& rect) const
{
    if (!getExtent().isIntersect(rect))
        return false;

    Point2d points[16];
    int n = mgcurv::arcToBezier(points, getCenter(), getRadius(), 0, getStartAngle(), getSweepAngle());
    
    return rect.contains(getCenter()) || mgnear::beziersIntersectBox(rect, n, points);
}
Example #30
0
    GiTransformImpl(bool _ydown)
        : cxWnd(1), cyWnd(1), dpiX(96), dpiY(96), ydown(_ydown), viewScale(1)
        , zoomEnabled(true), tmpViewScale(1.f), zoomTimes(0)
    {
        minViewScale = 0.01f;   // 最小显示比例为1%
        maxViewScale = 5.f;     // 最大显示比例为500%
        rectLimitsW.set(Point2d::kOrigin(), 2e5f, 2e5f);

        updateTransforms();
    }