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

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: Make computePositionScore impl. more clear. 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 | « LayoutTests/media/track/track-cue-rendering-best-position-expected.html ('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 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 LayoutUnit computeArea(const LayoutRect& rect)
244 {
245 return rect.size().width() * rect.size().height();
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 titleAreaBox = m_cueBox.containingBlock()->absoluteBoundingBoxRec t();
254 LayoutRect boxOverlap = intersection(titleAreaBox, boundingBox);
255 // We know the intersection/overlap, which means we can determine the
256 // non-overlapping part by subtracting that area from the bounding box area.
257 LayoutUnit overlappingArea = computeArea(boxOverlap);
258 LayoutUnit boundingBoxArea = computeArea(boundingBox);
259 ASSERT(overlappingArea >= 0 && overlappingArea <= boundingBoxArea);
260 return (boundingBoxArea - overlappingArea) / boundingBoxArea.toFloat();
261 }
262
234 void SnapToLinesLayouter::layout() 263 void SnapToLinesLayouter::layout()
235 { 264 {
236 // http://dev.w3.org/html5/webvtt/#dfn-apply-webvtt-cue-settings 265 // 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". 266 // Step 13, "If cue's text track cue snap-to-lines flag is set".
238 267
239 InlineFlowBox* firstLineBox; 268 InlineFlowBox* firstLineBox;
240 if (!findFirstLineBox(firstLineBox)) 269 if (!findFirstLineBox(firstLineBox))
241 return; 270 return;
242 271
243 // Step 1 skipped. 272 // Step 1 skipped.
244 273
245 LayoutUnit step; 274 LayoutUnit step;
246 LayoutUnit position; 275 LayoutUnit position;
247 if (!initializeLayoutParameters(firstLineBox, step, position)) 276 if (!initializeLayoutParameters(firstLineBox, step, position))
248 return; 277 return;
249 278
250 bool switched; 279 bool switched;
251 placeBoxInDefaultPosition(position, switched); 280 placeBoxInDefaultPosition(position, switched);
252 281
253 // Step 17 skipped. (margin == 0; title area == video area) 282 // Step 17 skipped. (margin == 0; title area == video area)
254 283
255 // 18. Step loop: If none of the boxes in boxes would overlap any of the 284 // 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 285 // 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. 286 // title area box, then jump to the step labeled done positioning below.
258 while (isOutside() || isOverlapping()) { 287 while (isOutside() || isOverlapping()) {
259 // 19. Let current position score be the percentage of the area of the 288 // 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 289 // bounding box of the boxes in boxes that is outside the title area
261 // box. 290 // box.
291 float currentPositionScore = computePositionScore();
292
262 // 20. If best position is null (i.e. this is the first run through 293 // 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 294 // 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 295 // specified position, and best position score is still null), or if
265 // current position score is a lower percentage than that in best 296 // current position score is a lower percentage than that in best
266 // position score, then remember the position of all the boxes in boxes 297 // position score, then remember the position of all the boxes in boxes
267 // as their best position, and set best position score to current 298 // as their best position, and set best position score to current
268 // position score. 299 // position score.
300 if (currentPositionScore < m_bestPositionScore) {
301 m_bestPosition = m_cueBox.location();
302 m_bestPositionScore = currentPositionScore;
303 }
304
269 if (!shouldSwitchDirection(firstLineBox, step)) { 305 if (!shouldSwitchDirection(firstLineBox, step)) {
270 // 22. Move all the boxes in boxes ... 306 // 22. Move all the boxes in boxes ...
271 moveBoxesByStep(step); 307 moveBoxesByStep(step);
272 // 23. Jump back to the step labeled step loop. 308 // 23. Jump back to the step labeled step loop.
273 } else if (!switchDirection(switched, step)) { 309 } else if (!switchDirection(switched, step)) {
274 break; 310 break;
275 } 311 }
276 312
277 // 28. Jump back to the step labeled step loop. 313 // 28. Jump back to the step labeled step loop.
278 } 314 }
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 SnapToLinesLayouter(*this, m_cue->getWritingDirection(), m_cue->calculat eComputedLinePosition()).layout(); 400 SnapToLinesLayouter(*this, m_cue->getWritingDirection(), m_cue->calculat eComputedLinePosition()).layout();
365 401
366 adjustForTopAndBottomMarginBorderAndPadding(); 402 adjustForTopAndBottomMarginBorderAndPadding();
367 } else { 403 } else {
368 repositionCueSnapToLinesNotSet(); 404 repositionCueSnapToLinesNotSet();
369 } 405 }
370 } 406 }
371 407
372 } // namespace blink 408 } // namespace blink
373 409
OLDNEW
« no previous file with comments | « LayoutTests/media/track/track-cue-rendering-best-position-expected.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698