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

Side by Side Diff: Source/core/rendering/RenderVTTCue.cpp

Issue 873483003: Move WebVTT snap-to-lines layout code to a helper class (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 11 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
« no previous file with comments | « Source/core/rendering/RenderVTTCue.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 26 matching lines...) Expand all
37 , m_cue(element->getCue()) 37 , m_cue(element->getCue())
38 { 38 {
39 } 39 }
40 40
41 void RenderVTTCue::trace(Visitor* visitor) 41 void RenderVTTCue::trace(Visitor* visitor)
42 { 42 {
43 visitor->trace(m_cue); 43 visitor->trace(m_cue);
44 RenderBlockFlow::trace(visitor); 44 RenderBlockFlow::trace(visitor);
45 } 45 }
46 46
47 void RenderVTTCue::layout() 47 class SnapToLinesLayouter {
48 STACK_ALLOCATED();
49 public:
50 SnapToLinesLayouter(RenderVTTCue& cueBox, VTTCue::WritingDirection writingDi rection, float linePosition)
51 : m_cueBox(cueBox)
52 , m_cueWritingDirection(writingDirection)
53 , m_linePosition(linePosition)
54 {
55 }
56
57 void layout();
58
59 private:
60 bool isOutside() const;
61 bool isOverlapping() const;
62 bool shouldSwitchDirection(InlineFlowBox*, LayoutUnit) const;
63
64 void moveBoxesByStep(LayoutUnit);
65 bool switchDirection(bool&, LayoutUnit&);
66
67 bool findFirstLineBox(InlineFlowBox*&);
68 bool initializeLayoutParameters(InlineFlowBox*, LayoutUnit&, LayoutUnit&);
69 void placeBoxInDefaultPosition(LayoutUnit, bool&);
70
71 LayoutPoint m_specifiedPosition;
72 RenderVTTCue& m_cueBox;
73 VTTCue::WritingDirection m_cueWritingDirection;
74 float m_linePosition;
75 };
76
77 bool SnapToLinesLayouter::findFirstLineBox(InlineFlowBox*& firstLineBox)
48 { 78 {
49 RenderBlockFlow::layout(); 79 if (m_cueBox.firstChild()->isRenderInline())
50 80 firstLineBox = toRenderInline(m_cueBox.firstChild())->firstLineBox();
51 // If WebVTT Regions are used, the regular WebVTT layout algorithm is no
52 // longer necessary, since cues having the region parameter set do not have
53 // any positioning parameters. Also, in this case, the regions themselves
54 // have positioning information.
55 if (!m_cue->regionId().isEmpty())
56 return;
57
58 LayoutState state(*this, locationOffset());
59
60 // http://dev.w3.org/html5/webvtt/#dfn-apply-webvtt-cue-settings - step 13.
61 if (m_cue->snapToLines())
62 repositionCueSnapToLinesSet();
63 else
64 repositionCueSnapToLinesNotSet();
65 }
66
67 bool RenderVTTCue::findFirstLineBox(InlineFlowBox*& firstLineBox)
68 {
69 if (firstChild()->isRenderInline())
70 firstLineBox = toRenderInline(firstChild())->firstLineBox();
71 else 81 else
72 return false; 82 return false;
73 83
74 return true; 84 return true;
75 } 85 }
76 86
77 bool RenderVTTCue::initializeLayoutParameters(InlineFlowBox* firstLineBox, Layou tUnit& step, LayoutUnit& position) 87 bool SnapToLinesLayouter::initializeLayoutParameters(InlineFlowBox* firstLineBox , LayoutUnit& step, LayoutUnit& position)
78 { 88 {
79 ASSERT(firstChild()); 89 ASSERT(m_cueBox.firstChild());
80 90
81 // 4. Horizontal: Let step be the height of the first line box in boxes. 91 // 4. Horizontal: Let step be the height of the first line box in boxes.
82 // Vertical: Let step be the width of the first line box in boxes. 92 // Vertical: Let step be the width of the first line box in boxes.
83 step = m_cue->getWritingDirection() == VTTCue::Horizontal ? firstLineBox->si ze().height() : firstLineBox->size().width(); 93 step = m_cueWritingDirection == VTTCue::Horizontal ? firstLineBox->size().he ight() : firstLineBox->size().width();
84 94
85 // 5. If step is zero, then jump to the step labeled done positioning below. 95 // 5. If step is zero, then jump to the step labeled done positioning below.
86 if (!step) 96 if (!step)
87 return false; 97 return false;
88 98
89 // 6. Let line position be the text track cue computed line position. 99 // 6. Let line position be the text track cue computed line position.
90 // 7. Round line position to an integer by adding 0.5 and then flooring it. 100 // 7. Round line position to an integer by adding 0.5 and then flooring it.
91 LayoutUnit linePosition = floorf(m_cue->calculateComputedLinePosition() + 0. 5f); 101 LayoutUnit linePosition = floorf(m_linePosition + 0.5f);
92 102
93 // 8. Vertical Growing Left: Add one to line position then negate it. 103 // 8. Vertical Growing Left: Add one to line position then negate it.
94 if (m_cue->getWritingDirection() == VTTCue::VerticalGrowingLeft) 104 if (m_cueWritingDirection == VTTCue::VerticalGrowingLeft)
95 linePosition = -(linePosition + 1); 105 linePosition = -(linePosition + 1);
96 106
97 // 9. Let position be the result of multiplying step and line position. 107 // 9. Let position be the result of multiplying step and line position.
98 position = step * linePosition; 108 position = step * linePosition;
99 109
100 // 10. Vertical Growing Left: Decrease position by the width of the 110 // 10. Vertical Growing Left: Decrease position by the width of the
101 // bounding box of the boxes in boxes, then increase position by step. 111 // bounding box of the boxes in boxes, then increase position by step.
102 if (m_cue->getWritingDirection() == VTTCue::VerticalGrowingLeft) { 112 if (m_cueWritingDirection == VTTCue::VerticalGrowingLeft) {
103 position -= size().width(); 113 position -= m_cueBox.size().width();
104 position += step; 114 position += step;
105 } 115 }
106 116
107 // 11. If line position is less than zero... 117 // 11. If line position is less than zero...
108 if (linePosition < 0) { 118 if (linePosition < 0) {
109 RenderBlock* parentBlock = containingBlock(); 119 RenderBlock* parentBlock = m_cueBox.containingBlock();
110 120
111 // Horizontal / Vertical: ... then increase position by the 121 // Horizontal / Vertical: ... then increase position by the
112 // height / width of the video's rendering area ... 122 // height / width of the video's rendering area ...
113 position += m_cue->getWritingDirection() == VTTCue::Horizontal ? parentB lock->size().height() : parentBlock->size().width(); 123 position += m_cueWritingDirection == VTTCue::Horizontal ? parentBlock->s ize().height() : parentBlock->size().width();
114 124
115 // ... and negate step. 125 // ... and negate step.
116 step = -step; 126 step = -step;
117 } 127 }
118 return true; 128 return true;
119 } 129 }
120 130
121 void RenderVTTCue::placeBoxInDefaultPosition(LayoutUnit position, bool& switched ) 131 void SnapToLinesLayouter::placeBoxInDefaultPosition(LayoutUnit position, bool& s witched)
122 { 132 {
123 // 12. Move all boxes in boxes ... 133 // 12. Move all boxes in boxes ...
124 if (m_cue->getWritingDirection() == VTTCue::Horizontal) { 134 if (m_cueWritingDirection == VTTCue::Horizontal) {
125 // Horizontal: ... down by the distance given by position 135 // Horizontal: ... down by the distance given by position
126 setY(location().y() + position); 136 m_cueBox.setY(m_cueBox.location().y() + position);
127 } else { 137 } else {
128 // Vertical: ... right by the distance given by position 138 // Vertical: ... right by the distance given by position
129 setX(location().x() + position); 139 m_cueBox.setX(m_cueBox.location().x() + position);
130 } 140 }
131 141
132 // 13. Remember the position of all the boxes in boxes as their specified po sition. 142 // 13. Remember the position of all the boxes in boxes as their specified po sition.
133 m_specifiedPosition = location(); 143 m_specifiedPosition = m_cueBox.location();
134 144
135 // 14. Let best position be null. It will hold a position for boxes, much li ke specified position in the previous step. 145 // 14. Let best position be null. It will hold a position for boxes, much li ke specified position in the previous step.
136 // 15. Let best position score be null. 146 // 15. Let best position score be null.
137 147
138 // 16. Let switched be false. 148 // 16. Let switched be false.
139 switched = false; 149 switched = false;
140 } 150 }
141 151
142 bool RenderVTTCue::isOutside() const 152 bool SnapToLinesLayouter::isOutside() const
143 { 153 {
144 return !containingBlock()->absoluteBoundingBoxRect().contains(absoluteConten tBox()); 154 return !m_cueBox.containingBlock()->absoluteBoundingBoxRect().contains(m_cue Box.absoluteContentBox());
145 } 155 }
146 156
147 bool RenderVTTCue::isOverlapping() const 157 bool SnapToLinesLayouter::isOverlapping() const
148 { 158 {
149 for (RenderObject* box = previousSibling(); box; box = box->previousSibling( )) { 159 for (RenderObject* box = m_cueBox.previousSibling(); box; box = box->previou sSibling()) {
150 IntRect boxRect = box->absoluteBoundingBoxRect(); 160 IntRect boxRect = box->absoluteBoundingBoxRect();
151 161
152 if (absoluteBoundingBoxRect().intersects(boxRect)) 162 if (m_cueBox.absoluteBoundingBoxRect().intersects(boxRect))
153 return true; 163 return true;
154 } 164 }
155 165
156 return false; 166 return false;
157 } 167 }
158 168
159 bool RenderVTTCue::shouldSwitchDirection(InlineFlowBox* firstLineBox, LayoutUnit step) const 169 bool SnapToLinesLayouter::shouldSwitchDirection(InlineFlowBox* firstLineBox, Lay outUnit step) const
160 { 170 {
161 LayoutUnit top = location().y(); 171 LayoutUnit top = m_cueBox.location().y();
162 LayoutUnit left = location().x(); 172 LayoutUnit left = m_cueBox.location().x();
163 LayoutUnit bottom = top + firstLineBox->size().height(); 173 LayoutUnit bottom = top + firstLineBox->size().height();
164 LayoutUnit right = left + firstLineBox->size().width(); 174 LayoutUnit right = left + firstLineBox->size().width();
165 175
166 // 21. Horizontal: If step is negative and the top of the first line box in 176 // 21. Horizontal: If step is negative and the top of the first line box in
167 // boxes is now above the top of the title area, or if step is positive and 177 // boxes is now above the top of the title area, or if step is positive and
168 // the bottom of the first line box in boxes is now below the bottom of the 178 // the bottom of the first line box in boxes is now below the bottom of the
169 // title area, jump to the step labeled switch direction. 179 // title area, jump to the step labeled switch direction.
170 LayoutUnit parentHeight = containingBlock()->size().height(); 180 LayoutUnit parentHeight = m_cueBox.containingBlock()->size().height();
171 if (m_cue->getWritingDirection() == VTTCue::Horizontal && ((step < 0 && top < 0) || (step > 0 && bottom > parentHeight))) 181 if (m_cueWritingDirection == VTTCue::Horizontal && ((step < 0 && top < 0) || (step > 0 && bottom > parentHeight)))
172 return true; 182 return true;
173 183
174 // 21. Vertical: If step is negative and the left edge of the first line 184 // 21. Vertical: If step is negative and the left edge of the first line
175 // box in boxes is now to the left of the left edge of the title area, or 185 // box in boxes is now to the left of the left edge of the title area, or
176 // if step is positive and the right edge of the first line box in boxes is 186 // if step is positive and the right edge of the first line box in boxes is
177 // now to the right of the right edge of the title area, jump to the step 187 // now to the right of the right edge of the title area, jump to the step
178 // labeled switch direction. 188 // labeled switch direction.
179 LayoutUnit parentWidth = containingBlock()->size().width(); 189 LayoutUnit parentWidth = m_cueBox.containingBlock()->size().width();
180 if (m_cue->getWritingDirection() != VTTCue::Horizontal && ((step < 0 && left < 0) || (step > 0 && right > parentWidth))) 190 if (m_cueWritingDirection != VTTCue::Horizontal && ((step < 0 && left < 0) | | (step > 0 && right > parentWidth)))
181 return true; 191 return true;
182 192
183 return false; 193 return false;
184 } 194 }
185 195
186 void RenderVTTCue::moveBoxesByStep(LayoutUnit step) 196 void SnapToLinesLayouter::moveBoxesByStep(LayoutUnit step)
187 { 197 {
188 // 22. Horizontal: Move all the boxes in boxes down by the distance 198 // 22. Horizontal: Move all the boxes in boxes down by the distance
189 // given by step. (If step is negative, then this will actually 199 // given by step. (If step is negative, then this will actually
190 // result in an upwards movement of the boxes in absolute terms.) 200 // result in an upwards movement of the boxes in absolute terms.)
191 if (m_cue->getWritingDirection() == VTTCue::Horizontal) 201 if (m_cueWritingDirection == VTTCue::Horizontal)
192 setY(location().y() + step); 202 m_cueBox.setY(m_cueBox.location().y() + step);
193 203
194 // 22. Vertical: Move all the boxes in boxes right by the distance 204 // 22. Vertical: Move all the boxes in boxes right by the distance
195 // given by step. (If step is negative, then this will actually 205 // given by step. (If step is negative, then this will actually
196 // result in a leftwards movement of the boxes in absolute terms.) 206 // result in a leftwards movement of the boxes in absolute terms.)
197 else 207 else
198 setX(location().x() + step); 208 m_cueBox.setX(m_cueBox.location().x() + step);
199 } 209 }
200 210
201 bool RenderVTTCue::switchDirection(bool& switched, LayoutUnit& step) 211 bool SnapToLinesLayouter::switchDirection(bool& switched, LayoutUnit& step)
202 { 212 {
203 // 24. Switch direction: If switched is true, then move all the boxes in 213 // 24. Switch direction: If switched is true, then move all the boxes in
204 // boxes back to their best position, and jump to the step labeled done 214 // boxes back to their best position, and jump to the step labeled done
205 // positioning below. 215 // positioning below.
206 216
207 // 25. Otherwise, move all the boxes in boxes back to their specified 217 // 25. Otherwise, move all the boxes in boxes back to their specified
208 // position as determined in the earlier step. 218 // position as determined in the earlier step.
209 setLocation(m_specifiedPosition); 219 m_cueBox.setLocation(m_specifiedPosition);
210 220
211 // XX. If switched is true, jump to the step labeled done 221 // XX. If switched is true, jump to the step labeled done
212 // positioning below. 222 // positioning below.
213 if (switched) 223 if (switched)
214 return false; 224 return false;
215 225
216 // 26. Negate step. 226 // 26. Negate step.
217 step = -step; 227 step = -step;
218 228
219 // 27. Set switched to true. 229 // 27. Set switched to true.
220 switched = true; 230 switched = true;
221 return true; 231 return true;
222 } 232 }
223 233
224 void RenderVTTCue::repositionCueSnapToLinesSet() 234 void SnapToLinesLayouter::layout()
225 { 235 {
226 // http://dev.w3.org/html5/webvtt/#dfn-apply-webvtt-cue-settings 236 // http://dev.w3.org/html5/webvtt/#dfn-apply-webvtt-cue-settings
227 // Step 13, "If cue's text track cue snap-to-lines flag is set". 237 // Step 13, "If cue's text track cue snap-to-lines flag is set".
228 238
229 InlineFlowBox* firstLineBox; 239 InlineFlowBox* firstLineBox;
230 if (!findFirstLineBox(firstLineBox)) 240 if (!findFirstLineBox(firstLineBox))
231 return; 241 return;
232 242
233 // Step 1 skipped. 243 // Step 1 skipped.
234 244
(...skipping 24 matching lines...) Expand all
259 if (!shouldSwitchDirection(firstLineBox, step)) { 269 if (!shouldSwitchDirection(firstLineBox, step)) {
260 // 22. Move all the boxes in boxes ... 270 // 22. Move all the boxes in boxes ...
261 moveBoxesByStep(step); 271 moveBoxesByStep(step);
262 // 23. Jump back to the step labeled step loop. 272 // 23. Jump back to the step labeled step loop.
263 } else if (!switchDirection(switched, step)) { 273 } else if (!switchDirection(switched, step)) {
264 break; 274 break;
265 } 275 }
266 276
267 // 28. Jump back to the step labeled step loop. 277 // 28. Jump back to the step labeled step loop.
268 } 278 }
269
270 // Acommodate extra top and bottom padding, border or margin.
271 // Note: this is supported only for internal UA styling, not through the cue selector.
272 if (hasInlineDirectionBordersPaddingOrMargin()) {
273 IntRect containerRect = containingBlock()->absoluteBoundingBoxRect();
274 IntRect cueRect = absoluteBoundingBoxRect();
275
276 int topOverflow = cueRect.y() - containerRect.y();
277 int bottomOverflow = containerRect.y() + containerRect.height() - cueRec t.y() - cueRect.height();
278
279 int adjustment = 0;
280 if (topOverflow < 0)
281 adjustment = -topOverflow;
282 else if (bottomOverflow < 0)
283 adjustment = bottomOverflow;
284
285 if (adjustment)
286 setY(location().y() + adjustment);
287 }
288 } 279 }
289 280
290 void RenderVTTCue::repositionCueSnapToLinesNotSet() 281 void RenderVTTCue::repositionCueSnapToLinesNotSet()
291 { 282 {
292 // FIXME: Implement overlapping detection when snap-to-lines is not set. htt p://wkb.ug/84296 283 // FIXME: Implement overlapping detection when snap-to-lines is not set. htt p://wkb.ug/84296
293 284
294 // http://dev.w3.org/html5/webvtt/#dfn-apply-webvtt-cue-settings 285 // http://dev.w3.org/html5/webvtt/#dfn-apply-webvtt-cue-settings
295 // Step 13, "If cue's text track cue snap-to-lines flag is not set". 286 // Step 13, "If cue's text track cue snap-to-lines flag is not set".
296 287
297 // 1. Let bounding box be the bounding box of the boxes in boxes. 288 // 1. Let bounding box be the bounding box of the boxes in boxes.
(...skipping 26 matching lines...) Expand all
324 // position to their current position, and then jump to the step labeled 315 // position to their current position, and then jump to the step labeled
325 // done positioning below. If there are multiple such positions that are 316 // done positioning below. If there are multiple such positions that are
326 // equidistant from their current position, use the highest one amongst 317 // equidistant from their current position, use the highest one amongst
327 // them; if there are several at that height, then use the leftmost one 318 // them; if there are several at that height, then use the leftmost one
328 // amongst them. 319 // amongst them.
329 320
330 // 5. Otherwise, jump to the step labeled done positioning below. (The 321 // 5. Otherwise, jump to the step labeled done positioning below. (The
331 // boxes will unfortunately overlap.) 322 // boxes will unfortunately overlap.)
332 } 323 }
333 324
325 void RenderVTTCue::adjustForTopAndBottomMarginBorderAndPadding()
philipj_slow 2015/01/27 05:06:59 Does this bit make sense to you? It looks like it'
fs 2015/01/27 12:15:53 Not really, no.
326 {
327 // Accommodate extra top and bottom padding, border or margin.
328 // Note: this is supported only for internal UA styling, not through the cue selector.
329 if (!hasInlineDirectionBordersPaddingOrMargin())
330 return;
331 IntRect containerRect = containingBlock()->absoluteBoundingBoxRect();
332 IntRect cueRect = absoluteBoundingBoxRect();
333
334 int topOverflow = cueRect.y() - containerRect.y();
335 int bottomOverflow = containerRect.y() + containerRect.height() - cueRect.y( ) - cueRect.height();
336
337 int adjustment = 0;
338 if (topOverflow < 0)
339 adjustment = -topOverflow;
340 else if (bottomOverflow < 0)
341 adjustment = bottomOverflow;
342
343 if (!adjustment)
344 return;
345
346 setY(location().y() + adjustment);
347 }
348
349 void RenderVTTCue::layout()
350 {
351 RenderBlockFlow::layout();
352
353 // If WebVTT Regions are used, the regular WebVTT layout algorithm is no
354 // longer necessary, since cues having the region parameter set do not have
355 // any positioning parameters. Also, in this case, the regions themselves
356 // have positioning information.
357 if (!m_cue->regionId().isEmpty())
358 return;
359
360 LayoutState state(*this, locationOffset());
361
362 // http://dev.w3.org/html5/webvtt/#dfn-apply-webvtt-cue-settings - step 13.
363 if (m_cue->snapToLines()) {
364 SnapToLinesLayouter(*this, m_cue->getWritingDirection(), m_cue->calculat eComputedLinePosition()).layout();
365
366 adjustForTopAndBottomMarginBorderAndPadding();
367 } else {
368 repositionCueSnapToLinesNotSet();
369 }
370 }
371
334 } // namespace blink 372 } // namespace blink
335 373
OLDNEW
« no previous file with comments | « Source/core/rendering/RenderVTTCue.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698