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

📄 renderview.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 1999 Lars Knoll (knoll@kde.org) * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB.  If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */#include "config.h"#include "RenderView.h"#include "Document.h"#include "Element.h"#include "FloatQuad.h"#include "Frame.h"#include "FrameView.h"#include "GraphicsContext.h"#include "HitTestResult.h"#include "RenderLayer.h"#include "RenderSelectionInfo.h"#include "RenderWidget.h"#include "TransformState.h"#if USE(ACCELERATED_COMPOSITING)#include "RenderLayerCompositor.h"#endifnamespace WebCore {RenderView::RenderView(Node* node, FrameView* view)    : RenderBlock(node)    , m_frameView(view)    , m_selectionStart(0)    , m_selectionEnd(0)    , m_selectionStartPos(-1)    , m_selectionEndPos(-1)    , m_printImages(true)    , m_maximalOutlineSize(0)    , m_layoutState(0)    , m_layoutStateDisableCount(0){    // Clear our anonymous bit, set because RenderObject assumes    // any renderer with document as the node is anonymous.    setIsAnonymous(false);    // init RenderObject attributes    setInline(false);        m_minPrefWidth = 0;    m_maxPrefWidth = 0;    setPrefWidthsDirty(true, false);        setPositioned(true); // to 0,0 :)    // Create a new root layer for our layer hierarchy.    m_layer = new (node->document()->renderArena()) RenderLayer(this);    setHasLayer(true);}RenderView::~RenderView(){}void RenderView::calcHeight(){    if (!printing() && m_frameView)        setHeight(viewHeight());}void RenderView::calcWidth(){    if (!printing() && m_frameView)        setWidth(viewWidth());    m_marginLeft = 0;    m_marginRight = 0;}void RenderView::calcPrefWidths(){    ASSERT(prefWidthsDirty());    RenderBlock::calcPrefWidths();    m_maxPrefWidth = m_minPrefWidth;}void RenderView::layout(){    if (printing())        m_minPrefWidth = m_maxPrefWidth = width();    // Use calcWidth/Height to get the new width/height, since this will take the full page zoom factor into account.    bool relayoutChildren = !printing() && (!m_frameView || width() != viewWidth() || height() != viewHeight());    if (relayoutChildren) {        setChildNeedsLayout(true, false);        for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {            if (child->style()->height().isPercent() || child->style()->minHeight().isPercent() || child->style()->maxHeight().isPercent())                child->setChildNeedsLayout(true, false);        }    }    ASSERT(!m_layoutState);    LayoutState state;    // FIXME: May be better to push a clip and avoid issuing offscreen repaints.    state.m_clipped = false;    m_layoutState = &state;    if (needsLayout())        RenderBlock::layout();    // Ensure that docWidth() >= width() and docHeight() >= height().    setOverflowWidth(width());    setOverflowHeight(height());    setOverflowWidth(docWidth());    setOverflowHeight(docHeight());    ASSERT(layoutDelta() == IntSize());    ASSERT(m_layoutStateDisableCount == 0);    ASSERT(m_layoutState == &state);    m_layoutState = 0;    setNeedsLayout(false);}void RenderView::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool /*useTransforms*/, TransformState& transformState) const{    // If a container was specified, and was not 0 or the RenderView,    // then we should have found it by now.    ASSERT_UNUSED(repaintContainer, !repaintContainer || repaintContainer == this);    if (fixed && m_frameView)        transformState.move(m_frameView->scrollOffset());}void RenderView::mapAbsoluteToLocalPoint(bool fixed, bool /*useTransforms*/, TransformState& transformState) const{    if (fixed && m_frameView)        transformState.move(-m_frameView->scrollOffset());}void RenderView::paint(PaintInfo& paintInfo, int tx, int ty){    // If we ever require layout but receive a paint anyway, something has gone horribly wrong.    ASSERT(!needsLayout());    // Cache the print rect because the dirty rect could get changed during painting.    if (printing())        setPrintRect(paintInfo.rect);    else        setPrintRect(IntRect());    paintObject(paintInfo, tx, ty);}static inline bool rendererObscuresBackground(RenderObject* object){    return object && object->style()->visibility() == VISIBLE && object->style()->opacity() == 1 && !object->style()->hasTransform();}    void RenderView::paintBoxDecorations(PaintInfo& paintInfo, int, int){    // Check to see if we are enclosed by a layer that requires complex painting rules.  If so, we cannot blit    // when scrolling, and we need to use slow repaints.  Examples of layers that require this are transparent layers,    // layers with reflections, or transformed layers.    // FIXME: This needs to be dynamic.  We should be able to go back to blitting if we ever stop being inside    // a transform, transparency layer, etc.    Element* elt;    for (elt = document()->ownerElement(); view() && elt && elt->renderer(); elt = elt->document()->ownerElement()) {        RenderLayer* layer = elt->renderer()->enclosingLayer();        if (layer->requiresSlowRepaints()) {            frameView()->setUseSlowRepaints();            break;        }    }    // If painting will entirely fill the view, no need to fill the background.    if (elt || rendererObscuresBackground(firstChild()) || !view())        return;    // This code typically only executes if the root element's visibility has been set to hidden,    // or there is a transform on the <html>.    // Only fill with the base background color (typically white) if we're the root document,     // since iframes/frames with no background in the child document should show the parent's background.    if (view()->isTransparent()) // FIXME: This needs to be dynamic.  We should be able to go back to blitting if we ever stop being transparent.        frameView()->setUseSlowRepaints(); // The parent must show behind the child.    else {        Color baseColor = frameView()->baseBackgroundColor();        if (baseColor.alpha() > 0) {            paintInfo.context->save();            paintInfo.context->setCompositeOperation(CompositeCopy);            paintInfo.context->fillRect(paintInfo.rect, baseColor);            paintInfo.context->restore();        } else            paintInfo.context->clearRect(paintInfo.rect);    }}bool RenderView::shouldRepaint(const IntRect& r) const{    if (printing() || r.width() == 0 || r.height() == 0)        return false;    if (!m_frameView)        return false;        return true;}void RenderView::repaintViewRectangle(const IntRect& ur, bool immediate){    if (!shouldRepaint(ur))        return;    // We always just invalidate the root view, since we could be an iframe that is clipped out    // or even invisible.    Element* elt = document()->ownerElement();    if (!elt)        m_frameView->repaintContentRectangle(ur, immediate);    else if (RenderBox* obj = elt->renderBox()) {        IntRect vr = viewRect();        IntRect r = intersection(ur, vr);                // Subtract out the contentsX and contentsY offsets to get our coords within the viewing        // rectangle.        r.move(-vr.x(), -vr.y());                // FIXME: Hardcoded offsets here are not good.        r.move(obj->borderLeft() + obj->paddingLeft(),               obj->borderTop() + obj->paddingTop());        obj->repaintRectangle(r, immediate);    }}void RenderView::repaintRectangleInViewAndCompositedLayers(const IntRect& ur, bool immediate){    if (!shouldRepaint(ur))        return;    repaintViewRectangle(ur, immediate);    #if USE(ACCELERATED_COMPOSITING)    // If we're a frame, repaintViewRectangle will have repainted via a RenderObject in the    // parent document.    if (document()->ownerElement())        return;    if (compositor()->inCompositingMode())        compositor()->repaintCompositedLayersAbsoluteRect(ur);#endif}void RenderView::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& rect, bool fixed){    // If a container was specified, and was not 0 or the RenderView,    // then we should have found it by now.    ASSERT_UNUSED(repaintContainer, !repaintContainer || repaintContainer == this);    if (printing())        return;    if (fixed && m_frameView)        rect.move(m_frameView->scrollX(), m_frameView->scrollY());            // Apply our transform if we have one (because of full page zooming).    if (m_layer && m_layer->transform())        rect = m_layer->transform()->mapRect(rect);}void RenderView::absoluteRects(Vector<IntRect>& rects, int tx, int ty, bool){    rects.append(IntRect(tx, ty, m_layer->width(), m_layer->height()));}void RenderView::absoluteQuads(Vector<FloatQuad>& quads, bool){    quads.append(FloatRect(0, 0, m_layer->width(), m_layer->height()));}static RenderObject* rendererAfterPosition(RenderObject* object, unsigned offset){    if (!object)        return 0;    RenderObject* child = object->childAt(offset);    return child ? child : object->nextInPreOrderAfterChildren();}IntRect RenderView::selectionBounds(bool clipToVisibleContent) const{    document()->updateRendering();    typedef HashMap<RenderObject*, RenderSelectionInfo*> SelectionMap;    SelectionMap selectedObjects;    RenderObject* os = m_selectionStart;    RenderObject* stop = rendererAfterPosition(m_selectionEnd, m_selectionEndPos);    while (os && os != stop) {        if ((os->canBeSelectionLeaf() || os == m_selectionStart || os == m_selectionEnd) && os->selectionState() != SelectionNone) {            // Blocks are responsible for painting line gaps and margin gaps. They must be examined as well.            selectedObjects.set(os, new RenderSelectionInfo(os, clipToVisibleContent));            RenderBlock* cb = os->containingBlock();            while (cb && !cb->isRenderView()) {                RenderSelectionInfo* blockInfo = selectedObjects.get(cb);                if (blockInfo)                    break;                selectedObjects.set(cb, new RenderSelectionInfo(cb, clipToVisibleContent));                cb = cb->containingBlock();            }        }        os = os->nextInPreOrder();    }    // Now create a single bounding box rect that encloses the whole selection.    IntRect selRect;    SelectionMap::iterator end = selectedObjects.end();    for (SelectionMap::iterator i = selectedObjects.begin(); i != end; ++i) {        RenderSelectionInfo* info = i->second;        selRect.unite(info->rect());        delete info;    }    return selRect;}#if USE(ACCELERATED_COMPOSITING)// Compositing layer dimensions take outline size into account, so we have to recompute layer// bounds when it changes.// FIXME: This is ugly; it would be nice to have a better way to do this.void RenderView::setMaximalOutlineSize(int o){    if (o != m_maximalOutlineSize) {        m_maximalOutlineSize = o;        if (m_frameView)            m_frameView->updateCompositingLayers(FrameView::ForcedCompositingUpdate);    }

⌨️ 快捷键说明

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