Changeset 154875 in webkit


Ignore:
Timestamp:
Aug 30, 2013 5:58:10 AM (11 years ago)
Author:
commit-queue@webkit.org
Message:

Source/WebCore: [CSS Masking] -webkit-mask-repeat: space does not work
Added the space option to background-repeat and -webkit-mask-repeat.
With the property value 'space', the background or mask image gets repeated as often as it fits within the background positioning
area. The repeated images are spaced equally to fill the unused area.
https://bugs.webkit.org/show_bug.cgi?id=119324

Patch by Andrei Parvu <parvu@adobe.com> on 2013-08-30
Reviewed by Dirk Schulze.

Tests: css3/background/background-repeat-space-border.html

css3/background/background-repeat-space-content.html
css3/background/background-repeat-space-padding.html
css3/masking/mask-repeat-space-border.html
css3/masking/mask-repeat-space-content.html
css3/masking/mask-repeat-space-padding.html

  • platform/graphics/GeneratorGeneratedImage.cpp:

(WebCore::GeneratorGeneratedImage::drawPattern): Passed the space values to the image buffer.

  • platform/graphics/Image.cpp:

(WebCore::Image::drawTiled): Added the space values when computing the location of the tile.

  • platform/graphics/Image.h: Added the space property.

(WebCore::Image::spaceSize):
(WebCore::Image::setSpaceSize):

  • platform/graphics/ImageBuffer.h: Added the space property.

(WebCore::ImageBuffer::spaceSize):
(WebCore::ImageBuffer::setSpaceSize):

  • platform/graphics/cg/ImageBufferCG.cpp: Passed the space values when copying an image.

(WebCore::ImageBuffer::copyImage):

  • platform/graphics/cg/ImageCG.cpp: Added the space values when creating a platform pattern.

(WebCore::Image::drawPattern):

  • rendering/RenderBoxModelObject.cpp:

(WebCore::RenderBoxModelObject::paintFillLayerExtended): Computed the space values on x and y axis.
(WebCore::getSpace):
(WebCore::RenderBoxModelObject::calculateBackgroundImageGeometry): Pass the space values to the Image class.

  • rendering/RenderBoxModelObject.h: Added the space property.

(WebCore::RenderBoxModelObject::BackgroundImageGeometry::spaceSize):
(WebCore::RenderBoxModelObject::BackgroundImageGeometry::setSpaceSize):

  • svg/graphics/SVGImage.cpp: Passed the space property to the created image.

(WebCore::SVGImage::drawPatternForContainer):

  • svg/graphics/SVGImageForContainer.cpp: Passed the space property to the image property.

(WebCore::SVGImageForContainer::drawPattern):

LayoutTests: [CSS Masking] -webkit-mask-repeat: space does not work
Added tests to verify correct usage of background-repeat: space and mask-repeat: space.
Added one test for each possible mask/background clip: border, padding and content
https://bugs.webkit.org/show_bug.cgi?id=119324

Patch by Andrei Parvu <parvu@adobe.com> on 2013-08-30
Reviewed by Dirk Schulze.

  • css3/background/background-repeat-space-border-expected.html: Added.
  • css3/background/background-repeat-space-border.html: Added.
  • css3/background/background-repeat-space-content-expected.html: Added.
  • css3/background/background-repeat-space-content.html: Added.
  • css3/background/background-repeat-space-padding-expected.html: Added.
  • css3/background/background-repeat-space-padding.html: Added.
  • css3/masking/mask-repeat-space-border-expected.html: Added.
  • css3/masking/mask-repeat-space-border.html: Added.
  • css3/masking/mask-repeat-space-content-expected.html: Added.
  • css3/masking/mask-repeat-space-content.html: Added.
  • css3/masking/mask-repeat-space-padding-expected.html: Added.
  • css3/masking/mask-repeat-space-padding.html: Added.
