Changeset 150452 in webkit


Ignore:
Timestamp:
May 21, 2013 10:14:53 AM (11 years ago)
Author:
jer.noble@apple.com
Message:

Implement overlap avoidance for cues with snap-to-lines flag not set
https://bugs.webkit.org/show_bug.cgi?id=84296

Reviewed by Eric Carlson.

Source/WebCore:

Test: media/track/track-cue-overlap-snap-to-lines-not-set.html

Support overlap avoidance for the non-snap-to-lines part of the WebVTT spec.

  • rendering/RenderTextTrackCue.cpp:

(WebCore::RenderTextTrackCue::isOutside): Split implementation into rectIsWithinContainer().
(WebCore::RenderTextTrackCue::rectIsWithinContainer): Ditto.
(WebCore::RenderTextTrackCue::isOverlapping): Split into overlappingObject() and overlappingObjectForRect().
(WebCore::RenderTextTrackCue::overlappingObject): Ditto.
(WebCore::RenderTextTrackCue::overlappingObjectForRect): Ditto.
(WebCore::RenderTextTrackCue::moveIfNecessaryToKeepWithinContainer): Added.
(WebCore::RenderTextTrackCue::findNonOverlappingPosition): When an overlapping object is found, move the

cue to just above or below that object and try again.

(WebCore::RenderTextTrackCue::repositionCueSnapToLinesSet): Move implementation into moveIfNecessaryToKeepWithinContainer().
(WebCore::RenderTextTrackCue::repositionCueSnapToLinesNotSet): Add implementanton based on above.

  • rendering/RenderTextTrackCue.h:

LayoutTests:

  • media/track/track-cue-overlap-snap-to-lines-not-set-expected.txt: Added.
  • media/track/track-cue-overlap-snap-to-lines-not-set.html: Added.
