Title: [231241] trunk/Source/WebCore
Revision
231241
Author
[email protected]
Date
2018-05-02 10:36:59 -0700 (Wed, 02 May 2018)

Log Message

Draw SystemPreview badge to specification on iOS
https://bugs.webkit.org/show_bug.cgi?id=185203
<rdar://problem/39908855>

Reviewed by Tim Horton.

Use CoreImage to render a badge with a blurred background,
at particular sizes.

This will be tested internally while we're getting artwork
from WebKitAdditions.

* Configurations/WebCore.xcconfig: Link against CoreImage.
* rendering/RenderThemeIOS.h:
* rendering/RenderThemeIOS.mm:
(WebCore::RenderThemeIOS::paintSystemPreviewBadge): New function
in the iOS platform RenderTheme that draws the system preview.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (231240 => 231241)


--- trunk/Source/WebCore/ChangeLog	2018-05-02 17:19:12 UTC (rev 231240)
+++ trunk/Source/WebCore/ChangeLog	2018-05-02 17:36:59 UTC (rev 231241)
@@ -1,3 +1,23 @@
+2018-05-02  Dean Jackson  <[email protected]>
+
+        Draw SystemPreview badge to specification on iOS
+        https://bugs.webkit.org/show_bug.cgi?id=185203
+        <rdar://problem/39908855>
+
+        Reviewed by Tim Horton.
+
+        Use CoreImage to render a badge with a blurred background,
+        at particular sizes.
+
+        This will be tested internally while we're getting artwork
+        from WebKitAdditions.
+
+        * Configurations/WebCore.xcconfig: Link against CoreImage.
+        * rendering/RenderThemeIOS.h:
+        * rendering/RenderThemeIOS.mm:
+        (WebCore::RenderThemeIOS::paintSystemPreviewBadge): New function
+        in the iOS platform RenderTheme that draws the system preview.
+
 2018-05-01  Brent Fulgham  <[email protected]>
 
         Prevent Debug ASSERT when changing forms

Modified: trunk/Source/WebCore/Configurations/WebCore.xcconfig (231240 => 231241)


--- trunk/Source/WebCore/Configurations/WebCore.xcconfig	2018-05-02 17:19:12 UTC (rev 231240)
+++ trunk/Source/WebCore/Configurations/WebCore.xcconfig	2018-05-02 17:36:59 UTC (rev 231241)
@@ -117,8 +117,12 @@
 WK_SYSTEM_CONFIGURATION_LDFLAGS = $(WK_SYSTEM_CONFIGURATION_LDFLAGS_$(WK_PLATFORM_NAME));
 WK_SYSTEM_CONFIGURATION_LDFLAGS_macosx = -framework SystemConfiguration;
 
+WK_SYSTEM_PREVIEW_LDFLAGS = $(WK_SYSTEM_PREVIEW_LDFLAGS_$(WK_PLATFORM_NAME));
+WK_SYSTEM_PREVIEW_LDFLAGS_iphoneos = -framework CoreImage;
+WK_SYSTEM_PREVIEW_LDFLAGS_iphonesimulator = -framework CoreImage;
+
 // FIXME: Reduce the number of allowable_clients <rdar://problem/31823969>
-OTHER_LDFLAGS = $(inherited) $(WK_RELOCATABLE_FRAMEWORK_LDFLAGS) $(WK_UNDEFINED_SYMBOLS_LDFLAGS) -lsqlite3 -lobjc -lANGLE -allowable_client WebCoreTestSupport -allowable_client WebKitLegacy -force_load $(BUILT_PRODUCTS_DIR)/libPAL.a -framework CFNetwork -framework CoreAudio -framework CoreGraphics -framework CoreText -framework Foundation -framework ImageIO -framework Metal $(OTHER_LDFLAGS_PLATFORM_$(WK_COCOA_TOUCH)) $(OTHER_LDFLAGS_PLATFORM_$(WK_PLATFORM_NAME)) $(WK_APPKIT_LDFLAGS) $(WK_AUDIO_UNIT_LDFLAGS) $(WK_CARBON_LDFLAGS)  $(WK_DATA_DETECTORS_CORE_LDFLAGS) $(WK_DEVICE_IDENTITY_LDFLAGS) $(WK_GRAPHICS_SERVICES_LDFLAGS) $(WK_IOSURFACE_LDFLAGS) $(WK_LIBWEBRTC_LDFLAGS) $(WK_MOBILE_CORE_SERVICES_LDFLAGS) $(WK_MOBILE_GESTALT_LDFLAGS) $(WK_OPENGL_LDFLAGS) $(WK_SYSTEM_CONFIGURATION_LDFLAGS);
+OTHER_LDFLAGS = $(inherited) $(WK_RELOCATABLE_FRAMEWORK_LDFLAGS) $(WK_UNDEFINED_SYMBOLS_LDFLAGS) -lsqlite3 -lobjc -lANGLE -allowable_client WebCoreTestSupport -allowable_client WebKitLegacy -force_load $(BUILT_PRODUCTS_DIR)/libPAL.a -framework CFNetwork -framework CoreAudio -framework CoreGraphics -framework CoreText -framework Foundation -framework ImageIO -framework Metal $(OTHER_LDFLAGS_PLATFORM_$(WK_COCOA_TOUCH)) $(OTHER_LDFLAGS_PLATFORM_$(WK_PLATFORM_NAME)) $(WK_APPKIT_LDFLAGS) $(WK_AUDIO_UNIT_LDFLAGS) $(WK_CARBON_LDFLAGS)  $(WK_DATA_DETECTORS_CORE_LDFLAGS) $(WK_DEVICE_IDENTITY_LDFLAGS) $(WK_GRAPHICS_SERVICES_LDFLAGS) $(WK_IOSURFACE_LDFLAGS) $(WK_LIBWEBRTC_LDFLAGS) $(WK_MOBILE_CORE_SERVICES_LDFLAGS) $(WK_MOBILE_GESTALT_LDFLAGS) $(WK_OPENGL_LDFLAGS) $(WK_SYSTEM_CONFIGURATION_LDFLAGS) $(WK_SYSTEM_PREVIEW_LDFLAGS);
 
 OTHER_LDFLAGS_PLATFORM_cocoatouch = -allowable_client WebKit -allowable_client iTunesU -allowable_client Casablanca -allowable_client Remote -allowable_client TVBooks -allowable_client DumpRenderTree -allowable_client WebKitTestRunner -allowable_client TestWebKitAPI;
 OTHER_LDFLAGS_PLATFORM_macosx = -sub_library libobjc -umbrella WebKit;

