[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.15-1-40151-g37bb677

rjw rjw at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 08:44:45 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit 1fb69189e39a4c99cebfee92cee70c3d9fb2bb46
Author: rjw <rjw at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Jun 9 19:46:51 2004 +0000

    WebKit:
            Implemented PDF rendering for the drawImage() function
            in Context2D.  This allows PDF files to be drawn in scaled
            or rotated context without rasterization artifacts.
    
            The PDF image is currently NOT cached.  Caching can/will be added
            as an optimization.  The hooks are already in place to flush
            the cache as necessary.
    
            Reviewed by John.
    
            * WebCoreSupport.subproj/WebImageRenderer.h:
            * WebCoreSupport.subproj/WebImageRenderer.m:
            (-[WebImageRenderer dealloc]):
            (-[WebImageRenderer _needsRasterFlush]):
            (-[WebImageRenderer drawClippedToValidInRect:fromRect:]):
            (-[WebImageRenderer _PDFDocumentRef]):
            (-[WebImageRenderer _PDFDraw]):
            (-[WebImageRenderer _PDFDrawFromRect:toRect:operation:alpha:flipped:]):
            (-[WebImageRenderer MIMEType]):
            (ReleasePDFDocumentData):
            (-[WebPDFDocument initWithData:]):
            (-[WebPDFDocument dealloc]):
            (-[WebPDFDocument documentRef]):
            (-[WebPDFDocument mediaBox]):
            (-[WebPDFDocument bounds]):
            (-[WebPDFDocument adjustCTM:]):
            (-[WebPDFDocument setCurrentPage:]):
            (-[WebPDFDocument currentPage]):
            (-[WebPDFDocument pageCount]):
    
            Added back check for old plugin API.
    
            * WebView.subproj/WebFrame.m:
            (-[WebFrame _reloadForPluginChanges]):
            * WebView.subproj/WebHTMLView.m:
            (-[WebHTMLView addSubview:]):
            * WebCoreSupport.subproj/WebBridge.m:
            (-[WebBridge frameRequiredForMIMEType:URL:]):
    
    WebCore:
    	Added support for drawing un-rasterized transformed PDFs.
    
            Reviewed by John.
    
            * khtml/ecma/kjs_html.cpp:
            (KJS::Context2DFunction::tryCall):
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@6801 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index 944cd77..6f87899 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,12 @@
+2004-06-09  Richard Williamson   <rjw at apple.com>
+
+	Added support for drawing un-rasterized transformed PDFs.
+
+        Reviewed by John.
+
+        * khtml/ecma/kjs_html.cpp:
+        (KJS::Context2DFunction::tryCall):
+
 2004-06-09  Darin Adler  <darin at apple.com>
 
         Reviewed by Ken.
diff --git a/WebCore/khtml/ecma/kjs_html.cpp b/WebCore/khtml/ecma/kjs_html.cpp
index 8cc9f7d..d35d762 100644
--- a/WebCore/khtml/ecma/kjs_html.cpp
+++ b/WebCore/khtml/ecma/kjs_html.cpp
@@ -3883,14 +3883,17 @@ Value KJS::Context2DFunction::tryCall(ExecState *exec, Object &thisObj, const Li
             int w = args[3].toInt32(exec);
             int h = args[4].toInt32(exec);
             QString compositeOperator = args[5].toString(exec).qstring().lower();
-            QPixmap pixmap = i->image()->pixmap();
-            QPainter p;
-            p.drawPixmap (x, y, pixmap, 0, 0, w, h, QPainter::compositeOperatorFromString(compositeOperator), drawingContext);
-            
-            if (contextObject->_needsFlushRasterCache)
-                pixmap.flushRasterCache();
+            khtml::CachedImage *ci = i->image();
+            if (ci) {
+                QPixmap pixmap = ci->pixmap();
+                QPainter p;
+                p.drawPixmap (x, y, pixmap, 0, 0, w, h, QPainter::compositeOperatorFromString(compositeOperator), drawingContext);
+                
+                if (contextObject->_needsFlushRasterCache)
+                    pixmap.flushRasterCache();
 
-            renderer->setNeedsImageUpdate();
+                renderer->setNeedsImageUpdate();
+            }
             break;
         }
         case Context2D::DrawImageFromRect: {
@@ -3915,15 +3918,18 @@ Value KJS::Context2DFunction::tryCall(ExecState *exec, Object &thisObj, const Li
             int dw = args[7].toInt32(exec);
             int dh = args[8].toInt32(exec);
             QString compositeOperator = args[9].toString(exec).qstring().lower();
-            QPixmap pixmap = i->image()->pixmap();
-            QPainter p;
+            khtml::CachedImage *ci = i->image();
+            if (ci) {
+                QPixmap pixmap = ci->pixmap();
+                QPainter p;
 
-            p.drawPixmap (dx, dy, dw, dh, pixmap, sx, sy, sw, sh, QPainter::compositeOperatorFromString(compositeOperator), drawingContext);
-            
-            if (contextObject->_needsFlushRasterCache)
-                pixmap.flushRasterCache();
+                p.drawPixmap (dx, dy, dw, dh, pixmap, sx, sy, sw, sh, QPainter::compositeOperatorFromString(compositeOperator), drawingContext);
+                
+                if (contextObject->_needsFlushRasterCache)
+                    pixmap.flushRasterCache();
 
-            renderer->setNeedsImageUpdate();
+                renderer->setNeedsImageUpdate();
+            }
             break;
         }
         case Context2D::SetAlpha: {
diff --git a/WebKit/ChangeLog b/WebKit/ChangeLog
index 1a39480..7dc50a5 100644
--- a/WebKit/ChangeLog
+++ b/WebKit/ChangeLog
@@ -1,3 +1,44 @@
+2004-06-09  Richard Williamson   <rjw at apple.com>
+
+        Implemented PDF rendering for the drawImage() function
+        in Context2D.  This allows PDF files to be drawn in scaled
+        or rotated context without rasterization artifacts.
+        
+        The PDF image is currently NOT cached.  Caching can/will be added
+        as an optimization.  The hooks are already in place to flush
+        the cache as necessary.
+        
+        Reviewed by John.
+
+        * WebCoreSupport.subproj/WebImageRenderer.h:
+        * WebCoreSupport.subproj/WebImageRenderer.m:
+        (-[WebImageRenderer dealloc]):
+        (-[WebImageRenderer _needsRasterFlush]):
+        (-[WebImageRenderer drawClippedToValidInRect:fromRect:]):
+        (-[WebImageRenderer _PDFDocumentRef]):
+        (-[WebImageRenderer _PDFDraw]):
+        (-[WebImageRenderer _PDFDrawFromRect:toRect:operation:alpha:flipped:]):
+        (-[WebImageRenderer MIMEType]):
+        (ReleasePDFDocumentData):
+        (-[WebPDFDocument initWithData:]):
+        (-[WebPDFDocument dealloc]):
+        (-[WebPDFDocument documentRef]):
+        (-[WebPDFDocument mediaBox]):
+        (-[WebPDFDocument bounds]):
+        (-[WebPDFDocument adjustCTM:]):
+        (-[WebPDFDocument setCurrentPage:]):
+        (-[WebPDFDocument currentPage]):
+        (-[WebPDFDocument pageCount]):
+
+        Added back check for old plugin API.
+        
+        * WebView.subproj/WebFrame.m:
+        (-[WebFrame _reloadForPluginChanges]):
+        * WebView.subproj/WebHTMLView.m:
+        (-[WebHTMLView addSubview:]):
+        * WebCoreSupport.subproj/WebBridge.m:
+        (-[WebBridge frameRequiredForMIMEType:URL:]):
+
 2004-06-08  Trey Matteson  <trey at apple.com>
 
 	In DHTML dragging there is no notion of registering for types, so we'd
diff --git a/WebKit/WebCoreSupport.subproj/WebBridge.m b/WebKit/WebCoreSupport.subproj/WebBridge.m
index 564439c..612f145 100644
--- a/WebKit/WebCoreSupport.subproj/WebBridge.m
+++ b/WebKit/WebCoreSupport.subproj/WebBridge.m
@@ -967,7 +967,7 @@ static BOOL loggedObjectCacheSize = NO;
     // Ultimately we should just use frames for all mime types (plugins and HTML/XML/text documents),
     // but for now we're burdened with making a distinction between the two.
     return !([viewClass isSubclassOfClass:[WebNetscapePluginDocumentView class]] ||
-             [viewClass respondsToSelector:@selector(webPlugInInitialize)]);
+             [viewClass respondsToSelector:@selector(webPlugInInitialize)] || [viewClass respondsToSelector:@selector(pluginInitialize)] );
 }
 
 - (void)loadEmptyDocumentSynchronously
diff --git a/WebKit/WebCoreSupport.subproj/WebImageRenderer.h b/WebKit/WebCoreSupport.subproj/WebImageRenderer.h
index 413dfca..5f05934 100644
--- a/WebKit/WebCoreSupport.subproj/WebImageRenderer.h
+++ b/WebKit/WebCoreSupport.subproj/WebImageRenderer.h
@@ -34,6 +34,8 @@
     NSString *MIMEType;
     BOOL isNull;
     int useCount;
+
+    id _PDFDoc;
 @public    
     NSData *originalData;
 }
