⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 render_layer.cpp

📁 手机浏览器源码程序,功能强大
💻 CPP
📖 第 1 页 / 共 5 页
字号:

    // overflow:scroll should just enable/disable.
    if (m_object->style()->overflow() == OSCROLL) {
        m_hBar->setEnabled(needHorizontalBar);
        m_vBar->setEnabled(needVerticalBar);
    }

    // overflow:auto may need to lay out again if scrollbars got added/removed.
    bool scrollbarsChanged = (m_object->hasAutoScrollbars()) &&
        (haveHorizontalBar != needHorizontalBar || haveVerticalBar != needVerticalBar);
    if (scrollbarsChanged) {
        setHasHorizontalScrollbar(needHorizontalBar);
        setHasVerticalScrollbar(needVerticalBar);

#if APPLE_CHANGES
    // Force an update since we know the scrollbars have changed things.
    if (m_object->document()->hasDashboardRegions())
        m_object->document()->setDashboardRegionsDirty(true);
#endif

        m_object->repaint();

        if (m_object->style()->overflow() == OAUTO) {
            // Our proprietary overflow: overlay value doesn't trigger a layout.
            m_object->setNeedsLayout(true);
            if (m_object->isRenderBlock())
                static_cast<RenderBlock*>(m_object)->layoutBlock(true);
            else
                m_object->layout();
        }
    }

    // Set up the range (and page step/line step).
    if (m_hBar) {
        int clientWidth = m_object->clientWidth();
        int pageStep = (clientWidth-PAGE_KEEP);
        if (pageStep < 0) pageStep = clientWidth;
        m_hBar->setSteps(LINE_STEP, pageStep);
#ifdef APPLE_CHANGES
        m_hBar->setKnobProportion(clientWidth, m_scrollWidth);
#else
        m_hBar->setRange(0, m_scrollWidth-clientWidth);
        m_object->repaintRectangle(QRect(m_object->borderLeft(), m_object->borderTop() + clientHeight(),
                                   horizontalScrollbarHeight(),
                                   m_object->width() - m_object->borderLeft() - m_object->borderRight()));
#endif
    }
    if (m_vBar) {
        int clientHeight = m_object->clientHeight();
        int pageStep = (clientHeight-PAGE_KEEP);
        if (pageStep < 0) pageStep = clientHeight;
        m_vBar->setSteps(LINE_STEP, pageStep);
#ifdef APPLE_CHANGES
        m_vBar->setKnobProportion(clientHeight, m_scrollHeight);
#else
        m_vBar->setRange(0, m_scrollHeight-clientHeight);
#endif
        m_object->repaintRectangle(QRect(m_object->borderLeft() + m_object->clientWidth(),
                                   m_object->borderTop(), verticalScrollbarWidth(),
                                   m_object->height() - m_object->borderTop() - m_object->borderBottom()));
    }

#if APPLE_CHANGES
    // Force an update since we know the scrollbars have changed things.
    if (m_object->document()->hasDashboardRegions())
    m_object->document()->setDashboardRegionsDirty(true);
#endif

    m_object->repaint();
}

#if APPLE_CHANGES
void
RenderLayer::paintScrollbars(QPainter* p, const QRect& damageRect)
{
    // Move the widgets if necessary.  We normally move and resize widgets during layout, but sometimes
    // widgets can move without layout occurring (most notably when you scroll a document that
    // contains fixed positioned elements).
    if (m_hBar || m_vBar) {
        int x = 0;
        int y = 0;
        convertToLayerCoords(root(), x, y);
        QRect layerBounds = QRect(x, y, width(), height());
        positionScrollbars(layerBounds);
    }

    // Now that we're sure the scrollbars are in the right place, paint them.
    if (m_hBar)
        m_hBar->paint(p, damageRect);
    if (m_vBar)
        m_vBar->paint(p, damageRect);
}
#endif

bool RenderLayer::scroll(KWQScrollDirection direction, KWQScrollGranularity granularity, float multiplier)
{
    bool didHorizontalScroll = false;
    bool didVerticalScroll = false;

    if (m_hBar != 0) {
        if (granularity == KWQScrollDocument) {
            // Special-case for the KWQScrollDocument granularity. A document scroll can only be up
            // or down and in both cases the horizontal bar goes all the way to the left.
            didHorizontalScroll = m_hBar->scroll(KWQScrollLeft, KWQScrollDocument, multiplier);
        } else {
            didHorizontalScroll = m_hBar->scroll(direction, granularity, multiplier);
        }
    }
    if (m_vBar != 0) {
        didVerticalScroll = m_vBar->scroll(direction, granularity, multiplier);
    }

    return (didHorizontalScroll || didVerticalScroll);
}

