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

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutVTTCue.cpp

Issue 2377193003: Don't use absolute bounding boxes in LayoutVTTCue (Closed)
Patch Set: Add test Created 4 years, 2 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2012 Victor Carbune (victor@rosedu.org) 2 * Copyright (C) 2012 Victor Carbune (victor@rosedu.org)
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 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 15 matching lines...) Expand all
26 #include "core/layout/LayoutVTTCue.h" 26 #include "core/layout/LayoutVTTCue.h"
27 27
28 #include "core/frame/Settings.h" 28 #include "core/frame/Settings.h"
29 #include "core/html/shadow/MediaControls.h" 29 #include "core/html/shadow/MediaControls.h"
30 #include "core/layout/LayoutInline.h" 30 #include "core/layout/LayoutInline.h"
31 #include "core/layout/LayoutState.h" 31 #include "core/layout/LayoutState.h"
32 #include "wtf/MathExtras.h" 32 #include "wtf/MathExtras.h"
33 33
34 namespace blink { 34 namespace blink {
35 35
36 LayoutVTTCue::LayoutVTTCue(ContainerNode* node, float snapToLinesPosition) 36 namespace {
37 : LayoutBlockFlow(node)
38 , m_snapToLinesPosition(snapToLinesPosition)
39 {
40 }
41 37
42 class SnapToLinesLayouter { 38 class SnapToLinesLayouter {
43 STACK_ALLOCATED(); 39 STACK_ALLOCATED();
44 public: 40 public:
45 SnapToLinesLayouter(LayoutVTTCue& cueBox, const IntRect& controlsRect) 41 SnapToLinesLayouter(LayoutVTTCue& cueBox, const IntRect& controlsRect)
46 : m_cueBox(cueBox) 42 : m_cueBox(cueBox)
47 , m_controlsRect(controlsRect) 43 , m_controlsRect(controlsRect)
48 , m_margin(0.0) 44 , m_margin(0.0)
49 { 45 {
50 if (Settings* settings = m_cueBox.document().settings()) 46 if (Settings* settings = m_cueBox.document().settings())
(...skipping 24 matching lines...) Expand all
75 InlineFlowBox* SnapToLinesLayouter::findFirstLineBox() const 71 InlineFlowBox* SnapToLinesLayouter::findFirstLineBox() const
76 { 72 {
77 if (!m_cueBox.firstChild()->isLayoutInline()) 73 if (!m_cueBox.firstChild()->isLayoutInline())
78 return nullptr; 74 return nullptr;
79 return toLayoutInline(m_cueBox.firstChild())->firstLineBox(); 75 return toLayoutInline(m_cueBox.firstChild())->firstLineBox();
80 } 76 }
81 77
82 LayoutUnit SnapToLinesLayouter::computeInitialPositionAdjustment(LayoutUnit& ste p, LayoutUnit maxDimension, 78 LayoutUnit SnapToLinesLayouter::computeInitialPositionAdjustment(LayoutUnit& ste p, LayoutUnit maxDimension,
83 LayoutUnit margin) const 79 LayoutUnit margin) const
84 { 80 {
85 ASSERT(std::isfinite(m_cueBox.snapToLinesPosition())); 81 DCHECK(std::isfinite(m_cueBox.snapToLinesPosition()));
86 82
87 // 6. Let line be cue's computed line. 83 // 6. Let line be cue's computed line.
88 // 7. Round line to an integer by adding 0.5 and then flooring it. 84 // 7. Round line to an integer by adding 0.5 and then flooring it.
89 LayoutUnit linePosition(floorf(m_cueBox.snapToLinesPosition() + 0.5f)); 85 LayoutUnit linePosition(floorf(m_cueBox.snapToLinesPosition() + 0.5f));
90 86
91 WritingMode writingMode = m_cueBox.style()->getWritingMode(); 87 WritingMode writingMode = m_cueBox.style()->getWritingMode();
92 // 8. Vertical Growing Left: Add one to line then negate it. 88 // 8. Vertical Growing Left: Add one to line then negate it.
93 if (writingMode == RightToLeftWritingMode) 89 if (writingMode == RightToLeftWritingMode)
94 linePosition = -(linePosition + 1); 90 linePosition = -(linePosition + 1);
95 91
(...skipping 14 matching lines...) Expand all
110 106
111 // ... and negate step. 107 // ... and negate step.
112 step = -step; 108 step = -step;
113 } else { 109 } else {
114 // ... Otherwise, increase position by margin. 110 // ... Otherwise, increase position by margin.
115 position += margin; 111 position += margin;
116 } 112 }
117 return position; 113 return position;
118 } 114 }
119 115
116 IntRect contentBoxRelativeToAncestor(
117 const LayoutBox& box, const LayoutBoxModelObject& ancestor)
118 {
119 FloatRect cueContentBox(box.contentBoxRect());
120 FloatQuad mappedContentQuad = box.localToAncestorQuad(cueContentBox, &ancest or, UseTransforms);
foolip 2016/09/29 19:25:19 Here or somewhere in this file it might be worth c
fs 2016/09/29 19:40:08 The reason we need UseTransforms here is because w
fs 2016/09/30 08:05:32 Added.
121 return mappedContentQuad.enclosingBoundingBox();
122 }
123
124 IntRect cueBoundingBox(const LayoutBox& cueBox)
125 {
126 return contentBoxRelativeToAncestor(cueBox, *cueBox.containingBlock());
127 }
128
120 bool SnapToLinesLayouter::isOutside(const IntRect& titleArea) const 129 bool SnapToLinesLayouter::isOutside(const IntRect& titleArea) const
121 { 130 {
122 return !titleArea.contains(m_cueBox.absoluteContentBox()); 131 return !titleArea.contains(cueBoundingBox(m_cueBox));
123 } 132 }
124 133
125 bool SnapToLinesLayouter::isOverlapping() const 134 bool SnapToLinesLayouter::isOverlapping() const
126 { 135 {
127 IntRect cueBoxRect = m_cueBox.absoluteBoundingBoxRect(); 136 IntRect cueBoxRect = cueBoundingBox(m_cueBox);
128 for (LayoutObject* box = m_cueBox.previousSibling(); box; box = box->previou sSibling()) { 137 for (LayoutBox* box = m_cueBox.previousSiblingBox(); box; box = box->previou sSiblingBox()) {
129 IntRect boxRect = box->absoluteBoundingBoxRect(); 138 if (cueBoxRect.intersects(cueBoundingBox(*box)))
130
131 if (cueBoxRect.intersects(boxRect))
132 return true; 139 return true;
133 } 140 }
134 141 return cueBoxRect.intersects(m_controlsRect);
135 if (cueBoxRect.intersects(m_controlsRect))
136 return true;
137
138 return false;
139 } 142 }
140 143
141 bool SnapToLinesLayouter::shouldSwitchDirection(InlineFlowBox* firstLineBox, Lay outUnit step, LayoutUnit margin) const 144 bool SnapToLinesLayouter::shouldSwitchDirection(InlineFlowBox* firstLineBox, Lay outUnit step, LayoutUnit margin) const
142 { 145 {
143 // 17. Horizontal: If step is negative and the top of the first line box in 146 // 17. Horizontal: If step is negative and the top of the first line box in
144 // boxes is now above the top of the title area, or if step is positive and 147 // boxes is now above the top of the title area, or if step is positive and
145 // the bottom of the first line box in boxes is now below the bottom of the 148 // the bottom of the first line box in boxes is now below the bottom of the
146 // title area, jump to the step labeled switch direction. 149 // title area, jump to the step labeled switch direction.
147 // Vertical: If step is negative and the left edge of the first line 150 // Vertical: If step is negative and the left edge of the first line
148 // box in boxes is now to the left of the left edge of the title area, or 151 // box in boxes is now to the left of the left edge of the title area, or
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 207
205 // XX. Let switched be false. 208 // XX. Let switched be false.
206 bool switched = false; 209 bool switched = false;
207 210
208 // 14. Horizontal: Let title area be a box that covers all of the video's 211 // 14. Horizontal: Let title area be a box that covers all of the video's
209 // rendering area except for a height of margin at the top of the rendering 212 // rendering area except for a height of margin at the top of the rendering
210 // area and a height of margin at the bottom of the rendering area. 213 // area and a height of margin at the bottom of the rendering area.
211 // Vertical: Let title area be a box that covers all of the video’s 214 // Vertical: Let title area be a box that covers all of the video’s
212 // rendering area except for a width of margin at the left of the rendering 215 // rendering area except for a width of margin at the left of the rendering
213 // area and a width of margin at the right of the rendering area. 216 // area and a width of margin at the right of the rendering area.
214 IntRect titleArea = m_cueBox.containingBlock()->absoluteBoundingBoxRect(); 217 IntRect titleArea = enclosingIntRect(m_cueBox.containingBlock()->contentBoxR ect());
215 if (blink::isHorizontalWritingMode(writingMode)) { 218 if (blink::isHorizontalWritingMode(writingMode)) {
216 titleArea.move(0, margin.toInt()); 219 titleArea.move(0, margin.toInt());
217 titleArea.contract(0, (2 * margin).toInt()); 220 titleArea.contract(0, (2 * margin).toInt());
218 } else { 221 } else {
219 titleArea.move(margin.toInt(), 0); 222 titleArea.move(margin.toInt(), 0);
220 titleArea.contract((2 * margin).toInt(), 0); 223 titleArea.contract((2 * margin).toInt(), 0);
221 } 224 }
222 225
223 // 15. Step loop: If none of the boxes in boxes would overlap any of the 226 // 15. Step loop: If none of the boxes in boxes would overlap any of the
224 // boxes in output, and all of the boxes in output are entirely within the 227 // boxes in output, and all of the boxes in output are entirely within the
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 // 22. Negate step. 260 // 22. Negate step.
258 step = -step; 261 step = -step;
259 262
260 // 23. Set switched to true. 263 // 23. Set switched to true.
261 switched = true; 264 switched = true;
262 265
263 // 24. Jump back to the step labeled step loop. 266 // 24. Jump back to the step labeled step loop.
264 } 267 }
265 } 268 }
266 269
270 } // unnamed namespace
271
272 LayoutVTTCue::LayoutVTTCue(ContainerNode* node, float snapToLinesPosition)
273 : LayoutBlockFlow(node)
274 , m_snapToLinesPosition(snapToLinesPosition)
275 {
276 }
277
267 void LayoutVTTCue::repositionCueSnapToLinesNotSet() 278 void LayoutVTTCue::repositionCueSnapToLinesNotSet()
268 { 279 {
269 // FIXME: Implement overlapping detection when snap-to-lines is not set. htt p://wkb.ug/84296 280 // FIXME: Implement overlapping detection when snap-to-lines is not set. htt p://wkb.ug/84296
270 281
271 // http://dev.w3.org/html5/webvtt/#dfn-apply-webvtt-cue-settings 282 // http://dev.w3.org/html5/webvtt/#dfn-apply-webvtt-cue-settings
272 // Step 13, "If cue's text track cue snap-to-lines flag is not set". 283 // Step 13, "If cue's text track cue snap-to-lines flag is not set".
273 284
274 // 1. Let bounding box be the bounding box of the boxes in boxes. 285 // 1. Let bounding box be the bounding box of the boxes in boxes.
275 286
276 // 2. Run the appropriate steps from the following list: 287 // 2. Run the appropriate steps from the following list:
(...skipping 24 matching lines...) Expand all
301 // position to their current position, and then jump to the step labeled 312 // position to their current position, and then jump to the step labeled
302 // done positioning below. If there are multiple such positions that are 313 // done positioning below. If there are multiple such positions that are
303 // equidistant from their current position, use the highest one amongst 314 // equidistant from their current position, use the highest one amongst
304 // them; if there are several at that height, then use the leftmost one 315 // them; if there are several at that height, then use the leftmost one
305 // amongst them. 316 // amongst them.
306 317
307 // 5. Otherwise, jump to the step labeled done positioning below. (The 318 // 5. Otherwise, jump to the step labeled done positioning below. (The
308 // boxes will unfortunately overlap.) 319 // boxes will unfortunately overlap.)
309 } 320 }
310 321
322 IntRect LayoutVTTCue::computeControlsRect() const
323 {
324 // Determine the area covered by the media controls, if any. If the controls
325 // are present, they are the next sibling of the text track container, which
326 // is our parent. (LayoutMedia ensures that the media controls are laid out
327 // before text tracks, so that the layout is up to date here.)
328 DCHECK(parent()->node()->isTextTrackContainer());
329 LayoutObject* controlsContainer = parent()->nextSibling();
330 if (!controlsContainer)
331 return IntRect();
332 // Only a part of the media controls is used for overlap avoidance.
333 MediaControls* controls = toMediaControls(controlsContainer->node());
334 LayoutObject* controlsLayout = controls->layoutObjectForTextTrackLayout();
335 // The (second part of) following is mostly defensive - in general there
336 // should be a LayoutBox representing the part of the controls that are
foolip 2016/09/29 19:25:19 And I guess it can actually happen, like if you pl
fs 2016/09/29 19:40:08 Right, "unlikely, but not impossible" (=> mostly).
fs 2016/09/30 08:05:32 Added additional note mentioning the potential pse
337 // relevant for overlap avoidance.
338 if (!controlsLayout || !controlsLayout->isBox())
339 return IntRect();
340 // Assume that the controls container are positioned in the same relative
341 // position as the text track container. (LayoutMedia::layout ensures this.)
342 return contentBoxRelativeToAncestor(
343 toLayoutBox(*controlsLayout), toLayoutBox(*controlsContainer));
344 }
345
311 void LayoutVTTCue::layout() 346 void LayoutVTTCue::layout()
312 { 347 {
313 LayoutBlockFlow::layout(); 348 LayoutBlockFlow::layout();
314 349
315 ASSERT(firstChild()); 350 DCHECK(firstChild());
316 351
317 LayoutState state(*this, locationOffset()); 352 LayoutState state(*this, locationOffset());
318 353
319 // Determine the area covered by the media controls, if any. If the controls
320 // are present, they are the next sibling of the text track container, which
321 // is our parent. (LayoutMedia ensures that the media controls are laid out
322 // before text tracks, so that the layout is up to date here.)
323 ASSERT(parent()->node()->isTextTrackContainer());
324 IntRect controlsRect;
325 if (LayoutObject* parentSibling = parent()->nextSibling()) {
326 // Only a part of the media controls is used for overlap avoidance.
327 MediaControls* controls = toMediaControls(parentSibling->node());
328 if (LayoutObject* controlsLayout = controls->layoutObjectForTextTrackLay out())
329 controlsRect = controlsLayout->absoluteBoundingBoxRect();
330 }
331
332 // http://dev.w3.org/html5/webvtt/#dfn-apply-webvtt-cue-settings - step 13. 354 // http://dev.w3.org/html5/webvtt/#dfn-apply-webvtt-cue-settings - step 13.
333 if (!std::isnan(m_snapToLinesPosition)) 355 if (!std::isnan(m_snapToLinesPosition))
334 SnapToLinesLayouter(*this, controlsRect).layout(); 356 SnapToLinesLayouter(*this, computeControlsRect()).layout();
335 else 357 else
336 repositionCueSnapToLinesNotSet(); 358 repositionCueSnapToLinesNotSet();
337 } 359 }
338 360
339 } // namespace blink 361 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698