diff --git a/WebKit/WebCoreSupport.subproj/WebImageRenderer.m b/WebKit/WebCoreSupport.subproj/WebImageRenderer.m
index 4bf4edf..00713c1 100644
--- a/WebKit/WebCoreSupport.subproj/WebImageRenderer.m
+++ b/WebKit/WebCoreSupport.subproj/WebImageRenderer.m
@@ -10,6 +10,8 @@
 #import <WebCore/WebCoreImageRenderer.h>
 #import <WebKit/WebAssertions.h>
 
+#import <CoreGraphics/CGContextGState.h>
+
 extern NSString *NSImageLoopCount;
 
 /*
@@ -37,6 +39,24 @@ extern NSString *NSImageLoopCount;
 - (NSRect)bounds;
 @end
 
+ at interface WebPDFDocument : NSObject
+{
+    CGPDFDocumentRef _document;
+    CGRect           _mediaBox;
+    NSRect           _cropBox;
+    float            _rotation;
+    int              _currentPage;
+}
+- (id)               initWithData:(NSData*)data;
+- (CGPDFDocumentRef) documentRef;
+- (CGRect)           mediaBox;
+- (NSRect)           bounds;	// adjust for rotation
+- (void)             setCurrentPage:(int)page;
+- (int)              currentPage;
+- (int)              pageCount;
+- (void)             adjustCTM:(CGContextRef)context;
+ at end
+
 @implementation WebImageContext
 
 - (id)initWithBounds:(NSRect)b context:(CGContextRef)context {
@@ -110,6 +130,7 @@ extern NSString *NSImageLoopCount;
 - (NSGraphicsContext *)_beginRedirectContext:(CGContextRef)aContext;
 - (void)_endRedirectContext:(NSGraphicsContext *)aContext;
 - (void)_needsRasterFlush;
+- (BOOL)_PDFDrawFromRect:(NSRect)srcRect toRect:(NSRect)dstRect operation:(NSCompositingOperation)op alpha:(float)alpha flipped:(BOOL)flipped;
 @end
 
 @implementation WebImageRenderer
@@ -352,6 +373,8 @@ static NSMutableSet *activeImageRenderers;
         context = 0;
     }
     
+    [_PDFDoc release];
+    
     [super dealloc];
 }
 
@@ -451,17 +474,8 @@ static NSMutableSet *activeImageRenderers;
 - (void)_needsRasterFlush
 {
 #if 0
-    // This doesn't work.  The PDF is always rasterized and cached!  Leaving
-    // this code in place, but excluded, pending response from AP.
-    NSImageRep *imageRep = [[self representations] objectAtIndex:0];
-    rasterFlushing = NO;
-    if (needFlushRasterCache && [imageRep isKindOfClass:[NSCachedImageRep class]] && [MIMEType isEqual: @"application/pdf"]) {
-        [self removeRepresentation:imageRep];
-        Class repClass = [NSImageRep imageRepClassForData:originalData];
-        if (repClass) {
-            NSImageRep *rep = [[repClass alloc] initWithData:originalData];
-            [self addRepresentation:rep];
-        }
+    if (needFlushRasterCache && [MIMEType isEqual: @"application/pdf"]) {
+        // FIXME:  At this point we need to flush the cached rasterized PDF.
     }
 #endif
 }
@@ -500,13 +514,88 @@ static NSMutableSet *activeImageRenderers;
         }
     }
     
-    NSGraphicsContext *oldContext = [self _beginRedirectContext:context];
-    [self _needsRasterFlush];
+    if (context) {
+        NSGraphicsContext *oldContext = [self _beginRedirectContext:context];
+        [self _needsRasterFlush];
+
+        // If we have PDF then draw the PDF ourselves, bypassing the NSImage caching mechanisms,
+        // but only do this when we're rendering to an offscreen context.  NSImage will always
+        // cache the PDF image at it's native resolution, thus, causing artifacts when the image
+        // is drawn into a scaled or rotated context.
+        if ([MIMEType isEqual:@"application/pdf"])
+            [self _PDFDrawFromRect:fr toRect:ir operation:compositeOperator alpha:1.0 flipped:YES];
+        else
+            [self drawInRect:ir fromRect:fr operation:compositeOperator fraction: 1.0];
+
+        [self _endRedirectContext:oldContext];
+    }
+    else {
+        [self drawInRect:ir fromRect:fr operation:compositeOperator fraction: 1.0];
+    }
+}
+
+- (CGPDFDocumentRef)_PDFDocumentRef
+{
+    if (!_PDFDoc) {
+        _PDFDoc = [[WebPDFDocument alloc] initWithData:originalData];
+    }
+        
+    return [_PDFDoc documentRef];
+}
+
+- (void)_PDFDraw
+{
+    CGPDFDocumentRef document = [self _PDFDocumentRef];
+    if (document != NULL) {
+        CGContextRef _context  = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
+        CGRect       mediaBox = [_PDFDoc mediaBox];
+        
+        CGContextSaveGState(_context);
+        // Rotate translate image into position according to doc properties.
+        [_PDFDoc adjustCTM:_context];	
 
-    // This is the operation that handles transparent portions of the source image correctly.
-    [self drawInRect:ir fromRect:fr operation:compositeOperator fraction: 1.0];
+        // Media box may have non-zero origin which we ignore. CGPDFDocumentShowPage pages start
+        // at 1, not 0.
+        CGContextDrawPDFDocument(_context, CGRectMake(0, 0, mediaBox.size.width, mediaBox.size.height), document, 1);
 
-    [self _endRedirectContext:oldContext];
+        CGContextRestoreGState(_context);
+    }
+}
+
+- (BOOL)_PDFDrawFromRect:(NSRect)srcRect toRect:(NSRect)dstRect operation:(NSCompositingOperation)op alpha:(float)alpha flipped:(BOOL)flipped
+{
+    // FIXME:  The rasterized PDF should be drawn into a cache, and the raster then composited.
+    
+    CGContextRef _context = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
+    float hScale, vScale;
+
+    CGContextSaveGState(_context);
+
+    CGContextSetCompositeOperation (_context, op);
+
+    // Scale and translate so the document is rendered in the correct location.
+    hScale = dstRect.size.width  / srcRect.size.width;
+    vScale = dstRect.size.height / srcRect.size.height;
+
+    CGContextTranslateCTM (_context, dstRect.origin.x - srcRect.origin.x * hScale, dstRect.origin.y - srcRect.origin.y * vScale);
+    CGContextScaleCTM (_context, hScale, vScale);
+
+    // Reverse if flipped image.
+    if (flipped) {
+        CGContextScaleCTM(_context, 1, -1);
+        CGContextTranslateCTM (_context, 0, -(dstRect.origin.y + dstRect.size.height));
+    }
+
+    // Clip to destination in case we are imaging part of the source only
+    CGContextClipToRect(_context, CGRectIntegral(*(CGRect*)&srcRect));
+
+    // and draw
+    [self _PDFDraw];
+
+    // done with our fancy transforms
+    CGContextRestoreGState(_context);
+
+    return YES;
 }
 
 - (void)nextFrame:(id)context
@@ -687,3 +776,125 @@ static NSMutableSet *activeImageRenderers;
 }
 
 @end
+
+
+//------------------------------------------------------------------------------------
+
+ at implementation WebPDFDocument
+
+static void ReleasePDFDocumentData(void *info, const void *data, size_t size) {
+    [(NSData*)info autorelease];
+}
+
+- (id) initWithData:(NSData*)data
+{
+    self = [super init];
+    if (self != nil)
+    {
+        if (data != nil) {
+            CGDataProviderRef dataProvider = CGDataProviderCreateWithData([data retain], [data bytes], [data length], ReleasePDFDocumentData);
+            _document = CGPDFDocumentCreateWithProvider(dataProvider);
+            CGDataProviderRelease(dataProvider);
+        }
+        _currentPage = -1;
+        [self setCurrentPage:0];
+    }
+    return self;
+}
+
+- (void)dealloc
+{
+    if (_document != NULL) CGPDFDocumentRelease(_document);
+    [super dealloc];
+}
+
+- (CGPDFDocumentRef) documentRef
+{
+    return _document;
+}
+
+- (CGRect) mediaBox
+{
+    return _mediaBox;
+}
+
+- (NSRect) bounds
+{
+    NSRect rotatedRect;
+
+    // rotate the media box and calculate bounding box
+    float sina   = sin (_rotation);
+    float cosa   = cos (_rotation);
+    float width  = NSWidth (_cropBox);
+    float height = NSHeight(_cropBox);
+
+    // calculate rotated x and y axis
+    NSPoint rx = NSMakePoint( width  * cosa, width  * sina);
+    NSPoint ry = NSMakePoint(-height * sina, height * cosa);
+
+    // find delta width and height of rotated points
+    rotatedRect.origin      = _cropBox.origin;
+    rotatedRect.size.width  = ceil(fabs(rx.x - ry.x));
+    rotatedRect.size.height = ceil(fabs(ry.y - rx.y));
+
+    return rotatedRect;
+}
+
+- (void) adjustCTM:(CGContextRef)context
+{
+    // rotate the crop box and calculate bounding box
+    float sina   = sin (-_rotation);
+    float cosa   = cos (-_rotation);
+    float width  = NSWidth (_cropBox);
+    float height = NSHeight(_cropBox);
+
+    // calculate rotated x and y edges of the corp box. if they're negative, it means part of the image has
+    // been rotated outside of the bounds and we need to shift over the image so it lies inside the bounds again
+    NSPoint rx = NSMakePoint( width  * cosa, width  * sina);
+    NSPoint ry = NSMakePoint(-height * sina, height * cosa);
+
+    // adjust so we are at the crop box origin
+    CGContextTranslateCTM(context, floor(-MIN(0,MIN(rx.x, ry.x))), floor(-MIN(0,MIN(rx.y, ry.y))));
+
+    // rotate -ve to remove rotation
+    CGContextRotateCTM(context, -_rotation);
+
+    // shift so we are completely within media box
+    CGContextTranslateCTM(context, _mediaBox.origin.x - _cropBox.origin.x, _mediaBox.origin.y - _cropBox.origin.y);
+}
+
+- (void) setCurrentPage:(int)page
+{
+    if (page != _currentPage && page >= 0 && page < [self pageCount]) {
+
+        CGRect r;
+
+        _currentPage = page;
+
+        // get media box (guaranteed)
+        _mediaBox = CGPDFDocumentGetMediaBox(_document, page + 1);
+
+        // get crop box (not always there). if not, use _mediaBox
+        r = CGPDFDocumentGetCropBox(_document, page + 1);
+        if (!CGRectIsEmpty(r)) {
+            _cropBox = NSMakeRect(r.origin.x, r.origin.y, r.size.width, r.size.height);
+        } else {
+            _cropBox = NSMakeRect(_mediaBox.origin.x, _mediaBox.origin.y, _mediaBox.size.width, _mediaBox.size.height);
+        }
+
+        // get page rotation angle
+        _rotation = CGPDFDocumentGetRotationAngle(_document, page + 1) * M_PI / 180.0;	// to radians
+    }
+}
+
+- (int) currentPage
+{
+    return _currentPage;
+}
+
+- (int) pageCount
+{
+    return CGPDFDocumentGetNumberOfPages(_document);
+}
+
+ at end
diff --git a/WebKit/WebView.subproj/WebFrame.m b/WebKit/WebView.subproj/WebFrame.m
index ad00aee..c10ba2f 100644
--- a/WebKit/WebView.subproj/WebFrame.m
+++ b/WebKit/WebView.subproj/WebFrame.m
@@ -2387,7 +2387,8 @@ static CFAbsoluteTime _timeOfLastCompletedLoad;
         while ((view = [viewEnumerator nextObject]) != nil) {
             if ([view isKindOfClass:[WebNetscapePluginEmbeddedView class]] ||
                 [view isKindOfClass:[WebNullPluginView class]] ||
-                [view respondsToSelector:@selector(webPlugInInitialize)]) {
+                [view respondsToSelector:@selector(webPlugInInitialize)] ||
+                [view respondsToSelector:@selector(pluginInitialize)]) {
                 [self reload];
                 break;
             }
diff --git a/WebKit/WebView.subproj/WebHTMLView.m b/WebKit/WebView.subproj/WebHTMLView.m
index ad04f95..6a64fee 100644
--- a/WebKit/WebView.subproj/WebHTMLView.m
+++ b/WebKit/WebView.subproj/WebHTMLView.m
@@ -1464,7 +1464,7 @@ static void FlipImageSpec(CoreDragImageSpec* imageSpec) {
 {
     [super addSubview:view];
 
-    if ([view respondsToSelector:@selector(webPlugInInitialize)]) {
+    if ([view respondsToSelector:@selector(webPlugInInitialize)] || [view respondsToSelector:@selector(pluginInitialize)]) {
         [[self _pluginController] addPlugin:view];
     }
 }

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list