diff options
12 files changed, 140 insertions, 17 deletions
diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc index cf34a67..8827e85 100644 --- a/chromecast/browser/cast_content_browser_client.cc +++ b/chromecast/browser/cast_content_browser_client.cc @@ -270,6 +270,9 @@ void CastContentBrowserClient::OverrideWebkitPrefs( // to retrieve media data chunks while running in a https page. This pref // should be disabled once all the content providers are no longer doing that. prefs->allow_running_insecure_content = true; + + // Enable 5% margins for WebVTT cues to keep within title-safe area + prefs->text_track_margin_percentage = 5; } void CastContentBrowserClient::ResourceDispatcherHostCreated() { diff --git a/content/public/common/common_param_traits_macros.h b/content/public/common/common_param_traits_macros.h index b0cf1d1..25ceadb 100644 --- a/content/public/common/common_param_traits_macros.h +++ b/content/public/common/common_param_traits_macros.h @@ -202,6 +202,7 @@ IPC_STRUCT_TRAITS_BEGIN(content::WebPreferences) IPC_STRUCT_TRAITS_MEMBER(pepper_accelerated_video_decode_enabled) IPC_STRUCT_TRAITS_MEMBER(animation_policy) IPC_STRUCT_TRAITS_MEMBER(user_gesture_required_for_presentation) + IPC_STRUCT_TRAITS_MEMBER(text_track_margin_percentage) #if defined(OS_ANDROID) IPC_STRUCT_TRAITS_MEMBER(text_autosizing_enabled) IPC_STRUCT_TRAITS_MEMBER(font_scale_factor) diff --git a/content/public/common/web_preferences.cc b/content/public/common/web_preferences.cc index c0563f5..1c445e9 100644 --- a/content/public/common/web_preferences.cc +++ b/content/public/common/web_preferences.cc @@ -163,6 +163,7 @@ WebPreferences::WebPreferences() pepper_accelerated_video_decode_enabled(false), animation_policy(IMAGE_ANIMATION_POLICY_ALLOWED), user_gesture_required_for_presentation(true), + text_track_margin_percentage(0.0f), #if defined(OS_ANDROID) text_autosizing_enabled(true), font_scale_factor(1.0f), diff --git a/content/public/common/web_preferences.h b/content/public/common/web_preferences.h index 636f7a2..23c655e 100644 --- a/content/public/common/web_preferences.h +++ b/content/public/common/web_preferences.h @@ -192,6 +192,11 @@ struct CONTENT_EXPORT WebPreferences { bool user_gesture_required_for_presentation; + // Specifies the margin for WebVTT text tracks as a percentage of media + // element height/width (for horizontal/vertical text respectively). + // Cues will not be placed in this margin area. + float text_track_margin_percentage; + #if defined(OS_ANDROID) bool text_autosizing_enabled; float font_scale_factor; diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index e95dd6e..edddc05 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc @@ -1052,6 +1052,8 @@ void RenderView::ApplyWebPreferences(const WebPreferences& prefs, settings->setPresentationRequiresUserGesture( prefs.user_gesture_required_for_presentation); + settings->setTextTrackMarginPercentage(prefs.text_track_margin_percentage); + // Needs to happen before setIgnoreVIewportTagScaleLimits below. web_view->setDefaultPageScaleLimits( prefs.default_minimum_page_scale_factor, diff --git a/third_party/WebKit/LayoutTests/media/track/captions-webvtt/captions-overscan.vtt b/third_party/WebKit/LayoutTests/media/track/captions-webvtt/captions-overscan.vtt new file mode 100644 index 0000000..7e47a48 --- /dev/null +++ b/third_party/WebKit/LayoutTests/media/track/captions-webvtt/captions-overscan.vtt @@ -0,0 +1,18 @@ +WEBVTT +Valid vertical direction settings. + +1 +00:00:00.000 --> 00:00:01.000 vertical:lr line:0 +Checks left margin + +2 +00:00:01.000 --> 00:00:02.000 vertical:lr +Checks right margin + +3 +00:00:02.000 --> 00:00:03.000 +Checks bottom margin + +4 +00:00:03.000 --> 00:00:04.000 line:0 +Checks top margin diff --git a/third_party/WebKit/LayoutTests/media/track/track-cue-rendering-overscan.html b/third_party/WebKit/LayoutTests/media/track/track-cue-rendering-overscan.html new file mode 100644 index 0000000..befc9fa --- /dev/null +++ b/third_party/WebKit/LayoutTests/media/track/track-cue-rendering-overscan.html @@ -0,0 +1,46 @@ +<!doctype html> +<title>WebVTT overscan margin test</title> +<script src="../media-file.js"></script> +<script src="../media-controls.js"></script> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script> + setup(function() { window.internals.settings.setTextTrackMarginPercentage(5); }); + + var makeTest = function(time, edgeName, marginAssertFunc) { + var expectedText = "Checks " + edgeName + " margin"; + var t = async_test(expectedText); + t.step(function() { + var video = document.createElement('video'); + video.width = 320; + video.height = 240; + var track = document.createElement('track'); + track.src = "captions-webvtt/captions-overscan.vtt"; + track['default'] = true; + track.kind = 'captions'; + video.appendChild(track); + document.body.appendChild(video); + + video.src = findMediaFile('video', '../content/test'); + video.oncanplaythrough = function() { video.currentTime = time; }; + video.onseeked = t.step_func(function() { + var testCueDisplayBox = textTrackDisplayElement(video, 'display'); + + assert_equals(video.currentTime, time, "video.currentTime"); + assert_equals(track.track.activeCues.length, 1, "activeCues.length"); + assert_equals(track.track.activeCues[0].text, expectedText, "activeCues[0].text"); + assert_equals(testCueDisplayBox.innerText, expectedText, "testCueDisplayBox.innerText"); + + marginAssertFunc(testCueDisplayBox, video); + t.done(); + }); + }); + }; + + onload = function() { + makeTest(0.5, "left", function(box, v) { assert_greater_than_equal(box.offsetLeft, v.width * 0.05); }); + makeTest(1.5, "right", function(box, v) { assert_less_than(box.offsetLeft + box.offsetWidth, v.width * 0.95); }); + makeTest(2.5, "bottom", function(box, v) { assert_less_than(box.offsetTop + box.offsetHeight, v.height * 0.95); }); + makeTest(3.5, "top", function(box, v) { assert_greater_than_equal(box.offsetTop, v.height * 0.05); }); + }; +</script> diff --git a/third_party/WebKit/Source/core/frame/Settings.in b/third_party/WebKit/Source/core/frame/Settings.in index 31adfc74..ddcda86 100644 --- a/third_party/WebKit/Source/core/frame/Settings.in +++ b/third_party/WebKit/Source/core/frame/Settings.in @@ -352,6 +352,10 @@ textTrackTextColor type=String textTrackTextShadow type=String textTrackTextSize type=String +# Margin for title-safe placement of cues with overscan, gives top and bottom margin size as +# percentage of video element height (for horizontal text) into which cues will not be placed. +textTrackMarginPercentage type=double, initial=0 + lowPriorityIframes initial=false reportWheelOverscroll initial=false diff --git a/third_party/WebKit/Source/core/layout/LayoutVTTCue.cpp b/third_party/WebKit/Source/core/layout/LayoutVTTCue.cpp index 32130be..35e6825 100644 --- a/third_party/WebKit/Source/core/layout/LayoutVTTCue.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutVTTCue.cpp @@ -25,9 +25,11 @@ #include "core/layout/LayoutVTTCue.h" +#include "core/frame/Settings.h" #include "core/html/shadow/MediaControls.h" #include "core/layout/LayoutInline.h" #include "core/layout/LayoutState.h" +#include "wtf/MathExtras.h" namespace blink { @@ -43,16 +45,19 @@ public: SnapToLinesLayouter(LayoutVTTCue& cueBox, const IntRect& controlsRect) : m_cueBox(cueBox) , m_controlsRect(controlsRect) + , m_margin(0.0) { + if (Settings* settings = m_cueBox.document().settings()) + m_margin = settings->textTrackMarginPercentage() / 100.0; } void layout(); private: - bool isOutside() const; + bool isOutside(const IntRect&) const; bool isOverlapping() const; - LayoutUnit computeInitialPositionAdjustment(LayoutUnit&) const; - bool shouldSwitchDirection(InlineFlowBox*, LayoutUnit) const; + LayoutUnit computeInitialPositionAdjustment(LayoutUnit&, LayoutUnit, LayoutUnit) const; + bool shouldSwitchDirection(InlineFlowBox*, LayoutUnit, LayoutUnit) const; void moveBoxesBy(LayoutUnit distance) { @@ -64,6 +69,7 @@ private: LayoutPoint m_specifiedPosition; LayoutVTTCue& m_cueBox; IntRect m_controlsRect; + double m_margin; }; InlineFlowBox* SnapToLinesLayouter::findFirstLineBox() const @@ -73,7 +79,8 @@ InlineFlowBox* SnapToLinesLayouter::findFirstLineBox() const return toLayoutInline(m_cueBox.firstChild())->firstLineBox(); } -LayoutUnit SnapToLinesLayouter::computeInitialPositionAdjustment(LayoutUnit& step) const +LayoutUnit SnapToLinesLayouter::computeInitialPositionAdjustment(LayoutUnit& step, LayoutUnit maxDimension, + LayoutUnit margin) const { ASSERT(std::isfinite(m_cueBox.snapToLinesPosition())); @@ -98,20 +105,21 @@ LayoutUnit SnapToLinesLayouter::computeInitialPositionAdjustment(LayoutUnit& ste // 11. If line is less than zero... if (linePosition < 0) { - LayoutBlock* parentBlock = m_cueBox.containingBlock(); - // ... then increase position by max dimension ... - position += blink::isHorizontalWritingMode(writingMode) ? parentBlock->size().height() : parentBlock->size().width(); + position += maxDimension; // ... and negate step. step = -step; + } else { + // ... Otherwise, increase position by margin. + position += margin; } return position; } -bool SnapToLinesLayouter::isOutside() const +bool SnapToLinesLayouter::isOutside(const IntRect& titleArea) const { - return !m_cueBox.containingBlock()->absoluteBoundingBoxRect().contains(m_cueBox.absoluteContentBox()); + return !titleArea.contains(m_cueBox.absoluteContentBox()); } bool SnapToLinesLayouter::isOverlapping() const @@ -130,7 +138,7 @@ bool SnapToLinesLayouter::isOverlapping() const return false; } -bool SnapToLinesLayouter::shouldSwitchDirection(InlineFlowBox* firstLineBox, LayoutUnit step) const +bool SnapToLinesLayouter::shouldSwitchDirection(InlineFlowBox* firstLineBox, LayoutUnit step, LayoutUnit margin) const { // 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 @@ -142,9 +150,9 @@ bool SnapToLinesLayouter::shouldSwitchDirection(InlineFlowBox* firstLineBox, Lay // now to the right of the right edge of the title area, jump to the step // labeled switch direction. LayoutUnit logicalTop = m_cueBox.logicalTop(); - if (step < 0 && logicalTop < 0) + if (step < 0 && logicalTop < margin) return true; - if (step > 0 && logicalTop + firstLineBox->logicalHeight() > m_cueBox.containingBlock()->logicalHeight()) + if (step > 0 && logicalTop + firstLineBox->logicalHeight() + margin > m_cueBox.containingBlock()->logicalHeight()) return true; return false; } @@ -158,7 +166,22 @@ void SnapToLinesLayouter::layout() if (!firstLineBox) return; - // Steps 1-3 skipped. + // 1. Horizontal: Let margin be a user-agent-defined vertical length which + // will be used to define a margin at the top and bottom edges of the video + // into which cues will not be placed. + // Vertical: Let margin be a user-agent-defined horizontal length which + // will be used to define a margin at the top and bottom edges of the video + // into which cues will not be placed. + // 2. Horizontal: Let full dimension be the height of video's rendering area + // Vertical: Let full dimension be the width of video's rendering area. + WritingMode writingMode = m_cueBox.style()->getWritingMode(); + LayoutBlock* parentBlock = m_cueBox.containingBlock(); + LayoutUnit fullDimension = blink::isHorizontalWritingMode(writingMode) ? parentBlock->size().height() : parentBlock->size().width(); + LayoutUnit margin(fullDimension * m_margin); + + // 3. Let max dimension be full dimension - (2 * margin) + LayoutUnit maxDimension = fullDimension - 2 * margin; + // 4. Horizontal: Let step be the height of the first line box in boxes. // Vertical: Let step be the width of the first line box in boxes. LayoutUnit step = firstLineBox->logicalHeight(); @@ -168,7 +191,7 @@ void SnapToLinesLayouter::layout() return; // Steps 6-11. - LayoutUnit positionAdjustment = computeInitialPositionAdjustment(step); + LayoutUnit positionAdjustment = computeInitialPositionAdjustment(step, maxDimension, margin); // 12. Move all boxes in boxes ... // Horizontal: ... down by the distance given by position @@ -182,16 +205,29 @@ void SnapToLinesLayouter::layout() // XX. Let switched be false. bool switched = false; - // Step 14 skipped. (margin == 0; title area == video area) + // 14. Horizontal: Let title area be a box that covers all of the video's + // rendering area except for a height of margin at the top of the rendering + // area and a height of margin at the bottom of the rendering area. + // Vertical: Let title area be a box that covers all of the video’s + // rendering area except for a width of margin at the left of the rendering + // area and a width of margin at the right of the rendering area. + IntRect titleArea = m_cueBox.containingBlock()->absoluteBoundingBoxRect(); + if (blink::isHorizontalWritingMode(writingMode)) { + titleArea.move(0, margin); + titleArea.contract(0, 2 * margin); + } else { + titleArea.move(margin, 0); + titleArea.contract(2 * margin, 0); + } // 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()) { + while (isOutside(titleArea) || isOverlapping()) { // 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. - if (!shouldSwitchDirection(firstLineBox, step)) { + if (!shouldSwitchDirection(firstLineBox, step, margin)) { // 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.) diff --git a/third_party/WebKit/Source/web/WebSettingsImpl.cpp b/third_party/WebKit/Source/web/WebSettingsImpl.cpp index a096948..f5179bb 100644 --- a/third_party/WebKit/Source/web/WebSettingsImpl.cpp +++ b/third_party/WebKit/Source/web/WebSettingsImpl.cpp @@ -407,6 +407,11 @@ void WebSettingsImpl::setTextTrackFontVariant(const WebString& fontVariant) m_settings->setTextTrackFontVariant(fontVariant); } +void WebSettingsImpl::setTextTrackMarginPercentage(float percentage) +{ + m_settings->setTextTrackMarginPercentage(percentage); +} + void WebSettingsImpl::setTextTrackTextColor(const WebString& color) { m_settings->setTextTrackTextColor(color); diff --git a/third_party/WebKit/Source/web/WebSettingsImpl.h b/third_party/WebKit/Source/web/WebSettingsImpl.h index 6bb6e6c..4bf1f42 100644 --- a/third_party/WebKit/Source/web/WebSettingsImpl.h +++ b/third_party/WebKit/Source/web/WebSettingsImpl.h @@ -169,6 +169,7 @@ public: void setTextTrackFontFamily(const WebString&) override; void setTextTrackFontStyle(const WebString&) override; void setTextTrackFontVariant(const WebString&) override; + void setTextTrackMarginPercentage(float) override; void setTextTrackTextColor(const WebString&) override; void setTextTrackTextShadow(const WebString&) override; void setTextTrackTextSize(const WebString&) override; diff --git a/third_party/WebKit/public/web/WebSettings.h b/third_party/WebKit/public/web/WebSettings.h index b486a00..bc6646c 100644 --- a/third_party/WebKit/public/web/WebSettings.h +++ b/third_party/WebKit/public/web/WebSettings.h @@ -229,6 +229,7 @@ public: virtual void setTextTrackFontFamily(const WebString&) = 0; virtual void setTextTrackFontStyle(const WebString&) = 0; virtual void setTextTrackFontVariant(const WebString&) = 0; + virtual void setTextTrackMarginPercentage(float) = 0; virtual void setTextTrackTextColor(const WebString&) = 0; virtual void setTextTrackTextShadow(const WebString&) = 0; virtual void setTextTrackTextSize(const WebString&) = 0; |