Location:
trunk
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r150439 r150452  
     12013-05-20  Jer Noble  <jer.noble@apple.com>
     2
     3        Implement overlap avoidance for cues with snap-to-lines flag not set
     4        https://bugs.webkit.org/show_bug.cgi?id=84296
     5
     6        Reviewed by Eric Carlson.
     7
     8        * media/track/track-cue-overlap-snap-to-lines-not-set-expected.txt: Added.
     9        * media/track/track-cue-overlap-snap-to-lines-not-set.html: Added.
     10
    1112013-05-21  Krzysztof Czech  <k.czech@samsung.com>
    212
  • trunk/Source/WebCore/ChangeLog

    r150446 r150452  
     12013-05-20  Jer Noble  <jer.noble@apple.com>
     2
     3        Implement overlap avoidance for cues with snap-to-lines flag not set
     4        https://bugs.webkit.org/show_bug.cgi?id=84296
     5
     6        Reviewed by Eric Carlson.
     7
     8        Test: media/track/track-cue-overlap-snap-to-lines-not-set.html
     9
     10        Support overlap avoidance for the non-snap-to-lines part of the WebVTT spec.
     11
     12        * rendering/RenderTextTrackCue.cpp:
     13        (WebCore::RenderTextTrackCue::isOutside): Split implementation into rectIsWithinContainer().
     14        (WebCore::RenderTextTrackCue::rectIsWithinContainer): Ditto.
     15        (WebCore::RenderTextTrackCue::isOverlapping): Split into overlappingObject() and overlappingObjectForRect().
     16        (WebCore::RenderTextTrackCue::overlappingObject): Ditto.
     17        (WebCore::RenderTextTrackCue::overlappingObjectForRect): Ditto.
     18        (WebCore::RenderTextTrackCue::moveIfNecessaryToKeepWithinContainer): Added.
     19        (WebCore::RenderTextTrackCue::findNonOverlappingPosition): When an overlapping object is found, move the
     20            cue to just above or below that object and try again.
     21        (WebCore::RenderTextTrackCue::repositionCueSnapToLinesSet): Move implementation into moveIfNecessaryToKeepWithinContainer().
     22        (WebCore::RenderTextTrackCue::repositionCueSnapToLinesNotSet): Add implementanton based on above.
     23        * rendering/RenderTextTrackCue.h:
     24
    1252013-05-21  Alberto Garcia  <agarcia@igalia.com>
    226
  • trunk/Source/WebCore/rendering/RenderTextTrackCue.cpp

    r148536 r150452  
    125125bool RenderTextTrackCue::isOutside() const
    126126{
    127     return !containingBlock()->absoluteBoundingBoxRect().contains(absoluteContentBox());
    128 }
     127    return !rectIsWithinContainer(absoluteContentBox());
     128}
     129
     130bool RenderTextTrackCue::rectIsWithinContainer(const IntRect& rect) const
     131{
     132    return containingBlock()->absoluteBoundingBoxRect().contains(rect);
     133}
     134
    129135
    130136bool RenderTextTrackCue::isOverlapping() const
     137{
     138    return overlappingObject();
     139}
     140
     141RenderObject* RenderTextTrackCue::overlappingObject() const
     142{
     143    return overlappingObjectForRect(absoluteBoundingBoxRect());
     144}
     145
     146RenderObject* RenderTextTrackCue::overlappingObjectForRect(const IntRect& rect) const
    131147{
    132148    for (RenderObject* box = previousSibling(); box; box = box->previousSibling()) {
    133149        IntRect boxRect = box->absoluteBoundingBoxRect();
    134150
    135         if (absoluteBoundingBoxRect().intersects(boxRect))
    136             return true;
    137     }
    138 
    139     return false;
     151        if (rect.intersects(boxRect))
     152            return box;
     153    }
     154
     155    return 0;
    140156}
    141157
     
    201217    switched = true;
    202218    return true;
     219}
     220
     221void RenderTextTrackCue::moveIfNecessaryToKeepWithinContainer()
     222{
     223    IntRect containerRect = containingBlock()->absoluteBoundingBoxRect();
     224    IntRect cueRect = absoluteBoundingBoxRect();
     225
     226    int topOverflow = cueRect.y() - containerRect.y();
     227    int bottomOverflow = containerRect.maxY() - cueRect.maxY();
     228
     229    int verticalAdjustment = 0;
     230    if (topOverflow < 0)
     231        verticalAdjustment = -topOverflow;
     232    else if (bottomOverflow < 0)
     233        verticalAdjustment = bottomOverflow;
     234
     235    if (verticalAdjustment)
     236        setY(y() + verticalAdjustment);
     237
     238    int leftOverflow = cueRect.x() - containerRect.x();
     239    int rightOverflow = containerRect.maxX() - cueRect.maxX();
     240
     241    int horizontalAdjustment = 0;
     242    if (leftOverflow < 0)
     243        horizontalAdjustment = -leftOverflow;
     244    else if (rightOverflow < 0)
     245        horizontalAdjustment = rightOverflow;
     246
     247    if (horizontalAdjustment)
     248        setX(x() + horizontalAdjustment);
     249}
     250
     251bool RenderTextTrackCue::findNonOverlappingPosition(int& newX, int& newY) const
     252{
     253    newX = x();
     254    newY = y();
     255    IntRect srcRect = absoluteBoundingBoxRect();
     256    IntRect destRect = srcRect;
     257
     258    // Move the box up, looking for a non-overlapping position:
     259    while (RenderObject* box = overlappingObjectForRect(destRect)) {
     260        if (m_cue->getWritingDirection() == TextTrackCue::Horizontal)
     261            destRect.setY(box->absoluteBoundingBoxRect().y() - destRect.height());
     262        else
     263            destRect.setX(box->absoluteBoundingBoxRect().x() - destRect.width());
     264    }
     265
     266    if (rectIsWithinContainer(destRect)) {
     267        newX += destRect.x() - srcRect.x();
     268        newY += destRect.y() - srcRect.y();
     269        return true;
     270    }
     271
     272    destRect = srcRect;
     273
     274    // Move the box down, looking for a non-overlapping position:
     275    while (RenderObject* box = overlappingObjectForRect(destRect)) {
     276        if (m_cue->getWritingDirection() == TextTrackCue::Horizontal)
     277            destRect.setY(box->absoluteBoundingBoxRect().maxY());
     278        else
     279            destRect.setX(box->absoluteBoundingBoxRect().maxX());
     280    }
     281
     282    if (rectIsWithinContainer(destRect)) {
     283        newX += destRect.x() - srcRect.x();
     284        newY += destRect.y() - srcRect.y();
     285        return true;
     286    }
     287
     288    return false;
    203289}
    204290
     
    230316    // Acommodate extra top and bottom padding, border or margin.
    231317    // Note: this is supported only for internal UA styling, not through the cue selector.
    232     if (hasInlineDirectionBordersPaddingOrMargin()) {
    233         IntRect containerRect = containingBlock()->absoluteBoundingBoxRect();
    234         IntRect cueRect = absoluteBoundingBoxRect();
    235 
    236         int topOverflow = cueRect.y() - containerRect.y();
    237         int bottomOverflow = containerRect.y() + containerRect.height() - cueRect.y() - cueRect.height();
    238 
    239         int adjustment = 0;
    240         if (topOverflow < 0)
    241             adjustment = -topOverflow;
    242         else if (bottomOverflow < 0)
    243             adjustment = bottomOverflow;
    244 
    245         if (adjustment)
    246             setY(y() + adjustment);
    247     }
     318    if (hasInlineDirectionBordersPaddingOrMargin())
     319        moveIfNecessaryToKeepWithinContainer();
    248320}
    249321
     
    268340void RenderTextTrackCue::repositionCueSnapToLinesNotSet()
    269341{
    270     // FIXME: Implement overlapping detection when snap-to-lines is not set. http://wkb.ug/84296
     342    // 3. If none of the boxes in boxes would overlap any of the boxes in output, and all the boxes in
     343    // output are within the video's rendering area, then jump to the step labeled done positioning below.
     344    if (!isOutside() && !isOverlapping())
     345        return;
     346
     347    // 4. If there is a position to which the boxes in boxes can be moved while maintaining the relative
     348    // positions of the boxes in boxes to each other such that none of the boxes in boxes would overlap
     349    // any of the boxes in output, and all the boxes in output would be within the video's rendering area,
     350    // then move the boxes in boxes to the closest such position to their current position, and then jump
     351    // to the step labeled done positioning below. If there are multiple such positions that are equidistant
     352    // from their current position, use the highest one amongst them; if there are several at that height,
     353    // then use the leftmost one amongst them.
     354    moveIfNecessaryToKeepWithinContainer();
     355    int x = 0;
     356    int y = 0;
     357    if (!findNonOverlappingPosition(x, y))
     358        return;
     359
     360    setX(x);
     361    setY(y);
    271362}
    272363
  • trunk/Source/WebCore/rendering/RenderTextTrackCue.h

    r150312 r150452  
    3636namespace WebCore {
    3737
     38class RenderBox;
    3839class TextTrackCueBox;
    3940
     
    4647
    4748    bool isOutside() const;
     49    bool rectIsWithinContainer(const IntRect&) const;
    4850    bool isOverlapping() const;
     51    RenderObject* overlappingObject() const;
     52    RenderObject* overlappingObjectForRect(const IntRect&) const;
    4953    bool shouldSwitchDirection(InlineFlowBox*, LayoutUnit) const;
    5054
    5155    void moveBoxesByStep(LayoutUnit);
    5256    bool switchDirection(bool&, LayoutUnit&);
     57    void moveIfNecessaryToKeepWithinContainer();
     58    bool findNonOverlappingPosition(int& x, int& y) const;
    5359
    5460    bool initializeLayoutParameters(InlineFlowBox*&, LayoutUnit&, LayoutUnit&);
Note: See TracChangeset for help on using the changeset viewer.