KHtml

render_table.h
1 /*
2  * This file is part of the DOM implementation for KDE.
3  *
4  * Copyright (C) 1997 Martin Jones ([email protected])
5  * (C) 1997 Torben Weis ([email protected])
6  * (C) 1998 Waldo Bastian ([email protected])
7  * (C) 1999-2003 Lars Knoll ([email protected])
8  * (C) 1999 Antti Koivisto ([email protected])
9  * (C) 2003 Apple Computer, Inc.
10  * (C) 2009 Carlos Licea ([email protected])
11  *
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Library General Public
14  * License as published by the Free Software Foundation; either
15  * version 2 of the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20  * Library General Public License for more details.
21  *
22  * You should have received a copy of the GNU Library General Public License
23  * along with this library; see the file COPYING.LIB. If not, write to
24  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25  * Boston, MA 02110-1301, USA.
26  *
27  */
28 #ifndef RENDER_TABLE_H
29 #define RENDER_TABLE_H
30 
31 #include <QColor>
32 #include <QVector>
33 
34 #include "rendering/render_box.h"
35 #include "rendering/render_block.h"
36 #include "rendering/render_style.h"
37 
38 #include "misc/khtmllayout.h"
39 
40 namespace khtml
41 {
42 
43 class RenderTable;
44 class RenderTableSection;
45 class RenderTableRow;
46 class RenderTableCell;
47 class RenderTableCol;
48 class TableLayout;
49 
50 class RenderTable : public RenderBlock
51 {
52 public:
53 
54  RenderTable(DOM::NodeImpl *node);
55  ~RenderTable();
56 
57  const char *renderName() const override
58  {
59  return "RenderTable";
60  }
61 
62  void setStyle(RenderStyle *style) override;
63 
64  bool isTable() const override
65  {
66  return true;
67  }
68 
69  int getColumnPos(int col) const
70  {
71  return columnPos[col];
72  }
73 
74  int borderHSpacing() const
75  {
76  return hspacing;
77  }
78  int borderVSpacing() const
79  {
80  return vspacing;
81  }
82 
83  bool collapseBorders() const
84  {
85  return style()->borderCollapse();
86  }
87  int borderLeft() const override;
88  int borderRight() const override;
89  int borderTop() const override;
90  int borderBottom() const override;
91  int paddingLeft() const override
92  {
93  return collapseBorders() ? 0 : RenderBlock::paddingLeft();
94  }
95  int paddingRight() const override
96  {
97  return collapseBorders() ? 0 : RenderBlock::paddingRight();
98  }
99  int paddingTop() const override
100  {
101  return collapseBorders() ? 0 : RenderBlock::paddingTop();
102  }
103  int paddingBottom() const override
104  {
105  return collapseBorders() ? 0 : RenderBlock::paddingBottom();
106  }
107 
108  const QColor &bgColor() const
109  {
110  return style()->backgroundColor();
111  }
112 
113  uint cellPadding() const
114  {
115  return padding;
116  }
117  void setCellPadding(uint p)
118  {
119  padding = p;
120  }
121 
122  // overrides
123  void addChild(RenderObject *child, RenderObject *beforeChild = nullptr) override;
124  void paint(PaintInfo &, int tx, int ty) override;
125  void paintBoxDecorations(PaintInfo &, int _tx, int _ty) override;
126  void layout() override;
127  void calcMinMaxWidth() override;
128  void close() override;
129 
130  short lineHeight(bool b) const override;
131  short baselinePosition(bool b) const override;
132 
133  virtual void setCellWidths();
134 
135  void calcWidth() override;
136 
137  QList< QRectF > getClientRects() override;
138 
139  virtual FindSelectionResult checkSelectionPoint(int _x, int _y, int _tx, int _ty,
140  DOM::NodeImpl *&node, int &offset,
141  SelPointState &);
142 
143 #ifdef ENABLE_DUMP
144  void dump(QTextStream &stream, const QString &ind) const override;
145 #endif
146  struct ColumnStruct {
147  enum {
148  WidthUndefined = 0xffff
149  };
150  ColumnStruct()
151  {
152  span = 1;
153  width = WidthUndefined;
154  }
155  ushort span;
156  ushort width; // the calculated position of the column
157  };
158 
159  QVector<int> columnPos;
160  QVector<ColumnStruct> columns;
161 
162  void splitColumn(int pos, int firstSpan);
163  void appendColumn(int span);
164  int numEffCols() const
165  {
166  return columns.size();
167  }
168  int spanOfEffCol(int effCol) const
169  {
170  return columns[effCol].span;
171  }
172  int colToEffCol(int col) const
173  {
174  int c = 0;
175  int i = 0;
176  while (c < col && i < (int)columns.size()) {
177  c += columns[i].span;
178  i++;
179  }
180  return i;
181  }
182  int effColToCol(int effCol) const
183  {
184  int c = 0;
185  for (int i = 0; i < effCol; i++) {
186  c += columns[i].span;
187  }
188  return c;
189  }
190 
191  int bordersPaddingAndSpacing() const
192  {
193  return borderLeft() + borderRight() +
194  (collapseBorders() ? 0 : (paddingLeft() + paddingRight() + (numEffCols() + 1) * borderHSpacing()));
195  }
196 
197  RenderTableCol *colElement(int col, bool *startEdge = nullptr, bool *endEdge = nullptr) const;
198 
199  void setNeedSectionRecalc()
200  {
201  needSectionRecalc = true;
202  }
203 
204  RenderObject *removeChildNode(RenderObject *child) override;
205 
206  RenderTableSection *sectionAbove(const RenderTableSection *, bool skipEmptySections = false);
207  RenderTableSection *sectionBelow(const RenderTableSection *, bool skipEmptySections = false);
208 
209  RenderTableCell *cellAbove(const RenderTableCell *cell);
210  RenderTableCell *cellBelow(const RenderTableCell *cell);
211  RenderTableCell *cellBefore(const RenderTableCell *cell);
212  RenderTableCell *cellAfter(const RenderTableCell *cell);
213 
214  CollapsedBorderValue *currentBorderStyle()
215  {
216  return m_currentBorder;
217  }
218 
219  RenderTableSection *firstBodySection() const
220  {
221  return firstBody;
222  }
223  RenderFlow *caption() const
224  {
225  return tCaption;
226  }
227 
228 protected:
229 
230  void recalcSections();
231 
232  friend class AutoTableLayout;
233  friend class FixedTableLayout;
234 
235  RenderFlow *tCaption;
236  RenderTableSection *head;
237  RenderTableSection *foot;
238  RenderTableSection *firstBody;
239 
240  TableLayout *tableLayout;
241 
242  CollapsedBorderValue *m_currentBorder;
243 
244  bool has_col_elems : 1;
245  uint needSectionRecalc : 1;
246  uint padding : 22;
247 
248  ushort hspacing;
249  ushort vspacing;
250 
251  friend class TableSectionIterator;
252 };
253 
254 // -------------------------------------------------------------------------
255 
256 class RenderTableSection : public RenderBox
257 {
258 public:
259  RenderTableSection(DOM::NodeImpl *node);
260  ~RenderTableSection();
261  void detach() override;
262 
263  void setStyle(RenderStyle *style) override;
264 
265  const char *renderName() const override
266  {
267  return "RenderTableSection";
268  }
269 
270  // overrides
271  void addChild(RenderObject *child, RenderObject *beforeChild = nullptr) override;
272  bool isTableSection() const override
273  {
274  return true;
275  }
276 
277  short lineHeight(bool) const override
278  {
279  return 0;
280  }
281  void position(InlineBox *, int, int, bool) override {}
282 
283  virtual FindSelectionResult checkSelectionPoint(int _x, int _y, int _tx, int _ty,
284  DOM::NodeImpl *&node, int &offset,
285  SelPointState &);
286 
287 #ifdef ENABLE_DUMP
288  void dump(QTextStream &stream, const QString &ind) const override;
289 #endif
290 
291  void addCell(RenderTableCell *cell, RenderTableRow *row);
292 
293  void setCellWidths();
294  void calcRowHeight();
295  int layoutRows(int height);
296 
297  RenderTable *table() const
298  {
299  return static_cast<RenderTable *>(parent());
300  }
301 
302  typedef QVector<RenderTableCell *> Row;
303  struct RowStruct {
304  Row *row;
305  RenderTableRow *rowRenderer;
306  int baseLine;
307  Length height;
308  bool needFlex;
309  };
310 
311  RenderTableCell *&cellAt(int row, int col)
312  {
313  return (*(grid[row].row))[col];
314  }
315  RenderTableCell *cellAt(int row, int col) const
316  {
317  return (*(grid[row].row))[col];
318  }
319 
320  int lowestPosition(bool includeOverflowInterior, bool includeSelf) const override;
321  int rightmostPosition(bool includeOverflowInterior, bool includeSelf) const override;
322  int leftmostPosition(bool includeOverflowInterior, bool includeSelf) const override;
323  int highestPosition(bool includeOverflowInterior, bool includeSelf) const override;
324 
325  int borderLeft() const override
326  {
327  return table()->collapseBorders() ? 0 : RenderBox::borderLeft();
328  }
329  int borderRight() const override
330  {
331  return table()->collapseBorders() ? 0 : RenderBox::borderRight();
332  }
333  int borderTop() const override
334  {
335  return table()->collapseBorders() ? 0 : RenderBox::borderTop();
336  }
337  int borderBottom() const override
338  {
339  return table()->collapseBorders() ? 0 : RenderBox::borderBottom();
340  }
341 
342  void paint(PaintInfo &i, int tx, int ty) override;
343 
344  int numRows() const
345  {
346  return grid.size();
347  }
348  int getBaseline(int row)
349  {
350  return grid[row].baseLine;
351  }
352 
353  void setNeedCellRecalc()
354  {
355  needCellRecalc = true;
356  table()->setNeedSectionRecalc();
357  }
358 
359  RenderObject *removeChildNode(RenderObject *child) override;
360 
361  bool canClear(RenderObject *child, PageBreakLevel level) override;
362  void addSpaceAt(int pos, int dy);
363 
364  bool nodeAtPoint(NodeInfo &info, int x, int y, int tx, int ty, HitTestAction action, bool inside) override;
365 
366  // this gets a cell grid data structure. changing the number of
367  // columns is done by the table
368  QVector<RowStruct> grid;
369  QVector<int> rowPos;
370 
371  int numColumns() const;
372 
373  //QMap< lastInsertedColumn, cell >
374  QMap< int, RenderTableCell * > cellsWithColSpanZero;
375  //QMap< nextRowToInsert, cell >
376  QMap< int, RenderTableCell * > cellsWithRowSpanZero;
377 
378  int cRow;
379  int cCol;
380  bool needCellRecalc;
381 
382  void recalcCells();
383 protected:
384  void ensureRows(int numRows);
385  void clearGrid();
386  bool emptyRow(int rowNum);
387  bool flexCellChildren(RenderObject *p) const;
388 
389  friend class TableSectionIterator;
390 };
391 
392 // -------------------------------------------------------------------------
393 
394 class RenderTableRow : public RenderBox
395 {
396 public:
397  RenderTableRow(DOM::NodeImpl *node);
398 
399  void detach() override;
400 
401  void setStyle(RenderStyle *) override;
402  const char *renderName() const override
403  {
404  return "RenderTableRow";
405  }
406  bool isTableRow() const override
407  {
408  return true;
409  }
410  void addChild(RenderObject *child, RenderObject *beforeChild = nullptr) override;
411 
412  short offsetWidth() const override;
413  int offsetHeight() const override;
414  int offsetLeft() const override;
415  int offsetTop() const override;
416 
417  short lineHeight(bool) const override
418  {
419  return 0;
420  }
421  void position(InlineBox *, int, int, bool) override {}
422 
423  bool nodeAtPoint(NodeInfo &info, int x, int y, int tx, int ty, HitTestAction action, bool inside) override;
424 
425  void layout() override;
426 
427  RenderObject *removeChildNode(RenderObject *child) override;
428 
429  // The only time rows get a layer is when they have transparency.
430  bool requiresLayer() const override
431  {
432  return style()->opacity() < 1.0f;
433  }
434  void paint(PaintInfo &i, int tx, int ty) override;
435 
436  void paintRow(PaintInfo &i, int tx, int ty, int w, int h);
437 
438  RenderTable *table() const
439  {
440  return static_cast<RenderTable *>(parent()->parent());
441  }
442  RenderTableSection *section() const
443  {
444  return static_cast<RenderTableSection *>(parent());
445  }
446 };
447 
448 // -------------------------------------------------------------------------
449 
450 class RenderTableCell : public RenderBlock
451 {
452 public:
453  RenderTableCell(DOM::NodeImpl *node);
454 
455  void layout() override;
456  void detach() override;
457 
458  const char *renderName() const override
459  {
460  return "RenderTableCell";
461  }
462  bool isTableCell() const override
463  {
464  return true;
465  }
466 
467  // ### FIX these two...
468  long cellIndex() const
469  {
470  return 0;
471  }
472  void setCellIndex(long) { }
473 
474  unsigned short colSpan() const
475  {
476  return cSpan;
477  }
478  void setColSpan(unsigned short c)
479  {
480  cSpan = c;
481  }
482 
483  unsigned short rowSpan() const
484  {
485  return rSpan;
486  }
487  void setRowSpan(unsigned short r)
488  {
489  rSpan = r;
490  }
491 
492  int col() const
493  {
494  return _col;
495  }
496  void setCol(int col)
497  {
498  _col = col;
499  }
500  int row() const
501  {
502  return _row;
503  }
504  void setRow(int r)
505  {
506  _row = r;
507  }
508 
509  Length styleOrColWidth();
510 
511  // overrides
512  void calcMinMaxWidth() override;
513  void calcWidth() override;
514  void setWidth(int width) override;
515  void setStyle(RenderStyle *style) override;
516  bool requiresLayer() const override;
517 
518  int borderLeft() const override;
519  int borderRight() const override;
520  int borderTop() const override;
521  int borderBottom() const override;
522 
523  CollapsedBorderValue collapsedLeftBorder(bool rtl) const;
524  CollapsedBorderValue collapsedRightBorder(bool rtl) const;
525  CollapsedBorderValue collapsedTopBorder() const;
526  CollapsedBorderValue collapsedBottomBorder() const;
527  void collectBorders(QList<CollapsedBorderValue> &borderStyles) override;
528 
529  void updateFromElement() override;
530 
531  void setCellTopExtra(int p)
532  {
533  _topExtra = p;
534  }
535  void setCellBottomExtra(int p)
536  {
537  _bottomExtra = p;
538  }
539  int cellTopExtra() const
540  {
541  return _topExtra;
542  }
543  int cellBottomExtra() const
544  {
545  return _bottomExtra;
546  }
547 
548  int pageTopAfter(int x) const override;
549 
550  void paint(PaintInfo &i, int tx, int ty) override;
551 
552  void paintCollapsedBorder(QPainter *p, int x, int y, int w, int h);
553  void paintBackgroundsBehindCell(PaintInfo &i, int _tx, int _ty, RenderObject *backgroundObject);
554 
555  void close() override;
556 
557  // lie position to outside observers
558  int yPos() const override
559  {
560  return m_y + _topExtra;
561  }
562 
563  void repaintRectangle(int x, int y, int w, int h, Priority p = NormalPriority, bool f = false) override;
564 
565  short baselinePosition(bool = false) const override;
566 
567  bool nodeAtPoint(NodeInfo &info, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction, bool inside) override;
568 
569  RenderTable *table() const
570  {
571  return static_cast<RenderTable *>(parent()->parent()->parent());
572  }
573  RenderTableSection *section() const
574  {
575  return static_cast<RenderTableSection *>(parent()->parent());
576  }
577 
578 #ifdef ENABLE_DUMP
579  void dump(QTextStream &stream, const QString &ind) const override;
580 #endif
581 
582  bool widthChanged()
583  {
584  bool retval = m_widthChanged;
585  m_widthChanged = false;
586  return retval;
587  }
588 
589  int cellPercentageHeight() const
590  {
591  return m_percentageHeight;
592  }
593  void setCellPercentageHeight(int h)
594  {
595  m_percentageHeight = h;
596  }
597  bool hasFlexedAnonymous() const
598  {
599  return m_hasFlexedAnonymous;
600  }
601  void setHasFlexedAnonymous(bool b = true)
602  {
603  m_hasFlexedAnonymous = b;
604  }
605 
606 protected:
607  void paintBoxDecorations(PaintInfo &p, int _tx, int _ty) override;
608  int borderTopExtra() const override
609  {
610  return _topExtra;
611  }
612  int borderBottomExtra() const override
613  {
614  return _bottomExtra;
615  }
616 
617  int _row;
618  int _col;
619  ushort rSpan;
620  ushort cSpan;
621  int _topExtra;
622  signed int _bottomExtra : 30;
623  bool m_widthChanged : 1;
624  bool m_hasFlexedAnonymous : 1;
625  int m_percentageHeight;
626 };
627 
628 // -------------------------------------------------------------------------
629 
630 class RenderTableCol : public RenderBox
631 {
632 public:
633  RenderTableCol(DOM::NodeImpl *node);
634 
635  const char *renderName() const override
636  {
637  return "RenderTableCol";
638  }
639 
640  bool isTableCol() const override
641  {
642  return true;
643  }
644 
645  short lineHeight(bool) const override
646  {
647  return 0;
648  }
649  void position(InlineBox *, int, int, bool) override {}
650  void layout() override {}
651  bool requiresLayer() const override
652  {
653  return false;
654  }
655 
656  void updateFromElement() override;
657 
658 #ifdef ENABLE_DUMP
659  void dump(QTextStream &stream, const QString &ind) const override;
660 #endif
661 
662  int span() const
663  {
664  return m_span;
665  }
666  void setSpan(int s)
667  {
668  m_span = s;
669  }
670 
671 private:
672  int m_span;
673 };
674 
675 // -------------------------------------------------------------------------
676 
677 /** This class provides an iterator to iterate through the sections of a
678  * render table in their visual order.
679  *
680  * In HTML, sections are specified in the order of THEAD, TFOOT, and TBODY.
681  * Visually, TBODY sections appear between THEAD and TFOOT, which this iterator
682  * takes into regard.
683  * @author Leo Savernik
684  * @internal
685  */
687 {
688 public:
689 
690  /**
691  * Initializes a new iterator
692  * @param table table whose sections to iterate
693  * @param fromEnd @p true, begin with last section, @p false, begin with
694  * first section.
695  */
696  TableSectionIterator(RenderTable *table, bool fromEnd = false);
697 
698  /**
699  * Initializes a new iterator
700  * @param start table section to start with.
701  */
702  TableSectionIterator(RenderTableSection *start) : sec(start) {}
703 
704  /**
705  * Uninitialized iterator.
706  */
708 
709  /** Returns the current section, or @p 0 if the end has been reached.
710  */
711  RenderTableSection *operator *() const
712  {
713  return sec;
714  }
715 
716  /** Moves to the next section in visual order. */
717  TableSectionIterator &operator ++();
718 
719  /** Moves to the previous section in visual order. */
720  TableSectionIterator &operator --();
721 
722 private:
723  RenderTableSection *sec;
724 };
725 
726 }
727 #endif
728 
QString caption()
This class provides an iterator to iterate through the sections of a render table in their visual ord...
Definition: render_table.h:686
TableSectionIterator(RenderTableSection *start)
Initializes a new iterator.
Definition: render_table.h:702
This file is part of the HTML rendering engine for KDE.
const QList< QKeySequence > & close()
TableSectionIterator()
Uninitialized iterator.
Definition: render_table.h:707
int size() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Mon Oct 25 2021 22:48:22 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.