KHtml

render_line.h
1 /*
2  * This file is part of the line box implementation for KDE.
3  *
4  * Copyright (C) 2003 Apple Computer, Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB. If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  *
21  */
22 #ifndef RENDER_LINE_H
23 #define RENDER_LINE_H
24 
25 #include "render_object.h"
26 
27 namespace khtml
28 {
29 
30 class EllipsisBox;
31 class InlineFlowBox;
32 class RootInlineBox;
33 class RenderArena;
34 struct BidiStatus;
35 class BidiContext;
36 
37 // InlineBox represents a rectangle that occurs on a line. It corresponds to
38 // some RenderObject (i.e., it represents a portion of that RenderObject).
39 class InlineBox
40 {
41 public:
42  InlineBox(RenderObject *obj)
43  : m_object(obj), m_x(0), m_width(0), m_y(0), m_height(0), m_baseline(0),
44  m_firstLine(false), m_constructed(false), m_dirty(false), m_extracted(false), m_endsWithBreak(false)
45  {
46  m_next = nullptr;
47  m_prev = nullptr;
48  m_parent = nullptr;
49  }
50 
51  virtual ~InlineBox() {}
52 
53  virtual void detach(RenderArena *renderArena, bool noRemove = false);
54 
55  virtual void paint(RenderObject::PaintInfo &i, int _tx, int _ty);
56  virtual bool nodeAtPoint(RenderObject::NodeInfo &i, int x, int y, int tx, int ty);
57 
58  // Overloaded new operator.
59  void *operator new(size_t sz, RenderArena *renderArena) throw();
60 
61  // Overridden to prevent the normal delete from being called.
62  void operator delete(void *ptr, size_t sz);
63 
64 #ifdef ENABLE_DUMP
65  QString information() const;
66  void printTree(int indent = 0) const;
67 #endif
68 
69 private:
70  // The normal operator new is disallowed.
71  void *operator new(size_t sz) throw();
72 
73 public:
74  virtual bool isPlaceHolderBox() const
75  {
76  return false;
77  }
78  virtual bool isInlineFlowBox() const
79  {
80  return false;
81  }
82  virtual bool isContainer() const
83  {
84  return false;
85  }
86  virtual bool isInlineTextBox() const
87  {
88  return false;
89  }
90  virtual bool isRootInlineBox() const
91  {
92  return false;
93  }
94  // SVG
95  virtual bool isSVGRootInlineBox() const
96  {
97  return false;
98  }
99 
100  bool isConstructed() const
101  {
102  return m_constructed;
103  }
104  virtual void setConstructed()
105  {
106  m_constructed = true;
107  if (m_next) {
108  m_next->setConstructed();
109  }
110  }
111 
112  void setFirstLineStyleBit(bool f)
113  {
114  m_firstLine = f;
115  }
116 
117  InlineBox *nextOnLine() const
118  {
119  return m_next;
120  }
121  InlineBox *prevOnLine() const
122  {
123  return m_prev;
124  }
125  void setNextOnLine(InlineBox *next)
126  {
127  m_next = next;
128  }
129  void setPrevOnLine(InlineBox *prev)
130  {
131  m_prev = prev;
132  }
133  bool nextOnLineExists() const;
134  bool prevOnLineExists() const;
135 
136  virtual InlineBox *firstLeafChild();
137  virtual InlineBox *lastLeafChild();
138  InlineBox *closestLeafChildForXPos(int _x, int _tx);
139 
140  RenderObject *object() const
141  {
142  return m_object;
143  }
144 
145  InlineFlowBox *parent() const
146  {
147  return m_parent;
148  }
149  void setParent(InlineFlowBox *par)
150  {
151  m_parent = par;
152  }
153 
154  RootInlineBox *root();
155 
156  void setWidth(short w)
157  {
158  m_width = w;
159  }
160  short width() const
161  {
162  return m_width;
163  }
164 
165  void setXPos(short x)
166  {
167  m_x = x;
168  }
169  short xPos() const
170  {
171  return m_x;
172  }
173 
174  void setYPos(int y)
175  {
176  m_y = y;
177  }
178  int yPos() const
179  {
180  return m_y;
181  }
182 
183  void setHeight(int h)
184  {
185  m_height = h;
186  }
187  int height() const
188  {
189  return m_height;
190  }
191 
192  void setBaseline(int b)
193  {
194  m_baseline = b;
195  }
196  int baseline() const
197  {
198  return m_baseline;
199  }
200 
201  virtual bool hasTextChildren() const
202  {
203  return true;
204  }
205  virtual bool hasTextDescendant() const
206  {
207  return true;
208  }
209 
210  virtual int topOverflow() const
211  {
212  return yPos();
213  }
214  virtual int bottomOverflow() const
215  {
216  return yPos() + height();
217  }
218 
219  virtual long caretMinOffset() const;
220  virtual long caretMaxOffset() const;
221  virtual unsigned long caretMaxRenderedOffset() const;
222 
223  bool isDirty() const
224  {
225  return m_dirty;
226  }
227  void markDirty(bool dirty = true)
228  {
229  m_dirty = dirty;
230  }
231 
232  void setExtracted(bool b = true)
233  {
234  m_extracted = b;
235  }
236  void remove();
237 
238  void dirtyInlineBoxes();
239  virtual void deleteLine(RenderArena *arena);
240  virtual void extractLine();
241  virtual void attachLine();
242  void adjustPosition(int dx, int dy);
243 
244  virtual void clearTruncation() {}
245 
246  virtual bool canAccommodateEllipsisBox(bool ltr, int blockEdge, int ellipsisWidth);
247  virtual int placeEllipsisBox(bool ltr, int blockEdge, int ellipsisWidth, bool &);
248 
249 public: // FIXME: Would like to make this protected, but methods are accessing these
250  // members over in the part.
251  RenderObject *m_object;
252 
253  short m_x;
254  short m_width;
255  int m_y;
256  int m_height;
257  int m_baseline;
258 
259  bool m_firstLine : 1;
260  bool m_constructed : 1;
261  bool m_dirty : 1;
262  bool m_extracted : 1;
263  bool m_endsWithBreak : 1;
264 
265  InlineBox *m_next; // The next element on the same line as us.
266  InlineBox *m_prev; // The previous element on the same line as us.
267 
268  InlineFlowBox *m_parent; // The box that contains us.
269 };
270 
271 class PlaceHolderBox: public InlineBox
272 {
273 public:
274  PlaceHolderBox(RenderObject *obj): InlineBox(obj) {}
275  bool isPlaceHolderBox() const override
276  {
277  return true;
278  }
279 };
280 
281 class InlineRunBox : public InlineBox
282 {
283 public:
284  InlineRunBox(RenderObject *obj)
285  : InlineBox(obj)
286  {
287  m_prevLine = nullptr;
288  m_nextLine = nullptr;
289  }
290 
291  InlineRunBox *prevLineBox() const
292  {
293  return m_prevLine;
294  }
295  InlineRunBox *nextLineBox() const
296  {
297  return m_nextLine;
298  }
299  void setNextLineBox(InlineRunBox *n)
300  {
301  m_nextLine = n;
302  }
303  void setPreviousLineBox(InlineRunBox *p)
304  {
305  m_prevLine = p;
306  }
307 
308  virtual void paintBackgroundAndBorder(RenderObject::PaintInfo &, int /*_tx*/, int /*_ty*/) {}
309  virtual void paintDecorations(RenderObject::PaintInfo &, int /*_tx*/, int /*_ty*/, bool /*paintedChildren*/ = false) {}
310 
311 protected:
312  InlineRunBox *m_prevLine; // The previous box that also uses our RenderObject
313  InlineRunBox *m_nextLine; // The next box that also uses our RenderObject
314 };
315 
316 class InlineFlowBox : public InlineRunBox
317 {
318 public:
319  InlineFlowBox(RenderObject *obj)
320  : InlineRunBox(obj)
321  {
322  m_firstChild = nullptr;
323  m_lastChild = nullptr;
324  m_includeLeftEdge = m_includeRightEdge = false;
325  m_hasTextChildren = false;
326  m_hasTextDescendant = false;
327  m_afterPageBreak = false;
328  }
329 
330  ~InlineFlowBox();
331 
332  bool isInlineFlowBox() const override
333  {
334  return true;
335  }
336 
337  InlineFlowBox *prevFlowBox() const
338  {
339  return static_cast<InlineFlowBox *>(m_prevLine);
340  }
341  InlineFlowBox *nextFlowBox() const
342  {
343  return static_cast<InlineFlowBox *>(m_nextLine);
344  }
345 
346  InlineBox *firstChild() const
347  {
348  return m_firstChild;
349  }
350  InlineBox *lastChild() const
351  {
352  return m_lastChild;
353  }
354 
355  InlineBox *firstLeafChild() override;
356  InlineBox *lastLeafChild() override;
357  InlineBox *closestChildForXPos(int _x, int _tx);
358 
359  void setConstructed() override
360  {
361  InlineBox::setConstructed();
362  if (m_firstChild) {
363  m_firstChild->setConstructed();
364  }
365  }
366  void addToLine(InlineBox *child)
367  {
368  if (!m_firstChild) {
369  m_firstChild = m_lastChild = child;
370  } else {
371  m_lastChild->m_next = child;
372  child->m_prev = m_lastChild;
373  m_lastChild = child;
374  }
375  child->setFirstLineStyleBit(m_firstLine);
376  child->setParent(this);
377  if (!m_hasTextChildren && child->isInlineTextBox()) {
378  m_hasTextDescendant = m_hasTextChildren = true;
379  for (InlineFlowBox *p = m_parent; p && !p->hasTextDescendant(); p = p->parent()) {
380  p->m_hasTextDescendant = true;
381  }
382  }
383  }
384 
385  void clearTruncation() override;
386 
387  void removeFromLine(InlineBox *child);
388  void paintBackgroundAndBorder(RenderObject::PaintInfo &, int _tx, int _ty) override;
389  void paintAllBackgrounds(QPainter *p, const QColor &c, const BackgroundLayer *bgLayer,
390  QRect clipr, int _tx, int _ty, int w, int h);
391  void paintOneBackground(QPainter *p, const QColor &c, const BackgroundLayer *bgLayer,
392  QRect clipr, int _tx, int _ty, int w, int h);
393  void paint(RenderObject::PaintInfo &i, int _tx, int _ty) override;
394  void paintDecorations(RenderObject::PaintInfo &, int _tx, int _ty, bool paintedChildren = false) override;
395  bool nodeAtPoint(RenderObject::NodeInfo &i, int x, int y, int tx, int ty) override;
396 
397  int marginBorderPaddingLeft() const;
398  int marginBorderPaddingRight() const;
399  int marginLeft() const;
400  int marginRight()const;
401  int borderLeft() const
402  {
403  if (includeLeftEdge()) {
404  return object()->borderLeft();
405  } return 0;
406  }
407  int borderRight() const
408  {
409  if (includeRightEdge()) {
410  return object()->borderRight();
411  } return 0;
412  }
413  int paddingLeft() const
414  {
415  if (includeLeftEdge()) {
416  return object()->paddingLeft();
417  } return 0;
418  }
419  int paddingRight() const
420  {
421  if (includeRightEdge()) {
422  return object()->paddingRight();
423  } return 0;
424  }
425 
426  bool includeLeftEdge() const
427  {
428  return m_includeLeftEdge;
429  }
430  bool includeRightEdge() const
431  {
432  return m_includeRightEdge;
433  }
434  void setEdges(bool includeLeft, bool includeRight)
435  {
436  m_includeLeftEdge = includeLeft;
437  m_includeRightEdge = includeRight;
438  }
439  bool hasTextChildren() const override
440  {
441  return m_hasTextChildren;
442  }
443  bool hasTextDescendant() const override
444  {
445  return m_hasTextDescendant;
446  }
447 
448  // Helper functions used during line construction and placement.
449  void determineSpacingForFlowBoxes(bool lastLine, RenderObject *endObject);
450  int getFlowSpacingWidth() const;
451  bool nextOnLineExists();
452  bool prevOnLineExists();
453  bool onEndChain(RenderObject *endObject);
454  int placeBoxesHorizontally(int x);
455  void verticallyAlignBoxes(int &heightOfBlock);
456  void computeLogicalBoxHeights(int &maxPositionTop, int &maxPositionBottom,
457  int &maxAscent, int &maxDescent, bool strictMode);
458  void adjustMaxAscentAndDescent(int &maxAscent, int &maxDescent,
459  int maxPositionTop, int maxPositionBottom);
460  void placeBoxesVertically(int y, int maxHeight, int maxAscent, bool strictMode,
461  int &topPosition, int &bottomPosition);
462  void shrinkBoxesWithNoTextChildren(int topPosition, int bottomPosition);
463 
464  virtual void setOverflowPositions(int /*top*/, int /*bottom*/) {}
465 
466  void setAfterPageBreak(bool b = true)
467  {
468  m_afterPageBreak = b;
469  }
470  bool afterPageBreak() const
471  {
472  return m_afterPageBreak;
473  }
474 
475  bool canAccommodateEllipsisBox(bool ltr, int blockEdge, int ellipsisWidth) override;
476  int placeEllipsisBox(bool ltr, int blockEdge, int ellipsisWidth, bool &) override;
477 
478  void deleteLine(RenderArena *arena) override;
479  void extractLine() override;
480  void attachLine() override;
481 
482 protected:
483  InlineBox *m_firstChild;
484  InlineBox *m_lastChild;
485  bool m_includeLeftEdge : 1;
486  bool m_includeRightEdge : 1;
487  bool m_hasTextChildren : 1;
488  bool m_hasTextDescendant : 1;
489  bool m_afterPageBreak : 1;
490 };
491 
492 class RootInlineBox : public InlineFlowBox
493 {
494 public:
495  RootInlineBox(RenderObject *obj) : InlineFlowBox(obj), m_lineBreakObj(nullptr), m_lineBreakPos(0),
496  m_lineBreakContext(nullptr), m_blockHeight(0), m_ellipsisBox(nullptr)
497  {
498  m_topOverflow = m_bottomOverflow = 0;
499  }
500 
501  void detach(RenderArena *renderArena, bool noRemove = false) override;
502  void detachEllipsisBox(RenderArena *renderArena);
503 
504  RootInlineBox *nextRootBox() const
505  {
506  return static_cast<RootInlineBox *>(m_nextLine);
507  }
508  RootInlineBox *prevRootBox() const
509  {
510  return static_cast<RootInlineBox *>(m_prevLine);
511  }
512 
513  bool isRootInlineBox() const override
514  {
515  return true;
516  }
517  int topOverflow() const override
518  {
519  return m_topOverflow;
520  }
521  int bottomOverflow() const override
522  {
523  return m_bottomOverflow;
524  }
525  void setOverflowPositions(int top, int bottom) override
526  {
527  m_topOverflow = top;
528  m_bottomOverflow = bottom;
529  }
530 
531  bool canAccommodateEllipsis(bool ltr, int blockEdge, int lineBoxEdge, int ellipsisWidth);
532  void placeEllipsis(const DOM::DOMString &ellipsisStr, bool ltr, int blockEdge, int ellipsisWidth, InlineBox *markupBox = nullptr);
533  int placeEllipsisBox(bool ltr, int blockEdge, int ellipsisWidth, bool &) override;
534 
535  EllipsisBox *ellipsisBox() const
536  {
537  return m_ellipsisBox;
538  }
539  void paintEllipsisBox(RenderObject::PaintInfo &i, int _tx, int _ty) const;
540  bool hitTestEllipsisBox(RenderObject::NodeInfo &info, int _x, int _y, int _tx, int _ty);
541 
542  void clearTruncation() override;
543 
544  void paint(RenderObject::PaintInfo &i, int _tx, int _ty) override;
545  bool nodeAtPoint(RenderObject::NodeInfo &i, int x, int y, int tx, int ty) override;
546 
547  RenderObject *lineBreakObj() const
548  {
549  return m_lineBreakObj;
550  }
551  BidiStatus lineBreakBidiStatus() const;
552  void setLineBreakInfo(RenderObject *, unsigned breakPos, const BidiStatus &, BidiContext *context);
553 
554  BidiContext *lineBreakBidiContext() const
555  {
556  return m_lineBreakContext;
557  }
558 
559  unsigned lineBreakPos() const
560  {
561  return m_lineBreakPos;
562  }
563  void setLineBreakPos(unsigned p)
564  {
565  m_lineBreakPos = p;
566  }
567 
568  int blockHeight() const
569  {
570  return m_blockHeight;
571  }
572  void setBlockHeight(int h)
573  {
574  m_blockHeight = h;
575  }
576 
577  bool endsWithBreak() const
578  {
579  return m_endsWithBreak;
580  }
581  void setEndsWithBreak(bool b)
582  {
583  m_endsWithBreak = b;
584  }
585 
586  void childRemoved(InlineBox *box);
587 
588 protected:
589  int m_topOverflow;
590  int m_bottomOverflow;
591 
592  // Where this line ended. The exact object and the position within that object are stored so that
593  // we can create a BidiIterator beginning just after the end of this line.
594  RenderObject *m_lineBreakObj;
595  unsigned m_lineBreakPos;
596  BidiContext *m_lineBreakContext;
597 
598  // The height of the block at the end of this line. This is where the next line starts.
599  int m_blockHeight;
600 
601  KDE_BF_ENUM(QChar::Direction) m_lineBreakBidiStatusEor : 5;
602  KDE_BF_ENUM(QChar::Direction) m_lineBreakBidiStatusLastStrong : 5;
603  KDE_BF_ENUM(QChar::Direction) m_lineBreakBidiStatusLast : 5;
604 
605  // An inline text box that represents our text truncation string.
606  EllipsisBox *m_ellipsisBox;
607 };
608 
609 } //namespace
610 
611 #endif
This file is part of the HTML rendering engine for KDE.
MESSAGECORE_EXPORT KMime::Content * firstChild(const KMime::Content *node)
This class implements the basic string we use in the DOM.
Definition: dom_string.h:44
Direction
void information(QWidget *parent, const QString &text, const QString &caption=QString(), const QString &dontShowAgainName=QString(), Options options=Notify)
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Tue Oct 26 2021 22:48:08 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.