OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2008 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 | 169 |
170 return true; | 170 return true; |
171 } | 171 } |
172 | 172 |
173 bool RenderLineBoxList::anyLineIntersectsRect(RenderBoxModelObject* renderer, co
nst LayoutRect& rect, const LayoutPoint& offset, LayoutUnit outlineSize) const | 173 bool RenderLineBoxList::anyLineIntersectsRect(RenderBoxModelObject* renderer, co
nst LayoutRect& rect, const LayoutPoint& offset, LayoutUnit outlineSize) const |
174 { | 174 { |
175 // We can check the first box and last box and avoid painting/hit testing if
we don't | 175 // We can check the first box and last box and avoid painting/hit testing if
we don't |
176 // intersect. This is a quick short-circuit that we can take to avoid walki
ng any lines. | 176 // intersect. This is a quick short-circuit that we can take to avoid walki
ng any lines. |
177 // FIXME: This check is flawed in the following extremely obscure way: | 177 // FIXME: This check is flawed in the following extremely obscure way: |
178 // if some line in the middle has a huge overflow, it might actually extend
below the last line. | 178 // if some line in the middle has a huge overflow, it might actually extend
below the last line. |
179 RootInlineBox* firstRootBox = firstLineBox()->root(); | 179 RootInlineBox& firstRootBox = firstLineBox()->root(); |
180 RootInlineBox* lastRootBox = lastLineBox()->root(); | 180 RootInlineBox& lastRootBox = lastLineBox()->root(); |
181 LayoutUnit firstLineTop = firstLineBox()->logicalTopVisualOverflow(firstRoot
Box->lineTop()); | 181 LayoutUnit firstLineTop = firstLineBox()->logicalTopVisualOverflow(firstRoot
Box.lineTop()); |
182 LayoutUnit lastLineBottom = lastLineBox()->logicalBottomVisualOverflow(lastR
ootBox->lineBottom()); | 182 LayoutUnit lastLineBottom = lastLineBox()->logicalBottomVisualOverflow(lastR
ootBox.lineBottom()); |
183 LayoutUnit logicalTop = firstLineTop - outlineSize; | 183 LayoutUnit logicalTop = firstLineTop - outlineSize; |
184 LayoutUnit logicalBottom = outlineSize + lastLineBottom; | 184 LayoutUnit logicalBottom = outlineSize + lastLineBottom; |
185 | 185 |
186 return rangeIntersectsRect(renderer, logicalTop, logicalBottom, rect, offset
); | 186 return rangeIntersectsRect(renderer, logicalTop, logicalBottom, rect, offset
); |
187 } | 187 } |
188 | 188 |
189 bool RenderLineBoxList::lineIntersectsDirtyRect(RenderBoxModelObject* renderer,
InlineFlowBox* box, const PaintInfo& paintInfo, const LayoutPoint& offset) const | 189 bool RenderLineBoxList::lineIntersectsDirtyRect(RenderBoxModelObject* renderer,
InlineFlowBox* box, const PaintInfo& paintInfo, const LayoutPoint& offset) const |
190 { | 190 { |
191 RootInlineBox* root = box->root(); | 191 RootInlineBox& root = box->root(); |
192 LayoutUnit logicalTop = min<LayoutUnit>(box->logicalTopVisualOverflow(root->
lineTop()), root->selectionTop()) - renderer->maximalOutlineSize(paintInfo.phase
); | 192 LayoutUnit logicalTop = min<LayoutUnit>(box->logicalTopVisualOverflow(root.l
ineTop()), root.selectionTop()) - renderer->maximalOutlineSize(paintInfo.phase); |
193 LayoutUnit logicalBottom = box->logicalBottomVisualOverflow(root->lineBottom
()) + renderer->maximalOutlineSize(paintInfo.phase); | 193 LayoutUnit logicalBottom = box->logicalBottomVisualOverflow(root.lineBottom(
)) + renderer->maximalOutlineSize(paintInfo.phase); |
194 | 194 |
195 return rangeIntersectsRect(renderer, logicalTop, logicalBottom, paintInfo.re
ct, offset); | 195 return rangeIntersectsRect(renderer, logicalTop, logicalBottom, paintInfo.re
ct, offset); |
196 } | 196 } |
197 | 197 |
198 void RenderLineBoxList::paint(RenderBoxModelObject* renderer, PaintInfo& paintIn
fo, const LayoutPoint& paintOffset) const | 198 void RenderLineBoxList::paint(RenderBoxModelObject* renderer, PaintInfo& paintIn
fo, const LayoutPoint& paintOffset) const |
199 { | 199 { |
200 // Only paint during the foreground/selection phases. | 200 // Only paint during the foreground/selection phases. |
201 if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhase
Selection && paintInfo.phase != PaintPhaseOutline | 201 if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhase
Selection && paintInfo.phase != PaintPhaseOutline |
202 && paintInfo.phase != PaintPhaseSelfOutline && paintInfo.phase != PaintP
haseChildOutlines && paintInfo.phase != PaintPhaseTextClip | 202 && paintInfo.phase != PaintPhaseSelfOutline && paintInfo.phase != PaintP
haseChildOutlines && paintInfo.phase != PaintPhaseTextClip |
203 && paintInfo.phase != PaintPhaseMask) | 203 && paintInfo.phase != PaintPhaseMask) |
(...skipping 11 matching lines...) Expand all Loading... |
215 | 215 |
216 PaintInfo info(paintInfo); | 216 PaintInfo info(paintInfo); |
217 ListHashSet<RenderInline*> outlineObjects; | 217 ListHashSet<RenderInline*> outlineObjects; |
218 info.setOutlineObjects(&outlineObjects); | 218 info.setOutlineObjects(&outlineObjects); |
219 | 219 |
220 // See if our root lines intersect with the dirty rect. If so, then we pain
t | 220 // See if our root lines intersect with the dirty rect. If so, then we pain
t |
221 // them. Note that boxes can easily overlap, so we can't make any assumptio
ns | 221 // them. Note that boxes can easily overlap, so we can't make any assumptio
ns |
222 // based off positions of our first line box or our last line box. | 222 // based off positions of our first line box or our last line box. |
223 for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox())
{ | 223 for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox())
{ |
224 if (lineIntersectsDirtyRect(renderer, curr, info, paintOffset)) { | 224 if (lineIntersectsDirtyRect(renderer, curr, info, paintOffset)) { |
225 RootInlineBox* root = curr->root(); | 225 RootInlineBox& root = curr->root(); |
226 curr->paint(info, paintOffset, root->lineTop(), root->lineBottom()); | 226 curr->paint(info, paintOffset, root.lineTop(), root.lineBottom()); |
227 } | 227 } |
228 } | 228 } |
229 | 229 |
230 if (info.phase == PaintPhaseOutline || info.phase == PaintPhaseSelfOutline |
| info.phase == PaintPhaseChildOutlines) { | 230 if (info.phase == PaintPhaseOutline || info.phase == PaintPhaseSelfOutline |
| info.phase == PaintPhaseChildOutlines) { |
231 ListHashSet<RenderInline*>::iterator end = info.outlineObjects()->end(); | 231 ListHashSet<RenderInline*>::iterator end = info.outlineObjects()->end(); |
232 for (ListHashSet<RenderInline*>::iterator it = info.outlineObjects()->be
gin(); it != end; ++it) { | 232 for (ListHashSet<RenderInline*>::iterator it = info.outlineObjects()->be
gin(); it != end; ++it) { |
233 RenderInline* flow = *it; | 233 RenderInline* flow = *it; |
234 flow->paintOutline(info, paintOffset); | 234 flow->paintOutline(info, paintOffset); |
235 } | 235 } |
236 info.outlineObjects()->clear(); | 236 info.outlineObjects()->clear(); |
(...skipping 16 matching lines...) Expand all Loading... |
253 IntRect(point.x(), point.y() - locationInContainer.topPadding(), 1, loca
tionInContainer.topPadding() + locationInContainer.bottomPadding() + 1) : | 253 IntRect(point.x(), point.y() - locationInContainer.topPadding(), 1, loca
tionInContainer.topPadding() + locationInContainer.bottomPadding() + 1) : |
254 IntRect(point.x() - locationInContainer.leftPadding(), point.y(), locati
onInContainer.rightPadding() + locationInContainer.leftPadding() + 1, 1); | 254 IntRect(point.x() - locationInContainer.leftPadding(), point.y(), locati
onInContainer.rightPadding() + locationInContainer.leftPadding() + 1, 1); |
255 | 255 |
256 if (!anyLineIntersectsRect(renderer, rect, accumulatedOffset)) | 256 if (!anyLineIntersectsRect(renderer, rect, accumulatedOffset)) |
257 return false; | 257 return false; |
258 | 258 |
259 // See if our root lines contain the point. If so, then we hit test | 259 // See if our root lines contain the point. If so, then we hit test |
260 // them further. Note that boxes can easily overlap, so we can't make any a
ssumptions | 260 // them further. Note that boxes can easily overlap, so we can't make any a
ssumptions |
261 // based off positions of our first line box or our last line box. | 261 // based off positions of our first line box or our last line box. |
262 for (InlineFlowBox* curr = lastLineBox(); curr; curr = curr->prevLineBox())
{ | 262 for (InlineFlowBox* curr = lastLineBox(); curr; curr = curr->prevLineBox())
{ |
263 RootInlineBox* root = curr->root(); | 263 RootInlineBox& root = curr->root(); |
264 if (rangeIntersectsRect(renderer, curr->logicalTopVisualOverflow(root->l
ineTop()), curr->logicalBottomVisualOverflow(root->lineBottom()), rect, accumula
tedOffset)) { | 264 if (rangeIntersectsRect(renderer, curr->logicalTopVisualOverflow(root.li
neTop()), curr->logicalBottomVisualOverflow(root.lineBottom()), rect, accumulate
dOffset)) { |
265 bool inside = curr->nodeAtPoint(request, result, locationInContainer
, accumulatedOffset, root->lineTop(), root->lineBottom()); | 265 bool inside = curr->nodeAtPoint(request, result, locationInContainer
, accumulatedOffset, root.lineTop(), root.lineBottom()); |
266 if (inside) { | 266 if (inside) { |
267 renderer->updateHitTestResult(result, locationInContainer.point(
) - toLayoutSize(accumulatedOffset)); | 267 renderer->updateHitTestResult(result, locationInContainer.point(
) - toLayoutSize(accumulatedOffset)); |
268 return true; | 268 return true; |
269 } | 269 } |
270 } | 270 } |
271 } | 271 } |
272 | 272 |
273 return false; | 273 return false; |
274 } | 274 } |
275 | 275 |
(...skipping 21 matching lines...) Expand all Loading... |
297 // parent's first line box. | 297 // parent's first line box. |
298 RootInlineBox* box = 0; | 298 RootInlineBox* box = 0; |
299 RenderObject* curr = 0; | 299 RenderObject* curr = 0; |
300 for (curr = child->previousSibling(); curr; curr = curr->previousSibling())
{ | 300 for (curr = child->previousSibling(); curr; curr = curr->previousSibling())
{ |
301 if (curr->isFloatingOrOutOfFlowPositioned()) | 301 if (curr->isFloatingOrOutOfFlowPositioned()) |
302 continue; | 302 continue; |
303 | 303 |
304 if (curr->isReplaced()) { | 304 if (curr->isReplaced()) { |
305 InlineBox* wrapper = toRenderBox(curr)->inlineBoxWrapper(); | 305 InlineBox* wrapper = toRenderBox(curr)->inlineBoxWrapper(); |
306 if (wrapper) | 306 if (wrapper) |
307 box = wrapper->root(); | 307 box = &wrapper->root(); |
308 } else if (curr->isText()) { | 308 } else if (curr->isText()) { |
309 InlineTextBox* textBox = toRenderText(curr)->lastTextBox(); | 309 InlineTextBox* textBox = toRenderText(curr)->lastTextBox(); |
310 if (textBox) | 310 if (textBox) |
311 box = textBox->root(); | 311 box = &textBox->root(); |
312 } else if (curr->isRenderInline()) { | 312 } else if (curr->isRenderInline()) { |
313 InlineBox* lastSiblingBox = toRenderInline(curr)->lastLineBoxIncludi
ngCulling(); | 313 InlineBox* lastSiblingBox = toRenderInline(curr)->lastLineBoxIncludi
ngCulling(); |
314 if (lastSiblingBox) | 314 if (lastSiblingBox) |
315 box = lastSiblingBox->root(); | 315 box = &lastSiblingBox->root(); |
316 } | 316 } |
317 | 317 |
318 if (box) | 318 if (box) |
319 break; | 319 break; |
320 } | 320 } |
321 if (!box) { | 321 if (!box) { |
322 if (inlineContainer && !inlineContainer->alwaysCreateLineBoxes()) { | 322 if (inlineContainer && !inlineContainer->alwaysCreateLineBoxes()) { |
323 // https://bugs.webkit.org/show_bug.cgi?id=60778 | 323 // https://bugs.webkit.org/show_bug.cgi?id=60778 |
324 // We may have just removed a <br> with no line box that was our fir
st child. In this case | 324 // We may have just removed a <br> with no line box that was our fir
st child. In this case |
325 // we won't find a previous sibling, but firstBox can be pointing to
a following sibling. | 325 // we won't find a previous sibling, but firstBox can be pointing to
a following sibling. |
326 // This isn't good enough, since we won't locate the root line box t
hat encloses the removed | 326 // This isn't good enough, since we won't locate the root line box t
hat encloses the removed |
327 // <br>. We have to just over-invalidate a bit and go up to our pare
nt. | 327 // <br>. We have to just over-invalidate a bit and go up to our pare
nt. |
328 if (!inlineContainer->ancestorLineBoxDirty()) { | 328 if (!inlineContainer->ancestorLineBoxDirty()) { |
329 inlineContainer->parent()->dirtyLinesFromChangedChild(inlineCont
ainer); | 329 inlineContainer->parent()->dirtyLinesFromChangedChild(inlineCont
ainer); |
330 inlineContainer->setAncestorLineBoxDirty(); // Mark the containe
r to avoid dirtying the same lines again across multiple destroy() calls of the
same subtree. | 330 inlineContainer->setAncestorLineBoxDirty(); // Mark the containe
r to avoid dirtying the same lines again across multiple destroy() calls of the
same subtree. |
331 } | 331 } |
332 return; | 332 return; |
333 } | 333 } |
334 box = firstBox->root(); | 334 box = &firstBox->root(); |
335 } | 335 } |
336 | 336 |
337 // If we found a line box, then dirty it. | 337 // If we found a line box, then dirty it. |
338 if (box) { | 338 if (box) { |
339 RootInlineBox* adjacentBox; | 339 RootInlineBox* adjacentBox; |
340 box->markDirty(); | 340 box->markDirty(); |
341 | 341 |
342 // dirty the adjacent lines that might be affected | 342 // dirty the adjacent lines that might be affected |
343 // NOTE: we dirty the previous line because RootInlineBox objects cache | 343 // NOTE: we dirty the previous line because RootInlineBox objects cache |
344 // the address of the first object on the next line after a BR, which we
may be | 344 // the address of the first object on the next line after a BR, which we
may be |
(...skipping 26 matching lines...) Expand all Loading... |
371 ASSERT(child->prevLineBox() == prev); | 371 ASSERT(child->prevLineBox() == prev); |
372 prev = child; | 372 prev = child; |
373 } | 373 } |
374 ASSERT(prev == m_lastLineBox); | 374 ASSERT(prev == m_lastLineBox); |
375 #endif | 375 #endif |
376 } | 376 } |
377 | 377 |
378 #endif | 378 #endif |
379 | 379 |
380 } | 380 } |
OLD | NEW |