OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |