📄 render_canvas.cpp
字号:
/** * This file is part of the HTML widget for KDE. * * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) * (C) 2003 Apple Computer, Inc. * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) * * 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 "rendering/render_canvas.h"#include "rendering/render_layer.h"#include "xml/dom_docimpl.h"#include "khtmlview.h"#include "khtml_part.h"#include <kdebug.h>#include <kglobal.h>using namespace khtml;//#define BOX_DEBUG//#define SPEED_DEBUGRenderCanvas::RenderCanvas(DOM::NodeImpl* node, KHTMLView *view) : RenderBlock(node){ // init RenderObject attributes setInline(false); setIsAnonymous(false); m_view = view; // try to contrain the width to the views width m_minWidth = 0; m_height = 0; m_width = m_minWidth; m_maxWidth = m_minWidth; m_rootWidth = m_rootHeight = 0; m_viewportWidth = m_viewportHeight = 0; setPositioned(true); // to 0,0 :) m_staticMode = false; m_pagedMode = false; m_printImages = true; m_pageTop = 0; m_pageBottom = 0; m_page = 0; m_maximalOutlineSize = 0; m_selectionStart = 0; m_selectionEnd = 0; m_selectionStartPos = -1; m_selectionEndPos = -1; // Create a new root layer for our layer hierarchy. m_layer = new (node->getDocument()->renderArena()) RenderLayer(this);}RenderCanvas::~RenderCanvas(){ delete m_page;}void RenderCanvas::setStyle(RenderStyle* style){ /* if (m_pagedMode) style->setOverflow(OHIDDEN); */ RenderBlock::setStyle(style);}void RenderCanvas::calcHeight(){ if (m_pagedMode || !m_view) m_height = m_rootHeight; else m_height = m_view->visibleHeight();}void RenderCanvas::calcWidth(){ // the width gets set by KHTMLView::print when printing to a printer. if(m_pagedMode || !m_view) { m_width = m_rootWidth; return; } m_width = m_view ? m_view->frameWidth() + paddingLeft() + paddingRight() + borderLeft() + borderRight() : m_minWidth; if (style()->marginLeft().isFixed()) m_marginLeft = style()->marginLeft().value(); else m_marginLeft = 0; if (style()->marginRight().isFixed()) m_marginRight = style()->marginRight().value(); else m_marginRight = 0;}void RenderCanvas::calcMinMaxWidth(){ KHTMLAssert( !minMaxKnown() ); RenderBlock::calcMinMaxWidth(); m_maxWidth = m_minWidth; setMinMaxKnown();}//#define SPEED_DEBUGvoid RenderCanvas::layout(){ if (m_pagedMode) { m_minWidth = m_width;// m_maxWidth = m_width; } m_needsFullRepaint = markedForRepaint() || !view() || view()->needsFullRepaint() || m_pagedMode; setChildNeedsLayout(true); setMinMaxKnown(false); for(RenderObject* c = firstChild(); c; c = c->nextSibling()) c->setChildNeedsLayout(true);#ifdef SPEED_DEBUG QTime qt; qt.start();#endif if ( recalcMinMax() ) recalcMinMaxWidths();#ifdef SPEED_DEBUG kdDebug() << "RenderCanvas::calcMinMax time used=" << qt.elapsed() << endl; qt.start();#endif#ifdef SPEED_DEBUG kdDebug() << "RenderCanvas::layout time used=" << qt.elapsed() << endl; qt.start();#endif if (m_pagedMode || !m_view) { m_width = m_rootWidth; m_height = m_rootHeight; } else { m_viewportWidth = m_width = m_view->visibleWidth(); m_viewportHeight = m_height = m_view->visibleHeight(); } RenderBlock::layout(); int docW = docWidth(); int docH = docHeight(); if (!m_pagedMode) { bool vss = m_view->verticalScrollBar()->isShown(); bool hss = m_view->horizontalScrollBar()->isShown(); QSize s = m_view->viewportSize(docW, docH); // content size, with scrollbar hysteresis int hDocH = docH; int hDocW = docW; // if we are about to show a scrollbar, and the document is sized to the viewport w or h, // then reserve the scrollbar space so that it doesn't trigger the _other_ scrollbar if (!vss && m_width - m_view->verticalScrollBar()->sizeHint().width() == s.width() && docW <= m_width) hDocW = kMin( docW, s.width() ); if (!hss && m_height - m_view->horizontalScrollBar()->sizeHint().height() == s.height() && docH <= m_height) hDocH = kMin( docH, s.height() ); // likewise, if a scrollbar is shown, and we have a cunning plan to turn it off, // think again if we are falling downright in the hysteresis zone if (vss && s.width() > docW && docW > m_view->visibleWidth()) hDocW = s.width()+1; if (hss && s.height() > docH && docH > m_view->visibleHeight()) hDocH = s.height()+1; m_view->resizeContents(hDocW, hDocH); setWidth( m_viewportWidth = s.width() ); setHeight( m_viewportHeight = s.height() ); } // ### we could maybe do the call below better and only pass true if the docsize changed. layoutPositionedObjects( true );#ifdef SPEED_DEBUG kdDebug() << "RenderCanvas::end time used=" << qt.elapsed() << endl;#endif// kdDebug(6040) << "RenderCanvas::resize layer to " << kMax( docW,int( m_width ) ) << "x" << kMax( docH,m_height ) << endl; layer()->resize( kMax( docW,int( m_width ) ), kMax( docH,m_height ) ); layer()->updateLayerPositions( layer(), needsFullRepaint(), true ); scheduleDeferredRepaints(); setNeedsLayout(false);}bool RenderCanvas::needsFullRepaint() const{ return m_needsFullRepaint || m_pagedMode;}void RenderCanvas::repaintViewRectangle(int x, int y, int w, int h){ KHTMLAssert( view() ); view()->scheduleRepaint( x, y, w, h );}bool RenderCanvas::absolutePosition(int &xPos, int &yPos, bool f){ if ( f && m_pagedMode) { xPos = 0; yPos = m_pageTop; } else if ( f && m_view) { xPos = m_view->contentsX(); yPos = m_view->contentsY(); } else { xPos = yPos = 0; } return true;}void RenderCanvas::paint(PaintInfo& paintInfo, int _tx, int _ty){#ifdef DEBUG_LAYOUT kdDebug( 6040 ) << renderName() << this << " ::paintObject() w/h = (" << width() << "/" << height() << ")" << endl;#endif // 1. paint background, borders etc if(paintInfo.phase == PaintActionElementBackground) { paintBoxDecorations(paintInfo, _tx, _ty); return; } // 2. paint contents for( RenderObject *child = firstChild(); child; child=child->nextSibling()) if(!child->layer() && !child->isFloating()) child->paint(paintInfo, _tx, _ty); // 3. paint floats. if (paintInfo.phase == PaintActionFloat) paintFloats(paintInfo, _tx, _ty);#ifdef BOX_DEBUG if (m_view) { _tx += m_view->contentsX(); _ty += m_view->contentsY(); } outlineBox(p, _tx, _ty);#endif}void RenderCanvas::paintBoxDecorations(PaintInfo& paintInfo, int /*_tx*/, int /*_ty*/){ if ((firstChild() && firstChild()->style()->visibility() == VISIBLE) || !view()) return; paintInfo.p->fillRect(paintInfo.r, view()->palette().active().color(QColorGroup::Base));}void RenderCanvas::repaintRectangle(int x, int y, int w, int h, bool immediate, bool f){ if (m_staticMode) return;// kdDebug( 6040 ) << "updating views contents (" << x << "/" << y << ") (" << w << "/" << h << ")" << endl; if (f && m_pagedMode) { y += m_pageTop; } else if ( f && m_view ) { x += m_view->contentsX(); y += m_view->contentsY(); } QRect vr = viewRect(); QRect ur(x, y, w, h); if (m_view && ur.intersects(vr)) { if (immediate) // ### KWQ's updateContents has an additional parameter "now". // It's not clear what the difference between updateContents(...,true) // and repaintContents(...) is. As Qt doesn't have this, I'm leaving it out. (LS) m_view->updateContents(ur/*, true*/); else m_view->scheduleRepaint(x, y, w, h); }}void RenderCanvas::deferredRepaint( RenderObject* o ){ m_dirtyChildren.append( o );}void RenderCanvas::scheduleDeferredRepaints(){ if (!needsFullRepaint()) { QValueList<RenderObject*>::const_iterator it; for ( it = m_dirtyChildren.begin(); it != m_dirtyChildren.end(); ++it ) (*it)->repaint(); } //kdDebug(6040) << "scheduled deferred repaints: " << m_dirtyChildren.count() << " needed full repaint: " << needsFullRepaint() << endl; m_dirtyChildren.clear();}void RenderCanvas::repaint(bool immediate){ if (m_view && !m_staticMode) { if (immediate) { //m_view->resizeContents(docWidth(), docHeight()); m_view->unscheduleRepaint(); if (needsLayout()) { m_view->scheduleRelayout(); return; } // ### same as in repaintRectangle m_view->updateContents(m_view->contentsX(), m_view->contentsY(), m_view->visibleWidth(), m_view->visibleHeight()/*, true*/); } else m_view->scheduleRepaint(m_view->contentsX(), m_view->contentsY(), m_view->visibleWidth(), m_view->visibleHeight()); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -