📄 render_line.cpp
字号:
/*** This file is part of the html renderer for KDE. * * 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 "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;#ifndef NDEBUGstatic bool inInlineBoxDetach;#endifnamespace khtml { class EllipsisBox : public InlineBox{public: EllipsisBox(RenderObject* obj, const DOM::AtomicString& ellipsisStr, InlineFlowBox* p, int w, int y, int h, int b, bool firstLine, InlineBox* markupBox) :InlineBox(obj), m_str(ellipsisStr) { m_parent = p; m_width = w; m_y = y; m_height = h; m_baseline = b; m_firstLine = firstLine; m_constructed = true; m_markupBox = markupBox; } void paint(RenderObject::PaintInfo& i, int _tx, int _ty); bool nodeAtPoint(RenderObject::NodeInfo& info, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction, bool inBox);private: DOM::AtomicString m_str; InlineBox* m_markupBox;};void InlineBox::remove(){ if (parent()) parent()->removeChild(this);}void InlineBox::detach(RenderArena* renderArena){#ifndef NDEBUG inInlineBoxDetach = true;#endif delete this;#ifndef NDEBUG inInlineBoxDetach = false;#endif // Recover the size left there for us by operator delete and free the memory. renderArena->free(*(size_t *)this, this);}void* InlineBox::operator new(size_t sz, RenderArena* renderArena) throw(){ return renderArena->allocate(sz);}void InlineBox::operator delete(void* ptr, size_t sz){ assert(inInlineBoxDetach); // Stash size where detach can find it. *(size_t *)ptr = sz;}long InlineBox::caretMinOffset() const { return 0; }long InlineBox::caretMaxOffset() const { return 1; }unsigned long InlineBox::caretMaxRenderedOffset() const { return 1; }void InlineBox::dirtyLineBoxes(){ markDirty(); for (InlineFlowBox* curr = parent(); curr && !curr->isDirty(); curr = curr->parent()) curr->markDirty();}void InlineBox::deleteLine(RenderArena* arena){ detach(arena);}void InlineBox::extractLine(){ m_extracted = true; m_object->setInlineBoxWrapper(0);}void InlineBox::attachLine(){ m_extracted = false; m_object->setInlineBoxWrapper(this);}void InlineBox::adjustPosition(int dx, int dy){ m_x += dx; m_y += dy; if (m_object->isReplaced() || m_object->isBR()) m_object->setPos(m_object->xPos() + dx, m_object->yPos() + dy);}RootInlineBox* InlineBox::root(){ if (m_parent) return m_parent->root(); return static_cast<RootInlineBox*>(this);}bool InlineBox::nextOnLineExists() const{ if (!parent()) return false; if (nextOnLine()) return true; return parent()->nextOnLineExists();}bool InlineBox::prevOnLineExists() const{ if (!parent()) return false; if (prevOnLine()) return true; return parent()->prevOnLineExists();}InlineBox* InlineBox::firstLeafChild(){ return this;}InlineBox* InlineBox::lastLeafChild(){ return this;}InlineBox* InlineBox::closestLeafChildForXPos(int _x, int _tx){ if (!isInlineFlowBox()) return this; InlineFlowBox *flowBox = static_cast<InlineFlowBox*>(this); if (!flowBox->firstChild()) return this; InlineBox *box = flowBox->closestChildForXPos(_x, _tx); if (!box) return this; return box->closestLeafChildForXPos(_x, _tx);}bool InlineBox::canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsisWidth){ // Non-replaced elements can always accommodate an ellipsis. if (!m_object || !m_object->isReplaced()) return true; QRect boxRect(m_x, 0, m_width, 10); QRect ellipsisRect(ltr ? blockEdge - ellipsisWidth : blockEdge, 0, ellipsisWidth, 10); return !(boxRect.intersects(ellipsisRect));}int InlineBox::placeEllipsisBox(bool ltr, int blockEdge, int ellipsisWidth, bool&){ // Use -1 to mean "we didn't set the position." return -1;}int InlineFlowBox::marginLeft(){ if (!includeLeftEdge()) return 0; RenderStyle* cstyle = object()->style(); Length margin = cstyle->marginLeft(); if (margin.type != Variable) return (margin.type == Fixed ? margin.value : object()->marginLeft()); return 0;}int InlineFlowBox::marginRight(){ if (!includeRightEdge()) return 0; RenderStyle* cstyle = object()->style(); Length margin = cstyle->marginRight(); if (margin.type != Variable) return (margin.type == Fixed ? margin.value : object()->marginRight()); return 0;}int InlineFlowBox::marginBorderPaddingLeft(){ return marginLeft() + borderLeft() + paddingLeft();}int InlineFlowBox::marginBorderPaddingRight(){ return marginRight() + borderRight() + paddingRight();}int InlineFlowBox::getFlowSpacingWidth(){ int totWidth = marginBorderPaddingLeft() + marginBorderPaddingRight(); for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) { if (curr->isInlineFlowBox()) totWidth += static_cast<InlineFlowBox*>(curr)->getFlowSpacingWidth(); } return totWidth;}void InlineFlowBox::removeChild(InlineBox* child){ if (!m_dirty) dirtyLineBoxes(); root()->childRemoved(child); if (child == m_firstChild) m_firstChild = child->nextOnLine(); if (child == m_lastChild) m_lastChild = child->prevOnLine(); if (child->nextOnLine()) child->nextOnLine()->setPrevOnLine(child->prevOnLine()); if (child->prevOnLine()) child->prevOnLine()->setNextOnLine(child->nextOnLine()); child->setParent(0);}void InlineFlowBox::deleteLine(RenderArena* arena){ InlineBox* child = m_firstChild; InlineBox* next = 0; while (child) { next = child->nextOnLine(); child->deleteLine(arena); child = next; } static_cast<RenderFlow*>(m_object)->removeLineBox(this); detach(arena);}void InlineFlowBox::extractLine(){ if (!m_extracted) static_cast<RenderFlow*>(m_object)->extractLineBox(this); for (InlineBox* child = m_firstChild; child; child = child->nextOnLine()) child->extractLine();}void InlineFlowBox::attachLine(){ if (m_extracted) static_cast<RenderFlow*>(m_object)->attachLineBox(this); for (InlineBox* child = m_firstChild; child; child = child->nextOnLine()) child->attachLine();}void InlineFlowBox::adjustPosition(int dx, int dy){ InlineRunBox::adjustPosition(dx, dy); for (InlineBox* child = m_firstChild; child; child = child->nextOnLine()) child->adjustPosition(dx, dy);}bool InlineFlowBox::onEndChain(RenderObject* endObject){ if (!endObject) return false; if (endObject == object()) return true; RenderObject* curr = endObject; RenderObject* parent = curr->parent(); while (parent && !parent->isRenderBlock()) { if (parent->lastChild() != curr) return false; curr = parent; parent = curr->parent(); } return true;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -