Commit 6fb78300 authored by fs@opera.com's avatar fs@opera.com

Sync snap-to-lines VTT cue layout steps with spec

 * Sync step documentation ('line position' -> 'line' and similar.)
 * Remove remnants of 'best position' and re-number steps.
 * Implement new cue dodging logic.

BUG=301580

Review URL: https://codereview.chromium.org/1306833003

git-svn-id: svn://svn.chromium.org/blink/trunk@200987 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 78efd70d
<!DOCTYPE html>
<script src="../media-file.js"></script>
<script>
var mediaFile = findMediaFile('video', '../content/test');
</script>
<style>
.container {
position: relative;
display: inline-block;
width: 320px;
height: 240px;
}
.cue {
position: absolute;
top: 0;
left: 0;
right: 0;
overflow: hidden;
}
.cue.start {
text-align: start;
}
.cue > span {
font-family: sans-serif;
background: green;
color: green;
font-size: 120px;
padding: 2px;
}
</style>
<div class="container">
<video><script>document.currentScript.parentNode.src = mediaFile;</script></video>
<div class=video>
<div class="cue start"><span>PAS</span></div>
</div>
</div>
<!DOCTYPE html>
<script src="../media-file.js"></script>
<script>
var mediaFile = findMediaFile('video', '../content/test');
function addCue(track, cueData) {
var cue = new VTTCue(0, 10, 'XXX');
for (var prop in cueData)
cue[prop] = cueData[prop];
track.addCue(cue);
}
</script>
<style>
video::cue {
font-size: 120px;
color: green;
background-color: green;
}
</style>
<video>
<script>
var video = document.currentScript.parentNode;
var track = video.addTextTrack('subtitles');
addCue(track, { line: 0, align: 'start', text: 'PAS' });
// This cue will not fit, and will not be displayed.
addCue(track, { line: 1, align: 'start', text: 'FAI' });
track.mode = 'showing';
video.src = mediaFile;
</script>
</video>
......@@ -189,8 +189,8 @@ void VTTCueBox::applyCSSProperties(const VTTDisplayParameters& displayParameters
// The 'text-align' property on the (root) List of WebVTT Node Objects must
// be set to the value in the second cell of the row of the table below
// whose first cell is the value of the corresponding cue's text track cue
// alignment:
// whose first cell is the value of the corresponding cue's WebVTT cue
// text alignment:
setInlineStyleProperty(CSSPropertyTextAlign, displayParameters.textAlign);
// TODO(philipj): The position adjustment for non-snap-to-lines cues has
......@@ -324,10 +324,9 @@ void VTTCue::line(DoubleOrAutoKeyword& result) const
void VTTCue::setLine(const DoubleOrAutoKeyword& position)
{
// http://dev.w3.org/html5/webvtt/#dfn-vttcue-line
// On setting, the text track cue line position must be set to the new
// value; if the new value is the string "auto", then it must be
// interpreted as the special value auto.
// ("auto" is translated to NaN.)
// On setting, the WebVTT cue line must be set to the new value; if the new
// value is the string "auto", then it must be interpreted as the special
// value auto. ("auto" is translated to NaN.)
float floatPosition;
if (position.isAutoKeyword()) {
if (lineIsAuto())
......@@ -362,9 +361,9 @@ void VTTCue::setPosition(const DoubleOrAutoKeyword& position, ExceptionState& ex
{
// http://dev.w3.org/html5/webvtt/#dfn-vttcue-position
// On setting, if the new value is negative or greater than 100, then an
// IndexSizeError exception must be thrown. Otherwise, the text track cue
// text position must be set to the new value; if the new value is the
// string "auto", then it must be interpreted as the special value auto.
// IndexSizeError exception must be thrown. Otherwise, the WebVTT cue
// position must be set to the new value; if the new value is the string
// "auto", then it must be interpreted as the special value auto.
float floatPosition;
if (position.isAutoKeyword()) {
if (textPositionIsAuto())
......@@ -386,13 +385,13 @@ void VTTCue::setPosition(const DoubleOrAutoKeyword& position, ExceptionState& ex
void VTTCue::setSize(double size, ExceptionState& exceptionState)
{
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-texttrackcue-size
// On setting, if the new value is negative or greater than 100, then throw an IndexSizeError
// exception. Otherwise, set the text track cue size to the new value.
// http://dev.w3.org/html5/webvtt/#dfn-vttcue-size
// On setting, if the new value is negative or greater than 100, then throw
// an IndexSizeError exception.
if (isInvalidPercentage(size, exceptionState))
return;
// Otherwise, set the text track cue line position to the new value.
// Otherwise, set the WebVTT cue size to the new value.
float floatSize = narrowPrecisionToFloat(size);
if (m_cueSize == floatSize)
return;
......@@ -498,33 +497,32 @@ void VTTCue::setRegionId(const String& regionId)
float VTTCue::calculateComputedLinePosition() const
{
// http://dev.w3.org/html5/webvtt/#dfn-text-track-cue-computed-line-position
// A text track cue has a text track cue computed line position whose value
// is that returned by the following algorithm, which is defined in terms
// of the other aspects of the cue:
// 1. If the text track cue line position is numeric, the text track cue
// snap-to-lines flag of the text track cue is not set, and the text
// track cue line position is negative or greater than 100, then return
// 100 and abort these steps.
// http://dev.w3.org/html5/webvtt/#dfn-cue-computed-line
// A WebVTT cue has a computed line whose value is that returned by the
// following algorithm, which is defined in terms of the other aspects of
// the cue:
// 1. If the line is numeric, the WebVTT cue snap-to-lines flag of the
// WebVTT cue is not set, and the line is negative or greater than 100,
// then return 100 and abort these steps.
if (!lineIsAuto() && !m_snapToLines && isInvalidPercentage(m_linePosition))
return 100;
// 2. If the text track cue line position is numeric, return the value of
// the text track cue line position and abort these steps. (Either the
// text track cue snap-to-lines flag is set, so any value, not just
// those in the range 0..100, is valid, or the value is in the range
// 0..100 and is thus valid regardless of the value of that flag.)
// 2. If the line is numeric, return the value of the WebVTT cue line and
// abort these steps. (Either the WebVTT cue snap-to-lines flag is set,
// so any value, not just those in the range 0..100, is valid, or the
// value is in the range 0..100 and is thus valid regardless of the
// value of that flag.)
if (!lineIsAuto())
return m_linePosition;
// 3. If the text track cue snap-to-lines flag of the text track cue is not
// set, return the value 100 and abort these steps. (The text track cue
// line position is the special value auto.)
// 3. If the WebVTT cue snap-to-lines flag of the WebVTT cue is not set,
// return the value 100 and abort these steps. (The WebVTT cue line is
// the special value auto.)
if (!m_snapToLines)
return 100;
// 4. Let cue be the text track cue.
// 4. Let cue be the WebVTT cue.
// 5. If cue is not in a list of cues of a text track, or if that text
// track is not in the list of text tracks of a media element, return -1
// and abort these steps.
......@@ -598,24 +596,23 @@ static CSSValueID determineTextDirection(DocumentFragment* vttRoot)
float VTTCue::calculateComputedTextPosition() const
{
// http://dev.w3.org/html5/webvtt/#dfn-text-track-cue-computed-text-position
// http://dev.w3.org/html5/webvtt/#dfn-cue-computed-position
// 1. If the text track cue text position is numeric, then return the value
// of the text track cue text position and abort these steps. (Otherwise,
// the text track cue text position is the special value auto.)
// 1. If the position is numeric, then return the value of the position and
// abort these steps. (Otherwise, the position is the special value auto.)
if (!textPositionIsAuto())
return m_textPosition;
switch (m_cueAlignment) {
// 2. If the text track cue text alignment is start or left, return 0 and abort these steps.
// 2. If the cue text alignment is start or left, return 0 and abort these steps.
case Start:
case Left:
return 0;
// 3. If the text track cue text alignment is end or right, return 100 and abort these steps.
// 3. If the cue text alignment is end or right, return 100 and abort these steps.
case End:
case Right:
return 100;
// 4. If the text track cue text alignment is middle, return 50 and abort these steps.
// 4. If the cue text alignment is middle, return 50 and abort these steps.
case Middle:
return 50;
default:
......@@ -659,11 +656,10 @@ VTTDisplayParameters VTTCue::calculateDisplayParameters() const
// VTTCueBox::applyCSSProperties need not have access to a VTTCue.
displayParameters.textAlign = displayAlignmentMap[cueAlignment()];
// 3. If the text track cue writing direction is horizontal, then let
// block-flow be 'tb'. Otherwise, if the text track cue writing direction is
// vertical growing left, then let block-flow be 'lr'. Otherwise, the text
// track cue writing direction is vertical growing right; let block-flow be
// 'rl'.
// 3. If the cue writing direction is horizontal, then let block-flow be
// 'tb'. Otherwise, if the cue writing direction is vertical growing left,
// then let block-flow be 'lr'. Otherwise, the cue writing direction is
// vertical growing right; let block-flow be 'rl'.
displayParameters.writingMode = displayWritingModeMap[m_writingDirection];
// Resolve the cue alignment to one of the values {start, end, middle}.
......@@ -684,11 +680,11 @@ VTTDisplayParameters VTTCue::calculateDisplayParameters() const
ASSERT_NOT_REACHED();
}
// 5. If the text track cue size is less than maximum size, then let size
// be text track cue size. Otherwise, let size be maximum size.
// 5. If the cue size is less than maximum size, then let size
// be cue size. Otherwise, let size be maximum size.
displayParameters.size = std::min(m_cueSize, maximumSize);
// 6. If the text track cue writing direction is horizontal, then let width
// 6. If the cue writing direction is horizontal, then let width
// be 'size vw' and height be 'auto'. Otherwise, let width be 'auto' and
// height be 'size vh'. (These are CSS values used by the next section to
// set CSS properties for the rendering; 'vw' and 'vh' are CSS units.)
......@@ -727,8 +723,8 @@ VTTDisplayParameters VTTCue::calculateDisplayParameters() const
}
}
// A text track cue has a text track cue computed line position whose value
// is defined in terms of the other aspects of the cue.
// A cue has a computed line whose value is defined in terms of
// the other aspects of the cue.
float computedLinePosition = calculateComputedLinePosition();
// 8. Determine the value of whichever of x-position or y-position is not
......@@ -886,16 +882,16 @@ void VTTCue::updateDisplay(HTMLDivElement& container)
region = track()->regions()->getRegionById(regionId());
if (!region) {
// If cue has an empty text track cue region identifier or there is no
// WebVTT region whose region identifier is identical to cue's text
// track cue region identifier, run the following substeps:
// If cue has an empty region identifier or there is no WebVTT region
// whose region identifier is identical to cue's region identifier, run
// the following substeps:
if (displayBox->hasChildren() && !container.contains(displayBox.get())) {
// Note: the display tree of a cue is removed when the active flag of the cue is unset.
container.appendChild(displayBox);
}
} else {
// Let region be the WebVTT region whose region identifier
// matches the text track cue region identifier of cue.
// Let region be the WebVTT region whose region identifier matches the
// region identifier of cue.
RefPtrWillBeRawPtr<HTMLDivElement> regionNode = region->getDisplayTree(document());
// Append the region to the viewport, if it was not already.
......@@ -978,13 +974,13 @@ void VTTCue::parseSettings(const String& inputString)
case Vertical: {
// If name is a case-sensitive match for "vertical"
// 1. If value is a case-sensitive match for the string "rl", then
// let cue's text track cue writing direction be vertical
// let cue's WebVTT cue writing direction be vertical
// growing left.
if (input.scanRun(valueRun, verticalGrowingLeftKeyword()))
m_writingDirection = VerticalGrowingLeft;
// 2. Otherwise, if value is a case-sensitive match for the string
// "lr", then let cue's text track cue writing direction be
// "lr", then let cue's WebVTT cue writing direction be
// vertical growing right.
else if (input.scanRun(valueRun, verticalGrowingRightKeyword()))
m_writingDirection = VerticalGrowingRight;
......@@ -1021,10 +1017,10 @@ void VTTCue::parseSettings(const String& inputString)
}
if (!input.isAt(valueRun.end()))
break;
// 5. Let cue's text track cue line position be number.
// 5. Let cue's WebVTT cue line be number.
m_linePosition = number;
// 6. If the last character in linepos is a U+0025 PERCENT SIGN
// character (%), then let cue's text track cue snap-to-lines
// character (%), then let cue's WebVTT cue snap-to-lines
// flag be false. Otherwise, let it be true.
m_snapToLines = !isPercentage;
// Steps 7 - 9 skipped.
......@@ -1042,7 +1038,7 @@ void VTTCue::parseSettings(const String& inputString)
break;
if (!input.isAt(valueRun.end()))
break;
// 4. Let cue's text track cue text position be number.
// 4. Let cue's cue position be number.
m_textPosition = number;
// Steps 5 - 7 skipped.
break;
......@@ -1057,34 +1053,34 @@ void VTTCue::parseSettings(const String& inputString)
break;
if (!input.isAt(valueRun.end()))
break;
// 2. Let cue's text track cue size be number.
// 2. Let cue's WebVTT cue size be number.
m_cueSize = number;
break;
}
case Align: {
// If name is a case-sensitive match for "align"
// 1. If value is a case-sensitive match for the string "start",
// then let cue's text track cue alignment be start alignment.
// then let cue's WebVTT cue text alignment be start alignment.
if (input.scanRun(valueRun, startKeyword()))
m_cueAlignment = Start;
// 2. If value is a case-sensitive match for the string "middle",
// then let cue's text track cue alignment be middle alignment.
// then let cue's WebVTT cue text alignment be middle alignment.
else if (input.scanRun(valueRun, middleKeyword()))
m_cueAlignment = Middle;
// 3. If value is a case-sensitive match for the string "end", then
// let cue's text track cue alignment be end alignment.
// let cue's WebVTT cue text alignment be end alignment.
else if (input.scanRun(valueRun, endKeyword()))
m_cueAlignment = End;
// 4. If value is a case-sensitive match for the string "left",
// then let cue's text track cue alignment be left alignment.
// then let cue's WebVTT cue text alignment be left alignment.
else if (input.scanRun(valueRun, leftKeyword()))
m_cueAlignment = Left;
// 5. If value is a case-sensitive match for the string "right",
// then let cue's text track cue alignment be right alignment.
// then let cue's WebVTT cue text alignment be right alignment.
else if (input.scanRun(valueRun, rightKeyword()))
m_cueAlignment = Right;
break;
......
......@@ -78,16 +78,16 @@ LayoutUnit SnapToLinesLayouter::computeInitialPositionAdjustment(LayoutUnit& ste
{
ASSERT(std::isfinite(m_cueBox.snapToLinesPosition()));
// 6. Let line position be the text track cue computed line position.
// 7. Round line position to an integer by adding 0.5 and then flooring it.
// 6. Let line be cue's computed line.
// 7. Round line to an integer by adding 0.5 and then flooring it.
LayoutUnit linePosition = floorf(m_cueBox.snapToLinesPosition() + 0.5f);
WritingMode writingMode = m_cueBox.style()->writingMode();
// 8. Vertical Growing Left: Add one to line position then negate it.
// 8. Vertical Growing Left: Add one to line then negate it.
if (writingMode == RightToLeftWritingMode)
linePosition = -(linePosition + 1);
// 9. Let position be the result of multiplying step and line position.
// 9. Let position be the result of multiplying step and line offset.
LayoutUnit position = step * linePosition;
// 10. Vertical Growing Left: Decrease position by the width of the
......@@ -97,12 +97,11 @@ LayoutUnit SnapToLinesLayouter::computeInitialPositionAdjustment(LayoutUnit& ste
position += step;
}
// 11. If line position is less than zero...
// 11. If line is less than zero...
if (linePosition < 0) {
LayoutBlock* parentBlock = m_cueBox.containingBlock();
// Horizontal / Vertical: ... then increase position by the
// height / width of the video's rendering area ...
// ... then increase position by max dimension ...
position += blink::isHorizontalWritingMode(writingMode) ? parentBlock->size().height() : parentBlock->size().width();
// ... and negate step.
......@@ -134,7 +133,7 @@ bool SnapToLinesLayouter::isOverlapping() const
bool SnapToLinesLayouter::shouldSwitchDirection(InlineFlowBox* firstLineBox, LayoutUnit step) const
{
// 21. Horizontal: If step is negative and the top of the first line box in
// 17. Horizontal: If step is negative and the top of the first line box in
// boxes is now above the top of the title area, or if step is positive and
// the bottom of the first line box in boxes is now below the bottom of the
// title area, jump to the step labeled switch direction.
......@@ -181,31 +180,20 @@ void SnapToLinesLayouter::layout()
// position.
m_specifiedPosition = m_cueBox.location();
// 14. Let best position be null. It will hold a position for boxes, much
// like specified position in the previous step.
// 15. Let best position score be null.
// 16. Let switched be false.
// XX. Let switched be false.
bool switched = false;
// Step 17 skipped. (margin == 0; title area == video area)
// Step 14 skipped. (margin == 0; title area == video area)
// 18. Step loop: If none of the boxes in boxes would overlap any of the
// 15. Step loop: If none of the boxes in boxes would overlap any of the
// boxes in output, and all of the boxes in output are entirely within the
// title area box, then jump to the step labeled done positioning below.
while (isOutside() || isOverlapping()) {
// 19. Let current position score be the percentage of the area of the
// 16. Let current position score be the percentage of the area of the
// bounding box of the boxes in boxes that is outside the title area
// box.
// 20. If best position is null (i.e. this is the first run through
// this loop, switched is still false, the boxes in boxes are at their
// specified position, and best position score is still null), or if
// current position score is a lower percentage than that in best
// position score, then remember the position of all the boxes in boxes
// as their best position, and set best position score to current
// position score.
if (!shouldSwitchDirection(firstLineBox, step)) {
// 22. Horizontal: Move all the boxes in boxes down by the distance
// 18. Horizontal: Move all the boxes in boxes down by the distance
// given by step. (If step is negative, then this will actually
// result in an upwards movement of the boxes in absolute terms.)
// Vertical: Move all the boxes in boxes right by the distance
......@@ -213,30 +201,31 @@ void SnapToLinesLayouter::layout()
// result in a leftwards movement of the boxes in absolute terms.)
moveBoxesBy(step);
// 23. Jump back to the step labeled step loop.
// 19. Jump back to the step labeled step loop.
continue;
}
// 24. Switch direction: If switched is true, then move all the boxes in
// boxes back to their best position, and jump to the step labeled done
// positioning below.
// 20. Switch direction: If switched is true, then remove all the boxes
// in boxes, and jump to the step labeled done positioning below.
if (switched) {
// This does not "remove" the boxes, but rather just pushes them
// out of the viewport. Otherwise we'd need to mutate the layout
// tree during layout.
m_cueBox.setLogicalTop(m_cueBox.containingBlock()->logicalHeight() + 1);
break;
}
// 25. Otherwise, move all the boxes in boxes back to their specified
// 21. Otherwise, move all the boxes in boxes back to their specified
// position as determined in the earlier step.
m_cueBox.setLocation(m_specifiedPosition);
// XX. If switched is true, jump to the step labeled done
// positioning below.
if (switched)
break;
// 26. Negate step.
// 22. Negate step.
step = -step;
// 27. Set switched to true.
// 23. Set switched to true.
switched = true;
// 28. Jump back to the step labeled step loop.
// 24. Jump back to the step labeled step loop.
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment