Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(64)

Side by Side Diff: third_party/WebKit/WebCore/rendering/RenderInline.cpp

Issue 21184: WebKit merge 40722:40785 (part 1) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 11 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * This file is part of the render object implementation for KHTML. 2 * This file is part of the render object implementation for KHTML.
3 * 3 *
4 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 4 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
5 * (C) 1999 Antti Koivisto (koivisto@kde.org) 5 * (C) 1999 Antti Koivisto (koivisto@kde.org)
6 * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc. 6 * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
7 * 7 *
8 * This library is free software; you can redistribute it and/or 8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public 9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either 10 * License as published by the Free Software Foundation; either
(...skipping 21 matching lines...) Expand all
32 #include "RenderArena.h" 32 #include "RenderArena.h"
33 #include "RenderBlock.h" 33 #include "RenderBlock.h"
34 #include "RenderView.h" 34 #include "RenderView.h"
35 #include "VisiblePosition.h" 35 #include "VisiblePosition.h"
36 36
37 using namespace std; 37 using namespace std;
38 38
39 namespace WebCore { 39 namespace WebCore {
40 40
41 RenderInline::RenderInline(Node* node) 41 RenderInline::RenderInline(Node* node)
42 : RenderBox(node) 42 : RenderBoxModelObject(node)
43 , m_continuation(0) 43 , m_continuation(0)
44 , m_lineHeight(-1) 44 , m_lineHeight(-1)
45 { 45 {
46 setChildrenInline(true); 46 setChildrenInline(true);
47 } 47 }
48 48
49 RenderInline::~RenderInline() 49 RenderInline::~RenderInline()
50 { 50 {
51 } 51 }
52 52
53 void RenderInline::destroy() 53 void RenderInline::destroy()
54 { 54 {
55 // Detach our continuation first. 55 // Detach our continuation first.
56 if (m_continuation) 56 if (m_continuation)
57 m_continuation->destroy(); 57 m_continuation->destroy();
58 m_continuation = 0; 58 m_continuation = 0;
59 59
60 // Make sure to destroy anonymous children first while they are still connec ted to the rest of the tree, so that they will 60 // Make sure to destroy anonymous children first while they are still connec ted to the rest of the tree, so that they will
61 // properly dirty line boxes that they are removed from. Effects that do :b efore/:after only on hover could crash otherwise. 61 // properly dirty line boxes that they are removed from. Effects that do :b efore/:after only on hover could crash otherwise.
62 children()->destroyLeftoverChildren(); 62 children()->destroyLeftoverChildren();
63 63
64 if (!documentBeingDestroyed()) { 64 if (!documentBeingDestroyed()) {
65 if (firstLineBox()) { 65 if (firstLineBox()) {
66 // We can't wait for RenderBox::destroy to clear the selection, 66 // We can't wait for RenderBoxModelObject::destroy to clear the sele ction,
67 // because by then we will have nuked the line boxes. 67 // because by then we will have nuked the line boxes.
68 // FIXME: The SelectionController should be responsible for this whe n it 68 // FIXME: The SelectionController should be responsible for this whe n it
69 // is notified of DOM mutations. 69 // is notified of DOM mutations.
70 if (isSelectionBorder()) 70 if (isSelectionBorder())
71 view()->clearSelection(); 71 view()->clearSelection();
72 72
73 // If line boxes are contained inside a root, that means we're an in line. 73 // If line boxes are contained inside a root, that means we're an in line.
74 // In that case, we need to remove all the line boxes so that the pa rent 74 // In that case, we need to remove all the line boxes so that the pa rent
75 // lines aren't pointing to deleted children. If the first line box does 75 // lines aren't pointing to deleted children. If the first line box does
76 // not have a parent that means they are either already disconnected or 76 // not have a parent that means they are either already disconnected or
77 // root lines that can just be destroyed without disconnecting. 77 // root lines that can just be destroyed without disconnecting.
78 if (firstLineBox()->parent()) { 78 if (firstLineBox()->parent()) {
79 for (InlineRunBox* box = firstLineBox(); box; box = box->nextLin eBox()) 79 for (InlineRunBox* box = firstLineBox(); box; box = box->nextLin eBox())
80 box->remove(); 80 box->remove();
81 } 81 }
82 } else if (isInline() && parent()) 82 } else if (isInline() && parent())
83 parent()->dirtyLinesFromChangedChild(this); 83 parent()->dirtyLinesFromChangedChild(this);
84 } 84 }
85 85
86 m_lineBoxes.deleteLineBoxes(renderArena()); 86 m_lineBoxes.deleteLineBoxes(renderArena());
87 87
88 RenderBox::destroy(); 88 RenderBoxModelObject::destroy();
89 } 89 }
90 90
91 RenderInline* RenderInline::inlineContinuation() const 91 RenderInline* RenderInline::inlineContinuation() const
92 { 92 {
93 if (!m_continuation || m_continuation->isInline()) 93 if (!m_continuation || m_continuation->isInline())
94 return toRenderInline(m_continuation); 94 return toRenderInline(m_continuation);
95 return toRenderBlock(m_continuation)->inlineContinuation(); 95 return toRenderBlock(m_continuation)->inlineContinuation();
96 } 96 }
97 97
98 void RenderInline::updateBoxModelInfoFromStyle() 98 void RenderInline::updateBoxModelInfoFromStyle()
99 { 99 {
100 RenderBoxModelObject::updateBoxModelInfoFromStyle(); 100 RenderBoxModelObject::updateBoxModelInfoFromStyle();
101 101
102 setInline(true); // Needed for run-ins, since run-in is considered a block d isplay type. 102 setInline(true); // Needed for run-ins, since run-in is considered a block d isplay type.
103 103
104 // FIXME: Support transforms and reflections on inline flows someday. 104 // FIXME: Support transforms and reflections on inline flows someday.
105 setHasTransform(false); 105 setHasTransform(false);
106 setHasReflection(false); 106 setHasReflection(false);
107 } 107 }
108 108
109 void RenderInline::styleDidChange(StyleDifference diff, const RenderStyle* oldSt yle) 109 void RenderInline::styleDidChange(StyleDifference diff, const RenderStyle* oldSt yle)
110 { 110 {
111 RenderBox::styleDidChange(diff, oldStyle); 111 RenderBoxModelObject::styleDidChange(diff, oldStyle);
112 112
113 // Ensure that all of the split inlines pick up the new style. We 113 // Ensure that all of the split inlines pick up the new style. We
114 // only do this if we're an inline, since we don't want to propagate 114 // only do this if we're an inline, since we don't want to propagate
115 // a block's style to the other inlines. 115 // a block's style to the other inlines.
116 // e.g., <font>foo <h4>goo</h4> moo</font>. The <font> inlines before 116 // e.g., <font>foo <h4>goo</h4> moo</font>. The <font> inlines before
117 // and after the block share the same style, but the block doesn't 117 // and after the block share the same style, but the block doesn't
118 // need to pass its style on to anyone else. 118 // need to pass its style on to anyone else.
119 for (RenderInline* currCont = inlineContinuation(); currCont; currCont = cur rCont->inlineContinuation()) { 119 for (RenderInline* currCont = inlineContinuation(); currCont; currCont = cur rCont->inlineContinuation()) {
120 RenderBox* nextCont = currCont->continuation(); 120 RenderBoxModelObject* nextCont = currCont->continuation();
121 currCont->setContinuation(0); 121 currCont->setContinuation(0);
122 currCont->setStyle(style()); 122 currCont->setStyle(style());
123 currCont->setContinuation(nextCont); 123 currCont->setContinuation(nextCont);
124 } 124 }
125 125
126 m_lineHeight = -1; 126 m_lineHeight = -1;
127 127
128 // Update pseudos for :before and :after now. 128 // Update pseudos for :before and :after now.
129 if (!isAnonymous() && document()->usesBeforeAfterRules()) { 129 if (!isAnonymous() && document()->usesBeforeAfterRules()) {
130 children()->updateBeforeAfterContent(this, BEFORE); 130 children()->updateBeforeAfterContent(this, BEFORE);
(...skipping 13 matching lines...) Expand all
144 return true; 144 return true;
145 } 145 }
146 146
147 void RenderInline::addChild(RenderObject* newChild, RenderObject* beforeChild) 147 void RenderInline::addChild(RenderObject* newChild, RenderObject* beforeChild)
148 { 148 {
149 if (continuation()) 149 if (continuation())
150 return addChildToContinuation(newChild, beforeChild); 150 return addChildToContinuation(newChild, beforeChild);
151 return addChildIgnoringContinuation(newChild, beforeChild); 151 return addChildIgnoringContinuation(newChild, beforeChild);
152 } 152 }
153 153
154 static RenderBox* nextContinuation(RenderObject* renderer) 154 static RenderBoxModelObject* nextContinuation(RenderObject* renderer)
155 { 155 {
156 if (renderer->isInline() && !renderer->isReplaced()) 156 if (renderer->isInline() && !renderer->isReplaced())
157 return toRenderInline(renderer)->continuation(); 157 return toRenderInline(renderer)->continuation();
158 return toRenderBlock(renderer)->inlineContinuation(); 158 return toRenderBlock(renderer)->inlineContinuation();
159 } 159 }
160 160
161 RenderBox* RenderInline::continuationBefore(RenderObject* beforeChild) 161 RenderBoxModelObject* RenderInline::continuationBefore(RenderObject* beforeChild )
162 { 162 {
163 if (beforeChild && beforeChild->parent() == this) 163 if (beforeChild && beforeChild->parent() == this)
164 return this; 164 return this;
165 165
166 RenderBox* curr = nextContinuation(this); 166 RenderBoxModelObject* curr = nextContinuation(this);
167 RenderBox* nextToLast = this; 167 RenderBoxModelObject* nextToLast = this;
168 RenderBox* last = this; 168 RenderBoxModelObject* last = this;
169 while (curr) { 169 while (curr) {
170 if (beforeChild && beforeChild->parent() == curr) { 170 if (beforeChild && beforeChild->parent() == curr) {
171 if (curr->firstChild() == beforeChild) 171 if (curr->firstChild() == beforeChild)
172 return last; 172 return last;
173 return curr; 173 return curr;
174 } 174 }
175 175
176 nextToLast = last; 176 nextToLast = last;
177 last = curr; 177 last = curr;
178 curr = nextContinuation(curr); 178 curr = nextContinuation(curr);
(...skipping 14 matching lines...) Expand all
193 // We are placing a block inside an inline. We have to perform a split o f this 193 // We are placing a block inside an inline. We have to perform a split o f this
194 // inline into continuations. This involves creating an anonymous block box to hold 194 // inline into continuations. This involves creating an anonymous block box to hold
195 // |newChild|. We then make that block box a continuation of this inlin e. We take all of 195 // |newChild|. We then make that block box a continuation of this inlin e. We take all of
196 // the children after |beforeChild| and put them in a clone of this obje ct. 196 // the children after |beforeChild| and put them in a clone of this obje ct.
197 RefPtr<RenderStyle> newStyle = RenderStyle::create(); 197 RefPtr<RenderStyle> newStyle = RenderStyle::create();
198 newStyle->inheritFrom(style()); 198 newStyle->inheritFrom(style());
199 newStyle->setDisplay(BLOCK); 199 newStyle->setDisplay(BLOCK);
200 200
201 RenderBlock* newBox = new (renderArena()) RenderBlock(document() /* anon ymous box */); 201 RenderBlock* newBox = new (renderArena()) RenderBlock(document() /* anon ymous box */);
202 newBox->setStyle(newStyle.release()); 202 newBox->setStyle(newStyle.release());
203 RenderBox* oldContinuation = continuation(); 203 RenderBoxModelObject* oldContinuation = continuation();
204 setContinuation(newBox); 204 setContinuation(newBox);
205 205
206 // Someone may have put a <p> inside a <q>, causing a split. When this happens, the :after content 206 // Someone may have put a <p> inside a <q>, causing a split. When this happens, the :after content
207 // has to move into the inline continuation. Call updateBeforeAfterCont ent to ensure that our :after 207 // has to move into the inline continuation. Call updateBeforeAfterCont ent to ensure that our :after
208 // content gets properly destroyed. 208 // content gets properly destroyed.
209 bool isLastChild = (beforeChild == lastChild()); 209 bool isLastChild = (beforeChild == lastChild());
210 if (document()->usesBeforeAfterRules()) 210 if (document()->usesBeforeAfterRules())
211 children()->updateBeforeAfterContent(this, AFTER); 211 children()->updateBeforeAfterContent(this, AFTER);
212 if (isLastChild && beforeChild != lastChild()) 212 if (isLastChild && beforeChild != lastChild())
213 beforeChild = 0; // We destroyed the last child, so now we need to u pdate our insertion 213 beforeChild = 0; // We destroyed the last child, so now we need to u pdate our insertion
214 // point to be 0. It's just a straight append now. 214 // point to be 0. It's just a straight append now.
215 215
216 splitFlow(beforeChild, newBox, newChild, oldContinuation); 216 splitFlow(beforeChild, newBox, newChild, oldContinuation);
217 return; 217 return;
218 } 218 }
219 219
220 RenderBox::addChild(newChild, beforeChild); 220 RenderBoxModelObject::addChild(newChild, beforeChild);
221 221
222 newChild->setNeedsLayoutAndPrefWidthsRecalc(); 222 newChild->setNeedsLayoutAndPrefWidthsRecalc();
223 } 223 }
224 224
225 RenderInline* RenderInline::cloneInline(RenderInline* src) 225 RenderInline* RenderInline::cloneInline(RenderInline* src)
226 { 226 {
227 RenderInline* o = new (src->renderArena()) RenderInline(src->element()); 227 RenderInline* o = new (src->renderArena()) RenderInline(src->element());
228 o->setStyle(src->style()); 228 o->setStyle(src->style());
229 return o; 229 return o;
230 } 230 }
231 231
232 void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock, 232 void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
233 RenderBlock* middleBlock, 233 RenderBlock* middleBlock,
234 RenderObject* beforeChild, RenderBox* oldCont) 234 RenderObject* beforeChild, RenderBoxModelObject* oldCont)
235 { 235 {
236 // Create a clone of this inline. 236 // Create a clone of this inline.
237 RenderInline* clone = cloneInline(this); 237 RenderInline* clone = cloneInline(this);
238 clone->setContinuation(oldCont); 238 clone->setContinuation(oldCont);
239 239
240 // Now take all of the children from beforeChild to the end and remove 240 // Now take all of the children from beforeChild to the end and remove
241 // them from |this| and place them in the clone. 241 // them from |this| and place them in the clone.
242 RenderObject* o = beforeChild; 242 RenderObject* o = beforeChild;
243 while (o) { 243 while (o) {
244 RenderObject* tmp = o; 244 RenderObject* tmp = o;
245 o = tmp->nextSibling(); 245 o = tmp->nextSibling();
246 clone->addChildIgnoringContinuation(children()->removeChildNode(this, tm p), 0); 246 clone->addChildIgnoringContinuation(children()->removeChildNode(this, tm p), 0);
247 tmp->setNeedsLayoutAndPrefWidthsRecalc(); 247 tmp->setNeedsLayoutAndPrefWidthsRecalc();
248 } 248 }
249 249
250 // Hook |clone| up as the continuation of the middle block. 250 // Hook |clone| up as the continuation of the middle block.
251 middleBlock->setInlineContinuation(clone); 251 middleBlock->setInlineContinuation(clone);
252 252
253 // We have been reparented and are now under the fromBlock. We need 253 // We have been reparented and are now under the fromBlock. We need
254 // to walk up our inline parent chain until we hit the containing block. 254 // to walk up our inline parent chain until we hit the containing block.
255 // Once we hit the containing block we're done. 255 // Once we hit the containing block we're done.
256 RenderBox* curr = static_cast<RenderBox*>(parent()); 256 RenderBoxModelObject* curr = static_cast<RenderBoxModelObject*>(parent());
257 RenderBox* currChild = this; 257 RenderBoxModelObject* currChild = this;
258 258
259 // FIXME: Because splitting is O(n^2) as tags nest pathologically, we cap th e depth at which we're willing to clone. 259 // FIXME: Because splitting is O(n^2) as tags nest pathologically, we cap th e depth at which we're willing to clone.
260 // There will eventually be a better approach to this problem that will let us nest to a much 260 // There will eventually be a better approach to this problem that will let us nest to a much
261 // greater depth (see bugzilla bug 13430) but for now we have a limit. This *will* result in 261 // greater depth (see bugzilla bug 13430) but for now we have a limit. This *will* result in
262 // incorrect rendering, but the alternative is to hang forever. 262 // incorrect rendering, but the alternative is to hang forever.
263 unsigned splitDepth = 1; 263 unsigned splitDepth = 1;
264 const unsigned cMaxSplitDepth = 200; 264 const unsigned cMaxSplitDepth = 200;
265 while (curr && curr != fromBlock) { 265 while (curr && curr != fromBlock) {
266 ASSERT(curr->isRenderInline()); 266 ASSERT(curr->isRenderInline());
267 if (splitDepth < cMaxSplitDepth) { 267 if (splitDepth < cMaxSplitDepth) {
(...skipping 22 matching lines...) Expand all
290 while (o) { 290 while (o) {
291 RenderObject* tmp = o; 291 RenderObject* tmp = o;
292 o = tmp->nextSibling(); 292 o = tmp->nextSibling();
293 clone->addChildIgnoringContinuation(inlineCurr->children()->remo veChildNode(curr, tmp), 0); 293 clone->addChildIgnoringContinuation(inlineCurr->children()->remo veChildNode(curr, tmp), 0);
294 tmp->setNeedsLayoutAndPrefWidthsRecalc(); 294 tmp->setNeedsLayoutAndPrefWidthsRecalc();
295 } 295 }
296 } 296 }
297 297
298 // Keep walking up the chain. 298 // Keep walking up the chain.
299 currChild = curr; 299 currChild = curr;
300 curr = static_cast<RenderBox*>(curr->parent()); 300 curr = static_cast<RenderBoxModelObject*>(curr->parent());
301 splitDepth++; 301 splitDepth++;
302 } 302 }
303 303
304 // Now we are at the block level. We need to put the clone into the toBlock. 304 // Now we are at the block level. We need to put the clone into the toBlock.
305 toBlock->children()->appendChildNode(toBlock, clone); 305 toBlock->children()->appendChildNode(toBlock, clone);
306 306
307 // Now take all the children after currChild and remove them from the fromBl ock 307 // Now take all the children after currChild and remove them from the fromBl ock
308 // and put them in the toBlock. 308 // and put them in the toBlock.
309 o = currChild->nextSibling(); 309 o = currChild->nextSibling();
310 while (o) { 310 while (o) {
311 RenderObject* tmp = o; 311 RenderObject* tmp = o;
312 o = tmp->nextSibling(); 312 o = tmp->nextSibling();
313 toBlock->children()->appendChildNode(toBlock, fromBlock->children()->rem oveChildNode(fromBlock, tmp)); 313 toBlock->children()->appendChildNode(toBlock, fromBlock->children()->rem oveChildNode(fromBlock, tmp));
314 } 314 }
315 } 315 }
316 316
317 void RenderInline::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox , 317 void RenderInline::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox ,
318 RenderObject* newChild, RenderBox* oldCont) 318 RenderObject* newChild, RenderBoxModelObject* oldCo nt)
319 { 319 {
320 RenderBlock* pre = 0; 320 RenderBlock* pre = 0;
321 RenderBlock* block = containingBlock(); 321 RenderBlock* block = containingBlock();
322 322
323 // Delete our line boxes before we do the inline split into continuations. 323 // Delete our line boxes before we do the inline split into continuations.
324 block->deleteLineBoxTree(); 324 block->deleteLineBoxTree();
325 325
326 bool madeNewBeforeBlock = false; 326 bool madeNewBeforeBlock = false;
327 if (block->isAnonymousBlock() && (!block->parent() || !block->parent()->crea tesAnonymousWrapper())) { 327 if (block->isAnonymousBlock() && (!block->parent() || !block->parent()->crea tesAnonymousWrapper())) {
328 // We can reuse this block and make it the preBlock of the next continua tion. 328 // We can reuse this block and make it the preBlock of the next continua tion.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 // Always just do a full layout in order to ensure that line boxes (especial ly wrappers for images) 367 // Always just do a full layout in order to ensure that line boxes (especial ly wrappers for images)
368 // get deleted properly. Because objects moves from the pre block into the post block, we want to 368 // get deleted properly. Because objects moves from the pre block into the post block, we want to
369 // make new line boxes instead of leaving the old line boxes around. 369 // make new line boxes instead of leaving the old line boxes around.
370 pre->setNeedsLayoutAndPrefWidthsRecalc(); 370 pre->setNeedsLayoutAndPrefWidthsRecalc();
371 block->setNeedsLayoutAndPrefWidthsRecalc(); 371 block->setNeedsLayoutAndPrefWidthsRecalc();
372 post->setNeedsLayoutAndPrefWidthsRecalc(); 372 post->setNeedsLayoutAndPrefWidthsRecalc();
373 } 373 }
374 374
375 void RenderInline::addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild) 375 void RenderInline::addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild)
376 { 376 {
377 RenderBox* flow = continuationBefore(beforeChild); 377 RenderBoxModelObject* flow = continuationBefore(beforeChild);
378 ASSERT(!beforeChild || beforeChild->parent()->isRenderBlock() || beforeChild ->parent()->isRenderInline()); 378 ASSERT(!beforeChild || beforeChild->parent()->isRenderBlock() || beforeChild ->parent()->isRenderInline());
379 RenderBox* beforeChildParent = 0; 379 RenderBoxModelObject* beforeChildParent = 0;
380 if (beforeChild) 380 if (beforeChild)
381 beforeChildParent = static_cast<RenderBox*>(beforeChild->parent()); 381 beforeChildParent = static_cast<RenderBoxModelObject*>(beforeChild->pare nt());
382 else { 382 else {
383 RenderBox* cont = nextContinuation(flow); 383 RenderBoxModelObject* cont = nextContinuation(flow);
384 if (cont) 384 if (cont)
385 beforeChildParent = cont; 385 beforeChildParent = cont;
386 else 386 else
387 beforeChildParent = flow; 387 beforeChildParent = flow;
388 } 388 }
389 389
390 if (newChild->isFloatingOrPositioned()) 390 if (newChild->isFloatingOrPositioned())
391 return beforeChildParent->addChildIgnoringContinuation(newChild, beforeC hild); 391 return beforeChildParent->addChildIgnoringContinuation(newChild, beforeC hild);
392 392
393 // A continuation always consists of two potential candidates: an inline or an anonymous 393 // A continuation always consists of two potential candidates: an inline or an anonymous
(...skipping 23 matching lines...) Expand all
417 417
418 void RenderInline::absoluteRects(Vector<IntRect>& rects, int tx, int ty, bool to pLevel) 418 void RenderInline::absoluteRects(Vector<IntRect>& rects, int tx, int ty, bool to pLevel)
419 { 419 {
420 for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) 420 for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox())
421 rects.append(IntRect(tx + curr->xPos(), ty + curr->yPos(), curr->width() , curr->height())); 421 rects.append(IntRect(tx + curr->xPos(), ty + curr->yPos(), curr->width() , curr->height()));
422 422
423 for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) { 423 for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
424 if (curr->isBox()) { 424 if (curr->isBox()) {
425 RenderBox* box = toRenderBox(curr); 425 RenderBox* box = toRenderBox(curr);
426 curr->absoluteRects(rects, tx + box->x(), ty + box->y(), false); 426 curr->absoluteRects(rects, tx + box->x(), ty + box->y(), false);
427 } 427 } else
428 curr->absoluteRects(rects, tx, ty, false);
428 } 429 }
429 430
430 if (continuation() && topLevel) 431 if (continuation() && topLevel) {
431 continuation()->absoluteRects(rects, 432 if (continuation()->isBox()) {
432 tx - containingBlock()->x() + continuation ()->x(), 433 RenderBox* box = toRenderBox(continuation());
433 ty - containingBlock()->y() + continuation ()->y(), 434 continuation()->absoluteRects(rects,
434 topLevel); 435 tx - containingBlock()->x() + box->x() ,
436 ty - containingBlock()->y() + box->y() ,
437 topLevel);
438 } else
439 continuation()->absoluteRects(rects, tx - containingBlock()->x(), ty - containingBlock()->y(), topLevel);
440 }
435 } 441 }
436 442
437 void RenderInline::absoluteQuads(Vector<FloatQuad>& quads, bool topLevel) 443 void RenderInline::absoluteQuads(Vector<FloatQuad>& quads, bool topLevel)
438 { 444 {
439 for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) { 445 for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
440 FloatRect localRect(curr->xPos(), curr->yPos(), curr->width(), curr->hei ght()); 446 FloatRect localRect(curr->xPos(), curr->yPos(), curr->width(), curr->hei ght());
441 quads.append(localToAbsoluteQuad(localRect)); 447 quads.append(localToAbsoluteQuad(localRect));
442 } 448 }
443 449
444 for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) { 450 for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
445 if (!curr->isText()) 451 if (!curr->isText())
446 curr->absoluteQuads(quads, false); 452 curr->absoluteQuads(quads, false);
447 } 453 }
448 454
449 if (continuation() && topLevel) 455 if (continuation() && topLevel)
450 continuation()->absoluteQuads(quads, topLevel); 456 continuation()->absoluteQuads(quads, topLevel);
451 } 457 }
452 458
453 int RenderInline::offsetLeft() const 459 int RenderInline::offsetLeft() const
454 { 460 {
455 int x = RenderBox::offsetLeft(); 461 int x = RenderBoxModelObject::offsetLeft();
456 if (firstLineBox()) 462 if (firstLineBox())
457 x += firstLineBox()->xPos(); 463 x += firstLineBox()->xPos();
458 return x; 464 return x;
459 } 465 }
460 466
461 int RenderInline::offsetTop() const 467 int RenderInline::offsetTop() const
462 { 468 {
463 int y = RenderBox::offsetTop(); 469 int y = RenderBoxModelObject::offsetTop();
464 if (firstLineBox()) 470 if (firstLineBox())
465 y += firstLineBox()->yPos(); 471 y += firstLineBox()->yPos();
466 return y; 472 return y;
467 } 473 }
468 474
475 int RenderInline::marginLeft() const
476 {
477 Length margin = style()->marginLeft();
478 if (margin.isAuto())
479 return 0;
480 if (margin.isFixed())
481 return margin.value();
482 if (margin.isPercent())
483 return margin.calcMinValue(max(0, containingBlockWidth()));
484 return 0;
485 }
486
487 int RenderInline::marginRight() const
488 {
489 Length margin = style()->marginRight();
490 if (margin.isAuto())
491 return 0;
492 if (margin.isFixed())
493 return margin.value();
494 if (margin.isPercent())
495 return margin.calcMinValue(max(0, containingBlockWidth()));
496 return 0;
497 }
498
469 const char* RenderInline::renderName() const 499 const char* RenderInline::renderName() const
470 { 500 {
471 if (isRelPositioned()) 501 if (isRelPositioned())
472 return "RenderInline (relative positioned)"; 502 return "RenderInline (relative positioned)";
473 if (isAnonymous()) 503 if (isAnonymous())
474 return "RenderInline (generated)"; 504 return "RenderInline (generated)";
475 if (isRunIn()) 505 if (isRunIn())
476 return "RenderInline (run-in)"; 506 return "RenderInline (run-in)";
477 return "RenderInline"; 507 return "RenderInline";
478 } 508 }
479 509
480 bool RenderInline::nodeAtPoint(const HitTestRequest& request, HitTestResult& res ult, 510 bool RenderInline::nodeAtPoint(const HitTestRequest& request, HitTestResult& res ult,
481 int x, int y, int tx, int ty, HitTestAction hitT estAction) 511 int x, int y, int tx, int ty, HitTestAction hitT estAction)
482 { 512 {
483 return m_lineBoxes.hitTest(this, request, result, x, y, tx, ty, hitTestActio n); 513 return m_lineBoxes.hitTest(this, request, result, x, y, tx, ty, hitTestActio n);
484 } 514 }
485 515
486 VisiblePosition RenderInline::positionForCoordinates(int x, int y) 516 VisiblePosition RenderInline::positionForCoordinates(int x, int y)
487 { 517 {
518 // FIXME: Does not deal with relative positioned inlines (should it?)
519 RenderBlock* cb = containingBlock();
520 if (firstLineBox()) {
521 // This inline actually has a line box. We must have clicked in the bor der/padding of one of these boxes. We
522 // should try to find a result by asking our containing block.
523 return cb->positionForCoordinates(x, y);
524 }
525
488 // Translate the coords from the pre-anonymous block to the post-anonymous b lock. 526 // Translate the coords from the pre-anonymous block to the post-anonymous b lock.
489 RenderBlock* cb = containingBlock();
490 int parentBlockX = cb->x() + x; 527 int parentBlockX = cb->x() + x;
491 int parentBlockY = cb->y() + y; 528 int parentBlockY = cb->y() + y;
492 RenderBox* c = continuation(); 529 RenderBoxModelObject* c = continuation();
493 while (c) { 530 while (c) {
494 RenderBox* contBlock = c; 531 RenderBox* contBlock = c->isInline() ? c->containingBlock() : toRenderBl ock(c);
495 if (c->isInline() || c->firstChild()) 532 if (c->isInline() || c->firstChild())
496 return c->positionForCoordinates(parentBlockX - contBlock->x(), pare ntBlockY - contBlock->y()); 533 return c->positionForCoordinates(parentBlockX - contBlock->x(), pare ntBlockY - contBlock->y());
497 c = toRenderBlock(c)->inlineContinuation(); 534 c = toRenderBlock(c)->inlineContinuation();
498 } 535 }
499 536
500 return RenderBox::positionForCoordinates(x, y); 537 return RenderBoxModelObject::positionForCoordinates(x, y);
501 } 538 }
502 539
503 IntRect RenderInline::linesBoundingBox() const 540 IntRect RenderInline::linesBoundingBox() const
504 { 541 {
505 IntRect result; 542 IntRect result;
506 543
507 // See <rdar://problem/5289721>, for an unknown reason the linked list here is sometimes inconsistent, first is non-zero and last is zero. We have been 544 // See <rdar://problem/5289721>, for an unknown reason the linked list here is sometimes inconsistent, first is non-zero and last is zero. We have been
508 // unable to reproduce this at all (and consequently unable to figure ot why this is happening). The assert will hopefully catch the problem in debug 545 // unable to reproduce this at all (and consequently unable to figure ot why this is happening). The assert will hopefully catch the problem in debug
509 // builds and help us someday figure out why. We also put in a redundant ch eck of lastLineBox() to avoid the crash for now. 546 // builds and help us someday figure out why. We also put in a redundant ch eck of lastLineBox() to avoid the crash for now.
510 ASSERT(!firstLineBox() == !lastLineBox()); // Either both are null or both exist. 547 ASSERT(!firstLineBox() == !lastLineBox()); // Either both are null or both exist.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 579
543 // Now invalidate a rectangle. 580 // Now invalidate a rectangle.
544 int ow = style() ? style()->outlineSize() : 0; 581 int ow = style() ? style()->outlineSize() : 0;
545 582
546 // We need to add in the relative position offsets of any inlines (including us) up to our 583 // We need to add in the relative position offsets of any inlines (including us) up to our
547 // containing block. 584 // containing block.
548 RenderBlock* cb = containingBlock(); 585 RenderBlock* cb = containingBlock();
549 for (RenderObject* inlineFlow = this; inlineFlow && inlineFlow->isRenderInli ne() && inlineFlow != cb; 586 for (RenderObject* inlineFlow = this; inlineFlow && inlineFlow->isRenderInli ne() && inlineFlow != cb;
550 inlineFlow = inlineFlow->parent()) { 587 inlineFlow = inlineFlow->parent()) {
551 if (inlineFlow->style()->position() == RelativePosition && inlineFlow-> hasLayer()) 588 if (inlineFlow->style()->position() == RelativePosition && inlineFlow-> hasLayer())
552 toRenderBox(inlineFlow)->layer()->relativePositionOffset(left, top); 589 toRenderInline(inlineFlow)->layer()->relativePositionOffset(left, to p);
553 } 590 }
554 591
555 IntRect r(-ow + left, -ow + top, boundingBox.width() + ow * 2, boundingBox.h eight() + ow * 2); 592 IntRect r(-ow + left, -ow + top, boundingBox.width() + ow * 2, boundingBox.h eight() + ow * 2);
556 if (cb->hasColumns()) 593 if (cb->hasColumns())
557 cb->adjustRectForColumns(r); 594 cb->adjustRectForColumns(r);
558 595
559 if (cb->hasOverflowClip()) { 596 if (cb->hasOverflowClip()) {
560 // cb->height() is inaccurate if we're in the middle of a layout of |cb| , so use the 597 // cb->height() is inaccurate if we're in the middle of a layout of |cb| , so use the
561 // layer's size instead. Even if the layer's size is wrong, the layer i tself will repaint 598 // layer's size instead. Even if the layer's size is wrong, the layer i tself will repaint
562 // anyway if its size does change. 599 // anyway if its size does change.
(...skipping 22 matching lines...) Expand all
585 IntRect contRect = continuation()->rectWithOutlineForRepaint(repaint Container, ow); 622 IntRect contRect = continuation()->rectWithOutlineForRepaint(repaint Container, ow);
586 r.unite(contRect); 623 r.unite(contRect);
587 } 624 }
588 } 625 }
589 626
590 return r; 627 return r;
591 } 628 }
592 629
593 IntRect RenderInline::rectWithOutlineForRepaint(RenderBoxModelObject* repaintCon tainer, int outlineWidth) 630 IntRect RenderInline::rectWithOutlineForRepaint(RenderBoxModelObject* repaintCon tainer, int outlineWidth)
594 { 631 {
595 IntRect r(RenderBox::rectWithOutlineForRepaint(repaintContainer, outlineWidt h)); 632 IntRect r(RenderBoxModelObject::rectWithOutlineForRepaint(repaintContainer, outlineWidth));
596 for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) { 633 for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
597 if (!curr->isText()) 634 if (!curr->isText())
598 r.unite(curr->rectWithOutlineForRepaint(repaintContainer, outlineWid th)); 635 r.unite(curr->rectWithOutlineForRepaint(repaintContainer, outlineWid th));
599 } 636 }
600 return r; 637 return r;
601 } 638 }
602 639
640 void RenderInline::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& rect, bool fixed)
641 {
642 if (RenderView* v = view()) {
643 // LayoutState is only valid for root-relative repainting
644 if (v->layoutStateEnabled() && !repaintContainer) {
645 LayoutState* layoutState = v->layoutState();
646 if (style()->position() == RelativePosition && layer())
647 rect.move(layer()->relativePositionOffset());
648 rect.move(layoutState->m_offset);
649 if (layoutState->m_clipped)
650 rect.intersect(layoutState->m_clipRect);
651 return;
652 }
653 }
654
655 if (repaintContainer == this)
656 return;
657
658 RenderObject* o = container();
659 if (!o)
660 return;
661
662 IntPoint topLeft = rect.location();
663
664 if (o->isBlockFlow() && style()->position() != AbsolutePosition && style()-> position() != FixedPosition) {
665 RenderBlock* cb = toRenderBlock(o);
666 if (cb->hasColumns()) {
667 IntRect repaintRect(topLeft, rect.size());
668 cb->adjustRectForColumns(repaintRect);
669 topLeft = repaintRect.location();
670 rect = repaintRect;
671 }
672 }
673
674 if (style()->position() == RelativePosition && layer()) {
675 // Apply the relative position offset when invalidating a rectangle. Th e layer
676 // is translated, but the render box isn't, so we need to do this to get the
677 // right dirty rect. Since this is called from RenderObject::setStyle, the relative position
678 // flag on the RenderObject has been cleared, so use the one on the styl e().
679 topLeft += layer()->relativePositionOffset();
680 }
681
682 // FIXME: We ignore the lightweight clipping rect that controls use, since i f |o| is in mid-layout,
683 // its controlClipRect will be wrong. For overflow clip we use the values ca ched by the layer.
684 if (o->hasOverflowClip()) {
685 RenderBox* containerBox = toRenderBox(o);
686
687 // o->height() is inaccurate if we're in the middle of a layout of |o|, so use the
688 // layer's size instead. Even if the layer's size is wrong, the layer i tself will repaint
689 // anyway if its size does change.
690 topLeft -= containerBox->layer()->scrolledContentOffset(); // For overfl ow:auto/scroll/hidden.
691
692 IntRect repaintRect(topLeft, rect.size());
693 IntRect boxRect(0, 0, containerBox->layer()->width(), containerBox->laye r()->height());
694 rect = intersection(repaintRect, boxRect);
695 if (rect.isEmpty())
696 return;
697 } else
698 rect.setLocation(topLeft);
699
700 o->computeRectForRepaint(repaintContainer, rect, fixed);
701 }
702
603 void RenderInline::updateDragState(bool dragOn) 703 void RenderInline::updateDragState(bool dragOn)
604 { 704 {
605 RenderBox::updateDragState(dragOn); 705 RenderBoxModelObject::updateDragState(dragOn);
606 if (continuation()) 706 if (continuation())
607 continuation()->updateDragState(dragOn); 707 continuation()->updateDragState(dragOn);
608 } 708 }
609 709
610 void RenderInline::childBecameNonInline(RenderObject* child) 710 void RenderInline::childBecameNonInline(RenderObject* child)
611 { 711 {
612 // We have to split the parent flow. 712 // We have to split the parent flow.
613 RenderBlock* newBox = createAnonymousBlock(); 713 RenderBlock* newBox = createAnonymousBlock();
614 RenderBox* oldContinuation = continuation(); 714 RenderBoxModelObject* oldContinuation = continuation();
615 setContinuation(newBox); 715 setContinuation(newBox);
616 RenderObject* beforeChild = child->nextSibling(); 716 RenderObject* beforeChild = child->nextSibling();
617 children()->removeChildNode(this, child); 717 children()->removeChildNode(this, child);
618 splitFlow(beforeChild, newBox, child, oldContinuation); 718 splitFlow(beforeChild, newBox, child, oldContinuation);
619 } 719 }
620 720
621 void RenderInline::updateHitTestResult(HitTestResult& result, const IntPoint& po int) 721 void RenderInline::updateHitTestResult(HitTestResult& result, const IntPoint& po int)
622 { 722 {
623 if (result.innerNode()) 723 if (result.innerNode())
624 return; 724 return;
625 725
626 Node* node = element(); 726 Node* node = element();
627 IntPoint localPoint(point); 727 IntPoint localPoint(point);
628 if (node) { 728 if (node) {
629 if (isInlineContinuation()) { 729 if (isInlineContinuation()) {
630 // We're in the continuation of a split inline. Adjust our local po int to be in the coordinate space 730 // We're in the continuation of a split inline. Adjust our local po int to be in the coordinate space
631 // of the principal renderer's containing block. This will end up b eing the innerNonSharedNode. 731 // of the principal renderer's containing block. This will end up b eing the innerNonSharedNode.
632 RenderBlock* firstBlock = node->renderer()->containingBlock(); 732 RenderBlock* firstBlock = node->renderer()->containingBlock();
633 733
634 // Get our containing block. 734 // Get our containing block.
635 RenderBox* block = this; 735 RenderBox* block = containingBlock();
636 if (isInline())
637 block = containingBlock();
638
639 localPoint.move(block->x() - firstBlock->x(), block->y() - firstBloc k->y()); 736 localPoint.move(block->x() - firstBlock->x(), block->y() - firstBloc k->y());
640 } 737 }
641 738
642 result.setInnerNode(node); 739 result.setInnerNode(node);
643 if (!result.innerNonSharedNode()) 740 if (!result.innerNonSharedNode())
644 result.setInnerNonSharedNode(node); 741 result.setInnerNonSharedNode(node);
645 result.setLocalPoint(localPoint); 742 result.setLocalPoint(localPoint);
646 } 743 }
647 } 744 }
648 745
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
705 else if (!child->style()->isOriginalDisplayInlineType()) 802 else if (!child->style()->isOriginalDisplayInlineType())
706 // Avoid adding in the left border/padding of the containing block twice . Subtract it out. 803 // Avoid adding in the left border/padding of the containing block twice . Subtract it out.
707 offset.setWidth(sx - (child->containingBlock()->borderLeft() + child->co ntainingBlock()->paddingLeft())); 804 offset.setWidth(sx - (child->containingBlock()->borderLeft() + child->co ntainingBlock()->paddingLeft()));
708 805
709 if (!child->style()->hasStaticY()) 806 if (!child->style()->hasStaticY())
710 offset.setHeight(sy); 807 offset.setHeight(sy);
711 808
712 return offset; 809 return offset;
713 } 810 }
714 811
812 void RenderInline::imageChanged(WrappedImagePtr, const IntRect*)
813 {
814 if (!parent())
815 return;
816
817 // FIXME: We can do better.
818 repaint();
819 }
820
715 void RenderInline::addFocusRingRects(GraphicsContext* graphicsContext, int tx, i nt ty) 821 void RenderInline::addFocusRingRects(GraphicsContext* graphicsContext, int tx, i nt ty)
716 { 822 {
717 for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) 823 for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox())
718 graphicsContext->addFocusRingRect(IntRect(tx + curr->xPos(), ty + curr-> yPos(), curr->width(), curr->height())); 824 graphicsContext->addFocusRingRect(IntRect(tx + curr->xPos(), ty + curr-> yPos(), curr->width(), curr->height()));
719 825
720 for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) { 826 for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
721 if (!curr->isText() && !curr->isListMarker() && curr->isBox()) { 827 if (!curr->isText() && !curr->isListMarker()) {
722 RenderBox* box = toRenderBox(curr); 828 FloatPoint pos(tx, ty);
723 FloatPoint pos;
724 // FIXME: This doesn't work correctly with transforms. 829 // FIXME: This doesn't work correctly with transforms.
725 if (box->layer()) 830 if (curr->hasLayer())
726 pos = curr->localToAbsolute(); 831 pos = curr->localToAbsolute();
727 else 832 else if (curr->isBox())
728 pos = FloatPoint(tx + box->x(), ty + box->y()); 833 pos.move(toRenderBox(curr)->x(), toRenderBox(curr)->y());
729 box->addFocusRingRects(graphicsContext, pos.x(), pos.y()); 834 curr->addFocusRingRects(graphicsContext, pos.x(), pos.y());
730 } 835 }
731 } 836 }
732 837
733 if (continuation()) 838 if (continuation()) {
734 continuation()->addFocusRingRects(graphicsContext, 839 if (continuation()->isInline())
735 tx - containingBlock()->x() + continua tion()->x(), 840 continuation()->addFocusRingRects(graphicsContext,
736 ty - containingBlock()->y() + continua tion()->y()); 841 tx - containingBlock()->x() + cont inuation()->containingBlock()->x(),
842 ty - containingBlock()->y() + cont inuation()->containingBlock()->y());
843 else
844 continuation()->addFocusRingRects(graphicsContext,
845 tx - containingBlock()->x() + toRe nderBox(continuation())->x(),
846 ty - containingBlock()->y() + toRe nderBox(continuation())->y());
847 }
737 } 848 }
738 849
739 void RenderInline::paintOutline(GraphicsContext* graphicsContext, int tx, int ty ) 850 void RenderInline::paintOutline(GraphicsContext* graphicsContext, int tx, int ty )
740 { 851 {
741 if (!hasOutline()) 852 if (!hasOutline())
742 return; 853 return;
743 854
744 if (style()->outlineStyleIsAuto() || hasOutlineAnnotation()) { 855 if (style()->outlineStyleIsAuto() || hasOutlineAnnotation()) {
745 int ow = style()->outlineWidth(); 856 int ow = style()->outlineWidth();
746 Color oc = style()->outlineColor(); 857 Color oc = style()->outlineColor();
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
897 region.clip.scale(pageScaleFactor); 1008 region.clip.scale(pageScaleFactor);
898 } 1009 }
899 } 1010 }
900 1011
901 regions.append(region); 1012 regions.append(region);
902 } 1013 }
903 } 1014 }
904 #endif 1015 #endif
905 1016
906 } // namespace WebCore 1017 } // namespace WebCore
OLDNEW
« no previous file with comments | « third_party/WebKit/WebCore/rendering/RenderInline.h ('k') | third_party/WebKit/WebCore/rendering/RenderLayer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698