summaryrefslogtreecommitdiffstats
path: root/khtml/rendering/render_table.h
diff options
context:
space:
mode:
Diffstat (limited to 'khtml/rendering/render_table.h')
-rw-r--r--khtml/rendering/render_table.h524
1 files changed, 524 insertions, 0 deletions
diff --git a/khtml/rendering/render_table.h b/khtml/rendering/render_table.h
new file mode 100644
index 000000000..979b92187
--- /dev/null
+++ b/khtml/rendering/render_table.h
@@ -0,0 +1,524 @@
+/*
+ * This file is part of the DOM implementation for KDE.
+ *
+ * Copyright (C) 1997 Martin Jones (mjones@kde.org)
+ * (C) 1997 Torben Weis (weis@kde.org)
+ * (C) 1998 Waldo Bastian (bastian@kde.org)
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (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_TABLE_H
+#define RENDER_TABLE_H
+
+#include <qcolor.h>
+#include <qptrvector.h>
+
+#include "rendering/render_box.h"
+#include "rendering/render_block.h"
+#include "rendering/render_style.h"
+
+#include "misc/khtmllayout.h"
+
+namespace DOM {
+ class DOMString;
+}
+
+namespace khtml {
+
+class RenderTable;
+class RenderTableSection;
+class RenderTableRow;
+class RenderTableCell;
+class RenderTableCol;
+class TableLayout;
+
+class RenderTable : public RenderBlock
+{
+public:
+
+ RenderTable(DOM::NodeImpl* node);
+ ~RenderTable();
+
+ virtual const char *renderName() const { return "RenderTable"; }
+
+ virtual void setStyle(RenderStyle *style);
+
+ virtual bool isTable() const { return true; }
+
+ int getColumnPos(int col) const
+ { return columnPos[col]; }
+
+ int borderHSpacing() const { return hspacing; }
+ int borderVSpacing() const { return vspacing; }
+
+ bool collapseBorders() const { return style()->borderCollapse(); }
+ int borderLeft() const;
+ int borderRight() const;
+ int borderTop() const;
+ int borderBottom() const;
+ int paddingLeft() const { return collapseBorders() ? 0 : RenderBlock::paddingLeft(); }
+ int paddingRight() const { return collapseBorders() ? 0 : RenderBlock::paddingRight(); }
+ int paddingTop() const { return collapseBorders() ? 0 : RenderBlock::paddingTop(); }
+ int paddingBottom() const { return collapseBorders() ? 0 : RenderBlock::paddingBottom(); }
+
+ const QColor &bgColor() const { return style()->backgroundColor(); }
+
+ uint cellPadding() const { return padding; }
+ void setCellPadding( uint p ) { padding = p; }
+
+ // overrides
+ virtual void addChild(RenderObject *child, RenderObject *beforeChild = 0);
+ virtual void paint( PaintInfo&, int tx, int ty);
+ virtual void paintBoxDecorations(PaintInfo&, int _tx, int _ty);
+ virtual void layout();
+ virtual void calcMinMaxWidth();
+ virtual void close();
+
+ virtual short lineHeight(bool b) const;
+ virtual short baselinePosition(bool b) const;
+
+ virtual void setCellWidths( );
+
+ virtual void calcWidth();
+
+ virtual FindSelectionResult checkSelectionPoint( int _x, int _y, int _tx, int _ty,
+ DOM::NodeImpl*& node, int & offset,
+ SelPointState & );
+
+#ifdef ENABLE_DUMP
+ virtual void dump(QTextStream &stream, const QString &ind) const;
+#endif
+ struct ColumnStruct {
+ enum {
+ WidthUndefined = 0xffff
+ };
+ ColumnStruct() {
+ span = 1;
+ width = WidthUndefined;
+ }
+ ushort span;
+ ushort width; // the calculated position of the column
+ };
+
+ QMemArray<int> columnPos;
+ QMemArray<ColumnStruct> columns;
+
+ void splitColumn( int pos, int firstSpan );
+ void appendColumn( int span );
+ int numEffCols() const { return columns.size(); }
+ int spanOfEffCol( int effCol ) const { return columns[effCol].span; }
+ int colToEffCol( int col ) const {
+ int c = 0;
+ int i = 0;
+ while ( c < col && i < (int)columns.size() ) {
+ c += columns[i].span;
+ i++;
+ }
+ return i;
+ }
+ int effColToCol( int effCol ) const {
+ int c = 0;
+ for ( int i = 0; i < effCol; i++ )
+ c += columns[i].span;
+ return c;
+ }
+
+ int bordersPaddingAndSpacing() const {
+ return borderLeft() + borderRight() +
+ (collapseBorders() ? 0 : (paddingLeft() + paddingRight() + (numEffCols()+1) * borderHSpacing()));
+ }
+
+ RenderTableCol *colElement( int col );
+
+ void setNeedSectionRecalc() { needSectionRecalc = true; }
+
+ virtual RenderObject* removeChildNode(RenderObject* child);
+
+ RenderTableSection* sectionAbove(const RenderTableSection*, bool skipEmptySections = false) const;
+ RenderTableSection* sectionBelow(const RenderTableSection*, bool skipEmptySections = false) const;
+
+ RenderTableCell* cellAbove(const RenderTableCell* cell) const;
+ RenderTableCell* cellBelow(const RenderTableCell* cell) const;
+ RenderTableCell* cellLeft(const RenderTableCell* cell) const;
+ RenderTableCell* cellRight(const RenderTableCell* cell) const;
+
+ CollapsedBorderValue* currentBorderStyle() { return m_currentBorder; }
+
+ RenderTableSection *firstBodySection() const { return firstBody; }
+ RenderFlow* caption() const { return tCaption; }
+
+protected:
+
+ void recalcSections();
+
+ friend class AutoTableLayout;
+ friend class FixedTableLayout;
+
+ RenderFlow *tCaption;
+ RenderTableSection *head;
+ RenderTableSection *foot;
+ RenderTableSection *firstBody;
+
+ TableLayout *tableLayout;
+
+ CollapsedBorderValue* m_currentBorder;
+
+ bool has_col_elems : 1;
+ uint needSectionRecalc : 1;
+ uint padding : 22;
+
+ ushort hspacing;
+ ushort vspacing;
+
+ friend class TableSectionIterator;
+};
+
+// -------------------------------------------------------------------------
+
+class RenderTableSection : public RenderBox
+{
+public:
+ RenderTableSection(DOM::NodeImpl* node);
+ ~RenderTableSection();
+ virtual void detach();
+
+ virtual void setStyle(RenderStyle *style);
+
+ virtual const char *renderName() const { return "RenderTableSection"; }
+
+ // overrides
+ virtual void addChild(RenderObject *child, RenderObject *beforeChild = 0);
+ virtual bool isTableSection() const { return true; }
+
+ virtual short lineHeight(bool) const { return 0; }
+ virtual void position(InlineBox*, int, int, bool) {}
+
+ virtual short width() const;
+
+ virtual FindSelectionResult checkSelectionPoint( int _x, int _y, int _tx, int _ty,
+ DOM::NodeImpl*& node, int & offset,
+ SelPointState & );
+
+#ifdef ENABLE_DUMP
+ virtual void dump(QTextStream &stream, const QString &ind) const;
+#endif
+
+ void addCell( RenderTableCell *cell, RenderTableRow *row );
+
+ void setCellWidths();
+ void calcRowHeight();
+ int layoutRows( int height );
+
+ RenderTable *table() const { return static_cast<RenderTable *>(parent()); }
+
+ typedef QMemArray<RenderTableCell *> Row;
+ struct RowStruct {
+ Row *row;
+ RenderTableRow* rowRenderer;
+ int baseLine;
+ Length height;
+ bool needFlex;
+ };
+
+ RenderTableCell *&cellAt( int row, int col ) {
+ return (*(grid[row].row))[col];
+ }
+ RenderTableCell *cellAt( int row, int col ) const {
+ return (*(grid[row].row))[col];
+ }
+
+ virtual int lowestPosition(bool includeOverflowInterior, bool includeSelf) const;
+ virtual int rightmostPosition(bool includeOverflowInterior, bool includeSelf) const;
+ virtual int leftmostPosition(bool includeOverflowInterior, bool includeSelf) const;
+ virtual int highestPosition(bool includeOverflowInterior, bool includeSelf) const;
+
+ int borderLeft() const { return table()->collapseBorders() ? 0 : RenderBox::borderLeft(); }
+ int borderRight() const { return table()->collapseBorders() ? 0 : RenderBox::borderRight(); }
+ int borderTop() const { return table()->collapseBorders() ? 0 : RenderBox::borderTop(); }
+ int borderBottom() const { return table()->collapseBorders() ? 0 : RenderBox::borderBottom(); }
+
+ virtual void paint( PaintInfo& i, int tx, int ty);
+
+ int numRows() const { return grid.size(); }
+ int getBaseline(int row) {return grid[row].baseLine;}
+
+ void setNeedCellRecalc() {
+ needCellRecalc = true;
+ table()->setNeedSectionRecalc();
+ }
+
+ virtual RenderObject* removeChildNode(RenderObject* child);
+
+ virtual bool canClear(RenderObject *child, PageBreakLevel level);
+ void addSpaceAt(int pos, int dy);
+
+ virtual bool nodeAtPoint(NodeInfo& info, int x, int y, int tx, int ty, HitTestAction action, bool inside);
+
+ // this gets a cell grid data structure. changing the number of
+ // columns is done by the table
+ QMemArray<RowStruct> grid;
+ QMemArray<int> rowPos;
+
+ signed short cRow;
+ ushort cCol;
+ bool needCellRecalc;
+
+ void recalcCells();
+protected:
+ void ensureRows( int numRows );
+ void clearGrid();
+ bool emptyRow(int rowNum);
+ bool flexCellChildren(RenderObject* p) const;
+
+
+ friend class TableSectionIterator;
+};
+
+// -------------------------------------------------------------------------
+
+class RenderTableRow : public RenderContainer
+{
+public:
+ RenderTableRow(DOM::NodeImpl* node);
+
+ virtual void detach();
+
+ virtual void setStyle( RenderStyle* );
+ virtual const char *renderName() const { return "RenderTableRow"; }
+ virtual bool isTableRow() const { return true; }
+ virtual void addChild(RenderObject *child, RenderObject *beforeChild = 0);
+
+ virtual short offsetWidth() const;
+ virtual int offsetHeight() const;
+ virtual int offsetLeft() const;
+ virtual int offsetTop() const;
+
+ virtual short lineHeight( bool ) const { return 0; }
+ virtual void position(InlineBox*, int, int, bool) {}
+
+ virtual bool nodeAtPoint(NodeInfo& info, int x, int y, int tx, int ty, HitTestAction action, bool inside);
+
+ virtual void layout();
+
+ virtual RenderObject* removeChildNode(RenderObject* child);
+
+ // The only time rows get a layer is when they have transparency.
+ virtual bool requiresLayer() const { return /* style()->opacity() < 1.0f; */ false ; }
+ virtual void paint(PaintInfo& i, int tx, int ty);
+
+ void paintRow( PaintInfo& i, int tx, int ty, int w, int h);
+
+ RenderTable *table() const { return static_cast<RenderTable *>(parent()->parent()); }
+ RenderTableSection *section() const { return static_cast<RenderTableSection *>(parent()); }
+};
+
+// -------------------------------------------------------------------------
+
+class RenderTableCell : public RenderBlock
+{
+public:
+ RenderTableCell(DOM::NodeImpl* node);
+
+ virtual void layout();
+ virtual void detach();
+
+ virtual const char *renderName() const { return "RenderTableCell"; }
+ virtual bool isTableCell() const { return true; }
+
+ // ### FIX these two...
+ long cellIndex() const { return 0; }
+ void setCellIndex( long ) { }
+
+ unsigned short colSpan() const { return cSpan; }
+ void setColSpan( unsigned short c ) { cSpan = c; }
+
+ unsigned short rowSpan() const { return rSpan; }
+ void setRowSpan( unsigned short r ) { rSpan = r; }
+
+ int col() const { return _col; }
+ void setCol(int col) { _col = col; }
+ int row() const { return _row; }
+ void setRow(int r) { _row = r; }
+
+ Length styleOrColWidth();
+
+ // overrides
+ virtual void calcMinMaxWidth();
+ virtual void calcWidth();
+ virtual void setWidth( int width );
+ virtual void setStyle( RenderStyle *style );
+ virtual bool requiresLayer() const;
+
+ int borderLeft() const;
+ int borderRight() const;
+ int borderTop() const;
+ int borderBottom() const;
+
+ CollapsedBorderValue collapsedLeftBorder() const;
+ CollapsedBorderValue collapsedRightBorder() const;
+ CollapsedBorderValue collapsedTopBorder() const;
+ CollapsedBorderValue collapsedBottomBorder() const;
+ virtual void collectBorders(QValueList<CollapsedBorderValue>& borderStyles);
+
+ virtual void updateFromElement();
+
+ void setCellTopExtra(int p) { _topExtra = p; }
+ void setCellBottomExtra(int p) { _bottomExtra = p; }
+ int cellTopExtra() const { return _topExtra; }
+ int cellBottomExtra() const { return _bottomExtra; }
+
+ int pageTopAfter(int x) const;
+
+ virtual void paint( PaintInfo& i, int tx, int ty);
+
+ void paintCollapsedBorder(QPainter* p, int x, int y, int w, int h);
+ void paintBackgroundsBehindCell(PaintInfo& i, int _tx, int _ty, RenderObject* backgroundObject);
+
+ virtual void close();
+
+ // lie position to outside observers
+ virtual int yPos() const { return m_y + _topExtra; }
+
+ virtual void repaintRectangle(int x, int y, int w, int h, Priority p=NormalPriority, bool f=false);
+ virtual bool absolutePosition(int &xPos, int &yPos, bool f = false) const;
+
+ virtual short baselinePosition( bool = false ) const;
+
+ virtual bool nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction, bool inside);
+
+ RenderTable *table() const { return static_cast<RenderTable *>(parent()->parent()->parent()); }
+ RenderTableSection *section() const { return static_cast<RenderTableSection *>(parent()->parent()); }
+
+#ifdef ENABLE_DUMP
+ virtual void dump(QTextStream &stream, const QString &ind) const;
+#endif
+
+ bool widthChanged() {
+ bool retval = m_widthChanged;
+ m_widthChanged = false;
+ return retval;
+ }
+
+ int cellPercentageHeight() const
+ { return m_percentageHeight; }
+ void setCellPercentageHeight(int h)
+ { m_percentageHeight = h; }
+ bool hasFlexedAnonymous() const
+ { return m_hasFlexedAnonymous; }
+ void setHasFlexedAnonymous(bool b=true)
+ { m_hasFlexedAnonymous = b; }
+
+protected:
+ virtual void paintBoxDecorations(PaintInfo& p, int _tx, int _ty);
+ virtual int borderTopExtra() const { return _topExtra; }
+ virtual int borderBottomExtra() const { return _bottomExtra; }
+
+ short _row;
+ short _col;
+ ushort rSpan;
+ ushort cSpan;
+ int _topExtra;
+ signed int _bottomExtra : 30;
+ bool m_widthChanged : 1;
+ bool m_hasFlexedAnonymous : 1;
+ int m_percentageHeight;
+};
+
+
+// -------------------------------------------------------------------------
+
+class RenderTableCol : public RenderContainer
+{
+public:
+ RenderTableCol(DOM::NodeImpl* node);
+
+ virtual const char *renderName() const { return "RenderTableCol"; }
+
+ virtual bool isTableCol() const { return true; }
+
+ virtual short lineHeight( bool ) const { return 0; }
+ virtual void position(InlineBox*, int, int, bool) {}
+ virtual void layout() {}
+ virtual bool requiresLayer() const { return false; }
+
+ virtual void updateFromElement();
+
+#ifdef ENABLE_DUMP
+ virtual void dump(QTextStream &stream, const QString& ind) const;
+#endif
+
+ int span() const { return m_span; }
+ void setSpan( int s ) { m_span = s; }
+
+private:
+ int m_span;
+};
+
+// -------------------------------------------------------------------------
+
+/** This class provides an iterator to iterate through the sections of a
+ * render table in their visual order.
+ *
+ * In HTML, sections are specified in the order of THEAD, TFOOT, and TBODY.
+ * Visually, TBODY sections appear between THEAD and TFOOT, which this iterator
+ * takes into regard.
+ * @author Leo Savernik
+ * @internal
+ * @since 3.2
+ */
+class TableSectionIterator {
+public:
+
+ /**
+ * Initializes a new iterator
+ * @param table table whose sections to iterate
+ * @param fromEnd @p true, begin with last section, @p false, begin with
+ * first section.
+ */
+ TableSectionIterator(RenderTable *table, bool fromEnd = false);
+
+ /**
+ * Initializes a new iterator
+ * @param start table section to start with.
+ */
+ TableSectionIterator(RenderTableSection *start) : sec(start) {}
+
+ /**
+ * Uninitialized iterator.
+ */
+ TableSectionIterator() {}
+
+ /** Returns the current section, or @p 0 if the end has been reached.
+ */
+ RenderTableSection *operator *() const { return sec; }
+
+ /** Moves to the next section in visual order. */
+ TableSectionIterator &operator ++();
+
+ /** Moves to the previous section in visual order. */
+ TableSectionIterator &operator --();
+
+private:
+ RenderTableSection *sec;
+};
+
+}
+#endif
+