]> git.saurik.com Git - iphone-api.git/blob - WebCore/RenderBlock.h
Adding the WebCore headers (for Cydget).
[iphone-api.git] / WebCore / RenderBlock.h
1 /*
2 * This file is part of the render object implementation for KHTML.
3 *
4 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
5 * (C) 1999 Antti Koivisto (koivisto@kde.org)
6 * (C) 2007 David Smith (catfish.man@gmail.com)
7 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
18 *
19 * You should have received a copy of the GNU Library General Public License
20 * along with this library; see the file COPYING.LIB. If not, write to
21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
23 */
24
25 #ifndef RenderBlock_h
26 #define RenderBlock_h
27
28 #include "DeprecatedPtrList.h"
29 #include "GapRects.h"
30 #include "RenderFlow.h"
31 #include "RootInlineBox.h"
32 #include <wtf/ListHashSet.h>
33
34 namespace WebCore {
35
36 class InlineIterator;
37 class BidiRun;
38 class Position;
39 class RootInlineBox;
40
41 template <class Iterator, class Run> class BidiResolver;
42 typedef BidiResolver<InlineIterator, BidiRun> InlineBidiResolver;
43
44 enum CaretType { CursorCaret, DragCaret };
45
46 class RenderBlock : public RenderFlow {
47 public:
48 RenderBlock(Node*);
49 virtual ~RenderBlock();
50
51 virtual const char* renderName() const;
52
53 // These two functions are overridden for inline-block.
54 virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const;
55 virtual int baselinePosition(bool firstLine, bool isRootLineBox = false) const;
56
57 virtual bool isRenderBlock() const { return true; }
58 virtual bool isBlockFlow() const { return (!isInline() || isReplaced()) && !isTable(); }
59 virtual bool isInlineBlockOrInlineTable() const { return isInline() && isReplaced(); }
60
61 virtual bool childrenInline() const { return m_childrenInline; }
62 virtual void setChildrenInline(bool b) { m_childrenInline = b; }
63 void makeChildrenNonInline(RenderObject* insertionPoint = 0);
64 void deleteLineBoxTree();
65
66 // The height (and width) of a block when you include overflow spillage out of the bottom
67 // of the block (e.g., a <div style="height:25px"> that has a 100px tall image inside
68 // it would have an overflow height of borderTop() + paddingTop() + 100px.
69 virtual int overflowHeight(bool includeInterior = true) const;
70 virtual int overflowWidth(bool includeInterior = true) const;
71 virtual int overflowLeft(bool includeInterior = true) const;
72 virtual int overflowTop(bool includeInterior = true) const;
73 virtual IntRect overflowRect(bool includeInterior = true) const;
74 virtual void setOverflowHeight(int h) { m_overflowHeight = h; }
75 virtual void setOverflowWidth(int w) { m_overflowWidth = w; }
76
77 void addVisualOverflow(const IntRect&);
78
79 virtual bool isSelfCollapsingBlock() const;
80 virtual bool isTopMarginQuirk() const { return m_topMarginQuirk; }
81 virtual bool isBottomMarginQuirk() const { return m_bottomMarginQuirk; }
82
83 virtual int maxTopMargin(bool positive) const { return positive ? maxTopPosMargin() : maxTopNegMargin(); }
84 virtual int maxBottomMargin(bool positive) const { return positive ? maxBottomPosMargin() : maxBottomNegMargin(); }
85
86 int maxTopPosMargin() const { return m_maxMargin ? m_maxMargin->m_topPos : MaxMargin::topPosDefault(this); }
87 int maxTopNegMargin() const { return m_maxMargin ? m_maxMargin->m_topNeg : MaxMargin::topNegDefault(this); }
88 int maxBottomPosMargin() const { return m_maxMargin ? m_maxMargin->m_bottomPos : MaxMargin::bottomPosDefault(this); }
89 int maxBottomNegMargin() const { return m_maxMargin ? m_maxMargin->m_bottomNeg : MaxMargin::bottomNegDefault(this); }
90 void setMaxTopMargins(int pos, int neg);
91 void setMaxBottomMargins(int pos, int neg);
92
93 void initMaxMarginValues()
94 {
95 if (m_maxMargin) {
96 m_maxMargin->m_topPos = MaxMargin::topPosDefault(this);
97 m_maxMargin->m_topNeg = MaxMargin::topNegDefault(this);
98 m_maxMargin->m_bottomPos = MaxMargin::bottomPosDefault(this);
99 m_maxMargin->m_bottomNeg = MaxMargin::bottomNegDefault(this);
100 }
101 }
102
103 virtual void addChildToFlow(RenderObject* newChild, RenderObject* beforeChild);
104 virtual void removeChild(RenderObject*);
105
106 virtual void repaintOverhangingFloats(bool paintAllDescendants);
107
108 virtual void layout();
109 virtual void layoutBlock(bool relayoutChildren);
110 void layoutBlockChildren(bool relayoutChildren, int& maxFloatBottom);
111 void layoutInlineChildren(bool relayoutChildren, int& repaintTop, int& repaintBottom);
112
113 void layoutPositionedObjects(bool relayoutChildren);
114 void insertPositionedObject(RenderBox*);
115 void removePositionedObject(RenderBox*);
116 void removePositionedObjects(RenderBlock*);
117
118 void addPercentHeightDescendant(RenderBox*);
119 static void removePercentHeightDescendant(RenderBox*);
120
121 virtual void positionListMarker() { }
122
123 virtual void borderFitAdjust(int& x, int& w) const; // Shrink the box in which the border paints if border-fit is set.
124
125 // Called to lay out the legend for a fieldset.
126 virtual RenderObject* layoutLegend(bool /*relayoutChildren*/) { return 0; }
127
128 // the implementation of the following functions is in bidi.cpp
129 struct FloatWithRect {
130 FloatWithRect(RenderBox* f)
131 : object(f)
132 , rect(IntRect(f->x() - f->marginLeft(), f->y() - f->marginTop(), f->width() + f->marginLeft() + f->marginRight(), f->height() + f->marginTop() + f->marginBottom()))
133 {
134 }
135
136 RenderBox* object;
137 IntRect rect;
138 };
139
140 void bidiReorderLine(InlineBidiResolver&, const InlineIterator& end);
141 RootInlineBox* determineStartPosition(bool& fullLayout, InlineBidiResolver&, Vector<FloatWithRect>& floats, unsigned& numCleanFloats);
142 RootInlineBox* determineEndPosition(RootInlineBox* startBox, InlineIterator& cleanLineStart,
143 BidiStatus& cleanLineBidiStatus,
144 int& yPos);
145 bool matchedEndLine(const InlineBidiResolver&, const InlineIterator& endLineStart, const BidiStatus& endLineStatus,
146 RootInlineBox*& endLine, int& endYPos, int& repaintBottom, int& repaintTop);
147 bool generatesLineBoxesForInlineChild(RenderObject*);
148 void skipTrailingWhitespace(InlineIterator&);
149 int skipLeadingWhitespace(InlineBidiResolver&);
150 void fitBelowFloats(int widthToFit, int& availableWidth);
151 InlineIterator findNextLineBreak(InlineBidiResolver&, EClear* clear = 0);
152 RootInlineBox* constructLine(unsigned runCount, BidiRun* firstRun, BidiRun* lastRun, bool lastLine, RenderObject* endObject);
153 InlineFlowBox* createLineBoxes(RenderObject*);
154 void computeHorizontalPositionsForLine(RootInlineBox*, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd);
155 void computeVerticalPositionsForLine(RootInlineBox*, BidiRun*);
156 void checkLinesForOverflow();
157 void deleteEllipsisLineBoxes();
158 void checkLinesForTextOverflow();
159 // end bidi.cpp functions
160
161 virtual void paint(PaintInfo&, int tx, int ty);
162 virtual void paintObject(PaintInfo&, int tx, int ty);
163 void paintFloats(PaintInfo&, int tx, int ty, bool preservePhase = false);
164 void paintContents(PaintInfo&, int tx, int ty);
165 void paintColumns(PaintInfo&, int tx, int ty, bool paintFloats = false);
166 void paintChildren(PaintInfo&, int tx, int ty);
167 void paintEllipsisBoxes(PaintInfo&, int tx, int ty);
168 void paintSelection(PaintInfo&, int tx, int ty);
169 void paintCaret(PaintInfo&, int tx, int ty, CaretType);
170
171 void insertFloatingObject(RenderBox*);
172 void removeFloatingObject(RenderBox*);
173
174 // Called from lineWidth, to position the floats added in the last line.
175 // Returns ture if and only if it has positioned any floats.
176 bool positionNewFloats();
177 void clearFloats();
178 int getClearDelta(RenderBox* child);
179 void markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove = 0, bool inLayout = true);
180 void markPositionedObjectsForLayout();
181
182 virtual bool containsFloats() { return m_floatingObjects && !m_floatingObjects->isEmpty(); }
183 virtual bool containsFloat(RenderObject*);
184
185 virtual bool avoidsFloats() const;
186
187 virtual bool hasOverhangingFloats() { return !hasColumns() && floatBottom() > height(); }
188 void addIntrudingFloats(RenderBlock* prev, int xoffset, int yoffset);
189 int addOverhangingFloats(RenderBlock* child, int xoffset, int yoffset, bool makeChildPaintOtherFloats);
190
191 int nextFloatBottomBelow(int) const;
192 int floatBottom() const;
193 inline int leftBottom();
194 inline int rightBottom();
195 IntRect floatRect() const;
196
197 virtual int lineWidth(int) const;
198 virtual int lowestPosition(bool includeOverflowInterior = true, bool includeSelf = true) const;
199 virtual int rightmostPosition(bool includeOverflowInterior = true, bool includeSelf = true) const;
200 virtual int leftmostPosition(bool includeOverflowInterior = true, bool includeSelf = true) const;
201
202 int rightOffset() const;
203 int rightRelOffset(int y, int fixedOffset, bool applyTextIndent = true, int* heightRemaining = 0) const;
204 int rightOffset(int y) const { return rightRelOffset(y, rightOffset(), true); }
205
206 int leftOffset() const;
207 int leftRelOffset(int y, int fixedOffset, bool applyTextIndent = true, int* heightRemaining = 0) const;
208 int leftOffset(int y) const { return leftRelOffset(y, leftOffset(), true); }
209
210 virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
211 virtual bool hitTestColumns(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
212 virtual bool hitTestContents(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
213
214 virtual bool isPointInOverflowControl(HitTestResult&, int x, int y, int tx, int ty);
215
216 virtual VisiblePosition positionForCoordinates(int x, int y);
217
218 // Block flows subclass availableWidth to handle multi column layout (shrinking the width available to children when laying out.)
219 virtual int availableWidth() const;
220
221 virtual void calcPrefWidths();
222 void calcInlinePrefWidths();
223 void calcBlockPrefWidths();
224
225 virtual int getBaselineOfFirstLineBox() const;
226 virtual int getBaselineOfLastLineBox() const;
227
228 RootInlineBox* firstRootBox() const { return static_cast<RootInlineBox*>(firstLineBox()); }
229 RootInlineBox* lastRootBox() const { return static_cast<RootInlineBox*>(lastLineBox()); }
230
231 bool containsNonZeroBidiLevel() const;
232
233 // Obtains the nearest enclosing block (including this block) that contributes a first-line style to our inline
234 // children.
235 virtual RenderBlock* firstLineBlock() const;
236 virtual void updateFirstLetter();
237
238 bool inRootBlockContext() const;
239
240 void setHasMarkupTruncation(bool b = true) { m_hasMarkupTruncation = b; }
241 bool hasMarkupTruncation() const { return m_hasMarkupTruncation; }
242
243 virtual bool hasSelectedChildren() const { return m_selectionState != SelectionNone; }
244 virtual SelectionState selectionState() const { return static_cast<SelectionState>(m_selectionState); }
245 virtual void setSelectionState(SelectionState s);
246
247 virtual IntRect selectionRectForRepaint(RenderBox* repaintContainer, bool /*clipToVisibleContent*/)
248 {
249 return selectionGapRectsForRepaint(repaintContainer);
250 }
251 GapRects selectionGapRectsForRepaint(RenderBox* repaintContainer);
252 virtual bool shouldPaintSelectionGaps() const;
253 bool isSelectionRoot() const;
254 GapRects fillSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty,
255 int& lastTop, int& lastLeft, int& lastRight, const PaintInfo* = 0);
256 GapRects fillInlineSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty,
257 int& lastTop, int& lastLeft, int& lastRight, const PaintInfo*);
258 GapRects fillBlockSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty,
259 int& lastTop, int& lastLeft, int& lastRight, const PaintInfo*);
260 IntRect fillVerticalSelectionGap(int lastTop, int lastLeft, int lastRight, int bottomY, RenderBlock* rootBlock,
261 int blockX, int blockY, const PaintInfo*);
262 IntRect fillLeftSelectionGap(RenderObject* selObj, int xPos, int yPos, int height, RenderBlock* rootBlock,
263 int blockX, int blockY, int tx, int ty, const PaintInfo*);
264 IntRect fillRightSelectionGap(RenderObject* selObj, int xPos, int yPos, int height, RenderBlock* rootBlock,
265 int blockX, int blockY, int tx, int ty, const PaintInfo*);
266 IntRect fillHorizontalSelectionGap(RenderObject* selObj, int xPos, int yPos, int width, int height, const PaintInfo*);
267
268 void getHorizontalSelectionGapInfo(SelectionState, bool& leftGap, bool& rightGap);
269 int leftSelectionOffset(RenderBlock* rootBlock, int y);
270 int rightSelectionOffset(RenderBlock* rootBlock, int y);
271
272 // Helper methods for computing line counts and heights for line counts.
273 RootInlineBox* lineAtIndex(int);
274 int lineCount();
275 int heightForLineCount(int);
276 void clearTruncation();
277
278 int immediateLineCount();
279 void adjustComputedFontSizes(float size, float visibleWidth);
280 void resetComputedFontSize() {
281 m_widthForTextAutosizing = -1;
282 m_lineCountForTextAutosizing = NOT_SET;
283 }
284
285 int desiredColumnWidth() const;
286 unsigned desiredColumnCount() const;
287 Vector<IntRect>* columnRects() const;
288 void setDesiredColumnCountAndWidth(int count, int width);
289
290 void adjustRectForColumns(IntRect&) const;
291
292 void addContinuationWithOutline(RenderFlow*);
293 void paintContinuationOutlines(PaintInfo&, int tx, int ty);
294
295 private:
296 void adjustPointToColumnContents(IntPoint&) const;
297 void adjustForBorderFit(int x, int& left, int& right) const; // Helper function for borderFitAdjust
298
299 void markLinesDirtyInVerticalRange(int top, int bottom);
300
301 protected:
302 virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
303 virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
304
305 void newLine(EClear);
306 virtual bool hasLineIfEmpty() const;
307 bool layoutOnlyPositionedObjects();
308
309 private:
310 Position positionForBox(InlineBox*, bool start = true) const;
311 Position positionForRenderer(RenderObject*, bool start = true) const;
312
313 // Adjust tx and ty from painting offsets to the local coords of this renderer
314 void offsetForContents(int& tx, int& ty) const;
315
316 int columnGap() const;
317 void calcColumnWidth();
318 int layoutColumns(int endOfContent = -1);
319
320 bool expandsToEncloseOverhangingFloats() const;
321
322 protected:
323 struct FloatingObject {
324 enum Type {
325 FloatLeft,
326 FloatRight
327 };
328
329 FloatingObject(Type type)
330 : m_renderer(0)
331 , m_top(0)
332 , m_bottom(0)
333 , m_left(0)
334 , m_width(0)
335 , m_type(type)
336 , m_shouldPaint(true)
337 , m_isDescendant(false)
338 {
339 }
340
341 Type type() { return static_cast<Type>(m_type); }
342
343 RenderBox* m_renderer;
344 int m_top;
345 int m_bottom;
346 int m_left;
347 int m_width;
348 unsigned m_type : 1; // Type (left or right aligned)
349 bool m_shouldPaint : 1;
350 bool m_isDescendant : 1;
351 };
352
353 class MarginInfo {
354 // Collapsing flags for whether we can collapse our margins with our children's margins.
355 bool m_canCollapseWithChildren : 1;
356 bool m_canCollapseTopWithChildren : 1;
357 bool m_canCollapseBottomWithChildren : 1;
358
359 // Whether or not we are a quirky container, i.e., do we collapse away top and bottom
360 // margins in our container. Table cells and the body are the common examples. We
361 // also have a custom style property for Safari RSS to deal with TypePad blog articles.
362 bool m_quirkContainer : 1;
363
364 // This flag tracks whether we are still looking at child margins that can all collapse together at the beginning of a block.
365 // They may or may not collapse with the top margin of the block (|m_canCollapseTopWithChildren| tells us that), but they will
366 // always be collapsing with one another. This variable can remain set to true through multiple iterations
367 // as long as we keep encountering self-collapsing blocks.
368 bool m_atTopOfBlock : 1;
369
370 // This flag is set when we know we're examining bottom margins and we know we're at the bottom of the block.
371 bool m_atBottomOfBlock : 1;
372
373 // If our last normal flow child was a self-collapsing block that cleared a float,
374 // we track it in this variable.
375 bool m_selfCollapsingBlockClearedFloat : 1;
376
377 // These variables are used to detect quirky margins that we need to collapse away (in table cells
378 // and in the body element).
379 bool m_topQuirk : 1;
380 bool m_bottomQuirk : 1;
381 bool m_determinedTopQuirk : 1;
382
383 // These flags track the previous maximal positive and negative margins.
384 int m_posMargin;
385 int m_negMargin;
386
387 public:
388 MarginInfo(RenderBlock* b, int top, int bottom);
389
390 void setAtTopOfBlock(bool b) { m_atTopOfBlock = b; }
391 void setAtBottomOfBlock(bool b) { m_atBottomOfBlock = b; }
392 void clearMargin() { m_posMargin = m_negMargin = 0; }
393 void setSelfCollapsingBlockClearedFloat(bool b) { m_selfCollapsingBlockClearedFloat = b; }
394 void setTopQuirk(bool b) { m_topQuirk = b; }
395 void setBottomQuirk(bool b) { m_bottomQuirk = b; }
396 void setDeterminedTopQuirk(bool b) { m_determinedTopQuirk = b; }
397 void setPosMargin(int p) { m_posMargin = p; }
398 void setNegMargin(int n) { m_negMargin = n; }
399 void setPosMarginIfLarger(int p) { if (p > m_posMargin) m_posMargin = p; }
400 void setNegMarginIfLarger(int n) { if (n > m_negMargin) m_negMargin = n; }
401
402 void setMargin(int p, int n) { m_posMargin = p; m_negMargin = n; }
403
404 bool atTopOfBlock() const { return m_atTopOfBlock; }
405 bool canCollapseWithTop() const { return m_atTopOfBlock && m_canCollapseTopWithChildren; }
406 bool canCollapseWithBottom() const { return m_atBottomOfBlock && m_canCollapseBottomWithChildren; }
407 bool canCollapseTopWithChildren() const { return m_canCollapseTopWithChildren; }
408 bool canCollapseBottomWithChildren() const { return m_canCollapseBottomWithChildren; }
409 bool selfCollapsingBlockClearedFloat() const { return m_selfCollapsingBlockClearedFloat; }
410 bool quirkContainer() const { return m_quirkContainer; }
411 bool determinedTopQuirk() const { return m_determinedTopQuirk; }
412 bool topQuirk() const { return m_topQuirk; }
413 bool bottomQuirk() const { return m_bottomQuirk; }
414 int posMargin() const { return m_posMargin; }
415 int negMargin() const { return m_negMargin; }
416 int margin() const { return m_posMargin - m_negMargin; }
417 };
418
419 void adjustPositionedBlock(RenderBox* child, const MarginInfo&);
420 void adjustFloatingBlock(const MarginInfo&);
421 RenderBox* handleSpecialChild(RenderBox* child, const MarginInfo&, bool& handled);
422 RenderBox* handleFloatingChild(RenderBox* child, const MarginInfo&, bool& handled);
423 RenderBox* handlePositionedChild(RenderBox* child, const MarginInfo&, bool& handled);
424 RenderBox* handleRunInChild(RenderBox* child, bool& handled);
425 void collapseMargins(RenderBox* child, MarginInfo&, int yPosEstimate);
426 void clearFloatsIfNeeded(RenderBox* child, MarginInfo&, int oldTopPosMargin, int oldTopNegMargin);
427 int estimateVerticalPosition(RenderBox* child, const MarginInfo&);
428 void determineHorizontalPosition(RenderBox* child);
429 void handleBottomOfBlock(int top, int bottom, MarginInfo&);
430 void setCollapsedBottomMargin(const MarginInfo&);
431 // End helper functions and structs used by layoutBlockChildren.
432
433 private:
434 typedef ListHashSet<RenderBox*>::const_iterator Iterator;
435 DeprecatedPtrList<FloatingObject>* m_floatingObjects;
436 ListHashSet<RenderBox*>* m_positionedObjects;
437
438 // Allocated only when some of these fields have non-default values
439 struct MaxMargin {
440 MaxMargin(const RenderBlock* o)
441 : m_topPos(topPosDefault(o))
442 , m_topNeg(topNegDefault(o))
443 , m_bottomPos(bottomPosDefault(o))
444 , m_bottomNeg(bottomNegDefault(o))
445 {
446 }
447
448 static int topPosDefault(const RenderBlock* o) { return o->marginTop() > 0 ? o->marginTop() : 0; }
449 static int topNegDefault(const RenderBlock* o) { return o->marginTop() < 0 ? -o->marginTop() : 0; }
450 static int bottomPosDefault(const RenderBlock* o) { return o->marginBottom() > 0 ? o->marginBottom() : 0; }
451 static int bottomNegDefault(const RenderBlock* o) { return o->marginBottom() < 0 ? -o->marginBottom() : 0; }
452
453 int m_topPos;
454 int m_topNeg;
455 int m_bottomPos;
456 int m_bottomNeg;
457 };
458
459 MaxMargin* m_maxMargin;
460
461 protected:
462 // How much content overflows out of our block vertically or horizontally.
463 int m_overflowHeight;
464 int m_overflowWidth;
465 int m_overflowLeft;
466 int m_overflowTop;
467
468 int m_widthForTextAutosizing;
469 };
470
471 } // namespace WebCore
472
473 #endif // RenderBlock_h