KHtml

render_object.h
1 /*
2  * This file is part of the html renderer for KDE.
3  *
4  * Copyright (C) 2000-2003 Lars Knoll ([email protected])
5  * (C) 2000 Antti Koivisto ([email protected])
6  * (C) 2000-2003 Dirk Mueller ([email protected])
7  * (C) 2002-2003 Apple Computer, Inc.
8  * (C) 2004 Allan Sandfeld Jensen
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public License
21  * along with this library; see the file COPYING.LIB. If not, write to
22  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23  * Boston, MA 02110-1301, USA.
24  *
25  */
26 #ifndef render_object_h
27 #define render_object_h
28 
29 #include <QColor>
30 #include <QRect>
31 #include <assert.h>
32 #include <QList>
33 
34 #include <QDebug>
35 
36 #include "xml/dom_docimpl.h"
37 #include "misc/khtmllayout.h"
38 #include "misc/loader_client.h"
39 #include "misc/helper.h"
40 #include "rendering/render_style.h"
41 #include "rendering/render_position.h"
42 #include <QTextStream>
43 
44 // svg
45 #include "FloatRect.h"
46 #include "AffineTransform.h"
47 
48 using WebCore::FloatRect;
49 using WebCore::AffineTransform;
50 
51 class QPainter;
52 class QTextStream;
53 template<class Key, class T> class QCache;
54 
55 #ifndef NDEBUG
56 #define KHTMLAssert( x ) if( !(x) ) { \
57  const RenderObject *o = this; while( o->parent() ) o = o->parent(); \
58  o->printTree(); \
59  qDebug(" this object = %p", (void*) this); \
60  assert( x ); \
61  }
62 #else
63 #define KHTMLAssert( x )
64 #endif
65 
66 /*
67  * The painting of a layer occurs in three distinct phases. Each phase involves
68  * a recursive descent into the layer's render objects. The first phase is the background phase.
69  * The backgrounds and borders of all blocks are painted. Inlines are not painted at all.
70  * Floats must paint above block backgrounds but entirely below inline content that can overlap them.
71  * In the foreground phase, all inlines are fully painted. Inline replaced elements will get all
72  * three phases invoked on them during this phase.
73  */
74 
75 typedef enum {
76  PaintActionElementBackground = 0,
77  PaintActionChildBackground,
78  PaintActionChildBackgrounds,
79  PaintActionFloat,
80  PaintActionForeground,
81  PaintActionOutline,
82  PaintActionSelection,
83  PaintActionCollapsedTableBorders
84 } PaintAction;
85 
86 typedef enum {
87  HitTestAll = 0,
88  HitTestSelfOnly = 1,
89  HitTestChildrenOnly = 2
90 } HitTestAction;
91 
92 typedef enum {
93  PageBreakNormal = 0, // all rules apply
94  PageBreakHarder = 1, // page-break-inside: avoid is ignored
95  PageBreakForced = 2 // page-break-after/before: avoid, orphans and widows ignored
96 } PageBreakLevel;
97 
98 typedef enum {
99  LowPriority = 0,
100  NormalPriority = 1,
101  HighPriority = 2,
102  RealtimePriority = 3
103 } Priority;
104 
105 inline PageBreakLevel operator| (PageBreakLevel a, PageBreakLevel b)
106 {
107  if (a == PageBreakForced || b == PageBreakForced) {
108  return PageBreakForced;
109  }
110  if (a == PageBreakHarder || b == PageBreakHarder) {
111  return PageBreakHarder;
112  }
113  return PageBreakNormal;
114 }
115 
116 namespace DOM
117 {
118 class HTMLAreaElementImpl;
119 class NodeImpl;
120 class DocumentImpl;
121 class ElementImpl;
122 class EventImpl;
123 class Selection;
124 }
125 
126 namespace khtml
127 {
128 class RenderFlow;
129 class RenderStyle;
130 class CachedObject;
131 class RenderObject;
132 class RenderCanvas;
133 class RenderText;
134 class RenderFrameSet;
135 class RenderArena;
136 class RenderLayer;
137 class RenderBlock;
138 class InlineBox;
139 class InlineFlowBox;
140 class CounterNode;
141 class RenderPosition;
142 
147 {
148  RenderObject(const RenderObject &);
149  RenderObject &operator=(const RenderObject &);
150 public:
151  KHTML_EXPORT static void cleanup();
152 
153  RenderObject(DOM::NodeImpl *node);
154  virtual ~RenderObject();
155 
156  RenderObject *parent() const
157  {
158  return m_parent;
159  }
160 
161  RenderObject *previousSibling() const
162  {
163  return m_previous;
164  }
165  RenderObject *nextSibling() const
166  {
167  return m_next;
168  }
169 
170  virtual RenderObject *firstChild() const
171  {
172  return nullptr;
173  }
174  virtual RenderObject *lastChild() const
175  {
176  return nullptr;
177  }
178 
179  RenderObject *nextRenderer() const;
180  RenderObject *previousRenderer() const;
181 
182  RenderObject *nextEditable() const;
183  RenderObject *previousEditable() const;
184 
185  RenderObject *firstLeafChild() const;
186  RenderObject *lastLeafChild() const;
187 
188  virtual bool childAllowed() const
189  {
190  return false;
191  }
192  virtual int borderTopExtra() const
193  {
194  return 0;
195  }
196  virtual int borderBottomExtra() const
197  {
198  return 0;
199  }
200 
201  virtual RenderLayer *layer() const
202  {
203  return nullptr;
204  }
205  RenderLayer *enclosingLayer() const;
206  RenderLayer *enclosingStackingContext() const;
207  void addLayers(RenderLayer *parentLayer, RenderObject *newObject);
208  void removeLayers(RenderLayer *parentLayer);
209  void moveLayers(RenderLayer *oldParent, RenderLayer *newParent);
210  RenderLayer *findNextLayer(RenderLayer *parentLayer, RenderObject *startPoint,
211  bool checkParent = true);
212  virtual void positionChildLayers() { }
213  virtual bool requiresLayer() const
214  {
215  return isRoot()/* ### */ || isPositioned() || isRelPositioned() || hasOverflowClip() || style()->opacity() < 1.0f;
216  }
217 
218  virtual QRect overflowClipRect(int /*tx*/, int /*ty*/)
219  {
220  return QRect(0, 0, 0, 0);
221  }
222  virtual QRect clipRect(int /*tx*/, int /*ty*/)
223  {
224  return QRect(0, 0, 0, 0);
225  }
226  bool hasClip() const
227  {
228  return isPositioned() && style()->hasClip();
229  }
230  bool hasOverflowClip() const
231  {
232  return m_hasOverflowClip;
233  }
234 
235  bool scrollsOverflow() const
236  {
237  return scrollsOverflowX() || scrollsOverflowY();
238  }
239  bool scrollsOverflowX() const
240  {
241  return hasOverflowClip() && (style()->overflowX() == OSCROLL || style()->overflowX() == OAUTO);
242  }
243  bool scrollsOverflowY() const
244  {
245  return hasOverflowClip() && (style()->overflowY() == OSCROLL || style()->overflowY() == OAUTO);
246  }
247 
248  virtual int getBaselineOfFirstLineBox()
249  {
250  return -1; // Tables and blocks implement this.
251  }
252  virtual InlineFlowBox *getFirstLineBox()
253  {
254  return nullptr; // Tables and blocks implement this.
255  }
256 
257  // Whether or not a positioned element requires normal flow x/y to be computed
258  // to determine its position.
259  bool hasStaticX() const
260  {
261  return style()->left().isAuto() && style()->right().isAuto();
262  }
263  bool hasStaticY() const
264  {
265  return style()->top().isAuto() && style()->bottom().isAuto();
266  }
267  bool isPosWithStaticDim() const
268  {
269  return isPositioned() && (hasStaticX() || hasStaticY());
270  }
271 
272  // Linear tree traversal
273  RenderObject *objectBelow() const;
274  RenderObject *objectAbove() const;
275 
276  // Returns if an object has counter-increment or counter-reset
277  bool hasCounter(const DOMString &counter) const;
278  // Calculates the value of the counter
279  CounterNode *getCounter(const DOMString &counter, bool view = false, bool counters = false);
280  // Detaches all counterNodes
281  void detachCounters();
282 
283 protected:
284  // Helper functions for counter-cache
285  void insertCounter(const DOMString &counter, CounterNode *value);
286  CounterNode *lookupCounter(const DOMString &counter) const;
287 
288 public:
290  // RenderObject tree manipulation
291  virtual void addChild(RenderObject *newChild, RenderObject *beforeChild = nullptr);
292  virtual void removeChild(RenderObject *oldChild);
293 
294  // raw tree manipulation
295  virtual RenderObject *removeChildNode(RenderObject *child);
296  virtual void appendChildNode(RenderObject *child);
297  virtual void insertChildNode(RenderObject *child, RenderObject *before);
299 
301  // Helper functions. Dangerous to use!
302  void setPreviousSibling(RenderObject *previous)
303  {
304  m_previous = previous;
305  }
306  void setNextSibling(RenderObject *next)
307  {
308  m_next = next;
309  }
310  void setParent(RenderObject *parent)
311  {
312  m_parent = parent;
313  }
315 
316 public:
317  virtual const char *renderName() const
318  {
319  return "RenderObject";
320  }
321 #ifdef ENABLE_DUMP
322  QString information() const;
323  virtual void printTree(int indent = 0) const;
324  virtual void dump(QTextStream &stream, const QString &ind = QString()) const;
325  void printLineBoxTree() const;
326 #endif
327 
328  static RenderObject *createObject(DOM::NodeImpl *node, RenderStyle *style);
329 
330  // Overloaded new operator. Derived classes must override operator new
331  // in order to allocate out of the RenderArena.
332  void *operator new(size_t sz, RenderArena *renderArena) throw();
333 
334  // Overridden to prevent the normal delete from being called.
335  void operator delete(void *ptr, size_t sz);
336 
337 private:
338  // The normal operator new is disallowed on all render objects.
339  void *operator new(size_t sz);
340 
341 public:
342  RenderArena *renderArena() const;
343  virtual RenderFlow *continuation() const
344  {
345  return nullptr;
346  }
347  virtual bool isInlineContinuation() const
348  {
349  return false;
350  }
351 
352  bool isRoot() const
353  {
354  return m_isRoot && !m_isAnonymous;
355  }
356  void setIsRoot(bool b)
357  {
358  m_isRoot = b;
359  }
360  bool isHR() const;
361  // some helper functions...
362  virtual bool isRenderBlock() const
363  {
364  return false;
365  }
366  virtual bool isRenderInline() const
367  {
368  return false;
369  }
370  virtual bool isInlineFlow() const
371  {
372  return false;
373  }
374  virtual bool isBlockFlow() const
375  {
376  return false;
377  }
378  virtual bool isInlineBlockOrInlineTable() const
379  {
380  return false;
381  }
382  virtual bool childrenInline() const
383  {
384  return false;
385  }
386  virtual bool isBox() const
387  {
388  return false;
389  }
390  virtual bool isRenderReplaced() const
391  {
392  return false;
393  }
394 
395  virtual bool isGlyph() const
396  {
397  return false;
398  }
399  virtual bool isCounter() const
400  {
401  return false;
402  }
403  virtual bool isQuote() const
404  {
405  return false;
406  }
407  virtual bool isListItem() const
408  {
409  return false;
410  }
411  virtual bool isListMarker() const
412  {
413  return false;
414  }
415  virtual bool isCanvas() const
416  {
417  return false;
418  }
419  virtual bool isBR() const
420  {
421  return false;
422  }
423  virtual bool isTableCell() const
424  {
425  return false;
426  }
427  virtual bool isTableRow() const
428  {
429  return false;
430  }
431  virtual bool isTableSection() const
432  {
433  return false;
434  }
435  virtual bool isTableCol() const
436  {
437  return false;
438  }
439  virtual bool isTable() const
440  {
441  return false;
442  }
443  virtual bool isWidget() const
444  {
445  return false;
446  }
447  virtual bool isBody() const
448  {
449  return false;
450  }
451  virtual bool isFormElement() const
452  {
453  return false;
454  }
455  virtual bool isFrameSet() const
456  {
457  return false;
458  }
459  virtual bool isApplet() const
460  {
461  return false;
462  }
463  virtual bool isMedia() const
464  {
465  return false;
466  }
467 
468  virtual bool isEditable() const;
469 
470  // svg
471  virtual bool isSVGRoot() const
472  {
473  return false;
474  }
475  virtual bool isRenderPath() const
476  {
477  return false;
478  }
479  virtual bool isSVGContainer() const
480  {
481  return false;
482  }
483  virtual bool isSVGText() const
484  {
485  return false;
486  }
487  virtual bool isSVGHiddenContainer() const
488  {
489  return false;
490  }
491 
492  virtual FloatRect relativeBBox(bool includeStroke = false) const;
493 
494  virtual AffineTransform localTransform() const;
495  virtual AffineTransform absoluteTransform() const;
496  // end svg
497 
498  bool isHTMLMarquee() const;
499  bool isWordBreak() const;
500 
501  bool isAnonymous() const
502  {
503  return m_isAnonymous;
504  }
505  void setIsAnonymous(bool b)
506  {
507  m_isAnonymous = b;
508  }
509  bool isAnonymousBlock() const
510  {
511  return isAnonymous() && style()->display() == BLOCK && node()->isDocumentNode();
512  }
513  bool isPseudoAnonymous() const
514  {
515  return isAnonymous() && !node()->isDocumentNode();
516  }
517 
518  bool isFloating() const
519  {
520  return m_floating;
521  }
522  bool isPositioned() const
523  {
524  return m_positioned;
525  }
526  bool isRelPositioned() const
527  {
528  return m_relPositioned;
529  }
530  bool isText() const
531  {
532  return m_isText;
533  }
534  bool isInline() const
535  {
536  return m_inline;
537  }
538  bool isCompact() const
539  {
540  return style()->display() == COMPACT; // compact
541  }
542  bool isRunIn() const
543  {
544  return style()->display() == RUN_IN; // run-in object
545  }
546  bool mouseInside() const;
547  bool isDragging() const;
548  bool isReplaced() const
549  {
550  return m_replaced;
551  }
552  bool isReplacedBlock() const
553  {
554  return isInline() && isReplaced() && isRenderBlock();
555  }
556  bool shouldPaintBackgroundOrBorder() const
557  {
558  return m_paintBackground;
559  }
560  bool needsLayout() const
561  {
562  return m_needsLayout || m_normalChildNeedsLayout || m_posChildNeedsLayout;
563  }
564  bool markedForRepaint() const
565  {
566  return m_markedForRepaint;
567  }
568  void setMarkedForRepaint(bool m)
569  {
570  m_markedForRepaint = m;
571  }
572  bool selfNeedsLayout() const
573  {
574  return m_needsLayout;
575  }
576  bool posChildNeedsLayout() const
577  {
578  return m_posChildNeedsLayout;
579  }
580  bool normalChildNeedsLayout() const
581  {
582  return m_normalChildNeedsLayout;
583  }
584  bool minMaxKnown() const
585  {
586  return m_minMaxKnown;
587  }
588  bool hasFirstLine() const
589  {
590  return m_hasFirstLine;
591  }
592  bool isSelectionBorder() const
593  {
594  return m_isSelectionBorder;
595  }
596  bool recalcMinMax() const
597  {
598  return m_recalcMinMax;
599  }
600 
601  RenderCanvas *canvas() const;
602  // don't even think about making this method virtual!
603  DOM::DocumentImpl *document() const;
604  DOM::NodeImpl *element() const
605  {
606  return isAnonymous() ? nullptr : m_node;
607  }
608  DOM::NodeImpl *node() const
609  {
610  return m_node;
611  }
612 
613  virtual bool handleEvent(const DOM::EventImpl &)
614  {
615  return false;
616  }
617 
622  RenderObject *container() const;
623 
624  void markContainingBlocksForLayout();
625  void dirtyFormattingContext(bool checkContainer);
626  void repaintDuringLayout();
627  void setNeedsLayout(bool b, bool markParents = true);
628  void setChildNeedsLayout(bool b, bool markParents = true);
629  void setMinMaxKnown(bool b = true)
630  {
631  m_minMaxKnown = b;
632  if (!b) {
633  RenderObject *o = this;
634  while (o) { // ### && !o->m_recalcMinMax ) {
635  o->m_recalcMinMax = true;
636  o = o->m_parent;
637  }
638  }
639  }
640  void setNeedsLayoutAndMinMaxRecalc()
641  {
642  setMinMaxKnown(false);
643  setNeedsLayout(true);
644  }
645  void setPositioned(bool b = true)
646  {
647  m_positioned = b;
648  }
649  void setRelPositioned(bool b = true)
650  {
651  m_relPositioned = b;
652  }
653  void setFloating(bool b = true)
654  {
655  m_floating = b;
656  }
657  void setInline(bool b = true)
658  {
659  m_inline = b;
660  }
661  void setMouseInside(bool b = true)
662  {
663  m_mouseInside = b;
664  }
665  void setShouldPaintBackgroundOrBorder(bool b = true)
666  {
667  m_paintBackground = b;
668  }
669  void setRenderText()
670  {
671  m_isText = true;
672  }
673  void setReplaced(bool b = true)
674  {
675  m_replaced = b;
676  }
677  void setHasOverflowClip(bool b = true)
678  {
679  m_hasOverflowClip = b;
680  }
681  void setIsSelectionBorder(bool b = true)
682  {
683  m_isSelectionBorder = b;
684  }
685 
686  void scheduleRelayout(RenderObject *clippedObj = nullptr);
687 
688  void updateBackgroundImages(RenderStyle *oldStyle);
689 
690  virtual InlineBox *createInlineBox(bool makePlaceHolderBox, bool isRootLineBox);
691  virtual void removeInlineBox(InlineBox * /*box*/) {}
692 
693  virtual InlineBox *inlineBox(long offset = 0);
694  virtual short lineHeight(bool firstLine) const;
695  virtual short verticalPositionHint(bool firstLine) const;
696  virtual short baselinePosition(bool firstLine) const;
697  short getVerticalPosition(bool firstLine, RenderObject *ref = nullptr) const;
698 
699  /*
700  * Print the object and its children, clipped by (x|y|w|h).
701  * (tx|ty) is the calculated position of the parent
702  */
703  struct PaintInfo {
704  PaintInfo(QPainter *_p, const QRect &_r, PaintAction _phase)
705  : p(_p), r(_r), phase(_phase), outlineObjects(nullptr) {}
706  ~PaintInfo()
707  {
708  delete outlineObjects;
709  }
710  QPainter *p;
711  QRect r;
712  PaintAction phase;
713  QList<RenderFlow *> *outlineObjects; // used to list which outlines should be painted by a block with inline children
714  };
715  virtual void paint(PaintInfo &i, int tx, int ty);
716 
717  void calcBorderRadii(QPoint &topLeftRadii, QPoint &topRightRadii, QPoint &bottomLeftRadii, QPoint &bottomRightRadii, int w, int h) const;
718 
719  void drawBorderArc(QPainter *p, int x, int y, float horThickness, float vertThickness,
720  const QPoint &radius, int angleStart, int angleSpan, const QBrush &brush,
721  const QColor &textColor, EBorderStyle style, qreal *dashOffset = nullptr) const;
722 
723  void paintBorder(QPainter *p, int _tx, int _ty, int w, int h, const RenderStyle *style, bool begin = true, bool end = true);
724  void paintOutline(QPainter *p, int _tx, int _ty, int w, int h, const RenderStyle *style);
725 
726  virtual void paintBoxDecorations(PaintInfo &, int /*_tx*/, int /*_ty*/) {}
727 
728  virtual void paintBackgroundExtended(QPainter * /*p*/, const QColor & /*c*/, const BackgroundLayer * /*bgLayer*/,
729  QRect /*clipr*/, int /*_tx*/, int /*_ty*/,
730  int /*w*/, int /*height*/, int /*bleft*/, int /*bright*/, int /*pleft*/, int /*pright*/,
731  int /*btop*/, int /*bbottom*/, int /*ptop*/, int /*pbottom*/) {}
732 
733  /*
734  * This function calculates the minimum & maximum width that the object
735  * can be set to.
736  *
737  * when the Element calls setMinMaxKnown(true), calcMinMaxWidth() will
738  * be no longer called.
739  *
740  * when a element has a fixed size, m_minWidth and m_maxWidth should be
741  * set to the same value. This has the special meaning that m_width,
742  * contains the actual value.
743  *
744  * assumes calcMinMaxWidth has already been called for all children.
745  */
746  virtual void calcMinMaxWidth() { }
747 
748  /*
749  * Does the min max width recalculations after changes.
750  */
751  void recalcMinMaxWidths();
752 
753  /*
754  * Calculates the actual width of the object (only for non inline
755  * objects)
756  */
757  virtual void calcWidth() {}
758 
759  /*
760  * Calculates the actual width of the object (only for non inline
761  * objects)
762  */
763  virtual void calcHeight() {}
764 
765  /*
766  * This function should cause the Element to calculate its
767  * width and height and the layout of its content
768  *
769  * when the Element calls setNeedsLayout(false), layout() is no
770  * longer called during relayouts, as long as there is no
771  * style sheet change. When that occurs, m_needsLayout will be
772  * set to true and the Element receives layout() calls
773  * again.
774  */
775  virtual void layout() = 0;
776 
777  /* This function performs a layout only if one is needed. */
778  void layoutIfNeeded()
779  {
780  if (needsLayout()) {
781  layout();
782  }
783  }
784 
785  // used for element state updates that can not be fixed with a
786  // repaint and do not need a relayout
787  virtual void updateFromElement() {}
788 
789  // Called immediately after render-object is inserted
790  virtual void attach()
791  {
792  m_attached = true;
793  }
794  bool attached()
795  {
796  return m_attached;
797  }
798  // The corresponding closing element has been parsed. ### remove me
799  virtual void close() { }
800 
801  virtual int availableHeight() const
802  {
803  return 0;
804  }
805 
806  // Whether or not the element shrinks to its max width (rather than filling the width
807  // of a containing block). HTML4 buttons, legends, and floating/compact elements do this.
808  bool sizesToMaxWidth() const;
809 
810  /*
811  * NeesPageClear indicates the object crossed a page-break but could not break itself and now
812  * needs to be moved clear by its parent.
813  */
814  void setNeedsPageClear(bool b = true)
815  {
816  m_needsPageClear = b;
817  }
818  virtual bool needsPageClear() const
819  {
820  return m_needsPageClear;
821  }
822 
823  /*
824  * ContainsPageBreak indicates the object contains a clean page-break.
825  * ### should be removed and replaced with (crossesPageBreak && !needsPageClear)
826  */
827  void setContainsPageBreak(bool b = true)
828  {
829  m_containsPageBreak = b;
830  }
831  virtual bool containsPageBreak() const
832  {
833  return m_containsPageBreak;
834  }
835 
836  virtual int pageTopAfter(int y) const
837  {
838  if (parent()) {
839  return parent()->pageTopAfter(y);
840  } else {
841  return 0;
842  }
843  }
844 
845  virtual int crossesPageBreak(int top, int bottom) const
846  {
847  if (parent()) {
848  return parent()->crossesPageBreak(top, bottom);
849  } else {
850  return 0;
851  }
852  }
853 
854  // Checks if a page-break before child is possible at the given page-break level
855  // false means the child should attempt the break self.
856  virtual bool canClear(RenderObject * /*child*/, PageBreakLevel level)
857  {
858  if (parent()) {
859  return parent()->canClear(this, level);
860  } else {
861  return false;
862  }
863  }
864 
865  void setAfterPageBreak(bool b = true)
866  {
867  m_afterPageBreak = b;
868  }
869  void setBeforePageBreak(bool b = true)
870  {
871  m_beforePageBreak = b;
872  }
873  virtual bool afterPageBreak() const
874  {
875  return m_afterPageBreak;
876  }
877  virtual bool beforePageBreak() const
878  {
879  return m_beforePageBreak;
880  }
881 
882  // does a query on the rendertree and finds the innernode
883  // and overURL for the given position
884  // if readonly == false, it will recalc hover styles accordingly
885  class NodeInfo
886  {
887  friend class RenderImage;
888  friend class RenderFlow;
889  friend class RenderInline;
890  friend class RenderText;
891  friend class RenderWidget;
892  friend class RenderObject;
893  friend class RenderFrameSet;
894  friend class RenderLayer;
895  friend class DOM::HTMLAreaElementImpl;
896  public:
897  NodeInfo(bool readonly, bool active)
898  : m_innerNode(nullptr), m_innerNonSharedNode(nullptr), m_innerURLElement(nullptr), m_readonly(readonly), m_active(active)
899  { }
900 
901  DOM::NodeImpl *innerNode() const
902  {
903  return m_innerNode;
904  }
905  DOM::NodeImpl *innerNonSharedNode() const
906  {
907  return m_innerNonSharedNode;
908  }
909  DOM::NodeImpl *URLElement() const
910  {
911  return m_innerURLElement;
912  }
913  bool readonly() const
914  {
915  return m_readonly;
916  }
917  bool active() const
918  {
919  return m_active;
920  }
921 
922  private:
923  void setInnerNode(DOM::NodeImpl *n)
924  {
925  m_innerNode = n;
926  }
927  void setInnerNonSharedNode(DOM::NodeImpl *n)
928  {
929  m_innerNonSharedNode = n;
930  }
931  void setURLElement(DOM::NodeImpl *n)
932  {
933  m_innerURLElement = n;
934  }
935 
936  DOM::NodeImpl *m_innerNode;
937  DOM::NodeImpl *m_innerNonSharedNode;
938  DOM::NodeImpl *m_innerURLElement;
939  bool m_readonly;
940  bool m_active;
941  };
942 
945  struct SelPointState {
947  DOM::NodeImpl *m_lastNode;
952 
953  SelPointState() : m_lastNode(nullptr), m_lastOffset(0), m_afterInLine(false)
954  {}
955  };
956 
957 #if 0
958  virtual FindSelectionResult checkSelectionPoint(int _x, int _y, int _tx, int _ty,
959  DOM::NodeImpl *&, int &offset,
960  SelPointState &);
961 #endif
962  virtual bool nodeAtPoint(NodeInfo &info, int x, int y, int tx, int ty, HitTestAction, bool inside = false);
963  void setInnerNode(NodeInfo &info);
964 
965  // Position/Selection stuff
966  virtual RenderPosition positionForCoordinates(int x, int y);
967 
968  // set the style of the object.
969  virtual void setStyle(RenderStyle *style);
970 
971  // returns the containing block level element for this element.
972  RenderBlock *containingBlock() const;
973 
974  // return just the width of the containing block
975  virtual short containingBlockWidth(RenderObject *providedCB = nullptr) const;
976  // return just the height of the containing block
977  virtual int containingBlockHeight(RenderObject *providedCB = nullptr) const;
978 
979  // size of the content area (box size minus padding/border)
980  virtual short contentWidth() const
981  {
982  return 0;
983  }
984  virtual int contentHeight() const
985  {
986  return 0;
987  }
988 
989  // intrinsic extend of replaced elements. undefined otherwise
990  virtual short intrinsicWidth() const
991  {
992  return 0;
993  }
994  virtual int intrinsicHeight() const
995  {
996  return 0;
997  }
998 
999  // relative to parent node
1000  virtual void setPos(int /*xPos*/, int /*yPos*/) { }
1001  virtual void setWidth(int /*width*/) { }
1002  virtual void setHeight(int /*height*/) { }
1003 
1004  virtual int xPos() const
1005  {
1006  return 0;
1007  }
1008  virtual int yPos() const
1009  {
1010  return 0;
1011  }
1012 
1016  int effectiveXPos() const
1017  {
1018  return xPos() + (hasOverflowClip() ? 0 : overflowLeft());
1019  }
1020 
1024  int effectiveYPos() const
1025  {
1026  return yPos() + (hasOverflowClip() ? -borderTopExtra() : qMin(overflowTop(), -borderTopExtra()));
1027  }
1028 
1032  virtual int inlineXPos() const
1033  {
1034  return 0;
1035  }
1039  virtual int inlineYPos() const
1040  {
1041  return 0;
1042  }
1043 
1044  // calculate client position of box
1045  virtual bool absolutePosition(int &/*xPos*/, int &/*yPos*/, bool fixed = false) const;
1046 
1047  // width and height are without margins but include paddings and borders
1048  virtual short width() const
1049  {
1050  return 0;
1051  }
1052  virtual int height() const
1053  {
1054  return 0;
1055  }
1056 
1057  // The height of a block when you include overflow spillage out of
1058  // the bottom of the block (e.g., a <div style="height:25px"> that
1059  // has a 100px tall image inside it would have an overflow height
1060  // of borderTop() + paddingTop() + 100px.
1061  virtual int overflowHeight() const
1062  {
1063  return height();
1064  }
1065  virtual int overflowWidth() const
1066  {
1067  return width();
1068  }
1069  // how much goes over the left hand side (0 or a negative number)
1070  virtual int overflowTop() const
1071  {
1072  return 0;
1073  }
1074  virtual int overflowLeft() const
1075  {
1076  return 0;
1077  }
1078 
1083  int effectiveHeight() const
1084  {
1085  return hasOverflowClip() ? height() + borderTopExtra() + borderBottomExtra() :
1086  qMax(overflowHeight() - overflowTop(), height() + borderTopExtra() + borderBottomExtra());
1087  }
1092  int effectiveWidth() const
1093  {
1094  return hasOverflowClip() ? width() : overflowWidth() - overflowLeft();
1095  }
1096 
1097  QRectF clientRectToViewport(const QRectF &rect);
1098  virtual QList< QRectF > getClientRects();
1099 
1100  // IE extensions, heavily used in ECMA
1101  virtual short offsetWidth() const
1102  {
1103  return width();
1104  }
1105  virtual int offsetHeight() const
1106  {
1107  return height() + borderTopExtra() + borderBottomExtra();
1108  }
1109  virtual int offsetLeft() const;
1110  virtual int offsetTop() const;
1111  virtual RenderObject *offsetParent() const;
1112  int clientLeft() const;
1113  int clientTop() const;
1114  short clientWidth() const;
1115  int clientHeight() const;
1116  virtual short scrollWidth() const;
1117  virtual int scrollHeight() const;
1118 
1119  virtual bool isSelfCollapsingBlock() const
1120  {
1121  return false;
1122  }
1123  short collapsedMarginTop() const
1124  {
1125  return maxTopMargin(true) - maxTopMargin(false);
1126  }
1127  short collapsedMarginBottom() const
1128  {
1129  return maxBottomMargin(true) - maxBottomMargin(false);
1130  }
1131 
1132  virtual bool isTopMarginQuirk() const
1133  {
1134  return false;
1135  }
1136  virtual bool isBottomMarginQuirk() const
1137  {
1138  return false;
1139  }
1140  virtual short maxTopMargin(bool positive) const
1141  {
1142  return positive ? qMax(int(marginTop()), 0) : - qMin(int(marginTop()), 0);
1143  }
1144  virtual short maxBottomMargin(bool positive) const
1145  {
1146  return positive ? qMax(int(marginBottom()), 0) : - qMin(int(marginBottom()), 0);
1147  }
1148 
1149  virtual short marginTop() const
1150  {
1151  return 0;
1152  }
1153  virtual short marginBottom() const
1154  {
1155  return 0;
1156  }
1157  virtual short marginLeft() const
1158  {
1159  return 0;
1160  }
1161  virtual short marginRight() const
1162  {
1163  return 0;
1164  }
1165 
1166  virtual int paddingTop() const;
1167  virtual int paddingBottom() const;
1168  virtual int paddingLeft() const;
1169  virtual int paddingRight() const;
1170 
1171  virtual int borderTop() const
1172  {
1173  return style()->borderTopWidth();
1174  }
1175  virtual int borderBottom() const
1176  {
1177  return style()->borderBottomWidth();
1178  }
1179  virtual int borderLeft() const
1180  {
1181  return style()->borderLeftWidth();
1182  }
1183  virtual int borderRight() const
1184  {
1185  return style()->borderRightWidth();
1186  }
1187 
1188  virtual short minWidth() const
1189  {
1190  return 0;
1191  }
1192  virtual int maxWidth() const
1193  {
1194  return 0;
1195  }
1196 
1197  RenderStyle *style() const
1198  {
1199  return m_style;
1200  }
1201  RenderStyle *style(bool firstLine) const
1202  {
1203  RenderStyle *s = m_style;
1204  if (firstLine && hasFirstLine()) {
1205  RenderStyle *pseudoStyle = style()->getPseudoStyle(RenderStyle::FIRST_LINE);
1206  if (pseudoStyle) {
1207  s = pseudoStyle;
1208  }
1209  }
1210  return s;
1211  }
1212 
1213  void getTextDecorationColors(int decorations, QColor &underline, QColor &overline,
1214  QColor &linethrough, bool quirksMode = false);
1215 
1216  enum BorderSide {
1217  BSTop, BSBottom, BSLeft, BSRight
1218  };
1219  void drawBorder(QPainter *p, int x1, int y1, int x2, int y2, BorderSide s,
1220  QColor c, const QColor &textcolor, EBorderStyle style,
1221  int adjbw1, int adjbw2, bool invalidisInvert = false, qreal *dashOffset = nullptr);
1222 
1223  // Used by collapsed border tables.
1224  virtual void collectBorders(QList<CollapsedBorderValue> &borderStyles);
1225 
1226  // force a complete repaint
1227  virtual void repaint(Priority p = NormalPriority)
1228  {
1229  if (m_parent) {
1230  m_parent->repaint(p);
1231  }
1232  }
1233  virtual void repaintRectangle(int x, int y, int w, int h, Priority p = NormalPriority, bool f = false);
1234 
1235  virtual unsigned int length() const
1236  {
1237  return 1;
1238  }
1239 
1240  virtual bool isHidden() const
1241  {
1242  return isFloating() || isPositioned();
1243  }
1244 
1245  // Special objects are objects that are neither really inline nor blocklevel
1246  bool isFloatingOrPositioned() const
1247  {
1248  return (isFloating() || isPositioned());
1249  }
1250  virtual bool hasOverhangingFloats() const
1251  {
1252  return false;
1253  }
1254  virtual bool hasFloats() const
1255  {
1256  return false;
1257  }
1258  virtual bool containsFloat(RenderObject * /*o*/) const
1259  {
1260  return false;
1261  }
1262  virtual void markAllDescendantsWithFloatsForLayout(RenderObject * /*floatToRemove*/ = nullptr) {}
1263 
1264  bool flowAroundFloats() const;
1265  bool usesLineWidth() const;
1266 
1267  // positioning of inline children (bidi)
1268  virtual void position(InlineBox *, int, int, bool) {}
1269 // virtual void position(int, int, int, int, int, bool, bool, int) {}
1270 
1271  // Applied as a "slop" to dirty rect checks during the outline painting phase's dirty-rect checks.
1272  int maximalOutlineSize(PaintAction p) const;
1273 
1274  enum SelectionState {
1275  SelectionNone,
1276  SelectionStart,
1277  SelectionInside,
1278  SelectionEnd,
1279  SelectionBoth
1280  };
1281 
1282  virtual SelectionState selectionState() const
1283  {
1284  return SelectionNone;
1285  }
1286  virtual void setSelectionState(SelectionState) {}
1287  bool shouldSelect() const;
1288  virtual bool isPointInsideSelection(int x, int y, const DOM::Selection &) const;
1289 
1290  DOM::NodeImpl *draggableNode(bool dhtmlOK, bool uaOK, bool &dhtmlWillDrag) const;
1291 
1301  enum CaretFlags { CFOverride = 0x01, CFOutside = 0x02, CFOutsideEnd = 0x04 };
1302 
1312  virtual void caretPos(int offset, int flags, int &_x, int &_y, int &width, int &height) const;
1313 
1314  // returns the lowest position of the lowest object in that particular object.
1315  // This 'height' is relative to the topleft of the margin box of the object.
1316  // Implemented in RenderFlow.
1317  virtual int lowestPosition(bool /*includeOverflowInterior*/ = true, bool /*includeSelf*/ = true) const
1318  {
1319  return 0;
1320  }
1321  virtual int rightmostPosition(bool /*includeOverflowInterior*/ = true, bool /*includeSelf*/ = true) const
1322  {
1323  return 0;
1324  }
1325  virtual int leftmostPosition(bool /*includeOverflowInterior*/ = true, bool /*includeSelf*/ = true) const
1326  {
1327  return 0;
1328  }
1329  virtual int highestPosition(bool /*includeOverflowInterior*/ = true, bool /*includeSelf*/ = true) const
1330  {
1331  return 0;
1332  }
1333 
1334  // recursively invalidate current layout
1335  // unused: void invalidateLayout();
1336 
1337  virtual void calcVerticalMargins() {}
1338  void removeFromObjectLists();
1339  void setInPosObjectList(bool b = true)
1340  {
1341  m_inPosObjectList = b;
1342  }
1343  bool inPosObjectList() const
1344  {
1345  return m_inPosObjectList;
1346  }
1347 
1348  virtual void deleteInlineBoxes(RenderArena *arena = nullptr)
1349  {
1350  (void)arena;
1351  }
1352  virtual void dirtyInlineBoxes(bool /*fullLayout*/, bool /*isRootLineBox*/ = false) {}
1353  virtual void dirtyLinesFromChangedChild(RenderObject *) {}
1354  virtual void detach();
1355 
1356  bool documentBeingDestroyed() const
1357  {
1358  return !document()->renderer();
1359  }
1360 
1361  void setDoNotDelete(bool b)
1362  {
1363  m_doNotDelete = b;
1364  }
1365  bool doNotDelete() const
1366  {
1367  return m_doNotDelete;
1368  }
1369 
1370  const QFont &font(bool firstLine) const
1371  {
1372  return style(firstLine)->font();
1373  }
1374 
1375  const QFontMetrics &fontMetrics(bool firstLine) const
1376  {
1377  return style(firstLine)->fontMetrics();
1378  }
1379 
1385  virtual long caretMinOffset() const;
1392  virtual long caretMaxOffset() const;
1393  virtual unsigned long caretMaxRenderedOffset() const;
1394 
1395  void updatePixmap(const QRect &, CachedImage *) override;
1396 
1397  QRegion visibleFlowRegion(int x, int y) const;
1398 
1399  virtual void removeSuperfluousAnonymousBlockChild(RenderObject *) {}
1400 
1401  // Unregisters from parent but does not destroy
1402  void remove();
1403 protected:
1404  virtual void selectionStartEnd(int &spos, int &epos);
1405 
1406  virtual QRect viewRect() const;
1407  void setDetached()
1408  {
1409  m_attached = false;
1410  }
1411  void invalidateVerticalPosition();
1412  bool attemptDirectLayerTranslation();
1413  void updateWidgetMasks();
1414 
1415  void arenaDelete(RenderArena *arena);
1416 
1417 private:
1418  RenderStyle *m_style;
1419  DOM::NodeImpl *m_node;
1420  RenderObject *m_parent;
1421  RenderObject *m_previous;
1422  RenderObject *m_next;
1423 
1424  short m_verticalPosition;
1425 
1426  bool m_needsLayout : 1;
1427  bool m_normalChildNeedsLayout : 1;
1428  bool m_markedForRepaint : 1;
1429  bool m_posChildNeedsLayout : 1;
1430 
1431  bool m_minMaxKnown : 1;
1432  bool m_floating : 1;
1433 
1434  bool m_positioned : 1;
1435  bool m_relPositioned : 1;
1436  bool m_paintBackground : 1; // if the box has something to paint in the
1437  // background painting phase (background, border, etc)
1438 
1439  bool m_isAnonymous : 1;
1440  bool m_recalcMinMax : 1;
1441  bool m_isText : 1;
1442  bool m_inline : 1;
1443  bool m_attached : 1;
1444 
1445  bool m_replaced : 1;
1446  bool m_mouseInside : 1;
1447  bool m_hasFirstLine : 1;
1448  bool m_isSelectionBorder : 1;
1449 
1450  bool m_isRoot : 1;
1451 
1452  bool m_beforePageBreak : 1;
1453  bool m_afterPageBreak : 1;
1454 
1455  bool m_needsPageClear : 1;
1456  bool m_containsPageBreak : 1;
1457 
1458  bool m_hasOverflowClip : 1;
1459  bool m_inPosObjectList : 1;
1460 
1461  bool m_doNotDelete : 1; // This object should not be auto-deleted
1462 
1463  // ### we have 16 + 26 bits.
1464 
1465  static QCache<quint64, QPixmap> *s_dashedLineCache;
1466 
1467  void arenaDelete(RenderArena *arena, void *objectBase);
1468 
1469  friend class RenderLayer;
1470  friend class RenderListItem;
1471  friend class RenderContainer;
1472  friend class RenderCanvas;
1473 };
1474 
1475 enum VerticalPositionHint {
1476  PositionTop = -0x4000,
1477  PositionBottom = 0x4000,
1478  PositionUndefined = 0x3fff
1479 };
1480 
1481 } //namespace
1482 #endif
bool m_afterInLine
true when the last node had the result SelectionAfterInLine
This file is part of the HTML rendering engine for KDE.
int effectiveXPos() const
the position of the object from where it begins drawing, including its negative overflow ...
Base class for rendering objects that can have children.
a cached image
Definition: loader.h:359
int effectiveWidth() const
Returns the width that is effectively considered when contemplating the object as a whole – usually ...
DOM::NodeImpl * m_lastNode
last node that was before the current position
This class implements the basic string we use in the DOM.
Definition: dom_string.h:44
long m_lastOffset
offset of last node
all geometry managing stuff is only in the block elements.
Definition: render_flow.h:44
This library provides a full-featured HTML parser and widget.
virtual int inlineXPos() const
Leftmost coordinate of this inline element relative to containing block.
int effectiveYPos() const
the position of the object from where it begins drawing, including its negative overflow ...
Base Class for all rendering tree objects.
contains stateful information for a checkSelectionPoint call
virtual int inlineYPos() const
Topmost coordinate of this inline element relative to containing block.
int effectiveHeight() const
Returns the height that is effectively considered when contemplating the object as a whole – usually...
CaretFlags
Flags which influence the appearance and position.
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Wed Sep 23 2020 22:46:34 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.