- Revision
- 150453
- Author
- jer.no...@apple.com
- Date
- 2013-05-21 10:16:34 -0700 (Tue, 21 May 2013)
Log Message
Implement overlap-avoidance for in-band text track cues.
https://bugs.webkit.org/show_bug.cgi?id=116540
Reviewed by Eric Carlson.
In-band (or Generic) cues need special casing for certain features
present in in-band tracks, like paint-on and roll-up modes. To avoid
the problem of overlap avoidance forcing a caption meant to appear
below a cue to appear above it when a larger font size is selected,
impose an additional sort ordering for "generic cues". Instead of
cues being ordered by the order they appear in the track, "generic
cues" further sorted by their position within the video area, such
that cues at the bottom of the video area appear first, and later
cues are pushed up to avoid them, preserving the desired apparent
ordering.
* html/HTMLMediaElement.cpp:
(WebCore::compareCueInterval): Added; wrapper around
TextTrackCue::isOrderedBefore.
(WebCore::HTMLMediaElement::updateActiveTextTrackCues):
After creating the list of current cues, sort them.
* html/track/TextTrackCue.cpp:
(WebCore::TextTrackCue::isOrderedBefore): Added; implementation moved
from TextTrackCueList::add().
* html/track/TextTrackCue.h:
* html/track/TextTrackCueGeneric.cpp:
(WebCore::TextTrackCueGeneric::isOrderedBefore): Added override;
impose additional oredring on generic cues.
* html/track/TextTrackCueGeneric.h:
* html/track/TextTrackCueList.cpp:
(WebCore::TextTrackCueList::add): Moved ordering test into
isOrderedBefore().
* rendering/RenderTextTrackCue.cpp:
(WebCore::RenderTextTrackCue::repositionGenericCue):
Call repositionCueSnapToLinesNotSet() after positioning the cue.
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (150452 => 150453)
--- trunk/Source/WebCore/ChangeLog 2013-05-21 17:14:53 UTC (rev 150452)
+++ trunk/Source/WebCore/ChangeLog 2013-05-21 17:16:34 UTC (rev 150453)
@@ -1,3 +1,41 @@
+2013-05-21 Jer Noble <jer.no...@apple.com>
+
+ Implement overlap-avoidance for in-band text track cues.
+ https://bugs.webkit.org/show_bug.cgi?id=116540
+
+ Reviewed by Eric Carlson.
+
+ In-band (or Generic) cues need special casing for certain features
+ present in in-band tracks, like paint-on and roll-up modes. To avoid
+ the problem of overlap avoidance forcing a caption meant to appear
+ below a cue to appear above it when a larger font size is selected,
+ impose an additional sort ordering for "generic cues". Instead of
+ cues being ordered by the order they appear in the track, "generic
+ cues" further sorted by their position within the video area, such
+ that cues at the bottom of the video area appear first, and later
+ cues are pushed up to avoid them, preserving the desired apparent
+ ordering.
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::compareCueInterval): Added; wrapper around
+ TextTrackCue::isOrderedBefore.
+ (WebCore::HTMLMediaElement::updateActiveTextTrackCues):
+ After creating the list of current cues, sort them.
+ * html/track/TextTrackCue.cpp:
+ (WebCore::TextTrackCue::isOrderedBefore): Added; implementation moved
+ from TextTrackCueList::add().
+ * html/track/TextTrackCue.h:
+ * html/track/TextTrackCueGeneric.cpp:
+ (WebCore::TextTrackCueGeneric::isOrderedBefore): Added override;
+ impose additional oredring on generic cues.
+ * html/track/TextTrackCueGeneric.h:
+ * html/track/TextTrackCueList.cpp:
+ (WebCore::TextTrackCueList::add): Moved ordering test into
+ isOrderedBefore().
+ * rendering/RenderTextTrackCue.cpp:
+ (WebCore::RenderTextTrackCue::repositionGenericCue):
+ Call repositionCueSnapToLinesNotSet() after positioning the cue.
+
2013-05-20 Jer Noble <jer.no...@apple.com>
Implement overlap avoidance for cues with snap-to-lines flag not set
Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (150452 => 150453)
--- trunk/Source/WebCore/html/HTMLMediaElement.cpp 2013-05-21 17:14:53 UTC (rev 150452)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp 2013-05-21 17:16:34 UTC (rev 150453)
@@ -1116,7 +1116,12 @@
return a.second->cueIndex() - b.second->cueIndex() < 0;
}
+static bool compareCueInterval(const CueInterval& one, const CueInterval& two)
+{
+ return one.data()->isOrderedBefore(two.data());
+};
+
void HTMLMediaElement::updateActiveTextTrackCues(double movieTime)
{
// 4.8.10.8 Playing the media resource
@@ -1138,8 +1143,10 @@
// The user agent must synchronously unset [the text track cue active] flag
// whenever ... the media element's readyState is changed back to HAVE_NOTHING.
- if (m_readyState != HAVE_NOTHING && m_player)
+ if (m_readyState != HAVE_NOTHING && m_player) {
currentCues = m_cueTree.allOverlaps(m_cueTree.createInterval(movieTime, movieTime));
+ std::sort(currentCues.begin(), currentCues.end(), &compareCueInterval);
+ }
CueList previousCues;
CueList missedCues;
Modified: trunk/Source/WebCore/html/track/TextTrackCue.cpp (150452 => 150453)
--- trunk/Source/WebCore/html/track/TextTrackCue.cpp 2013-05-21 17:14:53 UTC (rev 150452)
+++ trunk/Source/WebCore/html/track/TextTrackCue.cpp 2013-05-21 17:16:34 UTC (rev 150453)
@@ -1195,6 +1195,12 @@
return true;
}
+
+bool TextTrackCue::isOrderedBefore(const TextTrackCue* other) const
+{
+ return startTime() < other->startTime() || (startTime() == other->startTime() && endTime() > other->endTime());
+}
+
void TextTrackCue::setFontSize(int fontSize, const IntSize&, bool important)
{
if (!hasDisplayTree() || !fontSize)
Modified: trunk/Source/WebCore/html/track/TextTrackCue.h (150452 => 150453)
--- trunk/Source/WebCore/html/track/TextTrackCue.h 2013-05-21 17:14:53 UTC (rev 150452)
+++ trunk/Source/WebCore/html/track/TextTrackCue.h 2013-05-21 17:16:34 UTC (rev 150453)
@@ -151,6 +151,7 @@
void markFutureAndPastNodes(ContainerNode*, double, double);
int calculateComputedLinePosition();
+ std::pair<double, double> getPositionCoordinates() const;
virtual const AtomicString& interfaceName() const;
virtual ScriptExecutionContext* scriptExecutionContext() const;
@@ -184,6 +185,8 @@
};
virtual bool isEqual(const TextTrackCue&, CueMatchRules) const;
+ virtual bool isOrderedBefore(const TextTrackCue*) const;
+
enum CueType {
Generic,
WebVTT
@@ -214,7 +217,6 @@
void createWebVTTNodeTree();
void copyWebVTTNodeToDOMTree(ContainerNode* WebVTTNode, ContainerNode* root);
- std::pair<double, double> getPositionCoordinates() const;
void parseSettings(const String&);
void determineTextDirection();
Modified: trunk/Source/WebCore/html/track/TextTrackCueGeneric.cpp (150452 => 150453)
--- trunk/Source/WebCore/html/track/TextTrackCueGeneric.cpp 2013-05-21 17:14:53 UTC (rev 150452)
+++ trunk/Source/WebCore/html/track/TextTrackCueGeneric.cpp 2013-05-21 17:16:34 UTC (rev 150453)
@@ -172,6 +172,21 @@
return TextTrackCue::isEqual(cue, match);
}
+
+bool TextTrackCueGeneric::isOrderedBefore(const TextTrackCue* that) const
+{
+ if (TextTrackCue::isOrderedBefore(that))
+ return true;
+
+ if (that->cueType() == WebVTT && startTime() == that->startTime() && endTime() == that->endTime()) {
+ // Further order generic cues by their calculated line value.
+ std::pair<double, double> thisPosition = getPositionCoordinates();
+ std::pair<double, double> thatPosition = that->getPositionCoordinates();
+ return thisPosition.second > thatPosition.second || (thisPosition.second == thatPosition.second && thisPosition.first < thatPosition.first);
+ }
+
+ return false;
+}
} // namespace WebCore
Modified: trunk/Source/WebCore/html/track/TextTrackCueGeneric.h (150452 => 150453)
--- trunk/Source/WebCore/html/track/TextTrackCueGeneric.h 2013-05-21 17:14:53 UTC (rev 150452)
+++ trunk/Source/WebCore/html/track/TextTrackCueGeneric.h 2013-05-21 17:16:34 UTC (rev 150453)
@@ -78,6 +78,8 @@
virtual TextTrackCue::CueType cueType() const OVERRIDE { return TextTrackCue::Generic; }
private:
+ virtual bool isOrderedBefore(const TextTrackCue*) const OVERRIDE;
+
TextTrackCueGeneric(ScriptExecutionContext*, double start, double end, const String&);
Color m_foregroundColor;
Modified: trunk/Source/WebCore/html/track/TextTrackCueList.cpp (150452 => 150453)
--- trunk/Source/WebCore/html/track/TextTrackCueList.cpp 2013-05-21 17:14:53 UTC (rev 150452)
+++ trunk/Source/WebCore/html/track/TextTrackCueList.cpp 2013-05-21 17:16:34 UTC (rev 150453)
@@ -101,7 +101,7 @@
}
size_t index = (start + end) / 2;
- if (cue->startTime() < m_list[index]->startTime() || (cue->startTime() == m_list[index]->startTime() && cue->endTime() > m_list[index]->endTime()))
+ if (cue->isOrderedBefore(m_list[index].get()))
return add(cue.release(), start, index);
return add(cue.release(), index + 1, end);
Modified: trunk/Source/WebCore/rendering/RenderTextTrackCue.cpp (150452 => 150453)
--- trunk/Source/WebCore/rendering/RenderTextTrackCue.cpp 2013-05-21 17:14:53 UTC (rev 150452)
+++ trunk/Source/WebCore/rendering/RenderTextTrackCue.cpp 2013-05-21 17:16:34 UTC (rev 150453)
@@ -321,20 +321,16 @@
void RenderTextTrackCue::repositionGenericCue()
{
- TextTrackCueGeneric* cue = static_cast<TextTrackCueGeneric*>(m_cue);
- if (!cue->useDefaultPosition())
- return;
-
ASSERT(firstChild());
-
+ ASSERT(m_cue->cueType() == TextTrackCue::WebVTT);
InlineFlowBox* firstLineBox = toRenderInline(firstChild())->firstLineBox();
- if (!firstLineBox)
- return;
-
- LayoutUnit parentWidth = containingBlock()->logicalWidth();
- LayoutUnit width = firstLineBox->width();
- LayoutUnit right = (parentWidth / 2) - (width / 2);
- setX(right);
+ if (static_cast<TextTrackCueGeneric*>(m_cue)->useDefaultPosition() && firstLineBox) {
+ LayoutUnit parentWidth = containingBlock()->logicalWidth();
+ LayoutUnit width = firstLineBox->width();
+ LayoutUnit right = (parentWidth / 2) - (width / 2);
+ setX(right);
+ }
+ repositionCueSnapToLinesNotSet();
}
void RenderTextTrackCue::repositionCueSnapToLinesNotSet()