From 37f4ec6e162553d9f666506805fe5c4b7b0f80b7 Mon Sep 17 00:00:00 2001 From: Nick Lockwood Date: Mon, 25 Apr 2016 03:30:54 -0700 Subject: [PATCH] Removed placeholder image logic Summary: To prevent layout popping, when inserting images inside text we would render a blank placeholder image while the real image was loading. It turns out that this isn't necessary, as we can just specify the size of the image without having an actual image to display. Reviewed By: javache Differential Revision: D3212766 fb-gh-sync-id: e98851b32a2d0ae809fc0a4be47e6b77f3b17996 fbshipit-source-id: e98851b32a2d0ae809fc0a4be47e6b77f3b17996 --- .../UIExplorerUnitTests/RCTImageUtilTests.m | 48 ------------------- Libraries/Image/RCTImageUtils.h | 7 --- Libraries/Image/RCTImageUtils.m | 45 ----------------- Libraries/Image/RCTShadowVirtualImage.m | 4 -- Libraries/Text/RCTShadowText.m | 10 ++-- 5 files changed, 4 insertions(+), 110 deletions(-) diff --git a/Examples/UIExplorer/UIExplorerUnitTests/RCTImageUtilTests.m b/Examples/UIExplorer/UIExplorerUnitTests/RCTImageUtilTests.m index 810e079ab..19229d045 100644 --- a/Examples/UIExplorer/UIExplorerUnitTests/RCTImageUtilTests.m +++ b/Examples/UIExplorer/UIExplorerUnitTests/RCTImageUtilTests.m @@ -133,52 +133,4 @@ RCTAssertEqualSizes(a.size, b.size); \ RCTAssertEqualRects(expected, result); } -- (void)testPlaceholderImage -{ - CGSize size = {45, 22}; - CGFloat expectedScale = 1.0; - UIImage *image = RCTGetPlaceholderImage(size, nil); - RCTAssertEqualSizes(size, image.size); - XCTAssertEqual(expectedScale, image.scale); -} - -- (void)testPlaceholderNonintegralSize -{ - CGSize size = {3.0/2, 7.0/3}; - CGFloat expectedScale = 6; - CGSize pixelSize = { - round(size.width * expectedScale), - round(size.height * expectedScale) - }; - UIImage *image = RCTGetPlaceholderImage(size, nil); - RCTAssertEqualSizes(size, image.size); - XCTAssertEqual(pixelSize.width, CGImageGetWidth(image.CGImage)); - XCTAssertEqual(pixelSize.height, CGImageGetHeight(image.CGImage)); - XCTAssertEqual(expectedScale, image.scale); -} - -- (void)testPlaceholderSquareImage -{ - CGSize size = {333, 333}; - CGFloat expectedScale = 1.0/333; - CGSize pixelSize = {1, 1}; - UIImage *image = RCTGetPlaceholderImage(size, nil); - RCTAssertEqualSizes(size, image.size); - XCTAssertEqual(pixelSize.width, CGImageGetWidth(image.CGImage)); - XCTAssertEqual(pixelSize.height, CGImageGetHeight(image.CGImage)); - XCTAssertEqual(expectedScale, image.scale); -} - -- (void)testPlaceholderNonsquareImage -{ - CGSize size = {640, 480}; - CGFloat expectedScale = 1.0/160; - CGSize pixelSize = {4, 3}; - UIImage *image = RCTGetPlaceholderImage(size, nil); - RCTAssertEqualSizes(size, image.size); - XCTAssertEqual(pixelSize.width, CGImageGetWidth(image.CGImage)); - XCTAssertEqual(pixelSize.height, CGImageGetHeight(image.CGImage)); - XCTAssertEqual(expectedScale, image.scale); -} - @end diff --git a/Libraries/Image/RCTImageUtils.h b/Libraries/Image/RCTImageUtils.h index 0c855790e..f870bda67 100644 --- a/Libraries/Image/RCTImageUtils.h +++ b/Libraries/Image/RCTImageUtils.h @@ -93,11 +93,4 @@ RCT_EXTERN UIImage *__nullable RCTTransformImage(UIImage *image, */ RCT_EXTERN BOOL RCTImageHasAlpha(CGImageRef image); -/** - * Create a solid placeholder image of the specified size and color to display - * while loading an image. If color is not specified, image will be transparent. - */ -RCT_EXTERN UIImage *__nullable RCTGetPlaceholderImage(CGSize size, - UIColor *__nullable color); - NS_ASSUME_NONNULL_END diff --git a/Libraries/Image/RCTImageUtils.m b/Libraries/Image/RCTImageUtils.m index 5aeefad12..d218db3ed 100644 --- a/Libraries/Image/RCTImageUtils.m +++ b/Libraries/Image/RCTImageUtils.m @@ -16,8 +16,6 @@ #import "RCTLog.h" #import "RCTUtils.h" -static const CGFloat RCTThresholdValue = 0.0001; - static CGFloat RCTCeilValue(CGFloat value, CGFloat scale) { return ceil(value * scale) / scale; @@ -337,46 +335,3 @@ BOOL RCTImageHasAlpha(CGImageRef image) return YES; } } - -UIImage *__nullable RCTGetPlaceholderImage(CGSize size, - UIColor *__nullable color) -{ - if (size.width <= 0 || size.height <= 0) { - return nil; - } - - // If dimensions are nonintegral, increase scale - CGFloat scale = 1; - if (size.width - floor(size.width) > RCTThresholdValue) { - scale *= round(1.0 / (size.width - floor(size.width))); - } - if (size.height - floor(size.height) > RCTThresholdValue) { - scale *= round(1.0 / (size.height - floor(size.height))); - } - - // Use Euclid's algorithm to find the greatest common divisor - // between the specified placeholder width and height; - NSInteger a = size.width * scale; - NSInteger b = size.height * scale; - while (a != 0) { - NSInteger c = a; - a = b % a; - b = c; - } - - // Divide the placeholder image scale by the GCD we found above. This allows - // us to save memory by creating the smallest possible placeholder image - // with the correct aspect ratio, then scaling it up at display time. - scale /= b; - - // Fill image with specified color - CGFloat alpha = CGColorGetAlpha(color.CGColor); - UIGraphicsBeginImageContextWithOptions(size, ABS(1.0 - alpha) < RCTThresholdValue, scale); - if (alpha > 0) { - [color setFill]; - UIRectFill((CGRect){CGPointZero, size}); - } - UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - return image; -} diff --git a/Libraries/Image/RCTShadowVirtualImage.m b/Libraries/Image/RCTShadowVirtualImage.m index f950e6377..757a48c24 100644 --- a/Libraries/Image/RCTShadowVirtualImage.m +++ b/Libraries/Image/RCTShadowVirtualImage.m @@ -52,10 +52,6 @@ RCT_NOT_IMPLEMENTED(-(instancetype)init) RCTZeroIfNaN(self.height), }; - if (!_image) { - _image = RCTGetPlaceholderImage(imageSize, nil); - } - __weak RCTShadowVirtualImage *weakSelf = self; _cancellationBlock = [_bridge.imageLoader loadImageWithTag:_source.imageURL.absoluteString size:imageSize diff --git a/Libraries/Text/RCTShadowText.m b/Libraries/Text/RCTShadowText.m index 71086ec30..adf7be667 100644 --- a/Libraries/Text/RCTShadowText.m +++ b/Libraries/Text/RCTShadowText.m @@ -217,12 +217,10 @@ static css_dim_t RCTMeasure(void *context, float width, css_measure_mode_t width RCTShadowRawText *shadowRawText = (RCTShadowRawText *)child; [attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:shadowRawText.text ?: @""]]; } else if ([child conformsToProtocol:@protocol(RCTImageComponent)]) { - UIImage *image = ((id)child).image; - if (image) { - NSTextAttachment *imageAttachment = [NSTextAttachment new]; - imageAttachment.image = image; - [attributedString appendAttributedString:[NSAttributedString attributedStringWithAttachment:imageAttachment]]; - } + NSTextAttachment *imageAttachment = [NSTextAttachment new]; + imageAttachment.image = ((id)child).image; + imageAttachment.bounds = (CGRect){CGPointZero, {RCTZeroIfNaN(child.width), RCTZeroIfNaN(child.height)}}; + [attributedString appendAttributedString:[NSAttributedString attributedStringWithAttachment:imageAttachment]]; } else { RCTLogError(@" can't have any children except , or raw strings"); }