WebCore:
authorrjw <rjw@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 2 Sep 2004 20:53:54 +0000 (20:53 +0000)
committerrjw <rjw@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 2 Sep 2004 20:53:54 +0000 (20:53 +0000)
Support for patterns in <canvas>

        Reviewed by Hyatt.

        * khtml/ecma/kjs_html.cpp:
        (KJS::Context2DFunction::tryCall):
        (Context2D::putValue):
        (drawPattern):
        (ImagePattern::ImagePattern):
        (ImagePattern::~ImagePattern):
        * khtml/ecma/kjs_html.h:
        (KJS::ImagePattern::getPattern):
        (KJS::ImagePattern::pixmap):
        * kwq/KWQPixmap.h:
        * kwq/KWQPixmap.mm:
        (QPixmap::imageRef):
        * kwq/WebCoreImageRenderer.h:

WebKit:
        Support for patterns in <canvas>.
        (These changes attempt to create a CGImageRef from a WebImageRenderer that
        is used by the pattern drawing function.)

        Reviewed by Hyatt.

        * WebCoreSupport.subproj/WebImageRenderer.h:
        * WebCoreSupport.subproj/WebImageRenderer.m:
        (-[WebImageRenderer dealloc]):
        (-[WebImageRenderer finalize]):
        (-[WebImageRenderer imageRef]):
        (_createImageRef):
        * WebView.subproj/WebPDFView.h:
        * WebView.subproj/WebPDFView.m:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@7437 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog-2005-08-23
WebCore/khtml/ecma/kjs_html.cpp
WebCore/khtml/ecma/kjs_html.h
WebCore/kwq/KWQPixmap.h
WebCore/kwq/KWQPixmap.mm
WebCore/kwq/WebCoreImageRenderer.h
WebKit/ChangeLog
WebKit/WebCoreSupport.subproj/WebImageRenderer.h
WebKit/WebCoreSupport.subproj/WebImageRenderer.m
WebKit/WebView.subproj/WebPDFView.h
WebKit/WebView.subproj/WebPDFView.m

index 97a104b0037e04dbc9578911657cd7fc8f705279..5f71c4e12af3d2245d069726303175d124ffacb7 100644 (file)
@@ -1,3 +1,23 @@
+2004-09-02  Richard Williamson   <rjw@apple.com>
+
+       Support for patterns in <canvas>
+
+        Reviewed by Hyatt.
+
+        * khtml/ecma/kjs_html.cpp:
+        (KJS::Context2DFunction::tryCall):
+        (Context2D::putValue):
+        (drawPattern):
+        (ImagePattern::ImagePattern):
+        (ImagePattern::~ImagePattern):
+        * khtml/ecma/kjs_html.h:
+        (KJS::ImagePattern::getPattern):
+        (KJS::ImagePattern::pixmap):
+        * kwq/KWQPixmap.h:
+        * kwq/KWQPixmap.mm:
+        (QPixmap::imageRef):
+        * kwq/WebCoreImageRenderer.h:
+
 2004-09-01  David Hyatt  <hyatt@apple.com>
 
        Fix for 3769409, a regression from 10.3.4 to 10.3.5 involving <colgroup>s in malformed HTML.
index 688b04c89f35c892bdafc88f74245c16529a5865..4fb9268b7764c068b18dd2e4127b51a6e58b42fa 100644 (file)
@@ -3375,7 +3375,9 @@ static bool isImagePattern(const Value &value)
 }
 
 extern "C" {
-    extern void CGContextReplacePathWithStrokedPath(CGContextRef c);
+
+extern void CGContextReplacePathWithStrokedPath(CGContextRef c);
+
 }
 
 Value KJS::Context2DFunction::tryCall(ExecState *exec, Object &thisObj, const List &args)
@@ -3628,9 +3630,6 @@ Value KJS::Context2DFunction::tryCall(ExecState *exec, Object &thisObj, const Li
                 
                 CGContextRestoreGState(drawingContext);
             }
-            else if (isImagePattern(contextObject->_fillStyle)) {
-                // FIXME:  Implement filling patterns
-            }
             else
                 CGContextFillPath (drawingContext);
                 
@@ -3661,9 +3660,6 @@ Value KJS::Context2DFunction::tryCall(ExecState *exec, Object &thisObj, const Li
                 
                 CGContextRestoreGState(drawingContext);
             }
-            else if (isImagePattern(contextObject->_fillStyle)) {
-                // FIXME:  Implement stroking patterns
-            }
             else
                 CGContextStrokePath (drawingContext);
             renderer->setNeedsImageUpdate();
