| 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 , m_cueWritingDirection(writingDirection) | 52 , m_cueWritingDirection(writingDirection) |
| 53 , m_linePosition(linePosition) | 53 , m_linePosition(linePosition) |
| 54 { | 54 { |
| 55 } | 55 } |
| 56 | 56 |
| 57 void layout(); | 57 void layout(); |
| 58 | 58 |
| 59 private: | 59 private: |
| 60 bool isOutside() const; | 60 bool isOutside() const; |
| 61 bool isOverlapping() const; | 61 bool isOverlapping() const; |
| 62 LayoutUnit computeInitialPositionAdjustment(LayoutUnit&) const; |
| 62 bool shouldSwitchDirection(InlineFlowBox*, LayoutUnit) const; | 63 bool shouldSwitchDirection(InlineFlowBox*, LayoutUnit) const; |
| 63 | 64 |
| 64 void moveBoxesByStep(LayoutUnit); | 65 void moveBoxesBy(LayoutUnit distance) |
| 65 bool switchDirection(bool&, LayoutUnit&); | 66 { |
| 67 if (m_cueWritingDirection == VTTCue::Horizontal) |
| 68 m_cueBox.setY(m_cueBox.location().y() + distance); |
| 69 else |
| 70 m_cueBox.setX(m_cueBox.location().x() + distance); |
| 71 } |
| 66 | 72 |
| 67 bool findFirstLineBox(InlineFlowBox*&); | 73 InlineFlowBox* findFirstLineBox() const; |
| 68 bool initializeLayoutParameters(InlineFlowBox*, LayoutUnit&, LayoutUnit&); | |
| 69 void placeBoxInDefaultPosition(LayoutUnit, bool&); | |
| 70 | 74 |
| 71 LayoutPoint m_specifiedPosition; | 75 LayoutPoint m_specifiedPosition; |
| 72 RenderVTTCue& m_cueBox; | 76 RenderVTTCue& m_cueBox; |
| 73 VTTCue::WritingDirection m_cueWritingDirection; | 77 VTTCue::WritingDirection m_cueWritingDirection; |
| 74 float m_linePosition; | 78 float m_linePosition; |
| 75 }; | 79 }; |
| 76 | 80 |
| 77 bool SnapToLinesLayouter::findFirstLineBox(InlineFlowBox*& firstLineBox) | 81 InlineFlowBox* SnapToLinesLayouter::findFirstLineBox() const |
| 78 { | 82 { |
| 79 if (m_cueBox.firstChild()->isRenderInline()) | 83 if (!m_cueBox.firstChild()->isRenderInline()) |
| 80 firstLineBox = toRenderInline(m_cueBox.firstChild())->firstLineBox(); | 84 return nullptr; |
| 81 else | 85 return toRenderInline(m_cueBox.firstChild())->firstLineBox(); |
| 82 return false; | |
| 83 | |
| 84 return true; | |
| 85 } | 86 } |
| 86 | 87 |
| 87 bool SnapToLinesLayouter::initializeLayoutParameters(InlineFlowBox* firstLineBox
, LayoutUnit& step, LayoutUnit& position) | 88 LayoutUnit SnapToLinesLayouter::computeInitialPositionAdjustment(LayoutUnit& ste
p) const |
| 88 { | 89 { |
| 89 ASSERT(m_cueBox.firstChild()); | |
| 90 | |
| 91 // 4. Horizontal: Let step be the height of the first line box in boxes. | |
| 92 // Vertical: Let step be the width of the first line box in boxes. | |
| 93 step = m_cueWritingDirection == VTTCue::Horizontal ? firstLineBox->size().he
ight() : firstLineBox->size().width(); | |
| 94 | |
| 95 // 5. If step is zero, then jump to the step labeled done positioning below. | |
| 96 if (!step) | |
| 97 return false; | |
| 98 | |
| 99 // 6. Let line position be the text track cue computed line position. | 90 // 6. Let line position be the text track cue computed line position. |
| 100 // 7. Round line position to an integer by adding 0.5 and then flooring it. | 91 // 7. Round line position to an integer by adding 0.5 and then flooring it. |
| 101 LayoutUnit linePosition = floorf(m_linePosition + 0.5f); | 92 LayoutUnit linePosition = floorf(m_linePosition + 0.5f); |
| 102 | 93 |
| 103 // 8. Vertical Growing Left: Add one to line position then negate it. | 94 // 8. Vertical Growing Left: Add one to line position then negate it. |
| 104 if (m_cueWritingDirection == VTTCue::VerticalGrowingLeft) | 95 if (m_cueWritingDirection == VTTCue::VerticalGrowingLeft) |
| 105 linePosition = -(linePosition + 1); | 96 linePosition = -(linePosition + 1); |
| 106 | 97 |
| 107 // 9. Let position be the result of multiplying step and line position. | 98 // 9. Let position be the result of multiplying step and line position. |
| 108 position = step * linePosition; | 99 LayoutUnit position = step * linePosition; |
| 109 | 100 |
| 110 // 10. Vertical Growing Left: Decrease position by the width of the | 101 // 10. Vertical Growing Left: Decrease position by the width of the |
| 111 // bounding box of the boxes in boxes, then increase position by step. | 102 // bounding box of the boxes in boxes, then increase position by step. |
| 112 if (m_cueWritingDirection == VTTCue::VerticalGrowingLeft) { | 103 if (m_cueWritingDirection == VTTCue::VerticalGrowingLeft) { |
| 113 position -= m_cueBox.size().width(); | 104 position -= m_cueBox.size().width(); |
| 114 position += step; | 105 position += step; |
| 115 } | 106 } |
| 116 | 107 |
| 117 // 11. If line position is less than zero... | 108 // 11. If line position is less than zero... |
| 118 if (linePosition < 0) { | 109 if (linePosition < 0) { |
| 119 RenderBlock* parentBlock = m_cueBox.containingBlock(); | 110 RenderBlock* parentBlock = m_cueBox.containingBlock(); |
| 120 | 111 |
| 121 // Horizontal / Vertical: ... then increase position by the | 112 // Horizontal / Vertical: ... then increase position by the |
| 122 // height / width of the video's rendering area ... | 113 // height / width of the video's rendering area ... |
| 123 position += m_cueWritingDirection == VTTCue::Horizontal ? parentBlock->s
ize().height() : parentBlock->size().width(); | 114 position += m_cueWritingDirection == VTTCue::Horizontal ? parentBlock->s
ize().height() : parentBlock->size().width(); |
| 124 | 115 |
| 125 // ... and negate step. | 116 // ... and negate step. |
| 126 step = -step; | 117 step = -step; |
| 127 } | 118 } |
| 128 return true; | 119 return position; |
| 129 } | |
| 130 | |
| 131 void SnapToLinesLayouter::placeBoxInDefaultPosition(LayoutUnit position, bool& s
witched) | |
| 132 { | |
| 133 // 12. Move all boxes in boxes ... | |
| 134 if (m_cueWritingDirection == VTTCue::Horizontal) { | |
| 135 // Horizontal: ... down by the distance given by position | |
| 136 m_cueBox.setY(m_cueBox.location().y() + position); | |
| 137 } else { | |
| 138 // Vertical: ... right by the distance given by position | |
| 139 m_cueBox.setX(m_cueBox.location().x() + position); | |
| 140 } | |
| 141 | |
| 142 // 13. Remember the position of all the boxes in boxes as their specified po
sition. | |
| 143 m_specifiedPosition = m_cueBox.location(); | |
| 144 | |
| 145 // 14. Let best position be null. It will hold a position for boxes, much li
ke specified position in the previous step. | |
| 146 // 15. Let best position score be null. | |
| 147 | |
| 148 // 16. Let switched be false. | |
| 149 switched = false; | |
| 150 } | 120 } |
| 151 | 121 |
| 152 bool SnapToLinesLayouter::isOutside() const | 122 bool SnapToLinesLayouter::isOutside() const |
| 153 { | 123 { |
| 154 return !m_cueBox.containingBlock()->absoluteBoundingBoxRect().contains(m_cue
Box.absoluteContentBox()); | 124 return !m_cueBox.containingBlock()->absoluteBoundingBoxRect().contains(m_cue
Box.absoluteContentBox()); |
| 155 } | 125 } |
| 156 | 126 |
| 157 bool SnapToLinesLayouter::isOverlapping() const | 127 bool SnapToLinesLayouter::isOverlapping() const |
| 158 { | 128 { |
| 159 for (RenderObject* box = m_cueBox.previousSibling(); box; box = box->previou
sSibling()) { | 129 for (RenderObject* box = m_cueBox.previousSibling(); box; box = box->previou
sSibling()) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 186 // if step is positive and the right edge of the first line box in boxes is | 156 // if step is positive and the right edge of the first line box in boxes is |
| 187 // now to the right of the right edge of the title area, jump to the step | 157 // now to the right of the right edge of the title area, jump to the step |
| 188 // labeled switch direction. | 158 // labeled switch direction. |
| 189 LayoutUnit parentWidth = m_cueBox.containingBlock()->size().width(); | 159 LayoutUnit parentWidth = m_cueBox.containingBlock()->size().width(); |
| 190 if (m_cueWritingDirection != VTTCue::Horizontal && ((step < 0 && left < 0) |
| (step > 0 && right > parentWidth))) | 160 if (m_cueWritingDirection != VTTCue::Horizontal && ((step < 0 && left < 0) |
| (step > 0 && right > parentWidth))) |
| 191 return true; | 161 return true; |
| 192 | 162 |
| 193 return false; | 163 return false; |
| 194 } | 164 } |
| 195 | 165 |
| 196 void SnapToLinesLayouter::moveBoxesByStep(LayoutUnit step) | |
| 197 { | |
| 198 // 22. Horizontal: Move all the boxes in boxes down by the distance | |
| 199 // given by step. (If step is negative, then this will actually | |
| 200 // result in an upwards movement of the boxes in absolute terms.) | |
| 201 if (m_cueWritingDirection == VTTCue::Horizontal) | |
| 202 m_cueBox.setY(m_cueBox.location().y() + step); | |
| 203 | |
| 204 // 22. Vertical: Move all the boxes in boxes right by the distance | |
| 205 // given by step. (If step is negative, then this will actually | |
| 206 // result in a leftwards movement of the boxes in absolute terms.) | |
| 207 else | |
| 208 m_cueBox.setX(m_cueBox.location().x() + step); | |
| 209 } | |
| 210 | |
| 211 bool SnapToLinesLayouter::switchDirection(bool& switched, LayoutUnit& step) | |
| 212 { | |
| 213 // 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 | |
| 215 // positioning below. | |
| 216 | |
| 217 // 25. Otherwise, move all the boxes in boxes back to their specified | |
| 218 // position as determined in the earlier step. | |
| 219 m_cueBox.setLocation(m_specifiedPosition); | |
| 220 | |
| 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. | |
| 227 step = -step; | |
| 228 | |
| 229 // 27. Set switched to true. | |
| 230 switched = true; | |
| 231 return true; | |
| 232 } | |
| 233 | |
| 234 void SnapToLinesLayouter::layout() | 166 void SnapToLinesLayouter::layout() |
| 235 { | 167 { |
| 236 // http://dev.w3.org/html5/webvtt/#dfn-apply-webvtt-cue-settings | 168 // 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". | 169 // Step 13, "If cue's text track cue snap-to-lines flag is set". |
| 238 | 170 |
| 239 InlineFlowBox* firstLineBox; | 171 InlineFlowBox* firstLineBox = findFirstLineBox(); |
| 240 if (!findFirstLineBox(firstLineBox)) | 172 if (!firstLineBox) |
| 241 return; | 173 return; |
| 242 | 174 |
| 243 // Step 1 skipped. | 175 // Steps 1-3 skipped. |
| 176 // 4. Horizontal: Let step be the height of the first line box in boxes. |
| 177 // Vertical: Let step be the width of the first line box in boxes. |
| 178 LayoutUnit step = m_cueWritingDirection == VTTCue::Horizontal ? firstLineBox
->size().height() : firstLineBox->size().width(); |
| 244 | 179 |
| 245 LayoutUnit step; | 180 // 5. If step is zero, then jump to the step labeled done positioning below. |
| 246 LayoutUnit position; | 181 if (!step) |
| 247 if (!initializeLayoutParameters(firstLineBox, step, position)) | |
| 248 return; | 182 return; |
| 249 | 183 |
| 250 bool switched; | 184 // Steps 6-11. |
| 251 placeBoxInDefaultPosition(position, switched); | 185 LayoutUnit positionAdjustment = computeInitialPositionAdjustment(step); |
| 186 |
| 187 // 12. Move all boxes in boxes ... |
| 188 // Horizontal: ... down by the distance given by position |
| 189 // Vertical: ... right by the distance given by position |
| 190 moveBoxesBy(positionAdjustment); |
| 191 |
| 192 // 13. Remember the position of all the boxes in boxes as their specified |
| 193 // position. |
| 194 m_specifiedPosition = m_cueBox.location(); |
| 195 |
| 196 // 14. Let best position be null. It will hold a position for boxes, much |
| 197 // like specified position in the previous step. |
| 198 // 15. Let best position score be null. |
| 199 |
| 200 // 16. Let switched be false. |
| 201 bool switched = false; |
| 252 | 202 |
| 253 // Step 17 skipped. (margin == 0; title area == video area) | 203 // Step 17 skipped. (margin == 0; title area == video area) |
| 254 | 204 |
| 255 // 18. Step loop: If none of the boxes in boxes would overlap any of the | 205 // 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 | 206 // 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. | 207 // title area box, then jump to the step labeled done positioning below. |
| 258 while (isOutside() || isOverlapping()) { | 208 while (isOutside() || isOverlapping()) { |
| 259 // 19. Let current position score be the percentage of the area of the | 209 // 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 | 210 // bounding box of the boxes in boxes that is outside the title area |
| 261 // box. | 211 // box. |
| 262 // 20. If best position is null (i.e. this is the first run through | 212 // 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 | 213 // 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 | 214 // specified position, and best position score is still null), or if |
| 265 // current position score is a lower percentage than that in best | 215 // current position score is a lower percentage than that in best |
| 266 // position score, then remember the position of all the boxes in boxes | 216 // position score, then remember the position of all the boxes in boxes |
| 267 // as their best position, and set best position score to current | 217 // as their best position, and set best position score to current |
| 268 // position score. | 218 // position score. |
| 269 if (!shouldSwitchDirection(firstLineBox, step)) { | 219 if (!shouldSwitchDirection(firstLineBox, step)) { |
| 270 // 22. Move all the boxes in boxes ... | 220 // 22. Horizontal: Move all the boxes in boxes down by the distance |
| 271 moveBoxesByStep(step); | 221 // given by step. (If step is negative, then this will actually |
| 222 // result in an upwards movement of the boxes in absolute terms.) |
| 223 // Vertical: Move all the boxes in boxes right by the distance |
| 224 // given by step. (If step is negative, then this will actually |
| 225 // result in a leftwards movement of the boxes in absolute terms.) |
| 226 moveBoxesBy(step); |
| 227 |
| 272 // 23. Jump back to the step labeled step loop. | 228 // 23. Jump back to the step labeled step loop. |
| 273 } else if (!switchDirection(switched, step)) { | 229 continue; |
| 230 } |
| 231 |
| 232 // 24. Switch direction: If switched is true, then move all the boxes in |
| 233 // boxes back to their best position, and jump to the step labeled done |
| 234 // positioning below. |
| 235 |
| 236 // 25. Otherwise, move all the boxes in boxes back to their specified |
| 237 // position as determined in the earlier step. |
| 238 m_cueBox.setLocation(m_specifiedPosition); |
| 239 |
| 240 // XX. If switched is true, jump to the step labeled done |
| 241 // positioning below. |
| 242 if (switched) |
| 274 break; | 243 break; |
| 275 } | 244 |
| 245 // 26. Negate step. |
| 246 step = -step; |
| 247 |
| 248 // 27. Set switched to true. |
| 249 switched = true; |
| 276 | 250 |
| 277 // 28. Jump back to the step labeled step loop. | 251 // 28. Jump back to the step labeled step loop. |
| 278 } | 252 } |
| 279 } | 253 } |
| 280 | 254 |
| 281 void RenderVTTCue::repositionCueSnapToLinesNotSet() | 255 void RenderVTTCue::repositionCueSnapToLinesNotSet() |
| 282 { | 256 { |
| 283 // FIXME: Implement overlapping detection when snap-to-lines is not set. htt
p://wkb.ug/84296 | 257 // FIXME: Implement overlapping detection when snap-to-lines is not set. htt
p://wkb.ug/84296 |
| 284 | 258 |
| 285 // http://dev.w3.org/html5/webvtt/#dfn-apply-webvtt-cue-settings | 259 // http://dev.w3.org/html5/webvtt/#dfn-apply-webvtt-cue-settings |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 350 { | 324 { |
| 351 RenderBlockFlow::layout(); | 325 RenderBlockFlow::layout(); |
| 352 | 326 |
| 353 // If WebVTT Regions are used, the regular WebVTT layout algorithm is no | 327 // 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 | 328 // longer necessary, since cues having the region parameter set do not have |
| 355 // any positioning parameters. Also, in this case, the regions themselves | 329 // any positioning parameters. Also, in this case, the regions themselves |
| 356 // have positioning information. | 330 // have positioning information. |
| 357 if (!m_cue->regionId().isEmpty()) | 331 if (!m_cue->regionId().isEmpty()) |
| 358 return; | 332 return; |
| 359 | 333 |
| 334 ASSERT(firstChild()); |
| 335 |
| 360 LayoutState state(*this, locationOffset()); | 336 LayoutState state(*this, locationOffset()); |
| 361 | 337 |
| 362 // http://dev.w3.org/html5/webvtt/#dfn-apply-webvtt-cue-settings - step 13. | 338 // http://dev.w3.org/html5/webvtt/#dfn-apply-webvtt-cue-settings - step 13. |
| 363 if (m_cue->snapToLines()) { | 339 if (m_cue->snapToLines()) { |
| 364 SnapToLinesLayouter(*this, m_cue->getWritingDirection(), m_cue->calculat
eComputedLinePosition()).layout(); | 340 SnapToLinesLayouter(*this, m_cue->getWritingDirection(), m_cue->calculat
eComputedLinePosition()).layout(); |
| 365 | 341 |
| 366 adjustForTopAndBottomMarginBorderAndPadding(); | 342 adjustForTopAndBottomMarginBorderAndPadding(); |
| 367 } else { | 343 } else { |
| 368 repositionCueSnapToLinesNotSet(); | 344 repositionCueSnapToLinesNotSet(); |
| 369 } | 345 } |
| 370 } | 346 } |
| 371 | 347 |
| 372 } // namespace blink | 348 } // namespace blink |
| 373 | 349 |
| OLD | NEW |