Warning, file /frameworks/khtml/src/rendering/render_table.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002  * This file is part of the DOM implementation for KDE.
0003  *
0004  * Copyright (C) 1997 Martin Jones (mjones@kde.org)
0005  *           (C) 1997 Torben Weis (weis@kde.org)
0006  *           (C) 1998 Waldo Bastian (bastian@kde.org)
0007  *           (C) 1999-2003 Lars Knoll (knoll@kde.org)
0008  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
0009  *           (C) 2003 Apple Computer, Inc.
0010  *           (C) 2009 Carlos Licea (carlos.licea@kdemail.net)
0011  *
0012  * This library is free software; you can redistribute it and/or
0013  * modify it under the terms of the GNU Library General Public
0014  * License as published by the Free Software Foundation; either
0015  * version 2 of the License, or (at your option) any later version.
0016  *
0017  * This library is distributed in the hope that it will be useful,
0018  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0019  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0020  * Library General Public License for more details.
0021  *
0022  * You should have received a copy of the GNU Library General Public License
0023  * along with this library; see the file COPYING.LIB.  If not, write to
0024  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0025  * Boston, MA 02110-1301, USA.
0026  *
0027  */
0028 #ifndef RENDER_TABLE_H
0029 #define RENDER_TABLE_H
0030 
0031 #include <QColor>
0032 #include <QVector>
0033 
0034 #include "rendering/render_box.h"
0035 #include "rendering/render_block.h"
0036 #include "rendering/render_style.h"
0037 
0038 #include "misc/khtmllayout.h"
0039 
0040 namespace khtml
0041 {
0042 
0043 class RenderTable;
0044 class RenderTableSection;
0045 class RenderTableRow;
0046 class RenderTableCell;
0047 class RenderTableCol;
0048 class TableLayout;
0049 
0050 class RenderTable : public RenderBlock
0051 {
0052 public:
0053 
0054     RenderTable(DOM::NodeImpl *node);
0055     ~RenderTable();
0056 
0057     const char *renderName() const override
0058     {
0059         return "RenderTable";
0060     }
0061 
0062     void setStyle(RenderStyle *style) override;
0063 
0064     bool isTable() const override
0065     {
0066         return true;
0067     }
0068 
0069     int getColumnPos(int col) const
0070     {
0071         return columnPos[col];
0072     }
0073 
0074     int borderHSpacing() const
0075     {
0076         return hspacing;
0077     }
0078     int borderVSpacing() const
0079     {
0080         return vspacing;
0081     }
0082 
0083     bool collapseBorders() const
0084     {
0085         return style()->borderCollapse();
0086     }
0087     int borderLeft() const override;
0088     int borderRight() const override;
0089     int borderTop() const override;
0090     int borderBottom() const override;
0091     int paddingLeft() const override
0092     {
0093         return collapseBorders() ? 0 : RenderBlock::paddingLeft();
0094     }
0095     int paddingRight() const override
0096     {
0097         return collapseBorders() ? 0 : RenderBlock::paddingRight();
0098     }
0099     int paddingTop() const override
0100     {
0101         return collapseBorders() ? 0 : RenderBlock::paddingTop();
0102     }
0103     int paddingBottom() const override
0104     {
0105         return collapseBorders() ? 0 : RenderBlock::paddingBottom();
0106     }
0107 
0108     const QColor &bgColor() const
0109     {
0110         return style()->backgroundColor();
0111     }
0112 
0113     uint cellPadding() const
0114     {
0115         return padding;
0116     }
0117     void setCellPadding(uint p)
0118     {
0119         padding = p;
0120     }
0121 
0122     // overrides
0123     void addChild(RenderObject *child, RenderObject *beforeChild = nullptr) override;
0124     void paint(PaintInfo &, int tx, int ty) override;
0125     void paintBoxDecorations(PaintInfo &, int _tx, int _ty) override;
0126     void layout() override;
0127     void calcMinMaxWidth() override;
0128     void close() override;
0129 
0130     short lineHeight(bool b) const override;
0131     short baselinePosition(bool b) const override;
0132 
0133     virtual void setCellWidths();
0134 
0135     void calcWidth() override;
0136 
0137     QList< QRectF > getClientRects() override;
0138 
0139     virtual FindSelectionResult checkSelectionPoint(int _x, int _y, int _tx, int _ty,
0140             DOM::NodeImpl *&node, int &offset,
0141             SelPointState &);
0142 
0143 #ifdef ENABLE_DUMP
0144     void dump(QTextStream &stream, const QString &ind) const override;
0145 #endif
0146     struct ColumnStruct {
0147         enum {
0148             WidthUndefined = 0xffff
0149         };
0150         ColumnStruct()
0151         {
0152             span = 1;
0153             width = WidthUndefined;
0154         }
0155         ushort span;
0156         ushort width; // the calculated position of the column
0157     };
0158 
0159     QVector<int> columnPos;
0160     QVector<ColumnStruct> columns;
0161 
0162     void splitColumn(int pos, int firstSpan);
0163     void appendColumn(int span);
0164     int numEffCols() const
0165     {
0166         return columns.size();
0167     }
0168     int spanOfEffCol(int effCol) const
0169     {
0170         return columns[effCol].span;
0171     }
0172     int colToEffCol(int col) const
0173     {
0174         int c = 0;
0175         int i = 0;
0176         while (c < col && i < (int)columns.size()) {
0177             c += columns[i].span;
0178             i++;
0179         }
0180         return i;
0181     }
0182     int effColToCol(int effCol) const
0183     {
0184         int c = 0;
0185         for (int i = 0; i < effCol; i++) {
0186             c += columns[i].span;
0187         }
0188         return c;
0189     }
0190 
0191     int bordersPaddingAndSpacing() const
0192     {
0193         return borderLeft() + borderRight() +
0194                (collapseBorders() ? 0 : (paddingLeft() + paddingRight() + (numEffCols() + 1) * borderHSpacing()));
0195     }
0196 
0197     RenderTableCol *colElement(int col, bool *startEdge = nullptr, bool *endEdge = nullptr) const;
0198 
0199     void setNeedSectionRecalc()
0200     {
0201         needSectionRecalc = true;
0202     }
0203 
0204     RenderObject *removeChildNode(RenderObject *child) override;
0205 
0206     RenderTableSection *sectionAbove(const RenderTableSection *, bool skipEmptySections = false);
0207     RenderTableSection *sectionBelow(const RenderTableSection *, bool skipEmptySections = false);
0208 
0209     RenderTableCell *cellAbove(const RenderTableCell *cell);
0210     RenderTableCell *cellBelow(const RenderTableCell *cell);
0211     RenderTableCell *cellBefore(const RenderTableCell *cell);
0212     RenderTableCell *cellAfter(const RenderTableCell *cell);
0213 
0214     CollapsedBorderValue *currentBorderStyle()
0215     {
0216         return m_currentBorder;
0217     }
0218 
0219     RenderTableSection *firstBodySection() const
0220     {
0221         return firstBody;
0222     }
0223     RenderFlow         *caption() const
0224     {
0225         return tCaption;
0226     }
0227 
0228 protected:
0229 
0230     void recalcSections();
0231 
0232     friend class AutoTableLayout;
0233     friend class FixedTableLayout;
0234 
0235     RenderFlow         *tCaption;
0236     RenderTableSection *head;
0237     RenderTableSection *foot;
0238     RenderTableSection *firstBody;
0239 
0240     TableLayout *tableLayout;
0241 
0242     CollapsedBorderValue *m_currentBorder;
0243 
0244     bool has_col_elems      : 1;
0245     uint needSectionRecalc  : 1;
0246     uint padding        : 22;
0247 
0248     ushort hspacing;
0249     ushort vspacing;
0250 
0251     friend class TableSectionIterator;
0252 };
0253 
0254 // -------------------------------------------------------------------------
0255 
0256 class RenderTableSection : public RenderBox
0257 {
0258 public:
0259     RenderTableSection(DOM::NodeImpl *node);
0260     ~RenderTableSection();
0261     void detach() override;
0262 
0263     void setStyle(RenderStyle *style) override;
0264 
0265     const char *renderName() const override
0266     {
0267         return "RenderTableSection";
0268     }
0269 
0270     // overrides
0271     void addChild(RenderObject *child, RenderObject *beforeChild = nullptr) override;
0272     bool isTableSection() const override
0273     {
0274         return true;
0275     }
0276 
0277     short lineHeight(bool) const override
0278     {
0279         return 0;
0280     }
0281     void position(InlineBox *, int, int, bool) override {}
0282 
0283     virtual FindSelectionResult checkSelectionPoint(int _x, int _y, int _tx, int _ty,
0284             DOM::NodeImpl *&node, int &offset,
0285             SelPointState &);
0286 
0287 #ifdef ENABLE_DUMP
0288     void dump(QTextStream &stream, const QString &ind) const override;
0289 #endif
0290 
0291     void addCell(RenderTableCell *cell, RenderTableRow *row);
0292 
0293     void setCellWidths();
0294     void calcRowHeight();
0295     int layoutRows(int height);
0296 
0297     RenderTable *table() const
0298     {
0299         return static_cast<RenderTable *>(parent());
0300     }
0301 
0302     typedef QVector<RenderTableCell *> Row;
0303     struct RowStruct {
0304         Row *row;
0305         RenderTableRow *rowRenderer;
0306         int baseLine;
0307         Length height;
0308         bool needFlex;
0309     };
0310 
0311     RenderTableCell *&cellAt(int row,  int col)
0312     {
0313         return (*(grid[row].row))[col];
0314     }
0315     RenderTableCell *cellAt(int row,  int col) const
0316     {
0317         return (*(grid[row].row))[col];
0318     }
0319 
0320     int lowestPosition(bool includeOverflowInterior, bool includeSelf) const override;
0321     int rightmostPosition(bool includeOverflowInterior, bool includeSelf) const override;
0322     int leftmostPosition(bool includeOverflowInterior, bool includeSelf) const override;
0323     int highestPosition(bool includeOverflowInterior, bool includeSelf) const override;
0324 
0325     int borderLeft() const override
0326     {
0327         return table()->collapseBorders() ? 0 : RenderBox::borderLeft();
0328     }
0329     int borderRight() const override
0330     {
0331         return table()->collapseBorders() ? 0 : RenderBox::borderRight();
0332     }
0333     int borderTop() const override
0334     {
0335         return table()->collapseBorders() ? 0 : RenderBox::borderTop();
0336     }
0337     int borderBottom() const override
0338     {
0339         return table()->collapseBorders() ? 0 : RenderBox::borderBottom();
0340     }
0341 
0342     void paint(PaintInfo &i, int tx, int ty) override;
0343 
0344     int numRows() const
0345     {
0346         return grid.size();
0347     }
0348     int getBaseline(int row)
0349     {
0350         return grid[row].baseLine;
0351     }
0352 
0353     void setNeedCellRecalc()
0354     {
0355         needCellRecalc = true;
0356         table()->setNeedSectionRecalc();
0357     }
0358 
0359     RenderObject *removeChildNode(RenderObject *child) override;
0360 
0361     bool canClear(RenderObject *child, PageBreakLevel level) override;
0362     void addSpaceAt(int pos, int dy);
0363 
0364     bool nodeAtPoint(NodeInfo &info, int x, int y, int tx, int ty, HitTestAction action, bool inside) override;
0365 
0366     // this gets a cell grid data structure. changing the number of
0367     // columns is done by the table
0368     QVector<RowStruct> grid;
0369     QVector<int> rowPos;
0370 
0371     int numColumns() const;
0372 
0373     //QMap< lastInsertedColumn, cell >
0374     QMap< int, RenderTableCell * > cellsWithColSpanZero;
0375     //QMap< nextRowToInsert, cell >
0376     QMap< int, RenderTableCell * > cellsWithRowSpanZero;
0377 
0378     int cRow;
0379     int cCol;
0380     bool needCellRecalc;
0381 
0382     void recalcCells();
0383 protected:
0384     void ensureRows(int numRows);
0385     void clearGrid();
0386     bool emptyRow(int rowNum);
0387     bool flexCellChildren(RenderObject *p) const;
0388 
0389     friend class TableSectionIterator;
0390 };
0391 
0392 // -------------------------------------------------------------------------
0393 
0394 class RenderTableRow : public RenderBox
0395 {
0396 public:
0397     RenderTableRow(DOM::NodeImpl *node);
0398 
0399     void detach() override;
0400 
0401     void setStyle(RenderStyle *) override;
0402     const char *renderName() const override
0403     {
0404         return "RenderTableRow";
0405     }
0406     bool isTableRow() const override
0407     {
0408         return true;
0409     }
0410     void addChild(RenderObject *child, RenderObject *beforeChild = nullptr) override;
0411 
0412     short offsetWidth() const override;
0413     int offsetHeight() const override;
0414     int offsetLeft() const override;
0415     int offsetTop() const override;
0416 
0417     short lineHeight(bool) const override
0418     {
0419         return 0;
0420     }
0421     void position(InlineBox *, int, int, bool) override {}
0422 
0423     bool nodeAtPoint(NodeInfo &info, int x, int y, int tx, int ty, HitTestAction action, bool inside) override;
0424 
0425     void layout() override;
0426 
0427     RenderObject *removeChildNode(RenderObject *child) override;
0428 
0429     // The only time rows get a layer is when they have transparency.
0430     bool requiresLayer() const override
0431     {
0432         return style()->opacity() < 1.0f;
0433     }
0434     void paint(PaintInfo &i, int tx, int ty) override;
0435 
0436     void paintRow(PaintInfo &i, int tx, int ty, int w, int h);
0437 
0438     RenderTable *table() const
0439     {
0440         return static_cast<RenderTable *>(parent()->parent());
0441     }
0442     RenderTableSection *section() const
0443     {
0444         return static_cast<RenderTableSection *>(parent());
0445     }
0446 };
0447 
0448 // -------------------------------------------------------------------------
0449 
0450 class RenderTableCell : public RenderBlock
0451 {
0452 public:
0453     RenderTableCell(DOM::NodeImpl *node);
0454 
0455     void layout() override;
0456     void detach() override;
0457 
0458     const char *renderName() const override
0459     {
0460         return "RenderTableCell";
0461     }
0462     bool isTableCell() const override
0463     {
0464         return true;
0465     }
0466 
0467     // ### FIX these two...
0468     long cellIndex() const
0469     {
0470         return 0;
0471     }
0472     void setCellIndex(long) { }
0473 
0474     unsigned short colSpan() const
0475     {
0476         return cSpan;
0477     }
0478     void setColSpan(unsigned short c)
0479     {
0480         cSpan = c;
0481     }
0482 
0483     unsigned short rowSpan() const
0484     {
0485         return rSpan;
0486     }
0487     void setRowSpan(unsigned short r)
0488     {
0489         rSpan = r;
0490     }
0491 
0492     int col() const
0493     {
0494         return _col;
0495     }
0496     void setCol(int col)
0497     {
0498         _col = col;
0499     }
0500     int row() const
0501     {
0502         return _row;
0503     }
0504     void setRow(int r)
0505     {
0506         _row = r;
0507     }
0508 
0509     Length styleOrColWidth();
0510 
0511     // overrides
0512     void calcMinMaxWidth() override;
0513     void calcWidth() override;
0514     void setWidth(int width) override;
0515     void setStyle(RenderStyle *style) override;
0516     bool requiresLayer() const override;
0517 
0518     int borderLeft() const override;
0519     int borderRight() const override;
0520     int borderTop() const override;
0521     int borderBottom() const override;
0522 
0523     CollapsedBorderValue collapsedLeftBorder(bool rtl) const;
0524     CollapsedBorderValue collapsedRightBorder(bool rtl) const;
0525     CollapsedBorderValue collapsedTopBorder() const;
0526     CollapsedBorderValue collapsedBottomBorder() const;
0527     void collectBorders(QList<CollapsedBorderValue> &borderStyles) override;
0528 
0529     void updateFromElement() override;
0530 
0531     void setCellTopExtra(int p)
0532     {
0533         _topExtra = p;
0534     }
0535     void setCellBottomExtra(int p)
0536     {
0537         _bottomExtra = p;
0538     }
0539     int cellTopExtra() const
0540     {
0541         return _topExtra;
0542     }
0543     int cellBottomExtra() const
0544     {
0545         return _bottomExtra;
0546     }
0547 
0548     int pageTopAfter(int x) const override;
0549 
0550     void paint(PaintInfo &i, int tx, int ty) override;
0551 
0552     void paintCollapsedBorder(QPainter *p, int x, int y, int w, int h);
0553     void paintBackgroundsBehindCell(PaintInfo &i, int _tx, int _ty, RenderObject *backgroundObject);
0554 
0555     void close() override;
0556 
0557     // lie position to outside observers
0558     int yPos() const override
0559     {
0560         return m_y + _topExtra;
0561     }
0562 
0563     void repaintRectangle(int x, int y, int w, int h, Priority p = NormalPriority, bool f = false) override;
0564 
0565     short baselinePosition(bool = false) const override;
0566 
0567     bool nodeAtPoint(NodeInfo &info, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction, bool inside) override;
0568 
0569     RenderTable *table() const
0570     {
0571         return static_cast<RenderTable *>(parent()->parent()->parent());
0572     }
0573     RenderTableSection *section() const
0574     {
0575         return static_cast<RenderTableSection *>(parent()->parent());
0576     }
0577 
0578 #ifdef ENABLE_DUMP
0579     void dump(QTextStream &stream, const QString &ind) const override;
0580 #endif
0581 
0582     bool widthChanged()
0583     {
0584         bool retval = m_widthChanged;
0585         m_widthChanged = false;
0586         return retval;
0587     }
0588 
0589     int cellPercentageHeight() const
0590     {
0591         return m_percentageHeight;
0592     }
0593     void setCellPercentageHeight(int h)
0594     {
0595         m_percentageHeight = h;
0596     }
0597     bool hasFlexedAnonymous() const
0598     {
0599         return m_hasFlexedAnonymous;
0600     }
0601     void setHasFlexedAnonymous(bool b = true)
0602     {
0603         m_hasFlexedAnonymous = b;
0604     }
0605 
0606 protected:
0607     void paintBoxDecorations(PaintInfo &p, int _tx, int _ty) override;
0608     int borderTopExtra() const override
0609     {
0610         return _topExtra;
0611     }
0612     int borderBottomExtra() const override
0613     {
0614         return _bottomExtra;
0615     }
0616 
0617     int _row;
0618     int _col;
0619     ushort rSpan;
0620     ushort cSpan;
0621     int _topExtra;
0622     signed int _bottomExtra : 30;
0623     bool m_widthChanged : 1;
0624     bool m_hasFlexedAnonymous : 1;
0625     int m_percentageHeight;
0626 };
0627 
0628 // -------------------------------------------------------------------------
0629 
0630 class RenderTableCol : public RenderBox
0631 {
0632 public:
0633     RenderTableCol(DOM::NodeImpl *node);
0634 
0635     const char *renderName() const override
0636     {
0637         return "RenderTableCol";
0638     }
0639 
0640     bool isTableCol() const override
0641     {
0642         return true;
0643     }
0644 
0645     short lineHeight(bool) const override
0646     {
0647         return 0;
0648     }
0649     void position(InlineBox *, int, int, bool) override {}
0650     void layout() override {}
0651     bool requiresLayer() const override
0652     {
0653         return false;
0654     }
0655 
0656     void updateFromElement() override;
0657 
0658 #ifdef ENABLE_DUMP
0659     void dump(QTextStream &stream, const QString &ind) const override;
0660 #endif
0661 
0662     int span() const
0663     {
0664         return m_span;
0665     }
0666     void setSpan(int s)
0667     {
0668         m_span = s;
0669     }
0670 
0671 private:
0672     int m_span;
0673 };
0674 
0675 // -------------------------------------------------------------------------
0676 
0677 /** This class provides an iterator to iterate through the sections of a
0678  * render table in their visual order.
0679  *
0680  * In HTML, sections are specified in the order of THEAD, TFOOT, and TBODY.
0681  * Visually, TBODY sections appear between THEAD and TFOOT, which this iterator
0682  * takes into regard.
0683  * @author Leo Savernik
0684  * @internal
0685  */
0686 class TableSectionIterator
0687 {
0688 public:
0689 
0690     /**
0691      * Initializes a new iterator
0692      * @param table table whose sections to iterate
0693      * @param fromEnd @p true, begin with last section, @p false, begin with
0694      *    first section.
0695      */
0696     TableSectionIterator(RenderTable *table, bool fromEnd = false);
0697 
0698     /**
0699      * Initializes a new iterator
0700      * @param start table section to start with.
0701      */
0702     TableSectionIterator(RenderTableSection *start) : sec(start) {}
0703 
0704     /**
0705      * Uninitialized iterator.
0706      */
0707     TableSectionIterator() {}
0708 
0709     /** Returns the current section, or @p 0 if the end has been reached.
0710      */
0711     RenderTableSection *operator *() const
0712     {
0713         return sec;
0714     }
0715 
0716     /** Moves to the next section in visual order. */
0717     TableSectionIterator &operator ++();
0718 
0719     /** Moves to the previous section in visual order. */
0720     TableSectionIterator &operator --();
0721 
0722 private:
0723     RenderTableSection *sec;
0724 };
0725 
0726 }
0727 #endif
0728