Replace PassRef with Ref/Ref&& across the board.
[WebKit-https.git] / Source / WebCore / html / track / VTTCue.cpp
index bb133c5..a66015b 100644 (file)
@@ -58,6 +58,9 @@
 
 namespace WebCore {
 
+// This constant should correspond with the percentage returned by CaptionUserPreferences::captionFontSizeScaleAndImportance.
+const static double DEFAULTCAPTIONFONTSIZEPERCENTAGE = 5;
+
 static const int undefinedPosition = -1;
 
 static const CSSValueID displayWritingModeMap[] = {
@@ -138,7 +141,7 @@ VTTCue* VTTCueBox::getCue() const
     return &m_cue;
 }
 
-void VTTCueBox::applyCSSProperties(const IntSize&)
+void VTTCueBox::applyCSSProperties(const IntSize& videoSize)
 {
     // FIXME: Apply all the initial CSS positioning properties. http://wkb.ug/79916
 #if ENABLE(WEBVTT_REGIONS)
@@ -170,13 +173,35 @@ void VTTCueBox::applyCSSProperties(const IntSize&)
     // the 'left' property must be set to left
     setInlineStyleProperty(CSSPropertyLeft, static_cast<double>(position.first), CSSPrimitiveValue::CSS_PERCENTAGE);
 
+    double authorFontSize = std::min(videoSize.width(), videoSize.height()) * DEFAULTCAPTIONFONTSIZEPERCENTAGE / 100.0;
+    double multiplier = 1.0;
+    if (authorFontSize)
+        multiplier = m_fontSizeFromCaptionUserPrefs / authorFontSize;
+
+    double textPosition = m_cue.position();
+    double maxSize = 100.0;
+    CSSValueID alignment = m_cue.getCSSAlignment();
+    if (alignment == CSSValueEnd || alignment == CSSValueRight)
+        maxSize = textPosition;
+    else if (alignment == CSSValueStart || alignment == CSSValueLeft)
+        maxSize = 100.0 - textPosition;
+
+    double newCueSize = std::min(m_cue.getCSSSize() * multiplier, 100.0);
     // the 'width' property must be set to width, and the 'height' property  must be set to height
     if (m_cue.vertical() == horizontalKeyword()) {
-        setInlineStyleProperty(CSSPropertyWidth, static_cast<double>(m_cue.getCSSSize()), CSSPrimitiveValue::CSS_PERCENTAGE);
+        setInlineStyleProperty(CSSPropertyWidth, newCueSize, CSSPrimitiveValue::CSS_PERCENTAGE);
         setInlineStyleProperty(CSSPropertyHeight, CSSValueAuto);
+        setInlineStyleProperty(CSSPropertyMinWidth, "-webkit-min-content");
+        setInlineStyleProperty(CSSPropertyMaxWidth, maxSize, CSSPrimitiveValue::CSS_PERCENTAGE);
+        if ((alignment == CSSValueMiddle || alignment == CSSValueCenter) && multiplier != 1.0)
+            setInlineStyleProperty(CSSPropertyLeft, static_cast<double>(position.first - (newCueSize - m_cue.getCSSSize()) / 2), CSSPrimitiveValue::CSS_PERCENTAGE);
     } else {
         setInlineStyleProperty(CSSPropertyWidth, CSSValueAuto);
-        setInlineStyleProperty(CSSPropertyHeight, static_cast<double>(m_cue.getCSSSize()),  CSSPrimitiveValue::CSS_PERCENTAGE);
+        setInlineStyleProperty(CSSPropertyHeight, newCueSize, CSSPrimitiveValue::CSS_PERCENTAGE);
+        setInlineStyleProperty(CSSPropertyMinHeight, "-webkit-min-content");
+        setInlineStyleProperty(CSSPropertyMaxHeight, maxSize, CSSPrimitiveValue::CSS_PERCENTAGE);
+        if ((alignment == CSSValueMiddle || alignment == CSSValueCenter) && multiplier != 1.0)
+            setInlineStyleProperty(CSSPropertyTop, static_cast<double>(position.second - (newCueSize - m_cue.getCSSSize()) / 2), CSSPrimitiveValue::CSS_PERCENTAGE);
     }
 
     // The 'text-align' property on the (root) List of WebVTT Node Objects must
@@ -184,7 +209,7 @@ void VTTCueBox::applyCSSProperties(const IntSize&)
     // whose first cell is the value of the corresponding cue's text track cue
     // alignment:
     setInlineStyleProperty(CSSPropertyTextAlign, m_cue.getCSSAlignment());
-
+    
     if (!m_cue.snapToLines()) {
         // 10.13.1 Set up x and y:
         // Note: x and y are set through the CSS left and top above.
@@ -209,16 +234,17 @@ const AtomicString& VTTCueBox::vttCueBoxShadowPseudoId()
     return trackDisplayBoxShadowPseudoId;
 }
 
-RenderPtr<RenderElement> VTTCueBox::createElementRenderer(PassRef<RenderStyle> style)
+RenderPtr<RenderElement> VTTCueBox::createElementRenderer(Ref<RenderStyle>&& style)
 {
-    return createRenderer<RenderVTTCue>(*this, std::move(style));
+    return createRenderer<RenderVTTCue>(*this, WTF::move(style));
 }
 
 // ----------------------------
 
-PassRefPtr<VTTCue> VTTCue::create(ScriptExecutionContext& context, double start, double end, const String& content)
+const AtomicString& VTTCue::cueBackdropShadowPseudoId()
 {
-    return adoptRef(new VTTCue(context, start, end, content));
+    DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, cueBackdropShadowPseudoId, ("-webkit-media-text-track-display-backdrop", AtomicString::ConstructFromLiteral));
+    return cueBackdropShadowPseudoId;
 }
 
 PassRefPtr<VTTCue> VTTCue::create(ScriptExecutionContext& context, const WebVTTCueData& data)
@@ -226,7 +252,7 @@ PassRefPtr<VTTCue> VTTCue::create(ScriptExecutionContext& context, const WebVTTC
     return adoptRef(new VTTCue(context, data));
 }
 
-VTTCue::VTTCue(ScriptExecutionContext& context, double start, double end, const String& content)
+VTTCue::VTTCue(ScriptExecutionContext& context, const MediaTime& start, const MediaTime& end, const String& content)
     : TextTrackCue(context, start, end)
     , m_content(content)
 {
@@ -234,12 +260,12 @@ VTTCue::VTTCue(ScriptExecutionContext& context, double start, double end, const
 }
 
 VTTCue::VTTCue(ScriptExecutionContext& context, const WebVTTCueData& cueData)
-    : TextTrackCue(context, 0, 0)
+    : TextTrackCue(context, MediaTime::zeroTime(), MediaTime::zeroTime())
 {
     initialize(context);
     setText(cueData.content());
-    setStartTime(cueData.startTime(), IGNORE_EXCEPTION);
-    setEndTime(cueData.endTime(), IGNORE_EXCEPTION);
+    setStartTime(cueData.startTime());
+    setEndTime(cueData.endTime());
     setId(cueData.id());
     setCueSettings(cueData.settings());
     m_originalStartTime = cueData.originalStartTime();
@@ -262,13 +288,14 @@ void VTTCue::initialize(ScriptExecutionContext& context)
     m_writingDirection = Horizontal;
     m_cueAlignment = Middle;
     m_webVTTNodeTree = nullptr;
-    m_cueBackgroundBox = HTMLSpanElement::create(spanTag, toDocument(context));
+    m_cueBackdropBox = HTMLDivElement::create(downcast<Document>(context));
+    m_cueHighlightBox = HTMLSpanElement::create(spanTag, downcast<Document>(context));
     m_displayDirection = CSSValueLtr;
     m_displaySize = 0;
     m_snapToLines = true;
     m_displayTreeShouldChange = true;
     m_notifyRegion = true;
-    m_originalStartTime = 0;
+    m_originalStartTime = MediaTime::zeroTime();
 }
 
 PassRefPtr<VTTCueBox> VTTCue::createDisplayTree()
@@ -470,13 +497,13 @@ void VTTCue::copyWebVTTNodeToDOMTree(ContainerNode* webVTTNode, ContainerNode* p
 {
     for (Node* node = webVTTNode->firstChild(); node; node = node->nextSibling()) {
         RefPtr<Node> clonedNode;
-        if (node->isWebVTTElement())
-            clonedNode = toWebVTTElement(node)->createEquivalentHTMLElement(ownerDocument());
+        if (is<WebVTTElement>(*node))
+            clonedNode = downcast<WebVTTElement>(*node).createEquivalentHTMLElement(ownerDocument());
         else
             clonedNode = node->cloneNode(false);
         parent->appendChild(clonedNode, ASSERT_NO_EXCEPTION);
-        if (node->isContainerNode())
-            copyWebVTTNodeToDOMTree(toContainerNode(node), toContainerNode(clonedNode.get()));
+        if (is<ContainerNode>(*node))
+            copyWebVTTNodeToDOMTree(downcast<ContainerNode>(node), downcast<ContainerNode>(clonedNode.get()));
     }
 }
 
@@ -719,18 +746,18 @@ void VTTCue::calculateDisplayParameters()
         m_displayPosition.first = m_computedLinePosition;
 }
     
-void VTTCue::markFutureAndPastNodes(ContainerNode* root, double previousTimestamp, double movieTime)
+void VTTCue::markFutureAndPastNodes(ContainerNode* root, const MediaTime& previousTimestamp, const MediaTime& movieTime)
 {
     DEPRECATED_DEFINE_STATIC_LOCAL(const String, timestampTag, (ASCIILiteral("timestamp")));
     
     bool isPastNode = true;
-    double currentTimestamp = previousTimestamp;
+    MediaTime currentTimestamp = previousTimestamp;
     if (currentTimestamp > movieTime)
         isPastNode = false;
     
     for (Node* child = root->firstChild(); child; child = NodeTraversal::next(child, root)) {
         if (child->nodeName() == timestampTag) {
-            double currentTimestamp;
+            MediaTime currentTimestamp;
             bool check = WebVTTParser::collectTimeStamp(child->nodeValue(), currentTimestamp);
             ASSERT_UNUSED(check, check);
             
@@ -739,16 +766,16 @@ void VTTCue::markFutureAndPastNodes(ContainerNode* root, double previousTimestam
                 isPastNode = false;
         }
         
-        if (child->isWebVTTElement()) {
-            toWebVTTElement(child)->setIsPastNode(isPastNode);
+        if (is<WebVTTElement>(*child)) {
+            downcast<WebVTTElement>(*child).setIsPastNode(isPastNode);
             // Make an elemenet id match a cue id for style matching purposes.
             if (!id().isEmpty())
-                toElement(child)->setIdAttribute(id());
+                downcast<WebVTTElement>(*child).setIdAttribute(id());
         }
     }
 }
 
-void VTTCue::updateDisplayTree(double movieTime)
+void VTTCue::updateDisplayTree(const MediaTime& movieTime)
 {
     // The display tree may contain WebVTT timestamp objects representing
     // timestamps (processing instructions), along with displayable nodes.
@@ -757,18 +784,18 @@ void VTTCue::updateDisplayTree(double movieTime)
         return;
 
     // Clear the contents of the set.
-    m_cueBackgroundBox->removeChildren();
+    m_cueHighlightBox->removeChildren();
 
     // Update the two sets containing past and future WebVTT objects.
     RefPtr<DocumentFragment> referenceTree = createCueRenderingTree();
     if (!referenceTree)
         return;
 
-    markFutureAndPastNodes(referenceTree.get(), startTime(), movieTime);
-    m_cueBackgroundBox->appendChild(referenceTree);
+    markFutureAndPastNodes(referenceTree.get(), startMediaTime(), movieTime);
+    m_cueHighlightBox->appendChild(referenceTree);
 }
 
-VTTCueBox* VTTCue::getDisplayTree(const IntSize& videoSize)
+VTTCueBox* VTTCue::getDisplayTree(const IntSize& videoSize, int fontSize)
 {
     RefPtr<VTTCueBox> displayTree = displayTreeInternal();
     if (!m_displayTreeShouldChange || !track()->isRendered())
@@ -788,21 +815,18 @@ VTTCueBox* VTTCue::getDisplayTree(const IntSize& videoSize)
     // 'display' property has the value 'inline'. This is the WebVTT cue
     // background box.
 
-    // Note: This is contained by default in m_cueBackgroundBox.
-    m_cueBackgroundBox->setPseudo(cueShadowPseudoId());
-    displayTree->appendChild(m_cueBackgroundBox, ASSERT_NO_EXCEPTION);
+    // Note: This is contained by default in m_cueHighlightBox.
+    m_cueHighlightBox->setPseudo(cueShadowPseudoId());
+
+    m_cueBackdropBox->setPseudo(cueBackdropShadowPseudoId());
+    m_cueBackdropBox->appendChild(m_cueHighlightBox, ASSERT_NO_EXCEPTION);
+    displayTree->appendChild(m_cueBackdropBox, ASSERT_NO_EXCEPTION);
 
     // FIXME(BUG 79916): Runs of children of WebVTT Ruby Objects that are not
     // WebVTT Ruby Text Objects must be wrapped in anonymous boxes whose
     // 'display' property has the value 'ruby-base'.
 
-    // FIXME(BUG 79916): Text runs must be wrapped according to the CSS
-    // line-wrapping rules, except that additionally, regardless of the value of
-    // the 'white-space' property, lines must be wrapped at the edge of their
-    // containing blocks, even if doing so requires splitting a word where there
-    // is no line breaking opportunity. (Thus, normally text wraps as needed,
-    // but if there is a particularly long word, it does not overflow as it
-    // normally would in CSS, it is instead forcibly wrapped at the box's edge.)
+    displayTree->setFontSizeFromCaptionUserPrefs(fontSize);
     displayTree->applyCSSProperties(videoSize);
 
     m_displayTreeShouldChange = false;
@@ -1131,6 +1155,7 @@ void VTTCue::setFontSize(int fontSize, const IntSize&, bool important)
     
     LOG(Media, "TextTrackCue::setFontSize - setting cue font size to %i", fontSize);
 
+    m_displayTreeShouldChange = true;
     displayTreeInternal()->setInlineStyleProperty(CSSPropertyFontSize, fontSize, CSSPrimitiveValue::CSS_PX, important);
 }