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); } }
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; }
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; }
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; }