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 |