@@ -4094,7 +4090,7 @@ Value KJS::Context2DFunction::tryCall(ExecState *exec, Object &thisObj, const Li
                 repetitionType = ImagePattern::RepeatY;
             else if (repetitionString == "no-repeat")
                 repetitionType = ImagePattern::NoRepeat;
-            return Object(new ImagePattern(args[0], repetitionType));
+            return Object(new ImagePattern(static_cast<Image*>(o), repetitionType));
         }
     }
 
@@ -4308,11 +4304,20 @@ void Context2D::putValue(ExecState *exec, int token, const Value& value, int /*a
                 ObjectImp *o = static_cast<ObjectImp*>(value.imp());
                 
                 if (o->type() != ObjectType || 
-                    (o->type() == ObjectType && !(o->inherits(&Gradient::info) || o->inherits(&ImagePattern::info)))) {
+                    (!(o->inherits(&Gradient::info) || o->inherits(&ImagePattern::info)))) {
                     Object err = Error::create(exec,TypeError);
                     exec->setException(err);
                     return;
                 }
+
+                if (isImagePattern(value)) {
+                    float patternAlpha = 1;
+                    ImagePattern *imagePattern = static_cast<ImagePattern*>(o);
+                    CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(NULL);
+                    CGContextSetStrokeColorSpace(context, patternSpace);
+                    CGContextSetStrokePattern(context, imagePattern->getPattern(), &patternAlpha);
+                    CGColorSpaceRelease(patternSpace);
+                }
             }
             break;
         }
@@ -4329,11 +4334,22 @@ void Context2D::putValue(ExecState *exec, int token, const Value& value, int /*a
                 ObjectImp *o = static_cast<ObjectImp*>(value.imp());
                 
                 if (o->type() != ObjectType || 
-                    (o->type() == ObjectType && !(o->inherits(&Gradient::info) || o->inherits(&ImagePattern::info)))) {
+                    (!(o->inherits(&Gradient::info) || o->inherits(&ImagePattern::info)))) {
                     Object err = Error::create(exec,TypeError);
                     exec->setException(err);
                     return;
                 }
+
+                if (isImagePattern(value)) {
+                    float patternAlpha = 1;
+                    ImagePattern *imagePattern = static_cast<ImagePattern*>(o);
+                    CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(NULL);
+                    CGContextSetFillColorSpace(context, patternSpace);
+                    CGContextSetFillPattern(context, imagePattern->getPattern(), &patternAlpha);
+                    CGColorSpaceRelease(patternSpace);
+                }
+
+                // Gradients are constructed when needed during fill and stroke operations.
             }
             break;
         }
@@ -4771,10 +4787,55 @@ const ClassInfo KJS::ImagePattern::info = { "ImagePattern", 0, &ImagePatternTabl
 @end
 */
 
-ImagePattern::ImagePattern(Value i, int repetitionType)
+static void drawPattern (void * info, CGContextRef context)
+{
+    ImagePattern *pattern = static_cast<ImagePattern*>(info);
+    QPainter p;
+    QPixmap pixmap = pattern->pixmap();
+    float w = pixmap.width();
+    float h = pixmap.height();
+    
+    // Try and draw bitmap directly
+    CGImageRef ref = pixmap.imageRef();
+    if (ref) {
+        CGContextDrawImage (context, CGRectMake(0, 0, w, h), ref);    
+    }
+    else
+        p.drawFloatPixmap (0, 0, w, h, pixmap, 0.f, 0.f, w, h, 
+            QPainter::compositeOperatorFromString(QString("source-over")), context);
+}
+
+CGPatternCallbacks patternCallbacks = { 0, drawPattern, NULL };
+ImagePattern::ImagePattern(Image *i, int repetitionType)
 {
     _repetitionType = repetitionType;
-    _image = i;
+    khtml::CachedImage *ci = i->image();
+    if (ci) {
+        _pixmap = ci->pixmap();
+        float w = _pixmap.width(), rw = 0;
+        float h = _pixmap.height(), rh = 0;
+        CGRect bounds = CGRectMake (0, 0, w, h);
+        if (repetitionType == Repeat) {
+            rw = w; rh = h;
+        }
+        else if (repetitionType == RepeatX) {
+            rw = w; rh = 0;
+        }
+        else if (repetitionType == RepeatY) {
+            rw = 0; rh = h;
+        }
+        else if (repetitionType == NoRepeat) {
+            rw = 0; rh = 0;
+        }
+            
+        CGAffineTransform transform = CGAffineTransformIdentity;
+        transform = CGAffineTransformScale (transform, 1, -1);
+        transform = CGAffineTransformTranslate (transform, 0, -h);
+        
+        _patternRef = CGPatternCreate(this, bounds, transform, rw, rh, 
+            kCGPatternTilingConstantSpacing, true, &patternCallbacks);
+    }
 }
 
 Value ImagePattern::tryGet(ExecState *exec, const Identifier &propertyName) const
@@ -4806,6 +4867,10 @@ void ImagePattern::putValue(ExecState *exec, int token, const Value& value, int
 
 ImagePattern::~ImagePattern()
 {
+    if (_patternRef) {
+        CGPatternRelease (_patternRef);
+        _patternRef = 0;
+    }
 }
 
 ////////////////////////////////////////////////////////////////
index 7f972a59f400b6e0ad7835faebd9f0b251cacc50..0aa525744ad1349a2b4dafeba88c388d4f17aa0c 100644 (file)
@@ -372,8 +372,7 @@ private:
 
   class ImagePattern : public DOMObject {
   public:
-    //ImagePattern(const DOM::HTMLElement &e);
-    ImagePattern(Value i, int type);
+    ImagePattern(Image *i, int type);
     ~ImagePattern();
     virtual Value tryGet(ExecState *exec, const Identifier &propertyName) const;
     Value getValueProperty(ExecState *exec, int token) const;
@@ -383,13 +382,18 @@ private:
     virtual const ClassInfo* classInfo() const { return &info; }
     static const ClassInfo info;
     
+    CGPatternRef getPattern() { return _patternRef; }
+    
+    QPixmap pixmap() { return _pixmap; }
+    
     enum {
         Repeat, RepeatX, RepeatY, NoRepeat
     };
     
 private:
-    Value _image;
     int _repetitionType;
+    QPixmap _pixmap;
+    CGPatternRef _patternRef;
   };
 
   Value getHTMLCollection(ExecState *exec, const DOM::HTMLCollection &c);
index 8ad49dfccff2b3a91c049a8a53b925ff7e87cf13..30094df3f525a45af53acbd67c7971bd5638ef25 100644 (file)
@@ -88,6 +88,8 @@ public:
     
     void flushRasterCache();
     
+    CGImageRef imageRef();
+    
 private:
 
     WebCoreImageRendererPtr imageRenderer;
index 189afecfd7a0c2dd7a2370a925fe8d58e1b912d1..de228cf407e8654fa381e93a0cf69c3eac4c688b 100644 (file)
@@ -104,6 +104,11 @@ QPixmap::~QPixmap()
     KWQRelease(imageRenderer);
 }
 
+CGImageRef QPixmap::imageRef()
+{
+    return [imageRenderer imageRef];
+}
+
 bool QPixmap::receivedData(const QByteArray &bytes, bool isComplete)
 {
     if (imageRenderer == nil) {
index f60ed1e71721b300b63ba8489c6db168135b5dd1..4a9007b1534a9cc2b1386d1a5a69a816e5460b07 100644 (file)
@@ -40,4 +40,5 @@
 - (void)increaseUseCount;
 - (void)decreaseUseCount;
 - (void)flushRasterCache;
+- (CGImageRef)imageRef;
 @end
index bc173fb67916fcc82d3269c1568b472b9bcac7bd..b5210d9369eeaeb4c09ee87c7afe41d60c710dfe 100644 (file)
@@ -1,3 +1,20 @@
+2004-09-02  Richard Williamson   <rjw@apple.com>
+
+        Support for patterns in <canvas>.  
+        (These changes attempt to create a CGImageRef from a WebImageRenderer that
+        is used by the pattern drawing function.)
+        
+        Reviewed by Hyatt.
+
+        * WebCoreSupport.subproj/WebImageRenderer.h:
+        * WebCoreSupport.subproj/WebImageRenderer.m:
+        (-[WebImageRenderer dealloc]):
+        (-[WebImageRenderer finalize]):
+        (-[WebImageRenderer imageRef]):
+        (_createImageRef):
+        * WebView.subproj/WebPDFView.h:
+        * WebView.subproj/WebPDFView.m:
+
 2004-09-01  Chris Blumenberg  <cblu@apple.com>
 
        Fixed deployment build failure.
index 5f059344f3836690dd52064c944dbd635f9ac7b6..cae0169168937fe5445931dda8d35c64d7ed7a41 100644 (file)
@@ -35,6 +35,8 @@
     BOOL isNull;
     int useCount;
 
+    CGImageRef cachedImageRef;
+    
     id _PDFDoc;
 @public    
     NSData *originalData;
index c2202b53213299def099c718b5fa3f9468514e9d..5e5cda8afe5f02d5d06e530b4fca9d020ebd6936 100644 (file)
@@ -28,6 +28,12 @@ extern NSString *NSImageLoopCount;
 }
 @end
 
+static CGImageRef _createImageRef(NSBitmapImageRep *rep);
+
+@interface NSBitmapImageRep (AppKitInternals)
+- (CGImageRef)_CGImageRef;
+@end
+
 @interface NSFocusStack : NSObject
 @end
 
@@ -390,6 +396,11 @@ static NSMutableSet *activeImageRenderers;
         context = 0;
     }
 
+    if (cachedImageRef) {
+        CGImageRelease (cachedImageRef);
+        cachedImageRef = 0;
+    }
+    
     [_PDFDoc release];
 
     [super dealloc];
@@ -404,6 +415,11 @@ static NSMutableSet *activeImageRenderers;
         CGContextRelease(context);
     }
 
