Changeset 191590 in webkit


Ignore:
Timestamp:
Oct 26, 2015 11:39:05 AM (8 years ago)
Author:
Simon Fraser
Message:

Implement 'round' and 'space' values for border-image
https://bugs.webkit.org/show_bug.cgi?id=14185

Reviewed by Tim Horton.

Source/WebCore:

Add support for "round" and "space" values for border-image-repeat.
Following "stretch" and "repeat", the code is added to Image::drawTiled().

For "round", we compute an integral number of copies of the image that fit,
and then adjust the tile scale.

For "space", we also compute an integral number N of copies that will fit,
and then divide the remaining space amongst N+1 gaps, adjusting the tiling
phase so that with an even number of images, a gap is centered.

Tests: fast/borders/border-image-round.html

fast/borders/border-image-space.html

  • platform/graphics/Image.cpp:

(WebCore::Image::drawTiled):

  • platform/graphics/cg/GraphicsContextCG.cpp:

(WebCore::GraphicsContext::drawPattern):

LayoutTests:

Ref tests that clip, leaving relevant parts of the images.

  • fast/borders/border-image-round-expected.html: Added.
  • fast/borders/border-image-round.html: Added.
  • fast/borders/border-image-space-expected.html: Added.
  • fast/borders/border-image-space.html: Added.
  • fast/borders/resources/big-border-image-lines.png: Added.
  • fast/borders/resources/big-border-image.png: Added.
