TextTrackCue::TextTrackCue(ScriptExecutionContext* context, const String& id, double start, double end, const String& content, const String& settings, bool pauseOnExit) : m_id(id) , m_startTime(start) , m_endTime(end) , m_content(content) , m_linePosition(undefinedPosition) , m_computedLinePosition(undefinedPosition) , m_textPosition(50) , m_cueSize(100) , m_cueIndex(invalidCueIndex) , m_writingDirection(Horizontal) , m_cueAlignment(Middle) , m_scriptExecutionContext(context) , m_isActive(false) , m_pauseOnExit(pauseOnExit) , m_snapToLines(true) , m_displayTreeShouldChange(true) , m_displayTree(HTMLDivElement::create(static_cast<Document*>(context))) , m_displayXPosition(undefinedPosition) , m_displayYPosition(undefinedPosition) { ASSERT(m_scriptExecutionContext->isDocument()); // The text track cue writing directions are directly relatd to the // block-flow element, which can be set through the CSS writing modes. m_displayWritingModeMap[Horizontal] = CSSValueHorizontalTb; m_displayWritingModeMap[VerticalGrowingLeft] = CSSValueVerticalLr; m_displayWritingModeMap[VerticalGrowingRight] = CSSValueVerticalRl; parseSettings(settings); // 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. m_computedLinePosition = calculateComputedLinePosition(); }
void VTTCue::setLine(int position, ExceptionState& exceptionState) { // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-texttrackcue-line // On setting, if the text track cue snap-to-lines flag is not set, and the new // value is negative or greater than 100, then throw an IndexSizeError exception. if (!m_snapToLines && (position < 0 || position > 100)) { exceptionState.throwDOMException(IndexSizeError, "The snap-to-lines flag is not set, and the value provided (" + String::number(position) + ") is not between 0 and 100."); return; } // Otherwise, set the text track cue line position to the new value. if (m_linePosition == position) return; cueWillChange(); m_linePosition = position; m_computedLinePosition = calculateComputedLinePosition(); cueDidChange(); }
void TextTrackCue::setLine(int position, ExceptionCode& ec) { // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-texttrackcue-line // On setting, if the text track cue snap-to-lines flag is not set, and the new // value is negative or greater than 100, then throw an IndexSizeError exception. if (!m_snapToLines && (position < 0 || position > 100)) { ec = INDEX_SIZE_ERR; return; } // Otherwise, set the text track cue line position to the new value. if (m_linePosition == position) return; cueWillChange(); m_linePosition = position; m_computedLinePosition = calculateComputedLinePosition(); cueDidChange(); }
TextTrackCue::TextTrackCue(ScriptExecutionContext* context, double start, double end, const String& content) : m_startTime(start) , m_endTime(end) , m_content(content) , m_linePosition(undefinedPosition) , m_computedLinePosition(undefinedPosition) , m_textPosition(50) , m_cueSize(100) , m_cueIndex(invalidCueIndex) , m_writingDirection(Horizontal) , m_cueAlignment(Middle) , m_documentFragment(0) , m_scriptExecutionContext(context) , m_isActive(false) , m_pauseOnExit(false) , m_snapToLines(true) , m_hasInnerTimestamps(false) , m_pastDocumentNodes(HTMLDivElement::create(static_cast<Document*>(context))) , m_futureDocumentNodes(HTMLDivElement::create(static_cast<Document*>(context))) , m_displayTreeShouldChange(true) , m_displayTree(TextTrackCueBox::create(static_cast<Document*>(m_scriptExecutionContext), this)) { ASSERT(m_scriptExecutionContext->isDocument()); // 4. If the text track cue writing direction is horizontal, then let // writing-mode be 'horizontal-tb'. Otherwise, if the text track cue writing // direction is vertical growing left, then let writing-mode be // 'vertical-rl'. Otherwise, the text track cue writing direction is // vertical growing right; let writing-mode be 'vertical-lr'. m_displayWritingModeMap[Horizontal] = CSSValueHorizontalTb; m_displayWritingModeMap[VerticalGrowingLeft] = CSSValueVerticalRl; m_displayWritingModeMap[VerticalGrowingRight] = CSSValueVerticalLr; // 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. m_computedLinePosition = calculateComputedLinePosition(); }
void VTTCue::calculateDisplayParameters() { createVTTNodeTree(); // Steps 10.2, 10.3 m_displayDirection = determineTextDirection(m_vttNodeTree.get()); if (m_displayDirection == CSSValueRtl) UseCounter::count(document(), UseCounter::VTTCueRenderRtl); // 10.4 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'. // The above step is done through the writing direction static map. // 10.5 Determine the value of maximum size for cue as per the appropriate // rules from the following list: int maximumSize = m_textPosition; if ((m_writingDirection == Horizontal && m_cueAlignment == Start && m_displayDirection == CSSValueLtr) || (m_writingDirection == Horizontal && m_cueAlignment == End && m_displayDirection == CSSValueRtl) || (m_writingDirection == Horizontal && m_cueAlignment == Left) || (m_writingDirection == VerticalGrowingLeft && (m_cueAlignment == Start || m_cueAlignment == Left)) || (m_writingDirection == VerticalGrowingRight && (m_cueAlignment == Start || m_cueAlignment == Left))) { maximumSize = 100 - m_textPosition; } else if ((m_writingDirection == Horizontal && m_cueAlignment == End && m_displayDirection == CSSValueLtr) || (m_writingDirection == Horizontal && m_cueAlignment == Start && m_displayDirection == CSSValueRtl) || (m_writingDirection == Horizontal && m_cueAlignment == Right) || (m_writingDirection == VerticalGrowingLeft && (m_cueAlignment == End || m_cueAlignment == Right)) || (m_writingDirection == VerticalGrowingRight && (m_cueAlignment == End || m_cueAlignment == Right))) { maximumSize = m_textPosition; } else if (m_cueAlignment == Middle) { maximumSize = m_textPosition <= 50 ? m_textPosition : (100 - m_textPosition); maximumSize = maximumSize * 2; } else { ASSERT_NOT_REACHED(); } // 10.6 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. m_displaySize = std::min(m_cueSize, maximumSize); // FIXME: Understand why step 10.7 is missing (just a copy/paste error?) // Could be done within a spec implementation check - http://crbug.com/301580 // 10.8 Determine the value of x-position or y-position for cue as per the // appropriate rules from the following list: if (m_writingDirection == Horizontal) { switch (m_cueAlignment) { case Start: if (m_displayDirection == CSSValueLtr) m_displayPosition.first = m_textPosition; else m_displayPosition.first = 100 - m_textPosition - m_displaySize; break; case End: if (m_displayDirection == CSSValueRtl) m_displayPosition.first = 100 - m_textPosition; else m_displayPosition.first = m_textPosition - m_displaySize; break; case Left: if (m_displayDirection == CSSValueLtr) m_displayPosition.first = m_textPosition; else m_displayPosition.first = 100 - m_textPosition; break; case Right: if (m_displayDirection == CSSValueLtr) m_displayPosition.first = m_textPosition - m_displaySize; else m_displayPosition.first = 100 - m_textPosition - m_displaySize; break; case Middle: if (m_displayDirection == CSSValueLtr) m_displayPosition.first = m_textPosition - m_displaySize / 2; else m_displayPosition.first = 100 - m_textPosition - m_displaySize / 2; break; default: ASSERT_NOT_REACHED(); } } else { // Cases for m_writingDirection being VerticalGrowing{Left|Right} switch (m_cueAlignment) { case Start: case Left: m_displayPosition.second = m_textPosition; break; case End: case Right: m_displayPosition.second = m_textPosition - m_displaySize; break; case Middle: m_displayPosition.second = m_textPosition - m_displaySize / 2; break; default: ASSERT_NOT_REACHED(); } } // 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. m_computedLinePosition = calculateComputedLinePosition(); // 10.9 Determine the value of whichever of x-position or y-position is not // yet calculated for cue as per the appropriate rules from the following // list: if (m_snapToLines && m_displayPosition.second == undefinedPosition && m_writingDirection == Horizontal) m_displayPosition.second = 0; if (!m_snapToLines && m_displayPosition.second == undefinedPosition && m_writingDirection == Horizontal) m_displayPosition.second = m_computedLinePosition; if (m_snapToLines && m_displayPosition.first == undefinedPosition && (m_writingDirection == VerticalGrowingLeft || m_writingDirection == VerticalGrowingRight)) m_displayPosition.first = 0; if (!m_snapToLines && (m_writingDirection == VerticalGrowingLeft || m_writingDirection == VerticalGrowingRight)) m_displayPosition.first = m_computedLinePosition; }
void TextTrackCue::calculateDisplayParameters() { // Steps 10.2, 10.3 determineTextDirection(); // 10.4 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'. m_displayWritingMode = m_displayWritingModeMap[m_writingDirection]; // 10.5 Determine the value of maximum size for cue as per the appropriate // rules from the following list: int maximumSize = m_textPosition; if ((m_writingDirection == Horizontal && m_cueAlignment == Start && m_displayDirection == CSSValueLtr) || (m_writingDirection == Horizontal && m_cueAlignment == End && m_displayDirection == CSSValueRtl) || (m_writingDirection == VerticalGrowingLeft && m_cueAlignment == Start) || (m_writingDirection == VerticalGrowingRight && m_cueAlignment == Start)) { maximumSize = 100 - m_textPosition; } else if ((m_writingDirection == Horizontal && m_cueAlignment == End && m_displayDirection == CSSValueLtr) || (m_writingDirection == Horizontal && m_cueAlignment == Start && m_displayDirection == CSSValueRtl) || (m_writingDirection == VerticalGrowingLeft && m_cueAlignment == End) || (m_writingDirection == VerticalGrowingRight && m_cueAlignment == End)) { maximumSize = m_textPosition; } else if (m_cueAlignment == Middle) { maximumSize = m_textPosition <= 50 ? m_textPosition : (100 - m_textPosition); maximumSize = maximumSize * 2; } // 10.6 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. m_displaySize = std::min(m_cueSize, maximumSize); // 10.8 Determine the value of x-position or y-position for cue as per the // appropriate rules from the following list: if (m_writingDirection == Horizontal) { if (m_cueAlignment == Start) { if (m_displayDirection == CSSValueLtr) m_displayPosition.first = m_textPosition; else m_displayPosition.first = 100 - m_textPosition - m_displaySize; } else if (m_cueAlignment == End) { if (m_displayDirection == CSSValueRtl) m_displayPosition.first = 100 - m_textPosition; else m_displayPosition.first = m_textPosition - m_displaySize; } } if ((m_writingDirection == VerticalGrowingLeft && m_cueAlignment == Start) || (m_writingDirection == VerticalGrowingRight && m_cueAlignment == Start)) { m_displayPosition.second = m_textPosition; } else if ((m_writingDirection == VerticalGrowingLeft && m_cueAlignment == End) || (m_writingDirection == VerticalGrowingRight && m_cueAlignment == End)) { m_displayPosition.second = 100 - m_textPosition; } if (m_writingDirection == Horizontal && m_cueAlignment == Middle) { if (m_displayDirection == CSSValueLtr) m_displayPosition.first = m_textPosition - m_displaySize / 2; else m_displayPosition.first = 100 - m_textPosition - m_displaySize / 2; } if ((m_writingDirection == VerticalGrowingLeft && m_cueAlignment == Middle) || (m_writingDirection == VerticalGrowingRight && m_cueAlignment == Middle)) m_displayPosition.second = m_textPosition - m_displaySize / 2; // 10.9 Determine the value of whichever of x-position or y-position is not // yet calculated for cue as per the appropriate rules from the following // list: if (m_snapToLines && m_displayPosition.second == undefinedPosition && m_writingDirection == Horizontal) m_displayPosition.second = 0; if (!m_snapToLines && m_displayPosition.second == undefinedPosition && m_writingDirection == Horizontal) m_displayPosition.second = m_computedLinePosition; if (m_snapToLines && m_displayPosition.first == undefinedPosition && (m_writingDirection == VerticalGrowingLeft || m_writingDirection == VerticalGrowingRight)) m_displayPosition.first = 0; if (!m_snapToLines && (m_writingDirection == VerticalGrowingLeft || m_writingDirection == VerticalGrowingRight)) m_displayPosition.first = m_computedLinePosition; // 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. m_computedLinePosition = calculateComputedLinePosition(); }
VTTDisplayParameters VTTCue::calculateDisplayParameters() const { // http://dev.w3.org/html5/webvtt/#dfn-apply-webvtt-cue-settings VTTDisplayParameters displayParameters; // Steps 1 and 2. displayParameters.direction = determineTextDirection(m_vttNodeTree.get()); if (displayParameters.direction == CSSValueRtl) UseCounter::count(document(), UseCounter::VTTCueRenderRtl); // Note: The 'text-align' property is also determined here so that // VTTCueBox::applyCSSProperties need not have access to a VTTCue. displayParameters.textAlign = displayAlignmentMap[getCueAlignment()]; // 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}. CueAlignment computedCueAlignment = calculateComputedCueAlignment(); // 4. Determine the value of maximum size for cue as per the appropriate // rules from the following list: float computedTextPosition = calculateComputedTextPosition(); float maximumSize = computedTextPosition; if (computedCueAlignment == Start) { maximumSize = 100 - computedTextPosition; } else if (computedCueAlignment == End) { maximumSize = computedTextPosition; } else if (computedCueAlignment == Middle) { maximumSize = computedTextPosition <= 50 ? computedTextPosition : (100 - computedTextPosition); maximumSize = maximumSize * 2; } else { ASSERT_NOT_REACHED(); } // 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 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.) // (Emulated in VTTCueBox::applyCSSProperties.) // 7. Determine the value of x-position or y-position for cue as per the // appropriate rules from the following list: if (m_writingDirection == Horizontal) { switch (computedCueAlignment) { case Start: displayParameters.position.setX(computedTextPosition); break; case End: displayParameters.position.setX(computedTextPosition - displayParameters.size); break; case Middle: displayParameters.position.setX(computedTextPosition - displayParameters.size / 2); break; default: ASSERT_NOT_REACHED(); } } else { // Cases for m_writingDirection being VerticalGrowing{Left|Right} switch (computedCueAlignment) { case Start: displayParameters.position.setY(computedTextPosition); break; case End: displayParameters.position.setY(computedTextPosition - displayParameters.size); break; case Middle: displayParameters.position.setY(computedTextPosition - displayParameters.size / 2); break; default: ASSERT_NOT_REACHED(); } } // 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 // yet calculated for cue as per the appropriate rules from the following // list: if (!m_snapToLines) { if (m_writingDirection == Horizontal) displayParameters.position.setY(computedLinePosition); else displayParameters.position.setX(computedLinePosition); } else { if (m_writingDirection == Horizontal) displayParameters.position.setY(0); else displayParameters.position.setX(0); } // Step 9 not implemented (margin == 0). // The snap-to-lines position is propagated to LayoutVTTCue. displayParameters.snapToLinesPosition = m_snapToLines ? computedLinePosition : std::numeric_limits<float>::quiet_NaN(); ASSERT(std::isfinite(displayParameters.size)); ASSERT(displayParameters.direction != CSSValueNone); ASSERT(displayParameters.writingMode != CSSValueNone); return displayParameters; }