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

📄 render_layer.cpp

📁 khtml在gtk上的移植版本
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        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 : PaintActionChildBackgrounds,                                     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}boolRenderLayer::nodeAtPoint(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 = nodeAtPointForLayer(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::nodeAtPointForLayer(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->nodeAtPointForLayer(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) &&        renderer()->nodeAtPoint(info, xMousePos, yMousePos,                                layerBounds.x() - renderer()->xPos(),                                layerBounds.y() - renderer()->yPos(),                                HitTestChildrenOnly)) {	// for positioned generated content, we might still not have a	// node by the time we get to the layer level, since none of	// the content in the layer has an element. So just walk up	// the tree.         if (!info.innerNode()) {	    for (RenderObject *r = renderer(); r != NULL; r = r->parent()) { 		if (r->element()) {		    info.setInnerNode(r->element());		    break;		}	    }	 }	 if (!info.innerNonSharedNode()) {	     for (RenderObject *r = renderer(); r != NULL; r = r->parent()) { 		 if (r->element()) {		     info.setInnerNonSharedNode(r->element());		     break;		 }	     }	 }        return this;    }            // Now check our negative z-index children.    if (m_negZOrderList) {        uint count = m_negZOrderList->count();        for (int i = count-1; i >= 0; i--) {            RenderLayer* child = m_negZOrderList->at(i);            insideLayer = child->nodeAtPointForLayer(rootLayer, info, xMousePos, yMousePos, hitTestRect);            if (insideLayer)                return insideLayer;        }    }    // Next we want to see if the mouse pos is inside this layer but not any of its children.    if (containsPoint(xMousePos, yMousePos, bgRect) &&        renderer()->nodeAtPoint(info, xMousePos, yMousePos,                                layerBounds.x() - renderer()->xPos(),                                layerBounds.y() - renderer()->yPos(),                                HitTestSelfOnly))        return this;    // No luck.    return 0;}void RenderLayer::calculateClipRects(const RenderLayer* rootLayer, QRect& overflowClipRect,                                     QRect& posClipRect, QRect& fixedClipRect){    if (parent())        parent()->calculateClipRects(rootLayer, overflowClipRect, posClipRect, fixedClipRect);    // A fixed object is essentially the root of its containing block hierarchy, so when    // we encounter such an object, we reset our clip rects to the fixedClipRect.    if (m_object->style()->position() == FIXED) {        posClipRect = fixedClipRect;        overflowClipRect = fixedClipRect;    }    else if (m_object->style()->position() == RELATIVE)        posClipRect = overflowClipRect;        // Update the clip rects that will be passed to child layers.    if (m_object->hasOverflowClip() || m_object->hasClip()) {        // This layer establishes a clip of some kind.        int x = 0;        int y = 0;        convertToLayerCoords(rootLayer, x, y);                if (m_object->hasOverflowClip()) {            QRect newOverflowClip = m_object->getOverflowClipRect(x,y);            overflowClipRect  = newOverflowClip.intersect(overflowClipRect);            if (m_object->isPositioned() || m_object->isRelPositioned())                posClipRect = newOverflowClip.intersect(posClipRect);        }        if (m_object->hasClip()) {            QRect newPosClip = m_object->getClipRect(x,y);            posClipRect = posClipRect.intersect(newPosClip);            overflowClipRect = overflowClipRect.intersect(newPosClip);            fixedClipRect = fixedClipRect.intersect(newPosClip);        }    }}void RenderLayer::calculateRects(const RenderLayer* rootLayer, const QRect& paintDirtyRect, QRect& layerBounds,                                 QRect& backgroundRect, QRect& foregroundRect){    QRect overflowClipRect = paintDirtyRect;    QRect posClipRect = paintDirtyRect;    QRect fixedClipRect = paintDirtyRect;    if (parent())        parent()->calculateClipRects(rootLayer, overflowClipRect, posClipRect, fixedClipRect);    int x = 0;    int y = 0;    convertToLayerCoords(rootLayer, x, y);    layerBounds = QRect(x,y,width(),height());    backgroundRect = m_object->style()->position() == FIXED ? fixedClipRect :        (m_object->isPositioned() ? posClipRect : overflowClipRect);    foregroundRect = backgroundRect;        // Update the clip rects that will be passed to child layers.    if (m_object->hasOverflowClip() || m_object->hasClip()) {        // This layer establishes a clip of some kind.        if (m_object->hasOverflowClip())            foregroundRect = foregroundRect.intersect(m_object->getOverflowClipRect(x,y));        if (m_object->hasClip()) {            // Clip applies to *us* as well, so go ahead and update the damageRect.            QRect newPosClip = m_object->getClipRect(x,y);            backgroundRect = backgroundRect.intersect(newPosClip);            foregroundRect = foregroundRect.intersect(newPosClip);        }        // If we establish a clip at all, then go ahead and make sure our background        // rect is intersected with our layer's bounds.        backgroundRect = backgroundRect.intersect(layerBounds);    }}bool RenderLayer::intersectsDamageRect(const QRect& layerBounds, const QRect& damageRect) const{    return (renderer()->isCanvas() || renderer()->isRoot() || renderer()->isBody() ||            (renderer()->hasOverhangingFloats() && !renderer()->hasOverflowClip()) ||            (renderer()->isInline() && !renderer()->isReplaced()) ||            layerBounds.intersects(damageRect));}bool RenderLayer::containsPoint(int x, int y, const QRect& damageRect) const{    return (renderer()->isCanvas() || renderer()->isRoot() || renderer()->isBody() ||            (renderer()->hasOverhangingFloats() && !renderer()->hasOverflowClip()) ||            (renderer()->isInline() && !renderer()->isReplaced()) ||            damageRect.contains(x, y));}// This code has been written to anticipate the addition of CSS3-::outside and ::inside generated// content (and perhaps XBL).  That's why it uses the render tree and not the DOM tree.static RenderObject* hoverAncestor(RenderObject* obj){    return (!obj->isInline() && obj->continuation()) ? obj->continuation() : obj->parent();}static RenderObject* commonAncestor(RenderObject* obj1, RenderObject* obj2){    if (!obj1 || !obj2)        return 0;    for (RenderObject* currObj1 = obj1; currObj1; currObj1 = hoverAncestor(currObj1))        for (RenderObject* currObj2 = obj2; currObj2; currObj2 = hoverAncestor(currObj2))            if (currObj1 == currObj2)                return currObj1;    return 0;}void RenderLayer::updateHoverActiveState(RenderObject::NodeInfo& info){    // We don't update :hover/:active state when the info is marked as readonly.    if (info.readonly())        return;    // Check to see if the hovered node has changed.  If not, then we don't need to    // do anything.  An exception is if we just went from :hover into :hover:active,    // in which case we need to update to get the new :active state.    DOM::DocumentImpl* doc = renderer()->document();    DOM::NodeImpl* oldHoverNode = doc ? doc->hoverNode() : 0;    DOM::NodeImpl* newHoverNode = info.innerNode();    // Update our current hover node.    if (doc)        doc->setHoverNode(newHoverNode);    // We have two different objects.  Fetch their renderers.    RenderObject* oldHoverObj = oldHoverNode ? oldHoverNode->renderer() : 0;    RenderObject* newHoverObj = newHoverNode ? newHoverNode->renderer() : 0;        // Locate the common ancestor render object for the two renderers.    RenderObject* ancestor = commonAncestor(oldHoverObj, newHoverObj);        if (oldHoverObj != newHoverObj) {        // The old hover path only needs to be cleared up to (and not including) the common ancestor;        for (RenderObject* curr = oldHoverObj; curr && curr != ancestor; curr = hoverAncestor(curr)) {            curr->setMouseInside(false);            if (curr->element() && !curr->isText()) {                bool oldActive = curr->element()->active();                curr->element()->setActive(false);                if (curr->style()->affectedByHoverRules() ||                    (curr->style()->affectedByActiveRules() && oldActive))                    curr->element()->setChanged();            }        }    }    // Now set the hover state for our new object up to the root.    for (RenderObject* curr = newHoverObj; curr; curr = hoverAncestor(curr)) {        bool oldInside = curr->mouseInside();        curr->setMouseInside(true);        if (curr->element() && !curr->isText()) {            bool oldActive = curr->element()->active();            curr->element()->setActive(info.active());            if ((curr->style()->affectedByHoverRules() && !oldInside) ||                (curr->style()->affectedByActiveRules() && oldActive != info.active()))                curr->element()->setChanged();        }    }}// Sort the buffer from lowest z-index to highest.  The common scenario will have// most z-indices equal, so we optimize for that case (i.e., the list will be mostly// sorted already).static void sortByZOrder(QPtrVector<RenderLayer>* buffer,                         QPtrVector<RenderLayer>* mergeBuffer,                         uint start, uint end){    if (start >= end)        return; // Sanity check.    if (end - start <= 6) {        // Apply a bubble sort for smaller lists.        for (uint i = end-1; i > start; i--) {            bool sorted = true;            for (uint j = start; j < i; j++) {                RenderLayer* elt = buffer->at(j);                RenderLayer* elt2 = buffer->at(j+1);                if (elt->zIndex() > elt2->zIndex()) {                    sorted = false;                    buffer->insert(j, elt2);                    buffer->insert(j+1, elt);                }            }            if (sorted)                return;        }    }    else {        // Peform a merge sort for larger lists.        uint mid = (start+end)/2;        sortByZOrder(buffer, mergeBuffer, start, mid);        sortByZOrder(buffer, mergeBuffer, mid, end);        RenderLayer* elt = buffer->at(mid-1);        RenderLayer* elt2 = buffer->at(mid);        // Handle the fast common case (of equal z-indices).  The list may already        // be completely sorted.        if (elt->zIndex() <= elt2->zIndex())            return;        // We have to merge sort.  Ensure our merge buffer is big enough to hold        // all the items.        mergeBuffer->resize(end - start);        uint i1 = start;        uint i2 = mid;        elt = buffer->at(i1);        elt2 = buffer->at(i2);

⌨️ 快捷键说明

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