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

📄 render_flow.cpp

📁 khtml在gtk上的移植版本
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/** * This file is part of the html renderer for KDE. * * Copyright (C) 1999 Lars Knoll (knoll@kde.org) *           (C) 1999 Antti Koivisto (koivisto@kde.org) * Copyright (C) 2003 Apple Computer, Inc. * * 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., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */// -------------------------------------------------------------------------#include <kdebug.h>#include <assert.h>#include <qpainter.h>#include <kglobal.h>#include "rendering/render_flow.h"#include "rendering/render_text.h"#include "rendering/render_table.h"#include "rendering/render_canvas.h"#include "xml/dom_nodeimpl.h"#include "xml/dom_docimpl.h"#include "html/html_formimpl.h"#include "render_inline.h"#include "render_block.h"#include "render_arena.h"#include "render_line.h"#include "khtmlview.h"#include "htmltags.h"using namespace DOM;using namespace khtml;RenderFlow* RenderFlow::createAnonymousFlow(DOM::DocumentImpl* doc, RenderStyle* style){    RenderFlow* result;    if (style->display() == INLINE)        result = new (doc->renderArena()) RenderInline(doc);    else        result = new (doc->renderArena()) RenderBlock(doc);    result->setStyle(style);    return result;}RenderFlow* RenderFlow::continuationBefore(RenderObject* beforeChild){    if (beforeChild && beforeChild->parent() == this)        return this;        RenderFlow* curr = continuation();    RenderFlow* nextToLast = this;    RenderFlow* last = this;    while (curr) {        if (beforeChild && beforeChild->parent() == curr) {            if (curr->firstChild() == beforeChild)                return last;            return curr;        }                nextToLast = last;        last = curr;        curr = curr->continuation();    }        if (!beforeChild && !last->firstChild())        return nextToLast;    return last;}void RenderFlow::addChildWithContinuation(RenderObject* newChild, RenderObject* beforeChild){    RenderFlow* flow = continuationBefore(beforeChild);    KHTMLAssert(!beforeChild || beforeChild->parent()->isRenderBlock() ||                beforeChild->parent()->isRenderInline());    RenderFlow* beforeChildParent = beforeChild ? static_cast<RenderFlow*>(beforeChild->parent()) :                                     (flow->continuation() ? flow->continuation() : flow);        if (newChild->isFloatingOrPositioned())        return beforeChildParent->addChildToFlow(newChild, beforeChild);        // A continuation always consists of two potential candidates: an inline or an anonymous    // block box holding block children.    bool childInline = newChild->isInline();    bool bcpInline = beforeChildParent->isInline();    bool flowInline = flow->isInline();        if (flow == beforeChildParent)        return flow->addChildToFlow(newChild, beforeChild);    else {        // The goal here is to match up if we can, so that we can coalesce and create the        // minimal # of continuations needed for the inline.        if (childInline == bcpInline)            return beforeChildParent->addChildToFlow(newChild, beforeChild);        else if (flowInline == childInline)            return flow->addChildToFlow(newChild, 0); // Just treat like an append.        else             return beforeChildParent->addChildToFlow(newChild, beforeChild);    }}void RenderFlow::addChild(RenderObject *newChild, RenderObject *beforeChild){#ifdef DEBUG_LAYOUT    kdDebug( 6040 ) << renderName() << "(RenderFlow)::addChild( " << newChild->renderName() <<                       ", " << (beforeChild ? beforeChild->renderName() : "0") << " )" << endl;    kdDebug( 6040 ) << "current height = " << m_height << endl;#endif    if (continuation())        return addChildWithContinuation(newChild, beforeChild);    return addChildToFlow(newChild, beforeChild);}void RenderFlow::extractLineBox(InlineFlowBox* box){    m_lastLineBox = box->prevFlowBox();    if (box == m_firstLineBox)        m_firstLineBox = 0;    if (box->prevLineBox())        box->prevLineBox()->setNextLineBox(0);    box->setPreviousLineBox(0);    for (InlineRunBox* curr = box; curr; curr = curr->nextLineBox())        curr->setExtracted();}void RenderFlow::attachLineBox(InlineFlowBox* box){    if (m_lastLineBox) {        m_lastLineBox->setNextLineBox(box);        box->setPreviousLineBox(m_lastLineBox);    }    else        m_firstLineBox = box;    InlineFlowBox* last = box;    for (InlineFlowBox* curr = box; curr; curr = curr->nextFlowBox()) {        curr->setExtracted(false);        last = curr;    }    m_lastLineBox = last;}void RenderFlow::removeLineBox(InlineFlowBox* box){    if (box == m_firstLineBox)        m_firstLineBox = box->nextFlowBox();    if (box == m_lastLineBox)        m_lastLineBox = box->prevFlowBox();    if (box->nextLineBox())        box->nextLineBox()->setPreviousLineBox(box->prevLineBox());    if (box->prevLineBox())        box->prevLineBox()->setNextLineBox(box->nextLineBox());}void RenderFlow::deleteLineBoxes(){    if (m_firstLineBox) {        RenderArena* arena = renderArena();        InlineRunBox *curr=m_firstLineBox, *next=0;        while (curr) {            next = curr->nextLineBox();            curr->detach(arena);            curr = next;        }        m_firstLineBox = 0;        m_lastLineBox = 0;    }}void RenderFlow::detach(){    if (!documentBeingDestroyed() && m_firstLineBox && m_firstLineBox->parent()) {        for (InlineRunBox* box = m_firstLineBox; box; box = box->nextLineBox())            box->parent()->removeChild(box);    }    deleteLineBoxes();    RenderBox::detach();}void RenderFlow::dirtyLinesFromChangedChild(RenderObject* child){    if (!parent() || selfNeedsLayout() || isTable())        return;        if (!isInline() && (!child->nextSibling() || !firstLineBox())) {        // An append onto the end of a block or we don't have any lines anyway.          // In this case we don't have to dirty any specific lines.        static_cast<RenderBlock*>(this)->setLinesAppended();        return;    }        // For an empty inline, go ahead and propagate the check up to our parent.    if (isInline() && !firstLineBox())        return parent()->dirtyLinesFromChangedChild(this);        // Try to figure out which line box we belong in.  First try to find a previous    // line box by examining our siblings.  If we didn't find a line box, then use our     // parent's first line box.    RootInlineBox* box = 0;    for (RenderObject* curr = child->previousSibling(); curr; curr = curr->previousSibling()) {        if (curr->isFloatingOrPositioned())            continue;                if (curr->isReplaced()) {            InlineBox* wrapper = curr->inlineBoxWrapper();            if (wrapper)                box = wrapper->root();        }        else if (curr->isText()) {            InlineTextBox* textBox = static_cast<RenderText*>(curr)->lastTextBox();            if (textBox)                box = textBox->root();        }        else if (curr->isInlineFlow()) {            InlineRunBox* runBox = static_cast<RenderFlow*>(curr)->lastLineBox();            if (runBox)                box = runBox->root();        }                if (box)            break;    }    if (!box)        box = lastLineBox()->root();    // If we found a line box, then dirty it.    if (box) {        box->markDirty();        if (child->isBR()) {            RootInlineBox* next = box->nextRootBox();            if (next)                next->markDirty();        }    }}short RenderFlow::lineHeight(bool firstLine, bool isRootLineBox) const{    if (firstLine) {        RenderStyle* s = style(firstLine);        Length lh = s->lineHeight();        if (lh.value < 0) {            if (s == style()) {                if (m_lineHeight == -1)                    m_lineHeight = RenderObject::lineHeight(false);                return m_lineHeight;            }            return s->fontMetrics().lineSpacing();	}        if (lh.isPercent())

⌨️ 快捷键说明

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