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

📄 render_line.cpp

📁 手机浏览器源码程序,功能强大
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/**
* 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 NDEBUG
static bool inInlineBoxDetach;
#endif

namespace 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;
    }

    virtual void paint(RenderObject::PaintInfo& i, int _tx, int _ty);
    virtual bool nodeAtPoint(RenderObject::NodeInfo& info, int _x, int _y, int _tx, int _ty);

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)
{
    m_object->setInlineBoxWrapper(0);
    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);
}

void InlineBox::paint(RenderObject::PaintInfo& i, int tx, int ty)
{
    if (!object()->shouldPaintWithinRoot(i) || i.phase == PaintActionOutline)
        return;

    // Paint all phases of replaced elements atomically, as though the replaced element established its
    // own stacking context.  (See Appendix E.2, section 6.4 on inline block/table elements in the CSS2.1
    // specification.)
    bool paintSelectionOnly = i.phase == PaintActionSelection;
    RenderObject::PaintInfo info(i.p, i.r, paintSelectionOnly ? i.phase : PaintActionBlockBackground, i.paintingRoot);
    object()->paint(info, tx, ty);
    if (!paintSelectionOnly) {
        info.phase = PaintActionChildBlockBackgrounds;
        object()->paint(info, tx, ty);
        info.phase = PaintActionFloat;
        object()->paint(info, tx, ty);
        info.phase = PaintActionForeground;
        object()->paint(info, tx, ty);
        info.phase = PaintActionOutline;
        object()->paint(info, tx, ty);
    }
}

bool InlineBox::nodeAtPoint(RenderObject::NodeInfo& i, int x, int y, int tx, int ty)
{
    // Hit test all phases of replaced elements atomically, as though the replaced element established its
    // own stacking context.  (See Appendix E.2, section 6.4 on inline block/table elements in the CSS2.1
    // specification.)
    return object()->hitTest(i, x, y, tx, ty);
}

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::nextLeafChild()
{
    return parent() ? parent()->firstLeafChildAfterBox(this) : 0;
}

InlineBox* InlineBox::prevLeafChild()
{
    return parent() ? parent()->lastLeafChildBeforeBox(this) : 0;
}

RenderObject::SelectionState InlineBox::selectionState()
{
    return object()->selectionState();
}

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;
}

RenderFlow* InlineFlowBox::flowObject()
{
    return static_cast<RenderFlow*>(m_object);
}

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::addToLine(InlineBox* child) {
    if (!m_firstChild)
        m_firstChild = m_lastChild = child;
    else {
        m_lastChild->m_next = child;
        child->m_prev = m_lastChild;
        m_lastChild = child;
    }
    child->setFirstLineStyleBit(m_firstLine);
    child->setParent(this);
    if (child->isText())
        m_hasTextChildren = true;
    if (child->object()->selectionState() != RenderObject::SelectionNone)
        root()->setHasSelectedChildren(true);
}

void InlineFlowBox::removeChild(InlineBox* child)
{
    if (!m_dirty)
        dirtyLineBoxes();

    root()->childRemoved(child);

    if (child == m_firstChild)

⌨️ 快捷键说明

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