void
RenderLayer::paint(QPainter *p, const QRect& damageRect, bool selectionOnly, RenderObject *paintingRoot)
{
    paintLayer(this, p, damageRect, false, selectionOnly, paintingRoot);
}

static void setClip(QPainter* p, const QRect& paintDirtyRect, const QRect& clipRect)
{
    if (paintDirtyRect == clipRect)
        return;

    p->save();

#if APPLE_CHANGES
    p->addClip(clipRect);
#else
    QRect clippedRect = p->xForm(clipRect);
    QRegion creg(clippedRect);
    QRegion old = p->clipRegion();
    if (!old.isNull())
        creg = old.intersect(creg);
    p->setClipRegion(creg);
#endif

}

static void restoreClip(QPainter* p, const QRect& paintDirtyRect, const QRect& clipRect)
{
    if (paintDirtyRect == clipRect)
        return;
    p->restore();
}

#ifdef NOKIA_CHANGES
void RenderLayer::getRenderersInRect(RenderLayer* rootLayer, QPtrList<LayerInfo>* layerInfoList,const QRect& rect,int deltaX,int deltaY, int layerZIndex)
{
    // Calculate the top left position for the layer.
    int x = 0;
    int y = 0;
    convertToLayerCoords(rootLayer,x,y);

    // Ensure our z-order lists are up-to-date.
    updateZOrderLists();

    // Now walk the sorted list of children with negative z-indices.
    if (m_negZOrderList) {
        uint count = m_negZOrderList->count();
        for (uint i = 0; i < count; i++) {
            RenderLayer* child = m_negZOrderList->at(i);
            child->getRenderersInRect(rootLayer,layerInfoList,rect,deltaX,deltaY,layerZIndex + zIndex());
        }
    }

    LayerInfo *layerInfo = new LayerInfo;
    QPtrList<BoxInfo> *layerBoxInfoList = new QPtrList<BoxInfo>;
    layerBoxInfoList->setAutoDelete(true);
    layerInfo->boxInfoList = layerBoxInfoList;
    layerInfo->zIndex = layerZIndex + zIndex();
    layerInfoList->append(layerInfo);
    renderer()->getRenderersInRect(*layerBoxInfoList,deltaX + x - renderer()->xPos(), deltaY + y - renderer()->yPos(),rect);

    // Now walk the sorted list of children with positive z-indices.
    if (m_posZOrderList) {
        uint count = m_posZOrderList->count();
        for (uint i = 0; i < count; i++) {
            RenderLayer* child = m_posZOrderList->at(i);
            child->getRenderersInRect(rootLayer,layerInfoList,rect,deltaX,deltaY,layerZIndex + zIndex());
        }
    }


}
#endif

