Beispiel #1
0
bool GiTransform::zoomTo(const Box2d& rectWorld, const RECT_2D* rcTo, bool adjust)
{
    // 如果图形范围的宽或高接近于零,就返回
    if (rectWorld.isEmpty())
        return false;

    // 计算像素到毫米的比例
    const float d2mmX = m_impl->viewScale / m_impl->w2dx;
    const float d2mmY = m_impl->viewScale / m_impl->w2dy;

    // 计算目标窗口区域(毫米)
    float w = 0, h = 0;
    Point2d ptCen;

    if (rcTo != NULL) {
        w = fabsf(static_cast<float>(rcTo->right - rcTo->left));
        h = fabsf(static_cast<float>(rcTo->bottom - rcTo->top));
        ptCen.x = (rcTo->left + rcTo->right) * 0.5f;
        ptCen.y = (rcTo->top + rcTo->bottom) * 0.5f;
    }
    if (w < 4 || h < 4) {
        w = (float)m_impl->cxWnd;
        h = (float)m_impl->cyWnd;
        ptCen.set(w * 0.5f, h * 0.5f);
        w -= 8;
        h -= 8;
    }
    if (w < 4 || h < 4)
        return false;
    w *= d2mmX;
    h *= d2mmY;
    ptCen.scaleBy(d2mmX, d2mmY);

    // 计算新显示比例 (中心不变,缩小窗口区域使得宽高比例和图形范围相同)
    float scale;
    if (h * rectWorld.width() > w * rectWorld.height()) {
        //h = w * rectWorld.height() / rectWorld.width();
        scale = w / rectWorld.width();
    }
    else {
        //w = h * rectWorld.width() / rectWorld.height();
        scale = h / rectWorld.height();
    }

    // 检查显示比例
    if (!adjust && ScaleOutRange(scale, m_impl))
        return false;
    scale = mgMax(scale, m_impl->minViewScale);
    scale = mgMin(scale, m_impl->maxViewScale);

    // 计算在新显示比例下显示窗口中心的世界坐标
    Point2d ptW;
    ptW.x = rectWorld.center().x + (m_impl->cxWnd * d2mmX * 0.5f - ptCen.x) / scale;
    ptW.y = rectWorld.center().y - (m_impl->cyWnd * d2mmY * 0.5f - ptCen.y) / scale;

    // 检查新显示比例下显示窗口的世界坐标范围是否在极限范围内
    float halfw = m_impl->cxWnd * d2mmX  / scale * 0.5f;
    float halfh = m_impl->cyWnd * d2mmY  / scale * 0.5f;
    Box2d box (ptW, 2 * halfw, 2 * halfh);

    if (!AdjustCenterIn(adjust, box, m_impl->rectLimitsW, ptW, halfw, halfh)) {
        return false;
    }

    return m_impl->zoomNoAdjust(ptW, scale);
}