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

📄 render_layer.cpp

📁 konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版本源码包.
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/* * Copyright (C) 2003 Apple Computer, Inc. * * Portions are Copyright (C) 1998 Netscape Communications Corporation. * * Other contributors: *   Robert O'Callahan <roc+@cs.cmu.edu> *   David Baron <dbaron@fas.harvard.edu> *   Christian Biesinger <cbiesinger@web.de> *   Randall Jesup <rjesup@wgate.com> *   Roland Mainz <roland.mainz@informatik.med.uni-giessen.de> *   Josh Soref <timeless@mac.com> *   Boris Zbarsky <bzbarsky@mit.edu> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA * * Alternatively, the contents of this file may be used under the terms * of either the Mozilla Public License Version 1.1, found at * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html * (the "GPL"), in which case the provisions of the MPL or the GPL are * applicable instead of those above.  If you wish to allow use of your * version of this file only under the terms of one of those two * licenses (the MPL or the GPL) and not to allow others to use your * version of this file under the LGPL, indicate your decision by * deletingthe provisions above and replace them with the notice and * other provisions required by the MPL or the GPL, as the case may be. * If you do not delete the provisions above, a recipient may use your * version of this file under any of the LGPL, the MPL or the GPL. *///#define BOX_DEBUG#include "render_layer.h"#include <kdebug.h>#include <assert.h>#include "khtmlview.h"#include "render_canvas.h"#include "render_arena.h"#include "render_replaced.h"#include "xml/dom_docimpl.h"#include "xml/dom2_eventsimpl.h"#include "misc/htmltags.h"#include "html/html_blockimpl.h"#include <qscrollbar.h>#include <qptrvector.h>#include <qstyle.h>using namespace DOM;using namespace khtml;#ifdef APPLE_CHANGESQScrollBar* RenderLayer::gScrollBar = 0;#endif#ifndef NDEBUGstatic bool inRenderLayerDetach;#endifvoidRenderScrollMediator::slotValueChanged(){    m_layer->updateScrollPositionFromScrollbars();}RenderLayer::RenderLayer(RenderObject* object): m_object( object ),m_parent( 0 ),m_previous( 0 ),m_next( 0 ),m_first( 0 ),m_last( 0 ),m_x( 0 ),m_y( 0 ),m_scrollX( 0 ),m_scrollY( 0 ),m_scrollWidth( 0 ),m_scrollHeight( 0 ),m_hBar( 0 ),m_vBar( 0 ),m_scrollMediator( 0 ),m_posZOrderList( 0 ),m_negZOrderList( 0 ),m_zOrderListsDirty( true ),m_markedForRepaint( false ),m_marquee( 0 ){}RenderLayer::~RenderLayer(){    // Child layers will be deleted by their corresponding render objects, so    // our destructor doesn't have to do anything.    delete m_hBar;    delete m_vBar;    delete m_scrollMediator;    delete m_posZOrderList;    delete m_negZOrderList;    delete m_marquee;}void RenderLayer::updateLayerPosition(){    // The canvas is sized to the docWidth/Height over in RenderCanvas::layout, so we    // don't need to ever update our layer position here.    if (renderer()->isCanvas())        return;    int x = m_object->xPos();    int y = m_object->yPos();    if (!m_object->isPositioned()) {        // We must adjust our position by walking up the render tree looking for the        // nearest enclosing object with a layer.        RenderObject* curr = m_object->parent();        while (curr && !curr->layer()) {            x += curr->xPos();            y += curr->yPos();            curr = curr->parent();        }    }    if (m_object->isRelPositioned())        static_cast<RenderBox*>(m_object)->relativePositionOffset(x, y);    // Subtract our parent's scroll offset.    if (m_object->isPositioned() && enclosingPositionedAncestor()) {        RenderLayer* positionedParent = enclosingPositionedAncestor();        // For positioned layers, we subtract out the enclosing positioned layer's scroll offset.        positionedParent->subtractScrollOffset(x, y);                if (positionedParent->renderer()->isRelPositioned() &&            positionedParent->renderer()->isInlineFlow()) {            // When we have an enclosing relpositioned inline, we need to add in the offset of the first line            // box from the rest of the content, but only in the cases where we know we're positioned            // relative to the inline itself.            RenderFlow* flow = static_cast<RenderFlow*>(positionedParent->renderer());            int sx = 0, sy = 0;            if (flow->firstLineBox()) {                if (flow->style()->direction() == LTR)                    sx = flow->firstLineBox()->xPos();                else                    sx = flow->lastLineBox()->xPos();                sy = flow->firstLineBox()->yPos();            } else {                sx = flow->staticX(); // ###                sy = flow->staticY();            }            bool isInlineType = m_object->style()->isOriginalDisplayInlineType();                        if (!m_object->hasStaticX())                x += sx;                        // This is not terribly intuitive, but we have to match other browsers.  Despite being a block display type inside            // an inline, we still keep our x locked to the left of the relative positioned inline.  Arguably the correct            // behavior would be to go flush left to the block that contains the inline, but that isn't what other browsers            // do.            if (m_object->hasStaticX() && !isInlineType)                // Avoid adding in the left border/padding of the containing block twice.  Subtract it out.                x += sx - (m_object->containingBlock()->borderLeft() + m_object->containingBlock()->paddingLeft());                        if (!m_object->hasStaticY())                y += sy;        }    }    else if (parent())        parent()->subtractScrollOffset(x, y);    setPos(x,y);}void RenderLayer::repaint( bool markForRepaint ){    if (markForRepaint && m_markedForRepaint)        return;    for (RenderLayer* child = firstChild(); child; child = child->nextSibling())        child->repaint( markForRepaint );    QRect layerBounds, damageRect, fgrect;    calculateRects(renderer()->canvas()->layer(), renderer()->viewRect(), layerBounds, damageRect, fgrect);    m_visibleRect = damageRect.intersect( layerBounds );    if (m_visibleRect.isValid())        renderer()->canvas()->repaintViewRectangle( m_visibleRect.x(), m_visibleRect.y(), m_visibleRect.width(), m_visibleRect.height() );    if (markForRepaint)        m_markedForRepaint = true;}void RenderLayer::updateLayerPositions(RenderLayer* rootLayer, bool doFullRepaint, bool checkForRepaint){    if (doFullRepaint) {        m_object->repaint();        checkForRepaint = doFullRepaint = false;    }        updateLayerPosition(); // For relpositioned layers or non-positioned layers,                           // we need to keep in sync, since we may have shifted relative                           // to our parent layer.    if (m_hBar || m_vBar) {        // Need to position the scrollbars.        int x = 0;        int y = 0;        convertToLayerCoords(rootLayer, x, y);        QRect layerBounds = QRect(x,y,width(),height());        positionScrollbars(layerBounds);    }#ifdef APPLE_CHANGES    // FIXME: Child object could override visibility.    if (checkForRepaint && (m_object->style()->visibility() == VISIBLE))        m_object->repaintAfterLayoutIfNeeded(m_repaintRect, m_fullRepaintRect);#else        if (checkForRepaint && m_markedForRepaint) {        QRect layerBounds, damageRect, fgrect;        calculateRects(rootLayer, renderer()->viewRect(), layerBounds, damageRect, fgrect);        QRect vr = damageRect.intersect( layerBounds );        if (vr != m_visibleRect && vr.isValid())            renderer()->canvas()->repaintViewRectangle( vr.x(), vr.y(), vr.width(), vr.height() );    }    m_markedForRepaint = false;   #endif        for	(RenderLayer* child = firstChild(); child; child = child->nextSibling())        child->updateLayerPositions(rootLayer, doFullRepaint, checkForRepaint);            // With all our children positioned, now update our marquee if we need to.    if (m_marquee)        m_marquee->updateMarqueePosition();}short RenderLayer::width() const{    int w = m_object->width();    if (!m_object->style()->hidesOverflow())        w = kMax(m_object->overflowWidth(), w);    return w;}int RenderLayer::height() const{    int h = m_object->height();    if (!m_object->style()->hidesOverflow())        h = kMax(m_object->overflowHeight(), h);    return h;}RenderLayer *RenderLayer::stackingContext() const{    RenderLayer* curr = parent();    for ( ; curr && !curr->m_object->isCanvas() &&          curr->m_object->style()->hasAutoZIndex();          curr = curr->parent());    return curr;}RenderLayer* RenderLayer::enclosingPositionedAncestor() const{    RenderLayer* curr = parent();    for ( ; curr && !curr->m_object->isCanvas() &&         !curr->m_object->isPositioned() && !curr->m_object->isRelPositioned();         curr = curr->parent());    return curr;}#ifdef APPLE_CHANGESbool RenderLayer::isTransparent(){    return m_object->style()->opacity() < 1.0f;}RenderLayer* RenderLayer::transparentAncestor(){    RenderLayer* curr = parent();    for ( ; curr && curr->m_object->style()->opacity() == 1.0f; curr = curr->parent());    return curr;}#endifvoid* RenderLayer::operator new(size_t sz, RenderArena* renderArena) throw(){    return renderArena->allocate(sz);}void RenderLayer::operator delete(void* ptr, size_t sz){    assert(inRenderLayerDetach);    // Stash size where detach can find it.    *(size_t *)ptr = sz;}void RenderLayer::detach(RenderArena* renderArena){#ifndef NDEBUG    inRenderLayerDetach = true;#endif    delete this;#ifndef NDEBUG    inRenderLayerDetach = false;#endif    // Recover the size left there for us by operator delete and free the memory.    renderArena->free(*(size_t *)this, this);}void RenderLayer::addChild(RenderLayer *child, RenderLayer* beforeChild){    RenderLayer* prevSibling = beforeChild ? beforeChild->previousSibling() : lastChild();    if (prevSibling) {        child->setPreviousSibling(prevSibling);        prevSibling->setNextSibling(child);    }    else        setFirstChild(child);    if (beforeChild) {        beforeChild->setPreviousSibling(child);        child->setNextSibling(beforeChild);    }    else        setLastChild(child);    child->setParent(this);    // Dirty the z-order list in which we are contained.  The stackingContext() can be null in the    // case where we're building up generated content layers.  This is ok, since the lists will start    // off dirty in that case anyway.    RenderLayer* stackingContext = child->stackingContext();    if (stackingContext)        stackingContext->dirtyZOrderLists();}RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild){    // remove the child    if (oldChild->previousSibling())        oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());    if (oldChild->nextSibling())        oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling());    if (m_first == oldChild)        m_first = oldChild->nextSibling();    if (m_last == oldChild)        m_last = oldChild->previousSibling();    // Dirty the z-order list in which we are contained.  When called via the    // reattachment process in removeOnlyThisLayer, the layer may already be disconnected    // from the main layer tree, so we need to null-check the |stackingContext| value.    RenderLayer* stackingContext = oldChild->stackingContext();    if (stackingContext)        oldChild->stackingContext()->dirtyZOrderLists();    oldChild->setPreviousSibling(0);    oldChild->setNextSibling(0);    oldChild->setParent(0);    return oldChild;}void RenderLayer::removeOnlyThisLayer(){    if (!m_parent)        return;    // Remove us from the parent.    RenderLayer* parent = m_parent;    RenderLayer* nextSib = nextSibling();    parent->removeChild(this);    // Now walk our kids and reattach them to our parent.    RenderLayer* current = m_first;    while (current) {        RenderLayer* next = current->nextSibling();        removeChild(current);        parent->addChild(current, nextSib);        current = next;    }    detach(renderer()->renderArena());}void RenderLayer::insertOnlyThisLayer(){    if (!m_parent && renderer()->parent()) {        // We need to connect ourselves when our renderer() has a parent.        // Find our enclosingLayer and add ourselves.        RenderLayer* parentLayer = renderer()->parent()->enclosingLayer();        if (parentLayer)            parentLayer->addChild(this,                                  renderer()->parent()->findNextLayer(parentLayer, renderer()));    }    // Remove all descendant layers from the hierarchy and add them to the new position.    for (RenderObject* curr = renderer()->firstChild(); curr; curr = curr->nextSibling())        curr->moveLayers(m_parent, this);}void RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, int& x, int& y) const{    if (ancestorLayer == this)        return;    if (m_object->style()->position() == FIXED) {

⌨️ 快捷键说明

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