You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdelibs/khtml/rendering/render_line.h

319 lines
11 KiB

/*
* This file is part of the line box implementation 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., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
*/
#ifndef RENDER_LINE_H
#define RENDER_LINE_H
namespace khtml {
class EllipsisBox;
class InlineFlowBox;
class RootInlineBox;
// InlineBox represents a rectangle that occurs on a line. It corresponds to
// some RenderObject (i.e., it represents a portion of that RenderObject).
class InlineBox
{
public:
InlineBox(RenderObject* obj)
:m_object(obj), m_x(0), m_width(0), m_y(0), m_height(0), m_baseline(0),
m_firstLine(false), m_constructed(false)
{
m_next = 0;
m_prev = 0;
m_parent = 0;
}
virtual ~InlineBox() {}
void detach(RenderArena* renderArena);
virtual void paint(RenderObject::PaintInfo& i, int _tx, int _ty);
virtual bool nodeAtPoint(RenderObject::NodeInfo& i, int x, int y, int tx, int ty);
// Overloaded new operator.
void* operator new(size_t sz, RenderArena* renderArena) throw();
// Overridden to prevent the normal delete from being called.
void operator delete(void* ptr, size_t sz);
private:
// The normal operator new is disallowed.
void* operator new(size_t sz) throw();
public:
virtual bool isInlineBox() const { return false; }
virtual bool isInlineFlowBox() const { return false; }
virtual bool isContainer() const { return false; }
virtual bool isInlineTextBox() const { return false; }
virtual bool isRootInlineBox() const { return false; }
bool isConstructed() const { return m_constructed; }
virtual void setConstructed() {
m_constructed = true;
if (m_next)
m_next->setConstructed();
}
void setFirstLineStyleBit(bool f) { m_firstLine = f; }
InlineBox* nextOnLine() { return m_next; }
InlineBox* prevOnLine() { return m_prev; }
RenderObject* object() const { return m_object; }
InlineFlowBox* parent() { return m_parent; }
void setParent(InlineFlowBox* par) { m_parent = par; }
RootInlineBox* root();
void setWidth(short w) {
if (w < 0) {
m_width = SHRT_MAX;
kdDebug( 6040 ) << " InlineBox::setWidth() invalid negative width " << w << " specified!" << endl;
}
else {
m_width = w;
}
}
short width() const { return m_width; }
void setXPos(short x) { m_x = x; }
short xPos() const { return m_x; }
void setYPos(int y) { m_y = y; }
int yPos() const { return m_y; }
void setHeight(int h) { m_height = h; }
int height() const { return m_height; }
void setBaseline(int b) { m_baseline = b; }
int baseline() const { return m_baseline; }
virtual bool hasTextChildren() const { return true; }
virtual bool hasTextDescendant() const { return true; }
virtual int topOverflow() const { return yPos(); }
virtual int bottomOverflow() const { return yPos()+height(); }
virtual long minOffset() const { return 0; }
virtual long maxOffset() const { return 0; }
virtual void clearTruncation() {};
virtual bool canAccommodateEllipsisBox(bool ltr, int blockEdge, int ellipsisWidth);
virtual int placeEllipsisBox(bool ltr, int blockEdge, int ellipsisWidth, bool&);
public: // FIXME: Would like to make this protected, but methods are accessing these
// members over in the part.
RenderObject* m_object;
short m_x;
short m_width;
int m_y;
int m_height;
int m_baseline;
bool m_firstLine : 1;
bool m_constructed : 1;
InlineBox* m_next; // The next element on the same line as us.
InlineBox* m_prev; // The previous element on the same line as us.
InlineFlowBox* m_parent; // The box that contains us.
};
class InlineRunBox : public InlineBox
{
public:
InlineRunBox(RenderObject* obj)
:InlineBox(obj)
{
m_prevLine = 0;
m_nextLine = 0;
}
InlineRunBox* prevLineBox() { return m_prevLine; }
InlineRunBox* nextLineBox() { return m_nextLine; }
void setNextLineBox(InlineRunBox* n) { m_nextLine = n; }
void setPreviousLineBox(InlineRunBox* p) { m_prevLine = p; }
virtual void paintBackgroundAndBorder(RenderObject::PaintInfo&, int /*_tx*/, int /*_ty*/) {}
virtual void paintDecorations(RenderObject::PaintInfo&, int /*_tx*/, int /*_ty*/, bool /*paintedChildren*/ = false) {}
protected:
InlineRunBox* m_prevLine; // The previous box that also uses our RenderObject
InlineRunBox* m_nextLine; // The next box that also uses our RenderObject
};
class InlineFlowBox : public InlineRunBox
{
public:
InlineFlowBox(RenderObject* obj)
:InlineRunBox(obj)
{
m_firstChild = 0;
m_lastChild = 0;
m_includeLeftEdge = m_includeRightEdge = false;
m_hasTextChildren = false;
m_hasTextDescendant = false;
m_afterPageBreak = false;
}
~InlineFlowBox();
virtual bool isInlineFlowBox() const { return true; }
InlineFlowBox* prevFlowBox() const { return static_cast<InlineFlowBox*>(m_prevLine); }
InlineFlowBox* nextFlowBox() const { return static_cast<InlineFlowBox*>(m_nextLine); }
InlineBox* firstChild() const { return m_firstChild; }
InlineBox* lastChild() const { return m_lastChild; }
virtual void setConstructed() {
InlineBox::setConstructed();
if (m_firstChild)
m_firstChild->setConstructed();
}
void 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 (!m_hasTextChildren && child->isInlineTextBox()) {
m_hasTextDescendant = m_hasTextChildren = true;
for (InlineFlowBox* p = m_parent; p && !p->hasTextDescendant(); p = p->parent())
p->m_hasTextDescendant = true;
}
}
virtual void clearTruncation();
void removeFromLine(InlineBox* child);
virtual void paintBackgroundAndBorder(RenderObject::PaintInfo&, int _tx, int _ty);
void paintBackgrounds(TQPainter* p, const TQColor& c, const BackgroundLayer* bgLayer,
int my, int mh, int _tx, int _ty, int w, int h);
void paintBackground(TQPainter* p, const TQColor& c, const BackgroundLayer* bgLayer,
int my, int mh, int _tx, int _ty, int w, int h);
virtual void paint(RenderObject::PaintInfo& i, int _tx, int _ty);
virtual void paintDecorations(RenderObject::PaintInfo&, int _tx, int _ty, bool paintedChildren = false);
virtual bool nodeAtPoint(RenderObject::NodeInfo& i, int x, int y, int tx, int ty);
int marginBorderPaddingLeft() const;
int marginBorderPaddingRight() const;
int marginLeft() const;
int marginRight( )const;
int borderLeft() const { if (includeLeftEdge()) return object()->borderLeft(); return 0; }
int borderRight() const { if (includeRightEdge()) return object()->borderRight(); return 0; }
int paddingLeft() const { if (includeLeftEdge()) return object()->paddingLeft(); return 0; }
int paddingRight() const { if (includeRightEdge()) return object()->paddingRight(); return 0; }
bool includeLeftEdge() const { return m_includeLeftEdge; }
bool includeRightEdge() const { return m_includeRightEdge; }
void setEdges(bool includeLeft, bool includeRight) {
m_includeLeftEdge = includeLeft;
m_includeRightEdge = includeRight;
}
virtual bool hasTextChildren() const { return m_hasTextChildren; }
bool hasTextDescendant() const { return m_hasTextDescendant; }
// Helper functions used during line construction and placement.
void determineSpacingForFlowBoxes(bool lastLine, RenderObject* endObject);
int getFlowSpacingWidth() const;
bool nextOnLineExists();
bool prevOnLineExists();
bool onEndChain(RenderObject* endObject);
int placeBoxesHorizontally(int x);
void verticallyAlignBoxes(int& heightOfBlock);
void computeLogicalBoxHeights(int& maxPositionTop, int& maxPositionBottom,
int& maxAscent, int& maxDescent, bool strictMode);
void adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent,
int maxPositionTop, int maxPositionBottom);
void placeBoxesVertically(int y, int maxHeight, int maxAscent, bool strictMode,
int& topPosition, int& bottomPosition);
void shrinkBoxesWithNoTextChildren(int topPosition, int bottomPosition);
virtual void setOverflowPositions(int /*top*/, int /*bottom*/) {}
void setAfterPageBreak(bool b = true) { m_afterPageBreak = b; }
bool afterPageBreak() const { return m_afterPageBreak; }
virtual bool canAccommodateEllipsisBox(bool ltr, int blockEdge, int ellipsisWidth);
virtual int placeEllipsisBox(bool ltr, int blockEdge, int ellipsisWidth, bool&);
protected:
InlineBox* m_firstChild;
InlineBox* m_lastChild;
bool m_includeLeftEdge : 1;
bool m_includeRightEdge : 1;
bool m_hasTextChildren : 1;
bool m_hasTextDescendant : 1;
bool m_afterPageBreak : 1;
};
class RootInlineBox : public InlineFlowBox
{
public:
RootInlineBox(RenderObject* obj) : InlineFlowBox(obj), m_ellipsisBox(0)
{
m_topOverflow = m_bottomOverflow = 0;
}
virtual void detach(RenderArena* renderArena);
void detachEllipsisBox(RenderArena* renderArena);
RootInlineBox* nextRootBox() { return static_cast<RootInlineBox*>(m_nextLine); }
RootInlineBox* prevRootBox() { return static_cast<RootInlineBox*>(m_prevLine); }
virtual bool isRootInlineBox() const { return true; }
virtual int topOverflow() const { return m_topOverflow; }
virtual int bottomOverflow() const { return m_bottomOverflow; }
virtual void setOverflowPositions(int top, int bottom) { m_topOverflow = top; m_bottomOverflow = bottom; }
bool canAccommodateEllipsis(bool ltr, int blockEdge, int lineBoxEdge, int ellipsisWidth);
void placeEllipsis(const DOM::DOMString& ellipsisStr, bool ltr, int blockEdge, int ellipsisWidth, InlineBox* markupBox = 0);
virtual int placeEllipsisBox(bool ltr, int blockEdge, int ellipsisWidth, bool&);
EllipsisBox* ellipsisBox() const { return m_ellipsisBox; }
void paintEllipsisBox(RenderObject::PaintInfo& i, int _tx, int _ty) const;
bool hitTestEllipsisBox(RenderObject::NodeInfo& info, int _x, int _y, int _tx, int _ty);
virtual void clearTruncation();
virtual void paint(RenderObject::PaintInfo& i, int _tx, int _ty);
virtual bool nodeAtPoint(RenderObject::NodeInfo& i, int x, int y, int tx, int ty);
protected:
int m_topOverflow;
int m_bottomOverflow;
// An inline text box that represents our text truncation string.
EllipsisBox* m_ellipsisBox;
};
} //namespace
#endif