Location:
trunk
Files:
13 added
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r154871 r154875  
     12013-08-30  Andrei Parvu  <parvu@adobe.com>
     2
     3        [CSS Masking] -webkit-mask-repeat: space does not work
     4        Added tests to verify correct usage of background-repeat: space and mask-repeat: space.
     5        Added one test for each possible mask/background clip: border, padding and content
     6        https://bugs.webkit.org/show_bug.cgi?id=119324
     7
     8        Reviewed by Dirk Schulze.
     9
     10        * css3/background/background-repeat-space-border-expected.html: Added.
     11        * css3/background/background-repeat-space-border.html: Added.
     12        * css3/background/background-repeat-space-content-expected.html: Added.
     13        * css3/background/background-repeat-space-content.html: Added.
     14        * css3/background/background-repeat-space-padding-expected.html: Added.
     15        * css3/background/background-repeat-space-padding.html: Added.
     16        * css3/masking/mask-repeat-space-border-expected.html: Added.
     17        * css3/masking/mask-repeat-space-border.html: Added.
     18        * css3/masking/mask-repeat-space-content-expected.html: Added.
     19        * css3/masking/mask-repeat-space-content.html: Added.
     20        * css3/masking/mask-repeat-space-padding-expected.html: Added.
     21        * css3/masking/mask-repeat-space-padding.html: Added.
     22
    1232013-08-30  Commit Queue  <commit-queue@webkit.org>
    224
  • trunk/Source/WebCore/ChangeLog

    r154873 r154875  
     12013-08-30  Andrei Parvu  <parvu@adobe.com>
     2
     3        [CSS Masking] -webkit-mask-repeat: space does not work
     4        Added the space option to background-repeat and -webkit-mask-repeat.
     5        With the property value 'space', the background or mask image gets repeated as often as it fits within the background positioning
     6        area. The repeated images are spaced equally to fill the unused area.
     7        https://bugs.webkit.org/show_bug.cgi?id=119324
     8
     9        Reviewed by Dirk Schulze.
     10
     11        Tests: css3/background/background-repeat-space-border.html
     12               css3/background/background-repeat-space-content.html
     13               css3/background/background-repeat-space-padding.html
     14               css3/masking/mask-repeat-space-border.html
     15               css3/masking/mask-repeat-space-content.html
     16               css3/masking/mask-repeat-space-padding.html
     17
     18        * platform/graphics/GeneratorGeneratedImage.cpp:
     19        (WebCore::GeneratorGeneratedImage::drawPattern): Passed the space values to the image buffer.
     20        * platform/graphics/Image.cpp:
     21        (WebCore::Image::drawTiled): Added the space values when computing the location of the tile.
     22        * platform/graphics/Image.h: Added the space property.
     23        (WebCore::Image::spaceSize):
     24        (WebCore::Image::setSpaceSize):
     25        * platform/graphics/ImageBuffer.h: Added the space property.
     26        (WebCore::ImageBuffer::spaceSize):
     27        (WebCore::ImageBuffer::setSpaceSize):
     28        * platform/graphics/cg/ImageBufferCG.cpp: Passed the space values when copying an image.
     29        (WebCore::ImageBuffer::copyImage):
     30        * platform/graphics/cg/ImageCG.cpp: Added the space values when creating a platform pattern.
     31        (WebCore::Image::drawPattern):
     32        * rendering/RenderBoxModelObject.cpp:
     33        (WebCore::RenderBoxModelObject::paintFillLayerExtended): Computed the space values on x and y axis.
     34        (WebCore::getSpace):
     35        (WebCore::RenderBoxModelObject::calculateBackgroundImageGeometry): Pass the space values to the Image class.
     36        * rendering/RenderBoxModelObject.h: Added the space property.
     37        (WebCore::RenderBoxModelObject::BackgroundImageGeometry::spaceSize):
     38        (WebCore::RenderBoxModelObject::BackgroundImageGeometry::setSpaceSize):
     39        * svg/graphics/SVGImage.cpp: Passed the space property to the created image.
     40        (WebCore::SVGImage::drawPatternForContainer):
     41        * svg/graphics/SVGImageForContainer.cpp: Passed the space property to the image property.
     42        (WebCore::SVGImageForContainer::drawPattern):
     43
    1442013-08-30  Antti Koivisto  <antti@apple.com>
    245
  • trunk/Source/WebCore/platform/graphics/GeneratorGeneratedImage.cpp

    r151547 r154875  
    7575    }
    7676
     77    m_cachedImageBuffer->setSpaceSize(spaceSize());
    7778    // Tile the image buffer into the context.
    7879    m_cachedImageBuffer->drawPattern(destContext, adjustedSrcRect, adjustedPatternCTM, phase, styleColorSpace, compositeOp, destRect);
  • trunk/Source/WebCore/platform/graphics/Image.cpp

    r154088 r154875  
    115115
    116116    FloatRect oneTileRect;
    117     oneTileRect.setX(destRect.x() + fmodf(fmodf(-srcPoint.x(), scaledTileSize.width()) - scaledTileSize.width(), scaledTileSize.width()));
    118     oneTileRect.setY(destRect.y() + fmodf(fmodf(-srcPoint.y(), scaledTileSize.height()) - scaledTileSize.height(), scaledTileSize.height()));
     117    FloatSize actualTileSize(scaledTileSize.width() + spaceSize().width(), scaledTileSize.height() + spaceSize().height());
     118    oneTileRect.setX(destRect.x() + fmodf(fmodf(-srcPoint.x(), actualTileSize.width()) - actualTileSize.width(), actualTileSize.width()));
     119    oneTileRect.setY(destRect.y() + fmodf(fmodf(-srcPoint.y(), actualTileSize.height()) - actualTileSize.height(), actualTileSize.height()));
    119120    oneTileRect.setSize(scaledTileSize);
    120121   
     
    131132
    132133    AffineTransform patternTransform = AffineTransform().scaleNonUniform(scale.width(), scale.height());
    133     FloatRect tileRect(FloatPoint(), intrinsicTileSize);   
     134    FloatRect tileRect(FloatPoint(), intrinsicTileSize);
    134135    drawPattern(ctxt, tileRect, patternTransform, oneTileRect.location(), styleColorSpace, op, destRect, blendMode);
    135    
     136
    136137    startAnimation();
    137138}
  • trunk/Source/WebCore/platform/graphics/Image.h

    r154088 r154875  
    3030#include "Color.h"
    3131#include "ColorSpace.h"
     32#include "FloatSize.h"
    3233#include "GraphicsTypes.h"
    3334#include "ImageOrientation.h"
     
    188189#endif
    189190
     191    FloatSize spaceSize() const { return m_space; }
     192    void setSpaceSize(const FloatSize& space)
     193    {
     194        m_space = space;
     195    }
    190196protected:
    191197    Image(ImageObserver* = 0);
     
    210216    RefPtr<SharedBuffer> m_encodedImageData;
    211217    ImageObserver* m_imageObserver;
     218    FloatSize m_space;
    212219};
    213220
  • trunk/Source/WebCore/platform/graphics/ImageBuffer.h

    r153728 r154875  
    129129        bool copyToPlatformTexture(GraphicsContext3D&, Platform3DObject, GC3Denum, bool, bool);
    130130
     131        FloatSize spaceSize() const { return m_space; }
     132        void setSpaceSize(const FloatSize& space)
     133        {
     134            m_space = space;
     135        }
     136
    131137    private:
    132138#if USE(CG)
     
    153159        float m_resolutionScale;
    154160        OwnPtr<GraphicsContext> m_context;
     161        FloatSize m_space;
    155162
    156163        // This constructor will place its success into the given out-variable
  • trunk/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp

    r154201 r154875  
    238238        return 0;
    239239
    240     return BitmapImage::create(image.get());
     240    RefPtr<BitmapImage> bitmapImage = BitmapImage::create(image.get());
     241    bitmapImage->setSpaceSize(spaceSize());
     242
     243    return bitmapImage.release();
    241244}
    242245
  • trunk/Source/WebCore/platform/graphics/cg/ImageCG.cpp

    r149255 r154875  
    7474}
    7575
     76static void patternReleaseOnMainThreadCallback(void* info)
     77{
     78    CGImageRelease((CGImageRef)info);
     79}
     80
     81static void patternReleaseCallback(void* info)
     82{
     83    callOnMainThread(patternReleaseOnMainThreadCallback, info);
     84}
     85
    7686void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const AffineTransform& patternTransform,
    7787    const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect, BlendMode blendMode)
     
    113123    // Adjust the color space.
    114124    subImage = Image::imageWithColorSpace(subImage.get(), styleColorSpace);
    115    
     125
    116126    // Leopard has an optimized call for the tiling of image patterns, but we can only use it if the image has been decoded enough that
    117127    // its buffer is the same size as the overall image.  Because a partially decoded CGImageRef with a smaller width or height than the
     
    120130    float scaledTileWidth = tileRect.width() * narrowPrecisionToFloat(patternTransform.a());
    121131    float w = CGImageGetWidth(tileImage);
    122     if (w == size().width() && h == size().height())
     132    if (w == size().width() && h == size().height() && !spaceSize().width() && !spaceSize().height())
    123133        CGContextDrawTiledImage(context, FloatRect(adjustedX, adjustedY, scaledTileWidth, scaledTileHeight), subImage.get());
    124134    else {
     135        // On Leopard and newer, this code now only runs for partially decoded images whose buffers do not yet match the overall size of the image.
     136        static const CGPatternCallbacks patternCallbacks = { 0, drawPatternCallback, patternReleaseCallback };
     137        CGAffineTransform matrix = CGAffineTransformMake(narrowPrecisionToCGFloat(patternTransform.a()), 0, 0, narrowPrecisionToCGFloat(patternTransform.d()), adjustedX, adjustedY);
     138        matrix = CGAffineTransformConcat(matrix, CGContextGetCTM(context));
     139        // The top of a partially-decoded image is drawn at the bottom of the tile. Map it to the top.
     140        matrix = CGAffineTransformTranslate(matrix, 0, size().height() - h);
     141        CGImageRef platformImage = CGImageRetain(subImage.get());
     142        RetainPtr<CGPatternRef> pattern = adoptCF(CGPatternCreate(platformImage, CGRectMake(0, 0, tileRect.width(), tileRect.height()), matrix,
     143            tileRect.width() + spaceSize().width() * (1 / narrowPrecisionToFloat(patternTransform.a())),
     144            tileRect.height() + spaceSize().height() * (1 / narrowPrecisionToFloat(patternTransform.d())),
     145            kCGPatternTilingConstantSpacing, true, &patternCallbacks));
     146       
     147        if (!pattern)
     148            return;
    125149
    126     // On Leopard and newer, this code now only runs for partially decoded images whose buffers do not yet match the overall size of the image.
    127     static const CGPatternCallbacks patternCallbacks = { 0, drawPatternCallback, NULL };
    128     CGAffineTransform matrix = CGAffineTransformMake(narrowPrecisionToCGFloat(patternTransform.a()), 0, 0, narrowPrecisionToCGFloat(patternTransform.d()), adjustedX, adjustedY);
    129     matrix = CGAffineTransformConcat(matrix, CGContextGetCTM(context));
    130     // The top of a partially-decoded image is drawn at the bottom of the tile. Map it to the top.
    131     matrix = CGAffineTransformTranslate(matrix, 0, size().height() - h);
    132     RetainPtr<CGPatternRef> pattern = adoptCF(CGPatternCreate(subImage.get(), CGRectMake(0, 0, tileRect.width(), tileRect.height()),
    133                                              matrix, tileRect.width(), tileRect.height(),
    134                                              kCGPatternTilingConstantSpacing, true, &patternCallbacks));
    135     if (!pattern)
    136         return;
     150        RetainPtr<CGColorSpaceRef> patternSpace = adoptCF(CGColorSpaceCreatePattern(0));
    137151
    138     RetainPtr<CGColorSpaceRef> patternSpace = adoptCF(CGColorSpaceCreatePattern(0));
    139    
    140     CGFloat alpha = 1;
    141     RetainPtr<CGColorRef> color = adoptCF(CGColorCreateWithPattern(patternSpace.get(), pattern.get(), &alpha));
    142     CGContextSetFillColorSpace(context, patternSpace.get());
     152        CGFloat alpha = 1;
     153        RetainPtr<CGColorRef> color = adoptCF(CGColorCreateWithPattern(patternSpace.get(), pattern.get(), &alpha));
     154        CGContextSetFillColorSpace(context, patternSpace.get());
    143155
    144     // FIXME: Really want a public API for this. It is just CGContextSetBaseCTM(context, CGAffineTransformIdentiy).
    145     wkSetBaseCTM(context, CGAffineTransformIdentity);
    146     CGContextSetPatternPhase(context, CGSizeZero);
     156        // FIXME: Really want a public API for this. It is just CGContextSetBaseCTM(context, CGAffineTransformIdentiy).
     157        wkSetBaseCTM(context, CGAffineTransformIdentity);
     158        CGContextSetPatternPhase(context, CGSizeZero);
    147159
    148     CGContextSetFillColorWithColor(context, color.get());
    149     CGContextFillRect(context, CGContextGetClipBoundingBox(context));
    150 
     160        CGContextSetFillColorWithColor(context, color.get());
     161        CGContextFillRect(context, CGContextGetClipBoundingBox(context));
    151162    }
    152163
  • trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp

    r154702 r154875  
    995995            RefPtr<Image> image = bgImage->image(clientForBackgroundImage, geometry.tileSize());
    996996            bool useLowQualityScaling = shouldPaintAtLowQuality(context, image.get(), bgLayer, geometry.tileSize());
     997            if (image.get())
     998                image->setSpaceSize(geometry.spaceSize());
    997999            context->drawTiledImage(image.get(), style()->colorSpace(), geometry.destRect(), geometry.relativePhase(), geometry.tileSize(),
    9981000                compositeOp, useLowQualityScaling, bgLayer->blendMode());
     
    12261228}
    12271229
     1230static inline int getSpace(int areaSize, int tileSize)
     1231{
     1232    int numberOfTiles = areaSize / tileSize;
     1233    int space = 0;
     1234
     1235    if (numberOfTiles > 1)
     1236        space = roundedLayoutUnit((float)(areaSize - numberOfTiles * tileSize) / (numberOfTiles - 1));
     1237
     1238    return space;
     1239}
     1240
    12281241void RenderBoxModelObject::calculateBackgroundImageGeometry(const RenderLayerModelObject* paintContainer, const FillLayer* fillLayer, const LayoutRect& paintRect,
    12291242    BackgroundImageGeometry& geometry, RenderObject* backgroundObject) const
     
    13151328        geometry.setTileSize(fillTileSize);
    13161329        geometry.setPhaseX(geometry.tileSize().width() ? geometry.tileSize().width() - roundToInt(computedXPosition + left) % geometry.tileSize().width() : 0);
     1330        geometry.setSpaceSize(FloatSize());
    13171331    }
    13181332
     
    13271341        geometry.setTileSize(fillTileSize);
    13281342        geometry.setPhaseY(geometry.tileSize().height() ? geometry.tileSize().height() - roundToInt(computedYPosition + top) % geometry.tileSize().height() : 0);
    1329     }
    1330 
    1331     if (backgroundRepeatX == RepeatFill)
     1343        geometry.setSpaceSize(FloatSize());
     1344    }
     1345
     1346    if (backgroundRepeatX == RepeatFill) {
    13321347        geometry.setPhaseX(geometry.tileSize().width() ? geometry.tileSize().width() - roundToInt(computedXPosition + left) % geometry.tileSize().width() : 0);
    1333     else if (backgroundRepeatX == NoRepeatFill) {
     1348        geometry.setSpaceSize(FloatSize(0, geometry.spaceSize().height()));
     1349    } else if (backgroundRepeatX == SpaceFill && fillTileSize.width() > 0) {
     1350        int space = getSpace(positioningAreaSize.width(), geometry.tileSize().width());
     1351        int actualWidth = geometry.tileSize().width() + space;
     1352
     1353        geometry.setSpaceSize(FloatSize(space, 0));
     1354        geometry.setPhaseX(actualWidth ? actualWidth - roundToInt(computedXPosition + left) % actualWidth : 0);
     1355    } else if (backgroundRepeatX == NoRepeatFill) {
    13341356        int xOffset = fillLayer->backgroundXOrigin() == RightEdge ? availableWidth - computedXPosition : computedXPosition;
    13351357        geometry.setNoRepeatX(left + xOffset);
    1336     }
    1337 
    1338     if (backgroundRepeatY == RepeatFill)
     1358        geometry.setSpaceSize(FloatSize(0, geometry.spaceSize().height()));
     1359    }
     1360
     1361    if (backgroundRepeatY == RepeatFill) {
    13391362        geometry.setPhaseY(geometry.tileSize().height() ? geometry.tileSize().height() - roundToInt(computedYPosition + top) % geometry.tileSize().height() : 0);
    1340     else if (backgroundRepeatY == NoRepeatFill) {
     1363        geometry.setSpaceSize(FloatSize(geometry.spaceSize().width(), 0));
     1364    } else if (backgroundRepeatY == SpaceFill && fillTileSize.height() > 0) {
     1365        int space = getSpace(positioningAreaSize.height(), geometry.tileSize().height());
     1366        int actualHeight = geometry.tileSize().height() + space;
     1367
     1368        geometry.setSpaceSize(FloatSize(geometry.spaceSize().width(), space));
     1369        geometry.setPhaseY(actualHeight ? actualHeight - roundToInt(computedYPosition + top) % actualHeight : 0);
     1370    } else if (backgroundRepeatY == NoRepeatFill) {
    13411371        int yOffset = fillLayer->backgroundYOrigin() == BottomEdge ? availableHeight - computedYPosition : computedYPosition;
    13421372        geometry.setNoRepeatY(top + yOffset);
     1373        geometry.setSpaceSize(FloatSize(geometry.spaceSize().width(), 0));
    13431374    }
    13441375
  • trunk/Source/WebCore/rendering/RenderBoxModelObject.h

    r153688 r154875  
    229229            m_tileSize = tileSize;
    230230        }
    231        
     231        FloatSize spaceSize() const { return m_space; }
     232        void setSpaceSize(const FloatSize& space)
     233        {
     234            m_space = space;
     235        }
     236
    232237        void setPhaseX(int x) { m_phase.setX(x); }
    233238        void setPhaseY(int y) { m_phase.setY(y); }
     
    248253        IntPoint m_phase;
    249254        IntSize m_tileSize;
     255        FloatSize m_space;
    250256        bool m_hasNonLocalGeometry; // Has background-attachment: fixed. Implies that we can't always cheaply compute destRect.
    251257    };
  • trunk/Source/WebCore/svg/graphics/SVGImage.cpp

    r154679 r154875  
    202202    drawForContainer(buffer->context(), containerSize, zoom, imageBufferSize, zoomedContainerRect, ColorSpaceDeviceRGB, CompositeSourceOver, BlendModeNormal);
    203203    RefPtr<Image> image = buffer->copyImage(DontCopyBackingStore, Unscaled);
     204    image->setSpaceSize(spaceSize());
    204205
    205206    // Adjust the source rect and transform due to the image buffer's scaling.
  • trunk/Source/WebCore/svg/graphics/SVGImageForContainer.cpp

    r147622 r154875  
    4646    const FloatPoint& phase, ColorSpace colorSpace, CompositeOperator compositeOp, const FloatRect& dstRect, BlendMode)
    4747{
     48    m_image->setSpaceSize(spaceSize());
    4849    m_image->drawPatternForContainer(context, m_containerSize, m_zoom, srcRect, patternTransform, phase, colorSpace, compositeOp, dstRect);
    4950}
Note: See TracChangeset for help on using the changeset viewer.