Changeset 27060 in webkit


Ignore:
Timestamp:
Oct 25, 2007 2:03:41 PM (16 years ago)
Author:
hyatt
Message:

WebCore:

Fix for bug 15672, background images don't tile properly inside transforms. This patch fixes background
tiling to work in the presence of transforms and fixes bugs in both SVG and CSS transforms.

Reviewed by aroben and mitz

  • WebCore.base.exp:
  • platform/graphics/Image.cpp: (WebCore::Image::setData):
  • platform/graphics/cg/ImageCG.cpp: (WebCore::ImageInfo::ImageInfo): (WebCore::Image::drawPatternCallback): (WebCore::Image::drawPattern):
  • platform/graphics/mac/GraphicsContextMac.mm: (WebCore::GraphicsContext::drawLineForMisspellingOrBadGrammar):
  • platform/mac/WebCoreSystemInterface.h:
  • platform/mac/WebCoreSystemInterface.mm:

WebKit:

Fix for bug 15672, backgrounds don't tile properly inside transforms. This patch fixes tiling
of backgrounds inside CSS transforms and also of HTML content with background images inside SVG
transforms.

Reviewed by aroben and mmitz

  • WebCoreSupport/WebSystemInterface.m: (InitWebCoreSystemInterface):
  • WebKit.xcodeproj/project.pbxproj:
Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r27056 r27060  
     12007-10-25  David Hyatt  <hyatt@apple.com>
     2
     3        Fix for bug 15672, background images don't tile properly inside transforms.  This patch fixes background
     4        tiling to work in the presence of transforms and fixes bugs in both SVG and CSS transforms.
     5
     6        Reviewed by aroben and mitz
     7
     8        * WebCore.base.exp:
     9        * platform/graphics/Image.cpp:
     10        (WebCore::Image::setData):
     11        * platform/graphics/cg/ImageCG.cpp:
     12        (WebCore::ImageInfo::ImageInfo):
     13        (WebCore::Image::drawPatternCallback):
     14        (WebCore::Image::drawPattern):
     15        * platform/graphics/mac/GraphicsContextMac.mm:
     16        (WebCore::GraphicsContext::drawLineForMisspellingOrBadGrammar):
     17        * platform/mac/WebCoreSystemInterface.h:
     18        * platform/mac/WebCoreSystemInterface.mm:
     19
    1202007-10-25  Brady Eidson  <beidson@apple.com>
    221
  • trunk/WebCore/WebCore.base.exp

    r26787 r27060  
    739739_wkSetNSURLConnectionDefersCallbacks
    740740_wkSetNSURLRequestShouldContentSniff
     741_wkSetPatternBaseCTM
    741742_wkSetPatternPhaseInUserSpace
    742743_wkSetUpFontCache
  • trunk/WebCore/platform/graphics/Image.cpp

    r24417 r27060  
    6969    if (!length)
    7070        return true;
    71 
    72 #ifdef kImageBytesCutoff
    73     // This is a hack to help with testing display of partially-loaded images.
    74     // To enable it, define kImageBytesCutoff to be a size smaller than that of the image files
    75     // being loaded. They'll never finish loading.
    76     if (length > kImageBytesCutoff) {
    77         length = kImageBytesCutoff;
    78         allDataReceived = false;
    79     }
    80 #endif
    8171   
    8272    return dataChanged(allDataReceived);
  • trunk/WebCore/platform/graphics/cg/ImageCG.cpp

    r25187 r27060  
    3939#include "WebCoreSystemInterface.h"
    4040
     41#if PLATFORM(WIN)
     42#include <WebKitSystemInterface/WebKitSystemInterface.h>
     43#endif
     44
    4145namespace WebCore {
    4246
     
    168172}
    169173
     174struct ImageInfo {
     175    ImageInfo(const FloatPoint& point, Image* i)
     176    : tilePoint(point)
     177    , image(i)
     178    {}
     179   
     180    FloatPoint tilePoint;
     181    Image* image;
     182};
     183
    170184void Image::drawPatternCallback(void* info, CGContextRef context)
    171185{
    172     Image* data = (Image*)info;
    173     CGImageRef image = data->nativeImageForCurrentFrame();
    174     float w = CGImageGetWidth(image);
    175     float h = CGImageGetHeight(image);
    176     CGContextDrawImage(context, GraphicsContext(context).roundToDevicePixels(FloatRect(0, -h, w, h)), image);
     186    ImageInfo* data = (ImageInfo*)info;
     187    CGImageRef image = data->image->nativeImageForCurrentFrame();
     188    CGContextDrawImage(context, GraphicsContext(context).roundToDevicePixels(FloatRect(data->tilePoint.x(), data->tilePoint.y(), CGImageGetWidth(image), CGImageGetHeight(image))), image);
    177189}
    178190
     
    181193{
    182194    CGContextRef context = ctxt->platformContext();
    183 
     195    ctxt->save();
     196    CGContextClipToRect(context, destRect);
     197    ctxt->setCompositeOperation(op);
     198    CGContextTranslateCTM(context, destRect.x(), destRect.y());
     199    CGContextScaleCTM(context, 1, -1);
     200    CGContextTranslateCTM(context, 0, -destRect.height());
     201   
     202    // Compute the scaled tile size.
     203    float scaledTileHeight = tileRect.height() * narrowPrecisionToCGFloat(patternTransform.d());
     204   
     205    // We have to adjust the phase to deal with the fact we're in Cartesian space now (with the bottom left corner of destRect being
     206    // the origin).
     207    float adjustedX = phase.x() - destRect.x() + tileRect.x() * patternTransform.a(); // We translated the context so that destRect.x() is the origin, so subtract it out.
     208    float adjustedY = destRect.height() - (phase.y() - destRect.y() + tileRect.y() * patternTransform.d() + scaledTileHeight);
     209
     210    CGImageRef tileImage = nativeImageForCurrentFrame();
     211    float h = CGImageGetHeight(tileImage);
     212   
    184213#ifndef BUILDING_ON_TIGER
    185214    // 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
     
    188217    // when tiling portions of an image, since until we can actually cache the subimage we want to tile, this code won't be any faster.
    189218    // FIXME: Could create WebKitSystemInterface SPI for CGCreatePatternWithImage2 and probably make Tiger tile faster as well.
    190     CGImageRef tileImage = nativeImageForCurrentFrame();
     219    float scaledTileWidth = tileRect.width() * narrowPrecisionToCGFloat(patternTransform.a());
    191220    float w = CGImageGetWidth(tileImage);
    192     float h = CGImageGetHeight(tileImage);
    193     if (w == size().width() && h == size().height() && tileRect.size() == size()) {
    194         ctxt->save();
    195         CGContextClipToRect(context, destRect);
    196         ctxt->setCompositeOperation(op);
    197         CGContextTranslateCTM(context, destRect.x(), destRect.y());
    198         CGContextScaleCTM(context, 1, -1);
    199         CGContextTranslateCTM(context, 0, -destRect.height());
    200        
    201         // Compute the scaled tile size.
    202         float scaledTileWidth = tileRect.width() * narrowPrecisionToCGFloat(patternTransform.a());
    203         float scaledTileHeight = tileRect.height() * narrowPrecisionToCGFloat(patternTransform.d());
    204    
    205         // We have to adjust the phase to deal with the fact we're in Cartesian space now (with the bottom left corner of destRect being
    206         // the origin).
    207         float adjustedX = phase.x() - destRect.x(); // We translated the context so that destRect.x() is the origin, so subtract it out.
    208         float adjustedY = destRect.height() - (phase.y() - destRect.y() + scaledTileHeight);
    209 
     221    if (w == size().width() && h == size().height() && tileRect.size() == size())
    210222        CGContextDrawTiledImage(context, FloatRect(adjustedX, adjustedY, scaledTileWidth, scaledTileHeight), tileImage);
    211         ctxt->restore();
    212     } else {
     223    else {
    213224#endif
    214225
     
    219230    // redecode every time we paint.
    220231    static const CGPatternCallbacks patternCallbacks = { 0, drawPatternCallback, NULL };
    221     CGPatternRef pattern = CGPatternCreate(this, FloatRect(tileRect.x(), -tileRect.y() - tileRect.height(), tileRect.width(), tileRect.height()),
    222                                            CGAffineTransform(patternTransform), tileRect.width(), tileRect.height(),
     232    CGAffineTransform matrix = CGAffineTransformMake(narrowPrecisionToCGFloat(patternTransform.a()), 0, 0, narrowPrecisionToCGFloat(patternTransform.d()), adjustedX, adjustedY);
     233    matrix = CGAffineTransformConcat(matrix, CGContextGetCTM(context));
     234   
     235    // If we're painting a subimage, store the offset to the image.
     236    ImageInfo info(FloatPoint(-tileRect.x(), tileRect.y() + tileRect.height() - h), this);
     237    CGPatternRef pattern = CGPatternCreate(&info, CGRectMake(0, 0, tileRect.width(), tileRect.height()),
     238                                           matrix, tileRect.width(), tileRect.height(),
    223239                                           kCGPatternTilingConstantSpacing, true, &patternCallbacks);
    224     if (!pattern)
    225         return;
    226    
    227     ctxt->save();
    228    
    229     // FIXME: Really want a public API for this.
    230     wkSetPatternPhaseInUserSpace(context, phase);
    231    
     240    if (pattern == NULL) {
     241        ctxt->restore();
     242        return;
     243    }
     244
    232245    CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(NULL);
     246   
     247    CGFloat alpha = 1;
     248    CGColorRef color = CGColorCreateWithPattern(patternSpace, pattern, &alpha);
    233249    CGContextSetFillColorSpace(context, patternSpace);
    234250    CGColorSpaceRelease(patternSpace);
    235    
    236     CGFloat patternAlpha = 1;
    237     CGContextSetFillPattern(context, pattern, &patternAlpha);
    238    
    239     ctxt->setCompositeOperation(op);
    240    
    241     CGContextFillRect(context, destRect);
     251    CGPatternRelease(pattern);
     252
     253    // FIXME: Really want a public API for this.  It is just CGContextSetBaseCTM(context, CGAffineTransformIdentiy).
     254    wkSetPatternBaseCTM(context, CGAffineTransformIdentity);
     255    CGContextSetPatternPhase(context, CGSizeZero);
     256
     257    CGContextSetFillColorWithColor(context, color);
     258    CGContextFillRect(context, CGContextGetClipBoundingBox(context));
     259   
     260    CGColorRelease(color);
    242261   
    243262    ctxt->restore();
    244     CGPatternRelease(pattern);
    245 
     263   
    246264#ifndef BUILDING_ON_TIGER
    247265    }
  • trunk/WebCore/platform/graphics/mac/GraphicsContextMac.mm

    r21091 r27060  
    164164    // FIXME: This code should not use NSGraphicsContext currentContext
    165165    // In order to remove this requirement we will need to use CGPattern instead of NSColor
    166    
     166    // FIXME: This code should not be using wkSetPatternPhaseInUserSpace, as this approach is wrong
     167    // for transforms.
     168
    167169    // Draw underline
    168170    NSGraphicsContext *currentContext = [NSGraphicsContext currentContext];
  • trunk/WebCore/platform/mac/WebCoreSystemInterface.h

    r26484 r27060  
    113113extern void (*wkSetNSURLConnectionDefersCallbacks)(NSURLConnection *, BOOL);
    114114extern void (*wkSetNSURLRequestShouldContentSniff)(NSMutableURLRequest *, BOOL);
     115extern void (*wkSetPatternBaseCTM)(CGContextRef, CGAffineTransform);
    115116extern void (*wkSetPatternPhaseInUserSpace)(CGContextRef, CGPoint);
    116117extern void (*wkSetUpFontCache)(size_t);
  • trunk/WebCore/platform/mac/WebCoreSystemInterface.mm

    r26484 r27060  
    6060void (*wkSetCGFontRenderingMode)(CGContextRef, NSFont*);
    6161void (*wkSetDragImage)(NSImage*, NSPoint offset);
     62void (*wkSetPatternBaseCTM)(CGContextRef, CGAffineTransform);
    6263void (*wkSetPatternPhaseInUserSpace)(CGContextRef, CGPoint point);
    6364void (*wkSetUpFontCache)(size_t);
  • trunk/WebKit/ChangeLog

    r27059 r27060  
     12007-10-25  David Hyatt  <hyatt@apple.com>
     2
     3        Fix for bug 15672, backgrounds don't tile properly inside transforms.  This patch fixes tiling
     4        of backgrounds inside CSS transforms and also of HTML content with background images inside SVG
     5        transforms.
     6
     7        Reviewed by aroben and mmitz
     8
     9        * WebCoreSupport/WebSystemInterface.m:
     10        (InitWebCoreSystemInterface):
     11        * WebKit.xcodeproj/project.pbxproj:
     12
    1132007-10-25  John Sullivan  <sullivan@apple.com>
    214
  • trunk/WebKit/WebCoreSupport/WebSystemInterface.m

    r26491 r27060  
    7777    INIT(SetNSURLConnectionDefersCallbacks);
    7878    INIT(SetNSURLRequestShouldContentSniff);
     79    INIT(SetPatternBaseCTM);
    7980    INIT(SetPatternPhaseInUserSpace);
    8081    INIT(SetUpFontCache);
Note: See TracChangeset for help on using the changeset viewer.