| 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 |
| 11 * documentation and/or other materials provided with the distribution. | 11 * documentation and/or other materials provided with the distribution. |
| 12 * | 12 * |
| 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY | 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
| 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR | 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
| 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 24 */ | 24 */ |
| 25 | 25 |
| 26 #include "config.h" | 26 #include "config.h" |
| 27 #include "core/rendering/RenderTextTrackCue.h" | 27 #include "core/rendering/RenderVTTCue.h" |
| 28 | 28 |
| 29 #include "core/html/track/TextTrackCue.h" | 29 #include "core/html/track/vtt/VTTCue.h" |
| 30 #include "core/rendering/LayoutRectRecorder.h" | 30 #include "core/rendering/LayoutRectRecorder.h" |
| 31 #include "core/rendering/RenderView.h" | 31 #include "core/rendering/RenderView.h" |
| 32 | 32 |
| 33 namespace WebCore { | 33 namespace WebCore { |
| 34 | 34 |
| 35 RenderTextTrackCue::RenderTextTrackCue(TextTrackCueBox* element) | 35 RenderVTTCue::RenderVTTCue(VTTCueBox* element) |
| 36 : RenderBlockFlow(element) | 36 : RenderBlockFlow(element) |
| 37 , m_cue(element->getCue()) | 37 , m_cue(element->getCue()) |
| 38 { | 38 { |
| 39 } | 39 } |
| 40 | 40 |
| 41 void RenderTextTrackCue::layout() | 41 void RenderVTTCue::layout() |
| 42 { | 42 { |
| 43 LayoutRectRecorder recorder(*this); | 43 LayoutRectRecorder recorder(*this); |
| 44 RenderBlockFlow::layout(); | 44 RenderBlockFlow::layout(); |
| 45 | 45 |
| 46 // If WebVTT Regions are used, the regular WebVTT layout algorithm is no | 46 // If WebVTT Regions are used, the regular WebVTT layout algorithm is no |
| 47 // longer necessary, since cues having the region parameter set do not have | 47 // longer necessary, since cues having the region parameter set do not have |
| 48 // any positioning parameters. Also, in this case, the regions themselves | 48 // any positioning parameters. Also, in this case, the regions themselves |
| 49 // have positioning information. | 49 // have positioning information. |
| 50 if (!m_cue->regionId().isEmpty()) | 50 if (!m_cue->regionId().isEmpty()) |
| 51 return; | 51 return; |
| 52 | 52 |
| 53 LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasTransfo
rm() || hasReflection() || style()->isFlippedBlocksWritingMode()); | 53 LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasTransfo
rm() || hasReflection() || style()->isFlippedBlocksWritingMode()); |
| 54 | 54 |
| 55 if (m_cue->snapToLines()) | 55 if (m_cue->snapToLines()) |
| 56 repositionCueSnapToLinesSet(); | 56 repositionCueSnapToLinesSet(); |
| 57 else | 57 else |
| 58 repositionCueSnapToLinesNotSet(); | 58 repositionCueSnapToLinesNotSet(); |
| 59 | 59 |
| 60 statePusher.pop(); | 60 statePusher.pop(); |
| 61 } | 61 } |
| 62 | 62 |
| 63 bool RenderTextTrackCue::findFirstLineBox(InlineFlowBox*& firstLineBox) | 63 bool RenderVTTCue::findFirstLineBox(InlineFlowBox*& firstLineBox) |
| 64 { | 64 { |
| 65 if (firstChild()->isRenderInline()) | 65 if (firstChild()->isRenderInline()) |
| 66 firstLineBox = toRenderInline(firstChild())->firstLineBox(); | 66 firstLineBox = toRenderInline(firstChild())->firstLineBox(); |
| 67 else | 67 else |
| 68 return false; | 68 return false; |
| 69 | 69 |
| 70 return true; | 70 return true; |
| 71 } | 71 } |
| 72 | 72 |
| 73 bool RenderTextTrackCue::initializeLayoutParameters(InlineFlowBox* firstLineBox,
LayoutUnit& step, LayoutUnit& position) | 73 bool RenderVTTCue::initializeLayoutParameters(InlineFlowBox* firstLineBox, Layou
tUnit& step, LayoutUnit& position) |
| 74 { | 74 { |
| 75 ASSERT(firstChild()); | 75 ASSERT(firstChild()); |
| 76 | 76 |
| 77 RenderBlock* parentBlock = containingBlock(); | 77 RenderBlock* parentBlock = containingBlock(); |
| 78 | 78 |
| 79 // 1. Horizontal: Let step be the height of the first line box in boxes. | 79 // 1. Horizontal: Let step be the height of the first line box in boxes. |
| 80 // Vertical: Let step be the width of the first line box in boxes. | 80 // Vertical: Let step be the width of the first line box in boxes. |
| 81 step = m_cue->getWritingDirection() == TextTrackCue::Horizontal ? firstLineB
ox->height() : firstLineBox->width(); | 81 step = m_cue->getWritingDirection() == VTTCue::Horizontal ? firstLineBox->he
ight() : firstLineBox->width(); |
| 82 | 82 |
| 83 // 2. If step is zero, then jump to the step labeled done positioning below. | 83 // 2. If step is zero, then jump to the step labeled done positioning below. |
| 84 if (!step) | 84 if (!step) |
| 85 return false; | 85 return false; |
| 86 | 86 |
| 87 // 3. Let line position be the text track cue computed line position. | 87 // 3. Let line position be the text track cue computed line position. |
| 88 int linePosition = m_cue->calculateComputedLinePosition(); | 88 int linePosition = m_cue->calculateComputedLinePosition(); |
| 89 | 89 |
| 90 // 4. Vertical Growing Left: Add one to line position then negate it. | 90 // 4. Vertical Growing Left: Add one to line position then negate it. |
| 91 if (m_cue->getWritingDirection() == TextTrackCue::VerticalGrowingLeft) | 91 if (m_cue->getWritingDirection() == VTTCue::VerticalGrowingLeft) |
| 92 linePosition = -(linePosition + 1); | 92 linePosition = -(linePosition + 1); |
| 93 | 93 |
| 94 // 5. Let position be the result of multiplying step and line position. | 94 // 5. Let position be the result of multiplying step and line position. |
| 95 position = step * linePosition; | 95 position = step * linePosition; |
| 96 | 96 |
| 97 // 6. Vertical Growing Left: Decrease position by the width of the | 97 // 6. Vertical Growing Left: Decrease position by the width of the |
| 98 // bounding box of the boxes in boxes, then increase position by step. | 98 // bounding box of the boxes in boxes, then increase position by step. |
| 99 if (m_cue->getWritingDirection() == TextTrackCue::VerticalGrowingLeft) { | 99 if (m_cue->getWritingDirection() == VTTCue::VerticalGrowingLeft) { |
| 100 position -= width(); | 100 position -= width(); |
| 101 position += step; | 101 position += step; |
| 102 } | 102 } |
| 103 | 103 |
| 104 // 7. If line position is less than zero... | 104 // 7. If line position is less than zero... |
| 105 if (linePosition < 0) { | 105 if (linePosition < 0) { |
| 106 // Horizontal / Vertical: ... then increase position by the | 106 // Horizontal / Vertical: ... then increase position by the |
| 107 // height / width of the video's rendering area ... | 107 // height / width of the video's rendering area ... |
| 108 position += m_cue->getWritingDirection() == TextTrackCue::Horizontal ? p
arentBlock->height() : parentBlock->width(); | 108 position += m_cue->getWritingDirection() == VTTCue::Horizontal ? parentB
lock->height() : parentBlock->width(); |
| 109 | 109 |
| 110 // ... and negate step. | 110 // ... and negate step. |
| 111 step = -step; | 111 step = -step; |
| 112 } | 112 } |
| 113 | 113 |
| 114 return true; | 114 return true; |
| 115 } | 115 } |
| 116 | 116 |
| 117 void RenderTextTrackCue::placeBoxInDefaultPosition(LayoutUnit position, bool& sw
itched) | 117 void RenderVTTCue::placeBoxInDefaultPosition(LayoutUnit position, bool& switched
) |
| 118 { | 118 { |
| 119 // 8. Move all boxes in boxes ... | 119 // 8. Move all boxes in boxes ... |
| 120 if (m_cue->getWritingDirection() == TextTrackCue::Horizontal) | 120 if (m_cue->getWritingDirection() == VTTCue::Horizontal) { |
| 121 // Horizontal: ... down by the distance given by position | 121 // Horizontal: ... down by the distance given by position |
| 122 setY(y() + position); | 122 setY(y() + position); |
| 123 else | 123 } else { |
| 124 // Vertical: ... right by the distance given by position | 124 // Vertical: ... right by the distance given by position |
| 125 setX(x() + position); | 125 setX(x() + position); |
| 126 } |
| 126 | 127 |
| 127 // 9. Default: Remember the position of all the boxes in boxes as their | 128 // 9. Default: Remember the position of all the boxes in boxes as their |
| 128 // default position. | 129 // default position. |
| 129 m_fallbackPosition = FloatPoint(x(), y()); | 130 m_fallbackPosition = FloatPoint(x(), y()); |
| 130 | 131 |
| 131 // 10. Let switched be false. | 132 // 10. Let switched be false. |
| 132 switched = false; | 133 switched = false; |
| 133 } | 134 } |
| 134 | 135 |
| 135 bool RenderTextTrackCue::isOutside() const | 136 bool RenderVTTCue::isOutside() const |
| 136 { | 137 { |
| 137 return !containingBlock()->absoluteBoundingBoxRect().contains(absoluteConten
tBox()); | 138 return !containingBlock()->absoluteBoundingBoxRect().contains(absoluteConten
tBox()); |
| 138 } | 139 } |
| 139 | 140 |
| 140 bool RenderTextTrackCue::isOverlapping() const | 141 bool RenderVTTCue::isOverlapping() const |
| 141 { | 142 { |
| 142 for (RenderObject* box = previousSibling(); box; box = box->previousSibling(
)) { | 143 for (RenderObject* box = previousSibling(); box; box = box->previousSibling(
)) { |
| 143 IntRect boxRect = box->absoluteBoundingBoxRect(); | 144 IntRect boxRect = box->absoluteBoundingBoxRect(); |
| 144 | 145 |
| 145 if (absoluteBoundingBoxRect().intersects(boxRect)) | 146 if (absoluteBoundingBoxRect().intersects(boxRect)) |
| 146 return true; | 147 return true; |
| 147 } | 148 } |
| 148 | 149 |
| 149 return false; | 150 return false; |
| 150 } | 151 } |
| 151 | 152 |
| 152 bool RenderTextTrackCue::shouldSwitchDirection(InlineFlowBox* firstLineBox, Layo
utUnit step) const | 153 bool RenderVTTCue::shouldSwitchDirection(InlineFlowBox* firstLineBox, LayoutUnit
step) const |
| 153 { | 154 { |
| 154 LayoutUnit top = y(); | 155 LayoutUnit top = y(); |
| 155 LayoutUnit left = x(); | 156 LayoutUnit left = x(); |
| 156 LayoutUnit bottom = top + firstLineBox->height(); | 157 LayoutUnit bottom = top + firstLineBox->height(); |
| 157 LayoutUnit right = left + firstLineBox->width(); | 158 LayoutUnit right = left + firstLineBox->width(); |
| 158 | 159 |
| 159 // 12. Horizontal: If step is negative and the top of the first line | 160 // 12. Horizontal: If step is negative and the top of the first line |
| 160 // box in boxes is now above the top of the video's rendering area, | 161 // box in boxes is now above the top of the video's rendering area, |
| 161 // or if step is positive and the bottom of the first line box in | 162 // or if step is positive and the bottom of the first line box in |
| 162 // boxes is now below the bottom of the video's rendering area, jump | 163 // boxes is now below the bottom of the video's rendering area, jump |
| 163 // to the step labeled switch direction. | 164 // to the step labeled switch direction. |
| 164 LayoutUnit parentHeight = containingBlock()->height(); | 165 LayoutUnit parentHeight = containingBlock()->height(); |
| 165 if (m_cue->getWritingDirection() == TextTrackCue::Horizontal && ((step < 0 &
& top < 0) || (step > 0 && bottom > parentHeight))) | 166 if (m_cue->getWritingDirection() == VTTCue::Horizontal && ((step < 0 && top
< 0) || (step > 0 && bottom > parentHeight))) |
| 166 return true; | 167 return true; |
| 167 | 168 |
| 168 // 12. Vertical: If step is negative and the left edge of the first line | 169 // 12. Vertical: If step is negative and the left edge of the first line |
| 169 // box in boxes is now to the left of the left edge of the video's | 170 // box in boxes is now to the left of the left edge of the video's |
| 170 // rendering area, or if step is positive and the right edge of the | 171 // rendering area, or if step is positive and the right edge of the |
| 171 // first line box in boxes is now to the right of the right edge of | 172 // first line box in boxes is now to the right of the right edge of |
| 172 // the video's rendering area, jump to the step labeled switch direction. | 173 // the video's rendering area, jump to the step labeled switch direction. |
| 173 LayoutUnit parentWidth = containingBlock()->width(); | 174 LayoutUnit parentWidth = containingBlock()->width(); |
| 174 if (m_cue->getWritingDirection() != TextTrackCue::Horizontal && ((step < 0 &
& left < 0) || (step > 0 && right > parentWidth))) | 175 if (m_cue->getWritingDirection() != VTTCue::Horizontal && ((step < 0 && left
< 0) || (step > 0 && right > parentWidth))) |
| 175 return true; | 176 return true; |
| 176 | 177 |
| 177 return false; | 178 return false; |
| 178 } | 179 } |
| 179 | 180 |
| 180 void RenderTextTrackCue::moveBoxesByStep(LayoutUnit step) | 181 void RenderVTTCue::moveBoxesByStep(LayoutUnit step) |
| 181 { | 182 { |
| 182 // 13. Horizontal: Move all the boxes in boxes down by the distance | 183 // 13. Horizontal: Move all the boxes in boxes down by the distance |
| 183 // given by step. (If step is negative, then this will actually | 184 // given by step. (If step is negative, then this will actually |
| 184 // result in an upwards movement of the boxes in absolute terms.) | 185 // result in an upwards movement of the boxes in absolute terms.) |
| 185 if (m_cue->getWritingDirection() == TextTrackCue::Horizontal) | 186 if (m_cue->getWritingDirection() == VTTCue::Horizontal) |
| 186 setY(y() + step); | 187 setY(y() + step); |
| 187 | 188 |
| 188 // 13. Vertical: Move all the boxes in boxes right by the distance | 189 // 13. Vertical: Move all the boxes in boxes right by the distance |
| 189 // given by step. (If step is negative, then this will actually | 190 // given by step. (If step is negative, then this will actually |
| 190 // result in a leftwards movement of the boxes in absolute terms.) | 191 // result in a leftwards movement of the boxes in absolute terms.) |
| 191 else | 192 else |
| 192 setX(x() + step); | 193 setX(x() + step); |
| 193 } | 194 } |
| 194 | 195 |
| 195 bool RenderTextTrackCue::switchDirection(bool& switched, LayoutUnit& step) | 196 bool RenderVTTCue::switchDirection(bool& switched, LayoutUnit& step) |
| 196 { | 197 { |
| 197 // 15. Switch direction: Move all the boxes in boxes back to their | 198 // 15. Switch direction: Move all the boxes in boxes back to their |
| 198 // default position as determined in the step above labeled default. | 199 // default position as determined in the step above labeled default. |
| 199 setX(m_fallbackPosition.x()); | 200 setX(m_fallbackPosition.x()); |
| 200 setY(m_fallbackPosition.y()); | 201 setY(m_fallbackPosition.y()); |
| 201 | 202 |
| 202 // 16. If switched is true, jump to the step labeled done | 203 // 16. If switched is true, jump to the step labeled done |
| 203 // positioning below. | 204 // positioning below. |
| 204 if (switched) | 205 if (switched) |
| 205 return false; | 206 return false; |
| 206 | 207 |
| 207 // 17. Negate step. | 208 // 17. Negate step. |
| 208 step = -step; | 209 step = -step; |
| 209 | 210 |
| 210 // 18. Set switched to true. | 211 // 18. Set switched to true. |
| 211 switched = true; | 212 switched = true; |
| 212 return true; | 213 return true; |
| 213 } | 214 } |
| 214 | 215 |
| 215 void RenderTextTrackCue::repositionCueSnapToLinesSet() | 216 void RenderVTTCue::repositionCueSnapToLinesSet() |
| 216 { | 217 { |
| 217 InlineFlowBox* firstLineBox; | 218 InlineFlowBox* firstLineBox; |
| 218 LayoutUnit step; | 219 LayoutUnit step; |
| 219 LayoutUnit position; | 220 LayoutUnit position; |
| 220 | 221 |
| 221 if (!findFirstLineBox(firstLineBox)) | 222 if (!findFirstLineBox(firstLineBox)) |
| 222 return; | 223 return; |
| 223 | 224 |
| 224 if (!initializeLayoutParameters(firstLineBox, step, position)) | 225 if (!initializeLayoutParameters(firstLineBox, step, position)) |
| 225 return; | 226 return; |
| 226 | 227 |
| 227 bool switched; | 228 bool switched; |
| 228 placeBoxInDefaultPosition(position, switched); | 229 placeBoxInDefaultPosition(position, switched); |
| 229 | 230 |
| 230 // 11. Step loop: If none of the boxes in boxes would overlap any of the box
es | 231 // 11. Step loop: If none of the boxes in boxes would overlap any of the box
es |
| 231 // in output and all the boxes in output are within the video's rendering ar
ea | 232 // in output and all the boxes in output are within the video's rendering ar
ea |
| 232 // then jump to the step labeled done positioning. | 233 // then jump to the step labeled done positioning. |
| 233 while (isOutside() || isOverlapping()) { | 234 while (isOutside() || isOverlapping()) { |
| 234 if (!shouldSwitchDirection(firstLineBox, step)) | 235 if (!shouldSwitchDirection(firstLineBox, step)) { |
| 235 // 13. Move all the boxes in boxes ... | 236 // 13. Move all the boxes in boxes ... |
| 236 // 14. Jump back to the step labeled step loop. | 237 // 14. Jump back to the step labeled step loop. |
| 237 moveBoxesByStep(step); | 238 moveBoxesByStep(step); |
| 238 else if (!switchDirection(switched, step)) | 239 } else if (!switchDirection(switched, step)) { |
| 239 break; | 240 break; |
| 241 } |
| 240 | 242 |
| 241 // 19. Jump back to the step labeled step loop. | 243 // 19. Jump back to the step labeled step loop. |
| 242 } | 244 } |
| 243 | 245 |
| 244 // Acommodate extra top and bottom padding, border or margin. | 246 // Acommodate extra top and bottom padding, border or margin. |
| 245 // Note: this is supported only for internal UA styling, not through the cue
selector. | 247 // Note: this is supported only for internal UA styling, not through the cue
selector. |
| 246 if (hasInlineDirectionBordersPaddingOrMargin()) { | 248 if (hasInlineDirectionBordersPaddingOrMargin()) { |
| 247 IntRect containerRect = containingBlock()->absoluteBoundingBoxRect(); | 249 IntRect containerRect = containingBlock()->absoluteBoundingBoxRect(); |
| 248 IntRect cueRect = absoluteBoundingBoxRect(); | 250 IntRect cueRect = absoluteBoundingBoxRect(); |
| 249 | 251 |
| 250 int topOverflow = cueRect.y() - containerRect.y(); | 252 int topOverflow = cueRect.y() - containerRect.y(); |
| 251 int bottomOverflow = containerRect.y() + containerRect.height() - cueRec
t.y() - cueRect.height(); | 253 int bottomOverflow = containerRect.y() + containerRect.height() - cueRec
t.y() - cueRect.height(); |
| 252 | 254 |
| 253 int adjustment = 0; | 255 int adjustment = 0; |
| 254 if (topOverflow < 0) | 256 if (topOverflow < 0) |
| 255 adjustment = -topOverflow; | 257 adjustment = -topOverflow; |
| 256 else if (bottomOverflow < 0) | 258 else if (bottomOverflow < 0) |
| 257 adjustment = bottomOverflow; | 259 adjustment = bottomOverflow; |
| 258 | 260 |
| 259 if (adjustment) | 261 if (adjustment) |
| 260 setY(y() + adjustment); | 262 setY(y() + adjustment); |
| 261 } | 263 } |
| 262 } | 264 } |
| 263 | 265 |
| 264 void RenderTextTrackCue::repositionCueSnapToLinesNotSet() | 266 void RenderVTTCue::repositionCueSnapToLinesNotSet() |
| 265 { | 267 { |
| 266 // FIXME: Implement overlapping detection when snap-to-lines is not set. htt
p://wkb.ug/84296 | 268 // FIXME: Implement overlapping detection when snap-to-lines is not set. htt
p://wkb.ug/84296 |
| 267 } | 269 } |
| 268 | 270 |
| 269 } // namespace WebCore | 271 } // namespace WebCore |
| 270 | 272 |
| OLD | NEW |