void
RenderLayer::paintLayer(RenderLayer* rootLayer, QPainter *p,
                        const QRect& paintDirtyRect, bool haveTransparency, bool selectionOnly,
                        RenderObject *paintingRoot)
{
    // Calculate the clip rects we should use.
    QRect layerBounds, damageRect, clipRectToApply;
    calculateRects(rootLayer, paintDirtyRect, layerBounds, damageRect, clipRectToApply);
    int x = layerBounds.x();
    int y = layerBounds.y();

    // Ensure our z-order lists are up-to-date.
    updateZOrderLists();

#if APPLE_CHANGES
    if (isTransparent())
        haveTransparency = true;
#endif

    // If this layer's renderer is a child of the paintingRoot, we render unconditionally, which
    // is done by passing a nil paintingRoot down to our renderer (as if no paintingRoot was ever set).
    // Else, our renderer tree may or may not contain the painting root, so we pass that root along
    // so it will be tested against as we decend through the renderers.
    RenderObject *paintingRootForRenderer = 0;
    if (paintingRoot && !m_object->hasAncestor(paintingRoot)) {
        paintingRootForRenderer = paintingRoot;
    }

    // We want to paint our layer, but only if we intersect the damage rect.
    bool shouldPaint = intersectsDamageRect(layerBounds, damageRect);
    if (shouldPaint && !selectionOnly && !damageRect.isEmpty()) {
#if APPLE_CHANGES
        // Begin transparency layers lazily now that we know we have to paint something.
        if (haveTransparency)
            beginTransparencyLayers(p);
#endif

        // Paint our background first, before painting any child layers.
        // Establish the clip used to paint our background.
        setClip(p, paintDirtyRect, damageRect);

        // Paint the background.
        RenderObject::PaintInfo info(p, damageRect, PaintActionBlockBackground, paintingRootForRenderer);
        renderer()->paint(info, x - renderer()->xPos(), y - renderer()->yPos());
#if APPLE_CHANGES
        // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
        // z-index.  We paint after we painted the background/border, so that the scrollbars will
        // sit above the background/border.
        paintScrollbars(p, damageRect);
#endif
        // Restore the clip.
        restoreClip(p, paintDirtyRect, damageRect);
    }

    // Now walk the sorted list of children with negative z-indices.
    if (m_negZOrderList) {
        uint count = m_negZOrderList->count();
        for (uint i = 0; i < count; i++) {
            RenderLayer* child = m_negZOrderList->at(i);
            child->paintLayer(rootLayer, p, paintDirtyRect, haveTransparency, selectionOnly, paintingRoot);
        }
    }

    // Now establish the appropriate clip and paint our child RenderObjects.
    if (shouldPaint && !clipRectToApply.isEmpty()) {
#if APPLE_CHANGES
        // Begin transparency layers lazily now that we know we have to paint something.
        if (haveTransparency)
            beginTransparencyLayers(p);
#endif

        // Set up the clip used when painting our children.
        setClip(p, paintDirtyRect, clipRectToApply);

        int tx = x - renderer()->xPos();
        int ty = y - renderer()->yPos();
        RenderObject::PaintInfo info(p, clipRectToApply,
                                     selectionOnly ? PaintActionSelection : PaintActionChildBlockBackgrounds,
                                     paintingRootForRenderer);
        renderer()->paint(info, tx, ty);
        if (!selectionOnly) {
            info.phase = PaintActionFloat;
            renderer()->paint(info, tx, ty);
            info.phase = PaintActionForeground;
            renderer()->paint(info, tx, ty);
            info.phase = PaintActionOutline;
            renderer()->paint(info, tx, ty);
        }

        // Now restore our clip.
        restoreClip(p, paintDirtyRect, clipRectToApply);
    }

    // Now walk the sorted list of children with positive z-indices.
    if (m_posZOrderList) {
        uint count = m_posZOrderList->count();
        for (uint i = 0; i < count; i++) {
            RenderLayer* child = m_posZOrderList->at(i);
            child->paintLayer(rootLayer, p, paintDirtyRect, haveTransparency, selectionOnly, paintingRoot);
        }
    }

#if APPLE_CHANGES
    // End our transparency layer
    if (isTransparent() && m_usedTransparency) {
        p->endTransparencyLayer();
        m_usedTransparency = false;
    }
#endif
}

bool
RenderLayer::hitTest(RenderObject::NodeInfo& info, int x, int y)
{
#if APPLE_CHANGES
    // Clear our our scrollbar variable
    RenderLayer::gScrollBar = 0;
#endif

    QRect damageRect(m_x, m_y, width(), height());
    RenderLayer* insideLayer = hitTestLayer(this, info, x, y, damageRect);

    // Now determine if the result is inside an anchor; make sure an image map wins if
    // it already set URLElement and only use the innermost.
    DOM::NodeImpl* node = info.innerNode();
    while (node) {
        if (node->hasAnchor() && !info.URLElement())
            info.setURLElement(node);
        node = node->parentNode();
    }

    // Next set up the correct :hover/:active state along the new chain.
    updateHoverActiveState(info);

    // Now return whether we were inside this layer (this will always be true for the root
    // layer).
    return insideLayer;
}

RenderLayer*
RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderObject::NodeInfo& info,
                          int xMousePos, int yMousePos, const QRect& hitTestRect)
{
    // Calculate the clip rects we should use.
    QRect layerBounds, bgRect, fgRect;
    calculateRects(rootLayer, hitTestRect, layerBounds, bgRect, fgRect);

    // Ensure our z-order lists are up-to-date.
    updateZOrderLists();

    // This variable tracks which layer the mouse ends up being inside.  The minute we find an insideLayer,
    // we are done and can return it.
    RenderLayer* insideLayer = 0;

    // Begin by walking our list of positive layers from highest z-index down to the lowest
    // z-index.
    if (m_posZOrderList) {
        uint count = m_posZOrderList->count();
        for (int i = count-1; i >= 0; i--) {
            RenderLayer* child = m_posZOrderList->at(i);
            insideLayer = child->hitTestLayer(rootLayer, info, xMousePos, yMousePos, hitTestRect);
            if (insideLayer)
                return insideLayer;
        }
    }

    // Next we want to see if the mouse pos is inside the child RenderObjects of the layer.
    if (containsPoint(xMousePos, yMousePos, fgRect) &&

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -