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

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

Issue 880873002: WebVTT: Implement 'best position' from the rendering section (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Fix compilation w/ asserts enabled. 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
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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 RenderBlockFlow::trace(visitor); 44 RenderBlockFlow::trace(visitor);
45 } 45 }
46 46
47 class SnapToLinesLayouter { 47 class SnapToLinesLayouter {
48 STACK_ALLOCATED(); 48 STACK_ALLOCATED();
49 public: 49 public:
50 SnapToLinesLayouter(RenderVTTCue& cueBox, VTTCue::WritingDirection writingDi rection, float linePosition) 50 SnapToLinesLayouter(RenderVTTCue& cueBox, VTTCue::WritingDirection writingDi rection, float linePosition)
51 : m_cueBox(cueBox) 51 : m_cueBox(cueBox)
52 , m_cueWritingDirection(writingDirection) 52 , m_cueWritingDirection(writingDirection)
53 , m_linePosition(linePosition) 53 , m_linePosition(linePosition)
54 , m_bestPositionScore(std::numeric_limits<float>::infinity())
54 { 55 {
55 } 56 }
56 57
57 void layout(); 58 void layout();
58 59
59 private: 60 private:
60 bool isOutside() const; 61 bool isOutside() const;
61 bool isOverlapping() const; 62 bool isOverlapping() const;
63 float computePositionScore() const;
62 bool shouldSwitchDirection(InlineFlowBox*, LayoutUnit) const; 64 bool shouldSwitchDirection(InlineFlowBox*, LayoutUnit) const;
63 65
64 void moveBoxesByStep(LayoutUnit); 66 void moveBoxesByStep(LayoutUnit);
65 bool switchDirection(bool&, LayoutUnit&); 67 bool switchDirection(bool&, LayoutUnit&);
66 68
67 bool findFirstLineBox(InlineFlowBox*&); 69 bool findFirstLineBox(InlineFlowBox*&);
68 bool initializeLayoutParameters(InlineFlowBox*, LayoutUnit&, LayoutUnit&); 70 bool initializeLayoutParameters(InlineFlowBox*, LayoutUnit&, LayoutUnit&);
69 void placeBoxInDefaultPosition(LayoutUnit, bool&); 71 void placeBoxInDefaultPosition(LayoutUnit, bool&);
70 72
71 LayoutPoint m_specifiedPosition;
72 RenderVTTCue& m_cueBox; 73 RenderVTTCue& m_cueBox;
73 VTTCue::WritingDirection m_cueWritingDirection; 74 VTTCue::WritingDirection m_cueWritingDirection;
74 float m_linePosition; 75 float m_linePosition;
76 LayoutPoint m_specifiedPosition;
77 LayoutPoint m_bestPosition;
78 float m_bestPositionScore;
75 }; 79 };
76 80
77 bool SnapToLinesLayouter::findFirstLineBox(InlineFlowBox*& firstLineBox) 81 bool SnapToLinesLayouter::findFirstLineBox(InlineFlowBox*& firstLineBox)
78 { 82 {
79 if (m_cueBox.firstChild()->isRenderInline()) 83 if (m_cueBox.firstChild()->isRenderInline())
80 firstLineBox = toRenderInline(m_cueBox.firstChild())->firstLineBox(); 84 firstLineBox = toRenderInline(m_cueBox.firstChild())->firstLineBox();
81 else 85 else
82 return false; 86 return false;
83 87
84 return true; 88 return true;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 m_cueBox.setY(m_cueBox.location().y() + position); 140 m_cueBox.setY(m_cueBox.location().y() + position);
137 } else { 141 } else {
138 // Vertical: ... right by the distance given by position 142 // Vertical: ... right by the distance given by position
139 m_cueBox.setX(m_cueBox.location().x() + position); 143 m_cueBox.setX(m_cueBox.location().x() + position);
140 } 144 }
141 145
142 // 13. Remember the position of all the boxes in boxes as their specified po sition. 146 // 13. Remember the position of all the boxes in boxes as their specified po sition.
143 m_specifiedPosition = m_cueBox.location(); 147 m_specifiedPosition = m_cueBox.location();
144 148
145 // 14. Let best position be null. It will hold a position for boxes, much li ke specified position in the previous step. 149 // 14. Let best position be null. It will hold a position for boxes, much li ke specified position in the previous step.
150 ASSERT(m_bestPosition == LayoutPoint::zero());
151
146 // 15. Let best position score be null. 152 // 15. Let best position score be null.
153 // (Setting score to positive infinite that should be guaranteed to be
154 // larger than any overlap - and easily recognizable as 'best position is
155 // null' as well.)
156 ASSERT(std::isinf(m_bestPositionScore));
147 157
148 // 16. Let switched be false. 158 // 16. Let switched be false.
149 switched = false; 159 switched = false;
150 } 160 }
151 161
152 bool SnapToLinesLayouter::isOutside() const 162 bool SnapToLinesLayouter::isOutside() const
153 { 163 {
154 return !m_cueBox.containingBlock()->absoluteBoundingBoxRect().contains(m_cue Box.absoluteContentBox()); 164 return !m_cueBox.containingBlock()->absoluteBoundingBoxRect().contains(m_cue Box.absoluteContentBox());
155 } 165 }
156 166
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 // result in a leftwards movement of the boxes in absolute terms.) 216 // result in a leftwards movement of the boxes in absolute terms.)
207 else 217 else
208 m_cueBox.setX(m_cueBox.location().x() + step); 218 m_cueBox.setX(m_cueBox.location().x() + step);
209 } 219 }
210 220
211 bool SnapToLinesLayouter::switchDirection(bool& switched, LayoutUnit& step) 221 bool SnapToLinesLayouter::switchDirection(bool& switched, LayoutUnit& step)
212 { 222 {
213 // 24. Switch direction: If switched is true, then move all the boxes in 223 // 24. Switch direction: If switched is true, then move all the boxes in
214 // boxes back to their best position, and jump to the step labeled done 224 // boxes back to their best position, and jump to the step labeled done
215 // positioning below. 225 // positioning below.
226 if (switched) {
227 m_cueBox.setLocation(m_bestPosition);
228 return false;
229 }
216 230
217 // 25. Otherwise, move all the boxes in boxes back to their specified 231 // 25. Otherwise, move all the boxes in boxes back to their specified
218 // position as determined in the earlier step. 232 // position as determined in the earlier step.
219 m_cueBox.setLocation(m_specifiedPosition); 233 m_cueBox.setLocation(m_specifiedPosition);
220 234
221 // XX. If switched is true, jump to the step labeled done
222 // positioning below.
223 if (switched)
224 return false;
225
226 // 26. Negate step. 235 // 26. Negate step.
227 step = -step; 236 step = -step;
228 237
229 // 27. Set switched to true. 238 // 27. Set switched to true.
230 switched = true; 239 switched = true;
231 return true; 240 return true;
232 } 241 }
233 242
243 static float computeArea(const LayoutRect& rect)
244 {
245 return rect.size().width().toFloat() * rect.size().height().toFloat();
246 }
247
248 float SnapToLinesLayouter::computePositionScore() const
249 {
250 // Compute the percentage of the area of the bounding box of the boxes in
251 // boxes that is outside the title area box.
252 LayoutRect boundingBox = m_cueBox.absoluteBoundingBoxRect();
253 LayoutRect intersectingBox = intersection(m_cueBox.containingBlock()->absolu teBoundingBoxRect(), boundingBox);
philipj_slow 2015/01/27 10:36:09 Extract this into a LayoutRect titleAreaBox to be
fs 2015/01/27 11:54:53 Done.
254 // We know the intersection/overlap, so compute the percentage of the
255 // overlap and then invert.
256 return 1.0f - computeArea(intersectingBox) / computeArea(boundingBox);
philipj_slow 2015/01/27 10:36:09 Can you assert that it's in the range [0,1]? The t
fs 2015/01/27 11:54:53 Modified this a bit to compute the area in LayoutU
257 }
258
234 void SnapToLinesLayouter::layout() 259 void SnapToLinesLayouter::layout()
235 { 260 {
236 // http://dev.w3.org/html5/webvtt/#dfn-apply-webvtt-cue-settings 261 // http://dev.w3.org/html5/webvtt/#dfn-apply-webvtt-cue-settings
237 // Step 13, "If cue's text track cue snap-to-lines flag is set". 262 // Step 13, "If cue's text track cue snap-to-lines flag is set".
238 263
239 InlineFlowBox* firstLineBox; 264 InlineFlowBox* firstLineBox;
240 if (!findFirstLineBox(firstLineBox)) 265 if (!findFirstLineBox(firstLineBox))
241 return; 266 return;
242 267
243 // Step 1 skipped. 268 // Step 1 skipped.
244 269
245 LayoutUnit step; 270 LayoutUnit step;
246 LayoutUnit position; 271 LayoutUnit position;
247 if (!initializeLayoutParameters(firstLineBox, step, position)) 272 if (!initializeLayoutParameters(firstLineBox, step, position))
248 return; 273 return;
249 274
250 bool switched; 275 bool switched;
251 placeBoxInDefaultPosition(position, switched); 276 placeBoxInDefaultPosition(position, switched);
252 277
253 // Step 17 skipped. (margin == 0; title area == video area) 278 // Step 17 skipped. (margin == 0; title area == video area)
254 279
255 // 18. Step loop: If none of the boxes in boxes would overlap any of the 280 // 18. Step loop: If none of the boxes in boxes would overlap any of the
256 // boxes in output, and all of the boxes in output are entirely within the 281 // boxes in output, and all of the boxes in output are entirely within the
257 // title area box, then jump to the step labeled done positioning below. 282 // title area box, then jump to the step labeled done positioning below.
258 while (isOutside() || isOverlapping()) { 283 while (isOutside() || isOverlapping()) {
259 // 19. Let current position score be the percentage of the area of the 284 // 19. Let current position score be the percentage of the area of the
260 // bounding box of the boxes in boxes that is outside the title area 285 // bounding box of the boxes in boxes that is outside the title area
261 // box. 286 // box.
287 float currentPositionScore = computePositionScore();
288
262 // 20. If best position is null (i.e. this is the first run through 289 // 20. If best position is null (i.e. this is the first run through
263 // this loop, switched is still false, the boxes in boxes are at their 290 // this loop, switched is still false, the boxes in boxes are at their
264 // specified position, and best position score is still null), or if 291 // specified position, and best position score is still null), or if
265 // current position score is a lower percentage than that in best 292 // current position score is a lower percentage than that in best
266 // position score, then remember the position of all the boxes in boxes 293 // position score, then remember the position of all the boxes in boxes
267 // as their best position, and set best position score to current 294 // as their best position, and set best position score to current
268 // position score. 295 // position score.
296 if (currentPositionScore < m_bestPositionScore) {
297 m_bestPosition = m_cueBox.location();
298 m_bestPositionScore = currentPositionScore;
299 }
300
269 if (!shouldSwitchDirection(firstLineBox, step)) { 301 if (!shouldSwitchDirection(firstLineBox, step)) {
270 // 22. Move all the boxes in boxes ... 302 // 22. Move all the boxes in boxes ...
271 moveBoxesByStep(step); 303 moveBoxesByStep(step);
272 // 23. Jump back to the step labeled step loop. 304 // 23. Jump back to the step labeled step loop.
273 } else if (!switchDirection(switched, step)) { 305 } else if (!switchDirection(switched, step)) {
274 break; 306 break;
275 } 307 }
276 308
277 // 28. Jump back to the step labeled step loop. 309 // 28. Jump back to the step labeled step loop.
278 } 310 }
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 SnapToLinesLayouter(*this, m_cue->getWritingDirection(), m_cue->calculat eComputedLinePosition()).layout(); 396 SnapToLinesLayouter(*this, m_cue->getWritingDirection(), m_cue->calculat eComputedLinePosition()).layout();
365 397
366 adjustForTopAndBottomMarginBorderAndPadding(); 398 adjustForTopAndBottomMarginBorderAndPadding();
367 } else { 399 } else {
368 repositionCueSnapToLinesNotSet(); 400 repositionCueSnapToLinesNotSet();
369 } 401 }
370 } 402 }
371 403
372 } // namespace blink 404 } // namespace blink
373 405
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698