Modified: trunk/Source/WebCore/rendering/RenderThemeIOS.h (231240 => 231241)


--- trunk/Source/WebCore/rendering/RenderThemeIOS.h	2018-05-02 17:19:12 UTC (rev 231240)
+++ trunk/Source/WebCore/rendering/RenderThemeIOS.h	2018-05-02 17:36:59 UTC (rev 231241)
@@ -29,6 +29,10 @@
 
 #include "RenderThemeCocoa.h"
 
+#include <wtf/RetainPtr.h>
+
+OBJC_CLASS CIContext;
+
 namespace WebCore {
     
 class RenderStyle;
@@ -46,6 +50,10 @@
 
     WEBCORE_EXPORT static void setContentSizeCategory(const String&);
 
+#if USE(SYSTEM_PREVIEW)
+    void paintSystemPreviewBadge(Image&, const PaintInfo&, const FloatRect&) override;
+#endif
+
 protected:
     LengthBox popupInternalPaddingBox(const RenderStyle&) const override;
     
@@ -144,6 +152,10 @@
 
     mutable HashMap<int, Color> m_systemColorCache;
 
+#if USE(SYSTEM_PREVIEW)
+    RetainPtr<CIContext> m_ciContext;
+#endif
+
     bool m_shouldMockBoldSystemFontForAccessibility { false };
 };
 

Modified: trunk/Source/WebCore/rendering/RenderThemeIOS.mm (231240 => 231241)


--- trunk/Source/WebCore/rendering/RenderThemeIOS.mm	2018-05-02 17:19:12 UTC (rev 231240)
+++ trunk/Source/WebCore/rendering/RenderThemeIOS.mm	2018-05-02 17:36:59 UTC (rev 231241)
@@ -67,6 +67,7 @@
 #import "UserAgentStyleSheets.h"
 #import "WebCoreThreadRun.h"
 #import <CoreGraphics/CoreGraphics.h>
+#import <CoreImage/CoreImage.h>
 #import <objc/runtime.h>
 #import <pal/spi/cocoa/CoreTextSPI.h>
 #import <pal/spi/ios/UIKitSPI.h>
@@ -75,6 +76,10 @@
 #import <wtf/SoftLinking.h>
 #import <wtf/StdLibExtras.h>
 
+#if USE(SYSTEM_PREVIEW) && USE(APPLE_INTERNAL_SDK)
+#import <WebKitAdditions/SystemPreviewArtwork.cpp>
+#endif
+
 SOFT_LINK_FRAMEWORK(UIKit)
 SOFT_LINK_CLASS(UIKit, UIApplication)
 SOFT_LINK_CLASS(UIKit, UIColor)
@@ -1818,6 +1823,100 @@
 
 #endif
 