Location:
trunk
Files:
6 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r191589 r191590  
     12015-10-26  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Implement 'round' and 'space' values for border-image
     4        https://bugs.webkit.org/show_bug.cgi?id=14185
     5
     6        Reviewed by Tim Horton.
     7       
     8        Ref tests that clip, leaving relevant parts of the images.
     9
     10        * fast/borders/border-image-round-expected.html: Added.
     11        * fast/borders/border-image-round.html: Added.
     12        * fast/borders/border-image-space-expected.html: Added.
     13        * fast/borders/border-image-space.html: Added.
     14        * fast/borders/resources/big-border-image-lines.png: Added.
     15        * fast/borders/resources/big-border-image.png: Added.
     16
    1172015-10-26  Simon Fraser  <simon.fraser@apple.com>
    218
  • trunk/Source/WebCore/ChangeLog

    r191589 r191590  
     12015-10-26  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Implement 'round' and 'space' values for border-image
     4        https://bugs.webkit.org/show_bug.cgi?id=14185
     5
     6        Reviewed by Tim Horton.
     7       
     8        Add support for "round" and "space" values for border-image-repeat.
     9        Following "stretch" and "repeat", the code is added to Image::drawTiled().
     10       
     11        For "round", we compute an integral number of copies of the image that fit,
     12        and then adjust the tile scale.
     13       
     14        For "space", we also compute an integral number N of copies that will fit,
     15        and then divide the remaining space amongst N+1 gaps, adjusting the tiling
     16        phase so that with an even number of images, a gap is centered.
     17
     18        Tests: fast/borders/border-image-round.html
     19               fast/borders/border-image-space.html
     20
     21        * platform/graphics/Image.cpp:
     22        (WebCore::Image::drawTiled):
     23        * platform/graphics/cg/GraphicsContextCG.cpp:
     24        (WebCore::GraphicsContext::drawPattern):
     25
    1262015-10-26  Simon Fraser  <simon.fraser@apple.com>
    227
  • trunk/Source/WebCore/platform/graphics/Image.cpp

    r191352 r191590  
    215215    }
    216216   
    217     // FIXME: We do not support 'round' or 'space' yet. For now just map them to 'repeat'.
    218     if (hRule == RoundTile || hRule == SpaceTile)
    219         hRule = RepeatTile;
    220     if (vRule == RoundTile || vRule == SpaceTile)
    221         vRule = RepeatTile;
    222 
    223     AffineTransform patternTransform = AffineTransform().scaleNonUniform(tileScaleFactor.width(), tileScaleFactor.height());
     217    FloatSize tileScale = tileScaleFactor;
     218    FloatSize spacing;
     219   
     220    // FIXME: These rules follow CSS border-image rules, but they should not be down here in Image.
     221    bool centerOnGapHorizonally = false;
     222    bool centerOnGapVertically = false;
     223    switch (hRule) {
     224    case RoundTile: {
     225        int numItems = std::max<int>(floorf(dstRect.width() / srcRect.width()), 1);
     226        tileScale.setWidth(dstRect.width() / (srcRect.width() * numItems));
     227        break;
     228    }
     229    case SpaceTile: {
     230        int numItems = floorf(dstRect.width() / srcRect.width());
     231        if (!numItems)
     232            return;
     233        spacing.setWidth((dstRect.width() - srcRect.width() * numItems) / (numItems + 1));
     234        tileScale.setWidth(1);
     235        centerOnGapHorizonally = !(numItems & 1);
     236        break;
     237    }
     238    case StretchTile:
     239    case RepeatTile:
     240        break;
     241    }
     242
     243    switch (vRule) {
     244    case RoundTile: {
     245        int numItems = std::max<int>(floorf(dstRect.height() / srcRect.height()), 1);
     246        tileScale.setHeight(dstRect.height() / (srcRect.height() * numItems));
     247        break;
     248        }
     249    case SpaceTile: {
     250        int numItems = floorf(dstRect.height() / srcRect.height());
     251        if (!numItems)
     252            return;
     253        spacing.setHeight((dstRect.height() - srcRect.height() * numItems) / (numItems + 1));
     254        tileScale.setHeight(1);
     255        centerOnGapVertically = !(numItems & 1);
     256        break;
     257    }
     258    case StretchTile:
     259    case RepeatTile:
     260        break;
     261    }
     262
     263    AffineTransform patternTransform = AffineTransform().scaleNonUniform(tileScale.width(), tileScale.height());
    224264
    225265    // We want to construct the phase such that the pattern is centered (when stretch is not
    226266    // set for a particular rule).
    227     float hPhase = tileScaleFactor.width() * srcRect.x();
    228     float vPhase = tileScaleFactor.height() * srcRect.y();
    229     float scaledTileWidth = tileScaleFactor.width() * srcRect.width();
    230     float scaledTileHeight = tileScaleFactor.height() * srcRect.height();
    231     if (hRule == Image::RepeatTile)
     267    float hPhase = tileScale.width() * srcRect.x();
     268    float vPhase = tileScale.height() * srcRect.y();
     269    float scaledTileWidth = tileScale.width() * srcRect.width();
     270    float scaledTileHeight = tileScale.height() * srcRect.height();
     271
     272    if (centerOnGapHorizonally)
     273        hPhase -= spacing.width();
     274    else if (hRule == Image::RepeatTile || hRule == Image::SpaceTile)
    232275        hPhase -= (dstRect.width() - scaledTileWidth) / 2;
    233     if (vRule == Image::RepeatTile)
    234         vPhase -= (dstRect.height() - scaledTileHeight) / 2;
     276
     277    if (centerOnGapVertically)
     278        vPhase -= spacing.height();
     279    else if (vRule == Image::RepeatTile || vRule == Image::SpaceTile)
     280        vPhase -= (dstRect.height() - scaledTileHeight) / 2;
     281
    235282    FloatPoint patternPhase(dstRect.x() - hPhase, dstRect.y() - vPhase);
    236    
    237     drawPattern(ctxt, srcRect, patternTransform, patternPhase, FloatSize(), styleColorSpace, op, dstRect);
     283    drawPattern(ctxt, srcRect, patternTransform, patternPhase, spacing, styleColorSpace, op, dstRect);
    238284
    239285#if PLATFORM(IOS)
  • trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp

    r191466 r191590  
    328328    float scaledTileWidth = tileRect.width() * narrowPrecisionToFloat(patternTransform.a());
    329329    float w = CGImageGetWidth(tileImage);
    330     if (w == image.size().width() && h == image.size().height() && !spacing.width() && !spacing.height())
     330    if (w == image.size().width() && h == image.size().height() && !spacing.width() && !spacing.height()) {
     331        // FIXME: CG seems to snap the images to integral sizes. When we care (e.g. with border-image-repeat: round),
     332        // we should tile all but the last, and stetch the last image to fit.
    331333        CGContextDrawTiledImage(context, FloatRect(adjustedX, adjustedY, scaledTileWidth, scaledTileHeight), subImage.get());
    332     else {
     334    } else {
    333335        static const CGPatternCallbacks patternCallbacks = { 0, drawPatternCallback, patternReleaseCallback };
    334336        CGAffineTransform matrix = CGAffineTransformMake(narrowPrecisionToCGFloat(patternTransform.a()), 0, 0, narrowPrecisionToCGFloat(patternTransform.d()), adjustedX, adjustedY);
     
    359361
    360362        CGContextSetFillColorWithColor(context, color.get());
    361         CGContextFillRect(context, CGContextGetClipBoundingBox(context));
     363        CGContextFillRect(context, CGContextGetClipBoundingBox(context)); // FIXME: we know the clip; we set it above.
    362364    }
    363365}
Note: See TracChangeset for help on using the changeset viewer.