Index: Source/core/rendering/RenderVTTCue.cpp |
diff --git a/Source/core/rendering/RenderVTTCue.cpp b/Source/core/rendering/RenderVTTCue.cpp |
index 5d20273e884c1250f0c8b33b183c48fef4f1e35f..1902d1d8d531ad2d6512ba437ad10e690b10c76c 100644 |
--- a/Source/core/rendering/RenderVTTCue.cpp |
+++ b/Source/core/rendering/RenderVTTCue.cpp |
@@ -51,6 +51,7 @@ public: |
: m_cueBox(cueBox) |
, m_cueWritingDirection(writingDirection) |
, m_linePosition(linePosition) |
+ , m_bestPositionScore(std::numeric_limits<float>::infinity()) |
{ |
} |
@@ -59,6 +60,7 @@ public: |
private: |
bool isOutside() const; |
bool isOverlapping() const; |
+ float computePositionScore() const; |
bool shouldSwitchDirection(InlineFlowBox*, LayoutUnit) const; |
void moveBoxesByStep(LayoutUnit); |
@@ -68,10 +70,12 @@ private: |
bool initializeLayoutParameters(InlineFlowBox*, LayoutUnit&, LayoutUnit&); |
void placeBoxInDefaultPosition(LayoutUnit, bool&); |
- LayoutPoint m_specifiedPosition; |
RenderVTTCue& m_cueBox; |
VTTCue::WritingDirection m_cueWritingDirection; |
float m_linePosition; |
+ LayoutPoint m_specifiedPosition; |
+ LayoutPoint m_bestPosition; |
+ float m_bestPositionScore; |
}; |
bool SnapToLinesLayouter::findFirstLineBox(InlineFlowBox*& firstLineBox) |
@@ -143,7 +147,13 @@ void SnapToLinesLayouter::placeBoxInDefaultPosition(LayoutUnit position, bool& s |
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. |
+ ASSERT(m_bestPosition == LayoutPoint::zero()); |
+ |
// 15. Let best position score be null. |
+ // (Setting score to positive infinite that should be guaranteed to be |
+ // larger than any overlap - and easily recognizable as 'best position is |
+ // null' as well.) |
+ ASSERT(std::isinf(m_bestPositionScore)); |
// 16. Let switched be false. |
switched = false; |
@@ -213,16 +223,15 @@ bool SnapToLinesLayouter::switchDirection(bool& switched, LayoutUnit& step) |
// 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. |
+ if (switched) { |
+ m_cueBox.setLocation(m_bestPosition); |
+ return false; |
+ } |
// 25. 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) |
- return false; |
- |
// 26. Negate step. |
step = -step; |
@@ -231,6 +240,26 @@ bool SnapToLinesLayouter::switchDirection(bool& switched, LayoutUnit& step) |
return true; |
} |
+static LayoutUnit computeArea(const LayoutRect& rect) |
+{ |
+ return rect.size().width() * rect.size().height(); |
+} |
+ |
+float SnapToLinesLayouter::computePositionScore() const |
+{ |
+ // Compute the percentage of the area of the bounding box of the boxes in |
+ // boxes that is outside the title area box. |
+ LayoutRect boundingBox = m_cueBox.absoluteBoundingBoxRect(); |
+ LayoutRect titleAreaBox = m_cueBox.containingBlock()->absoluteBoundingBoxRect(); |
+ LayoutRect boxOverlap = intersection(titleAreaBox, boundingBox); |
+ // We know the intersection/overlap, which means we can determine the |
+ // non-overlapping part by subtracting that area from the bounding box area. |
+ LayoutUnit overlappingArea = computeArea(boxOverlap); |
+ LayoutUnit boundingBoxArea = computeArea(boundingBox); |
+ ASSERT(overlappingArea >= 0 && overlappingArea <= boundingBoxArea); |
+ return (boundingBoxArea - overlappingArea) / boundingBoxArea.toFloat(); |
+} |
+ |
void SnapToLinesLayouter::layout() |
{ |
// http://dev.w3.org/html5/webvtt/#dfn-apply-webvtt-cue-settings |
@@ -259,6 +288,8 @@ void SnapToLinesLayouter::layout() |
// 19. 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. |
+ float currentPositionScore = computePositionScore(); |
+ |
// 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 |
@@ -266,6 +297,11 @@ void SnapToLinesLayouter::layout() |
// 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 (currentPositionScore < m_bestPositionScore) { |
+ m_bestPosition = m_cueBox.location(); |
+ m_bestPositionScore = currentPositionScore; |
+ } |
+ |
if (!shouldSwitchDirection(firstLineBox, step)) { |
// 22. Move all the boxes in boxes ... |
moveBoxesByStep(step); |