+#if USE(SYSTEM_PREVIEW)
+void RenderThemeIOS::paintSystemPreviewBadge(Image& image, const PaintInfo& paintInfo, const FloatRect& rect)
+{
+    static const float largeBadgeDimension = 70;
+    static const float largeBadgeOffset = 20;
+
+    static const float smallBadgeDimension = 35;
+    static const float smallBadgeOffset = 8;
+
+    static const float minimumSizeForLargeBadge = 240;
+
+    bool useSmallBadge = rect.width() < minimumSizeForLargeBadge || rect.height() < minimumSizeForLargeBadge;
+    float badgeOffset = useSmallBadge ? smallBadgeOffset : largeBadgeOffset;
+    float badgeDimension = useSmallBadge ? smallBadgeDimension : largeBadgeDimension;
+
+    float minimumDimension = badgeDimension + 2 * badgeOffset;
+    if (rect.width() < minimumDimension || rect.height() < minimumDimension)
+        return;
+
+    CIImage *inputImage = [CIImage imageWithCGImage:image.nativeImage().get()];
+
+    // Scale from intrinsic size to render size.
+    CGAffineTransform transform = CGAffineTransformIdentity;
+    transform = CGAffineTransformScale(transform, rect.width() / image.width(), rect.height() / image.height());
+    CIImage *scaledImage = [inputImage imageByApplyingTransform:transform];
+
+    CGRect absoluteBadgeRect = CGRectMake(rect.x() + rect.width() - badgeDimension - badgeOffset, rect.y() + badgeOffset, badgeDimension, badgeDimension);
+    CGRect insetBadgeRect = CGRectMake(rect.width() - badgeDimension - badgeOffset, badgeOffset, badgeDimension, badgeDimension);
+    CGRect badgeRect = CGRectMake(0, 0, badgeDimension, badgeDimension);
+
+    // CI coordinates are y-up, so we need to flip the badge rectangle within the image frame.
+    CGRect flippedInsetBadgeRect = CGRectMake(insetBadgeRect.origin.x, rect.height() - insetBadgeRect.origin.y - insetBadgeRect.size.height, badgeDimension, badgeDimension);
+
+    // Create a cropped region with pixel values extending outwards.
+    CIImage *clampedImage = [scaledImage imageByClampingToRect:flippedInsetBadgeRect];
+
+    // Blur.
+    CIFilter *blurFilter = [CIFilter filterWithName:@"CIGaussianBlur"];
+    [blurFilter setDefaults];
+    [blurFilter setValue:@(10) forKey:kCIInputRadiusKey];
+    [blurFilter setValue:clampedImage forKey:kCIInputImageKey];
+
+    // Saturate.
+    CIFilter *saturationFilter = [CIFilter filterWithName:@"CIColorControls"];
+    [saturationFilter setValue:blurFilter.outputImage forKey:kCIInputImageKey];
+    [saturationFilter setValue:@1.8 forKey:kCIInputSaturationKey];
+
+    // Tint.
+    CIFilter *tintFilter1 = [CIFilter filterWithName:@"CIConstantColorGenerator"];
+    CIColor *tintColor1 = [CIColor colorWithRed:1 green:1 blue:1 alpha:0.18];
+    [tintFilter1 setValue:tintColor1 forKey:kCIInputColorKey];
+
+    // Blend the tint with the saturated output.
+    CIFilter *sourceOverFilter = [CIFilter filterWithName:@"CISourceOverCompositing"];
+    [sourceOverFilter setValue:tintFilter1.outputImage forKey:kCIInputImageKey];
+    [sourceOverFilter setValue:saturationFilter.outputImage forKey:kCIInputBackgroundImageKey];
+
+    // Before we render the result, we should clip to a circle around the badge rectangle.
+    CGContextRef ctx = paintInfo.context().platformContext();
+    CGContextSaveGState(ctx);
+    CGContextBeginPath(ctx);
+    CGPathRef circle = CGPathCreateWithRoundedRect(absoluteBadgeRect, badgeDimension / 2, badgeDimension / 2, nil);
+    CGContextAddPath(ctx, circle);
+    CGContextClosePath(ctx);
+    CGContextClip(ctx);
+    CGPathRelease(circle);
+
+    if (!m_ciContext)
+        m_ciContext = [CIContext context];
+    RetainPtr<CGImageRef> cgImage = adoptCF([m_ciContext.get() createCGImage:sourceOverFilter.outputImage fromRect:flippedInsetBadgeRect]);
+
+    CGContextSaveGState(ctx);
+    CGContextTranslateCTM(ctx, absoluteBadgeRect.origin.x, absoluteBadgeRect.origin.y);
+    CGContextTranslateCTM(ctx, 0, badgeDimension);
+    CGContextScaleCTM(ctx, 1, -1);
+    CGContextDrawImage(ctx, badgeRect, cgImage.get());
+    CGContextRestoreGState(ctx);
+
+#if USE(APPLE_INTERNAL_SDK)
+    if (auto logo = systemPreviewLogo()) {
+        // FIXME: Do we need to flip here too?
+        CGContextTranslateCTM(ctx, absoluteBadgeRect.origin.x, absoluteBadgeRect.origin.y);
+        CGSize pdfSize = CGPDFPageGetBoxRect(logo, kCGPDFMediaBox).size;
+        CGFloat scaleX = badgeDimension / pdfSize.width;
+        CGFloat scaleY = badgeDimension / pdfSize.height;
+        CGContextScaleCTM(ctx, scaleX, scaleY);
+        CGContextDrawPDFPage(ctx, logo);
+    }
+#endif
+
+    CGContextRestoreGState(ctx);
+}
+#endif
+
 } // namespace WebCore
 
 #endif //PLATFORM(IOS)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to