+    if (cachedImageRef) {
+        CGImageRelease (cachedImageRef);
+        cachedImageRef = 0;
+    }
+    
     [super finalize];
 }
 
@@ -816,6 +832,31 @@ static NSMutableSet *activeImageRenderers;
     return MIMEType;
 }
 
+// Try hard to get a CGImageRef.  First try to snag one from the
+// NSBitmapImageRep, then try to create one.  In some cases we may
+// not be able to create one.
+- (CGImageRef)imageRef
+{
+    CGImageRef ref = 0;
+    
+    if (cachedImageRef)
+        return cachedImageRef;
+        
+    if ([[self representations] count] > 0) {
+        NSBitmapImageRep *rep = [[self representations] objectAtIndex:0];
+        
+        if ([rep respondsToSelector:@selector(_CGImageRef)])
+            ref =  [rep _CGImageRef];
+            
+        if (!ref) {
+            cachedImageRef = _createImageRef(rep);
+            ref = cachedImageRef;
+        }
+    }
+    return ref;
+}
+
+
 @end
 
 
@@ -945,3 +986,31 @@ static void ReleasePDFDocumentData(void *info, const void *data, size_t size) {
 }
 
 @end
+
+static CGImageRef _createImageRef(NSBitmapImageRep *rep) {
+    BOOL isPlanar = [rep isPlanar];
+    if (isPlanar)
+        return 0;
+        
+    const unsigned char *bitmapData = [rep bitmapData];
+    int pixelsWide = [rep pixelsWide];
+    int pixelsHigh = [rep pixelsHigh];
+    int bitsPerSample = [rep bitsPerSample];
+    int bitsPerPixel = [rep bitsPerPixel];
+    int bytesPerRow = [rep bytesPerRow];
+    BOOL hasAlpha = [rep hasAlpha];
+    CGImageRef image;
+    CGDataProviderRef dataProvider;
+
+    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+    dataProvider = CGDataProviderCreateWithData(NULL, bitmapData, pixelsHigh * bytesPerRow, NULL);
+
+    image = CGImageCreate(pixelsWide, pixelsHigh, bitsPerSample, bitsPerPixel, bytesPerRow, colorSpace,
+                          hasAlpha ? kCGImageAlphaPremultipliedLast : kCGImageAlphaNone,
+                          dataProvider, NULL, false /*shouldInterpolate*/, kCGRenderingIntentDefault);
+
+    CGDataProviderRelease(dataProvider);
+    CGColorSpaceRelease(colorSpace);   
+
+    return image;
+}
index 4f569cf69b2fd88573e6bd490ca48b563b3c5a2b..c1877a29cb251ee7b5af1286a0d03e90922e6c42 100644 (file)
@@ -10,7 +10,7 @@
 
 @class WebDataSource;
 
-@interface WebPDFView : PDFView <WebDocumentView>
+@interface WebPDFView : PDFView <WebDocumentView, WebDocumentSearching>
 {
     WebDataSource *dataSource;
     NSString *path;
index 951c8d5c5e2604676e96e3a82d3a31dc71285ec8..98fe20ab042c9b5040474a1f388254edc2610fa3 100644 (file)
@@ -149,6 +149,16 @@ static void applicationInfoForMIMEType(NSString *type, NSString **name, NSImage
     }
 }
 
+- (BOOL)searchFor: (NSString *)string direction: (BOOL)forward caseSensitive: (BOOL)caseFlag wrap: (BOOL)wrapFlag;
+{
+    BOOL lastFindWasSuccessful = NO;
+    
+    // FIXME:  Insert find code here when ready.
+    
+    return lastFindWasSuccessful;
+}
+
+
 @end
 
 #endif //MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_3