Editable images should always return some data, even if the canvas doesn't have a...
authortimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 1 Dec 2018 01:11:12 +0000 (01:11 +0000)
committertimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 1 Dec 2018 01:11:12 +0000 (01:11 +0000)
https://bugs.webkit.org/show_bug.cgi?id=192265
<rdar://problem/46385911>

Reviewed by Wenson Hsieh.

* UIProcess/ios/WKDrawingView.mm:
(-[WKDrawingView layoutSubviews]):
(emptyImage):
(-[WKDrawingView renderedDrawing]):
(-[WKDrawingView PNGRepresentation]):
Some clients strongly depend on there being some data in an image, even if
it's not of a usable size yet. We'll invalidate the attachment when the
canvas size changes, so it will eventually settle at a usable size (after
the first layer tree commit that includes the editable image).

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

Source/WebKit/ChangeLog
Source/WebKit/UIProcess/ios/WKDrawingView.mm

index ee0d983..597b928 100644 (file)
@@ -1,3 +1,21 @@
+2018-11-30  Tim Horton  <timothy_horton@apple.com>
+
+        Editable images should always return some data, even if the canvas doesn't have a size yet
+        https://bugs.webkit.org/show_bug.cgi?id=192265
+        <rdar://problem/46385911>
+
+        Reviewed by Wenson Hsieh.
+
+        * UIProcess/ios/WKDrawingView.mm:
+        (-[WKDrawingView layoutSubviews]):
+        (emptyImage):
+        (-[WKDrawingView renderedDrawing]):
+        (-[WKDrawingView PNGRepresentation]):
+        Some clients strongly depend on there being some data in an image, even if
+        it's not of a usable size yet. We'll invalidate the attachment when the
+        canvas size changes, so it will eventually settle at a usable size (after
+        the first layer tree commit that includes the editable image).
+
 2018-11-30  Don Olmstead  <don.olmstead@sony.com>
 
         Rename ENABLE_SUBTLE_CRYPTO to ENABLE_WEB_CRYPTO
index f8d2500..d0d903d 100644 (file)
 @implementation WKDrawingView {
     RetainPtr<PKCanvasView> _pencilView;
 
+#if !PLATFORM(IOS_FAMILY_SIMULATOR)
     OSObjectPtr<dispatch_queue_t> _renderQueue;
     RetainPtr<PKImageRenderer> _renderer;
+#endif
 
     WeakPtr<WebKit::WebPageProxy> _webPageProxy;
 }
     if (!CGRectEqualToRect([_pencilView frame], self.bounds)) {
         [_pencilView setFrame:self.bounds];
 
+#if !PLATFORM(IOS_FAMILY_SIMULATOR)
         // The renderer is instantiated for a particular size output; if
         // the size changes, we need to re-create the renderer.
         _renderer = nil;
+#endif
 
         [self invalidateAttachment];
     }
 }
 
-- (NSData *)PNGRepresentation
+static UIImage *emptyImage()
+{
+    UIGraphicsBeginImageContext(CGSizeMake(1, 1));
+    CGContextClearRect(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, 1, 1));
+    UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
+    UIGraphicsEndImageContext();
+
+    return resultImage;
+}
+
+- (UIImage *)renderedDrawing
 {
+#if PLATFORM(IOS_FAMILY_SIMULATOR)
+    // PKImageRenderer currently doesn't work in the simulator. In order to
+    // allow strokes to persist regardless (mostly for testing), we'll
+    // synthesize an empty 1x1 image.
+    return emptyImage();
+#else
     if (!self.bounds.size.width || !self.bounds.size.height || !self.window.screen.scale)
-        return nil;
+        return emptyImage();
 
     if (!_renderQueue)
         _renderQueue = adoptOSObject(dispatch_queue_create("com.apple.WebKit.WKDrawingView.Rendering", DISPATCH_QUEUE_SERIAL));
     if (!_renderer)
         _renderer = adoptNS([WebKit::allocPKImageRendererInstance() initWithSize:self.bounds.size scale:self.window.screen.scale renderQueue:_renderQueue.get()]);
 
-    auto* drawing = [_pencilView drawing];
-
     __block RetainPtr<UIImage> resultImage;
-#if PLATFORM(IOS_FAMILY_SIMULATOR)
-    // PKImageRenderer currently doesn't work in the simulator. In order to
-    // allow strokes to persist regardless (mostly for testing), we'll
-    // synthesize an empty 1x1 image.
-    UIGraphicsBeginImageContext(CGSizeMake(1, 1));
-    CGContextClearRect(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, 1, 1));
-    resultImage = UIGraphicsGetImageFromCurrentImageContext();
-    UIGraphicsEndImageContext();
-#else
-    [_renderer renderDrawing:drawing completion:^(UIImage *image) {
+
+    [_renderer renderDrawing:[_pencilView drawing] completion:^(UIImage *image) {
         resultImage = image;
     }];
-#endif
 
     // FIXME: Ideally we would not synchronously wait for this rendering,
     // but NSFileWrapper requires data synchronously, and our clients expect
     // an NSFileWrapper to be available synchronously.
     dispatch_sync(_renderQueue.get(), ^{ });
 
+    return resultImage.get();
+#endif
+}
+
+- (NSData *)PNGRepresentation
+{
+    RetainPtr<UIImage> image = [self renderedDrawing];
     RetainPtr<NSMutableData> PNGData = adoptNS([[NSMutableData alloc] init]);
     RetainPtr<CGImageDestinationRef> imageDestination = adoptCF(CGImageDestinationCreateWithData((__bridge CFMutableDataRef)PNGData.get(), kUTTypePNG, 1, nil));
-    NSString *base64Drawing = [[drawing serialize] base64EncodedStringWithOptions:0];
+    NSString *base64Drawing = [[[_pencilView drawing] serialize] base64EncodedStringWithOptions:0];
     NSDictionary *properties = nil;
     if (base64Drawing) {
         // FIXME: We should put this somewhere less user-facing than the EXIF User Comment field.
         };
     }
     CGImageDestinationSetProperties(imageDestination.get(), (__bridge CFDictionaryRef)properties);
-    CGImageDestinationAddImage(imageDestination.get(), [resultImage CGImage], (__bridge CFDictionaryRef)properties);
+    CGImageDestinationAddImage(imageDestination.get(), [image CGImage], (__bridge CFDictionaryRef)properties);
     CGImageDestinationFinalize(imageDestination.get());
 
     return PNGData.autorelease();