diff --git a/Frameworks/AutoLayout/AutoLayout.mm b/Frameworks/AutoLayout/AutoLayout.mm index 642988114f..568fbb4b4e 100644 --- a/Frameworks/AutoLayout/AutoLayout.mm +++ b/Frameworks/AutoLayout/AutoLayout.mm @@ -473,10 +473,10 @@ - (BOOL)autoLayoutInvalidateContentSize { if (CGSizeEqualToSize(layoutProperties->_intrinsicContentSize, newContentSize)) { if (DEBUG_AUTO_LAYOUT_LIGHT) { TraceVerbose(TAG, L"autoLayoutInvalidateContentSize: Size {%f, %f} didn't change; no need to revalidate constraints; no need to re-layout %hs(0x%p).", - object_getClassName(self), - self, newContentSize.width, - newContentSize.height); + newContentSize.height, + object_getClassName(self), + self); } // No more work left to be done; the size didn't actually change. @@ -484,12 +484,12 @@ - (BOOL)autoLayoutInvalidateContentSize { } else { if (DEBUG_AUTO_LAYOUT_LIGHT) { TraceVerbose(TAG, L"autoLayoutInvalidateContentSize: intrinsicContentSize changed from {%f, %f} to {%f, %f}; need to revalidate constraints and re-layout %hs(0x%p).", - object_getClassName(self), - self, newContentSize.width, newContentSize.height, layoutProperties->_intrinsicContentSize.width, - layoutProperties->_intrinsicContentSize.height); + layoutProperties->_intrinsicContentSize.height, + object_getClassName(self), + self); } // Store the new intrinsicContentSize @@ -611,6 +611,12 @@ - (UIView*)autolayoutRoot { - (void)autoLayoutUpdateConstraints { AutoLayoutProperties* layoutProperties = self._autoLayoutProperties; + if (DEBUG_AUTO_LAYOUT_LIGHT) { + TraceVerbose(TAG, L"autoLayoutUpdateConstraints: %hs(0x%p).", + object_getClassName(self), + self); + } + if (![layoutProperties->_associatedConstraints count]) { return; } diff --git a/Frameworks/CoreGraphics/CGContext.mm b/Frameworks/CoreGraphics/CGContext.mm index 00a86e9254..54c81549a5 100644 --- a/Frameworks/CoreGraphics/CGContext.mm +++ b/Frameworks/CoreGraphics/CGContext.mm @@ -2935,7 +2935,20 @@ CGContextRef CGBitmapContextCreateWithData(void* data, RETURN_NULL_IF(!height); RETURN_NULL_IF(!colorSpace); + size_t imputedBitsPerPixel = _CGImageImputeBitsPerPixelFromFormat(colorSpace, bitsPerComponent, bitmapInfo); size_t bitsPerPixel = ((bytesPerRow / width) << 3); + size_t estimatedBytesPerRow = (imputedBitsPerPixel >> 3) * width; + + if (data && estimatedBytesPerRow > bytesPerRow) { + TraceError(TAG, L"Invalid data stride: a %ux%u %ubpp context requires at least a %u-byte stride (requested: %u bytes/row).", width, height, imputedBitsPerPixel, estimatedBytesPerRow, bytesPerRow); + return nullptr; + } + + if (!bytesPerRow) { // When data is not provided, we are allowed to use our estimates. + bitsPerPixel = imputedBitsPerPixel; + bytesPerRow = estimatedBytesPerRow; + } + WICPixelFormatGUID requestedPixelFormat; RETURN_NULL_IF_FAILED( _CGImageGetWICPixelFormatFromImageProperties(bitsPerComponent, bitsPerPixel, colorSpace, bitmapInfo, &requestedPixelFormat)); diff --git a/Frameworks/CoreGraphics/CGImage.mm b/Frameworks/CoreGraphics/CGImage.mm index 5d7099178d..de409a0801 100644 --- a/Frameworks/CoreGraphics/CGImage.mm +++ b/Frameworks/CoreGraphics/CGImage.mm @@ -39,15 +39,13 @@ static const wchar_t* TAG = L"CGImage"; -// TODO #1124: remove old code -#pragma region OLD_CODE +// This is used by XamlCompositor to flush the DisplayTexture cache. +// TODO GH#2098 look at where we're using the image cache and what we can do to avoid it. static std::vector _imageDestructionListeners; COREGRAPHICS_EXPORT void CGImageAddDestructionListener(CGImageDestructionListener listener) { _imageDestructionListeners.push_back(listener); } -#pragma endregion OLD_CODE - #pragma region CGImageImplementation struct __CGImageImpl { @@ -225,6 +223,12 @@ inline WICPixelFormatGUID PixelFormat() const { _impl.renderingIntent = intent; return *this; } + + ~__CGImage() { + for (auto listener : _imageDestructionListeners) { + listener(this); + } + } }; #pragma endregion CGImageImplementation @@ -362,7 +366,9 @@ CGDataProviderRef CGImageGetDataProvider(CGImageRef img) { RETURN_NULL_IF_FAILED(img->ImageSource()->CopyPixels(nullptr, stride, size, buffer.get())); CGDataProviderRef dataProvider = - CGDataProviderCreateWithData(nullptr, buffer.release(), size, [](void* info, const void* data, size_t size) { IwFree(const_cast(data)); }); + CGDataProviderCreateWithData(nullptr, buffer.release(), size, [](void* info, const void* data, size_t size) { + IwFree(const_cast(data)); + }); CFAutorelease(dataProvider); return dataProvider; } @@ -646,6 +652,12 @@ CGImageRef _CGImageCreateCopyWithPixelFormat(CGImageRef image, WICPixelFormatGUI return imageRef; } +CGImageRef _CGImageCreateFromDataProvider(CGDataProviderRef provider) { + RETURN_NULL_IF(!provider); + unsigned char* dataBytes = static_cast(const_cast(_CGDataProviderGetData(provider))); + return _CGImageGetImageFromData(dataBytes, _CGDataProviderGetSize(provider)); +} + CGImageRef _CGImageGetImageFromData(void* data, int length) { return _CGImageLoadImageWithWICDecoder(GUID_NULL, data, length); } @@ -710,6 +722,36 @@ CGImageRef _CGImageLoadImageWithWICDecoder(REFGUID decoderCls, void* bytes, int return nil; } +size_t _CGImageImputeBitsPerPixelFromFormat(CGColorSpaceRef colorSpace, size_t bitsPerComponent, CGBitmapInfo bitmapInfo) { + unsigned int alphaInfo = bitmapInfo & kCGBitmapAlphaInfoMask; + unsigned int byteOrder = bitmapInfo & kCGBitmapByteOrderMask; + + // Try byte order first: The user can specify 32 or 16 directly. + switch (byteOrder) { + case kCGBitmapByteOrder32Little: + case kCGBitmapByteOrder32Big: + return 32; + case kCGBitmapByteOrder16Little: + case kCGBitmapByteOrder16Big: + return 16; + } + + // Otherwise, try to figure out how many components there are. + size_t nComponents = CGColorSpaceGetNumberOfComponents(colorSpace); + switch (alphaInfo) { + case kCGImageAlphaNoneSkipFirst: + case kCGImageAlphaPremultipliedFirst: + case kCGImageAlphaFirst: + case kCGImageAlphaNoneSkipLast: + case kCGImageAlphaPremultipliedLast: + case kCGImageAlphaLast: + nComponents += 1; + break; + } + + return (bitsPerComponent * nComponents); +} + // CG packed format key // |Color |bits/px|CGBitmapInfo | // |-------|-------|---------------| @@ -719,7 +761,6 @@ CGImageRef _CGImageLoadImageWithWICDecoder(REFGUID decoderCls, void* bytes, int HRESULT _CGImageGetWICPixelFormatFromImageProperties( unsigned int bitsPerComponent, unsigned int bitsPerPixel, CGColorSpaceRef colorSpace, CGBitmapInfo bitmapInfo, GUID* pixelFormat) { - // clang-format off static std::map s_CGWICFormatMap{ { CG_FORMAT_KEY(kCGColorSpaceModelRGB , 24, kCGBitmapByteOrderDefault, kCGImageAlphaNone), GUID_WICPixelFormat24bppRGB }, @@ -766,23 +807,13 @@ HRESULT _CGImageGetWICPixelFormatFromImageProperties( RETURN_HR_IF(E_POINTER, !pixelFormat); - CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace); - - unsigned int alphaInfo = bitmapInfo & kCGBitmapAlphaInfoMask; - unsigned int byteOrder = bitmapInfo & kCGBitmapByteOrderMask; - unsigned int formatImputedBpp = 0; - switch (byteOrder) { - case kCGBitmapByteOrder32Little: - case kCGBitmapByteOrder32Big: - formatImputedBpp = 32; - break; - case kCGBitmapByteOrder16Little: - case kCGBitmapByteOrder16Big: - formatImputedBpp = 16; - break; + size_t formatImputedBpp = _CGImageImputeBitsPerPixelFromFormat(colorSpace, bitsPerComponent, bitmapInfo); + if (bitsPerPixel == 0) { + bitsPerPixel = formatImputedBpp; } - if (formatImputedBpp == 0 || formatImputedBpp == bitsPerPixel) { + if (formatImputedBpp == bitsPerPixel) { + CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace); auto found = s_CGWICFormatMap.find(CG_FORMAT_KEY(colorSpaceModel, bitsPerPixel, bitmapInfo, 0)); if (found != s_CGWICFormatMap.end()) { *pixelFormat = found->second; diff --git a/Frameworks/GLKit/GLKTexture.mm b/Frameworks/GLKit/GLKTexture.mm index c92e4898eb..62ce46258f 100644 --- a/Frameworks/GLKit/GLKTexture.mm +++ b/Frameworks/GLKit/GLKTexture.mm @@ -1,6 +1,6 @@ //****************************************************************************** // -// Copyright (c) 2015 Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft. All rights reserved. // // This code is licensed under the MIT License (MIT). // @@ -25,6 +25,7 @@ #import #import #import "NSLogging.h" +#import "CGImageInternal.h" static const wchar_t* TAG = L"GLKTexture"; @@ -277,7 +278,7 @@ @implementation GLKTextureLoader { */ + (GLKTextureInfo*)textureWithContentsOfFile:(NSString*)fname options:(NSDictionary*)opts error:(NSError**)err { CGDataProviderRef provider = CGDataProviderCreateWithFilename([fname UTF8String]); - CGImageRef img = CGImageCreateWithPNGDataProvider(provider, NULL, NO, kCGRenderingIntentDefault); + CGImageRef img = _CGImageCreateFromDataProvider(provider); GLKTextureInfo* res = [self textureWithCGImage:img options:opts error:err]; @@ -395,7 +396,8 @@ + (GLKTextureInfo*)cubeMapWithContentsOfFile:(NSString*)fname options:(NSDiction if (!provider) { return nil; } - CGImageRef img = CGImageCreateWithPNGDataProvider(provider, NULL, NO, kCGRenderingIntentDefault); + + CGImageRef img = _CGImageCreateFromDataProvider(provider); if (!img) { CGDataProviderRelease(provider); return nil; @@ -541,7 +543,8 @@ + (GLKTextureInfo*)cubeMapWithContentsOfFiles:(NSArray*)fnames options:(NSDictio curSide++; continue; } - CGImageRef img = CGImageCreateWithPNGDataProvider(provider, NULL, NO, kCGRenderingIntentDefault); + + CGImageRef img = _CGImageCreateFromDataProvider(provider); if (!img) { CGDataProviderRelease(provider); NSTraceWarning(TAG, @"Unable to create image from cube side texture %@", fn); diff --git a/Frameworks/QuartzCore/CALayer.mm b/Frameworks/QuartzCore/CALayer.mm index 5725d6d83d..022f95558e 100644 --- a/Frameworks/QuartzCore/CALayer.mm +++ b/Frameworks/QuartzCore/CALayer.mm @@ -427,14 +427,20 @@ - (void)renderInContext:(CGContextRef)ctx { [priv->delegate drawLayer:self inContext:ctx]; } } else { - CGRect rect; - - rect.origin.x = 0; - rect.origin.y = priv->bounds.size.height * priv->contentsScale; - rect.size.width = priv->bounds.size.width * priv->contentsScale; - rect.size.height = -priv->bounds.size.height * priv->contentsScale; - - _CGContextDrawImageRect(ctx, priv->contents, rect, destRect); + // If the layer has cached contents, blit them directly. + + // Since the layer was rendered in Quartz referential (ULO) AND the current context + // is assumed to be Quartz referential (ULO), BUT the layer's cached contents + // were captured in a CGImage (CGImage referential, LLO), we have to flip + // the context again before we render it. + + // |1 0 0| is the transformation matrix for flipping a rect anchored at 0,0 about its Y midpoint. + // |0 -1 0| + // |0 h 1| + CGContextSaveGState(ctx); + CGContextConcatCTM(ctx, CGAffineTransformMake(1, 0, 0, -1, 0, destRect.size.height)); + CGContextDrawImage(ctx, destRect, priv->contents); + CGContextRestoreGState(ctx); } // Draw sublayers diff --git a/Frameworks/UIKit/UIButton.mm b/Frameworks/UIKit/UIButton.mm index f1dd269537..5e6b8d05c0 100644 --- a/Frameworks/UIKit/UIButton.mm +++ b/Frameworks/UIKit/UIButton.mm @@ -371,21 +371,32 @@ - (CGRect)contentRectForBounds:(CGRect)bounds { @Status Interoperable */ - (CGRect)imageRectForContentRect:(CGRect)contentRect { - CGSize titleSize = [self.currentTitle sizeWithFont:self.font]; - // TODO #1365 :: Currently cannot assume getting size from nil will return CGSizeZero - CGSize imageSize = CGSizeZero; - CGRect insetsRect = UIEdgeInsetsInsetRect(contentRect, self.imageEdgeInsets); - - if (!self.currentImage) { + ///////////////////////////////////////////////////////////////////// + // Note: #1365 All size calculations here must check for nil, + // as we cannot assume getting a size from nil will return CGSizeZero + ///////////////////////////////////////////////////////////////////// + UIImage* currentImage = self.currentImage; + if (!currentImage) { + // No image, so we return zero for the entire content rect return CGRectZero; } - imageSize = self.currentImage.size; + // Grab the size of the current title + // TODO: Should we be asking our label for this? + NSString* currentTitle = self.currentTitle; + CGSize titleSize = CGSizeZero; + if (currentTitle) { + // We need to round the font size to the nearest pixel value to avoid rounding errors when used in conjunction with the + // frame values that are rounded by UIView. + titleSize = doPixelRound([currentTitle sizeWithFont:self.font]); + } - CGSize totalSize = imageSize; + // Now calculate the total size based on the image and title sizes + CGSize totalSize = currentImage.size; totalSize.width += titleSize.width; // Get the frame based on the control alignment. + CGRect insetsRect = UIEdgeInsetsInsetRect(contentRect, self.imageEdgeInsets); CGRect ret = calculateContentRect(self, totalSize, insetsRect); ret.size.width -= titleSize.width; @@ -404,19 +415,34 @@ - (CGRect)imageRectForContentRect:(CGRect)contentRect { @Status Interoperable */ - (CGRect)titleRectForContentRect:(CGRect)contentRect { - // TODO: Should we be asking our label for its intrinsicContentSize? - // We need to round the font size to the nearest pixel value to avoid rounding errors when used in conjunction with the - // frame values that are rounded by UIView. - CGSize titleSize = doPixelRound([self.currentTitle sizeWithFont:self.font]); - CGSize totalSize = titleSize; - // TODO #1365 :: Currently cannot assume getting size from nil will return CGSizeZero - CGSize imageSize = self.currentImage ? [self.currentImage size] : CGSizeZero; - CGRect insetsRect = UIEdgeInsetsInsetRect(contentRect, self.titleEdgeInsets); + ///////////////////////////////////////////////////////////////////// + // Note: #1365 All size calculations here must check for nil, + // as we cannot assume getting a size from nil will return CGSizeZero + ///////////////////////////////////////////////////////////////////// - if ([self currentTitle].length == 0) { + // Grab the size of the current title + // TODO: Should we be asking our label for this? + NSString* currentTitle = self.currentTitle; + CGSize titleSize = CGSizeZero; + if (currentTitle && currentTitle.length > 0) { + // We need to round the font size to the nearest pixel value to avoid rounding errors when used in conjunction with the + // frame values that are rounded by UIView. + titleSize = doPixelRound([currentTitle sizeWithFont:self.font]); + } else { + // No title, so we return zero for the entire content rect return CGRectZero; } + // Grab the size of the current image + UIImage* currentImage = self.currentImage; + CGSize imageSize = CGSizeZero; + if (currentImage) { + imageSize = [currentImage size]; + } + + CGRect insetsRect = UIEdgeInsetsInsetRect(contentRect, self.titleEdgeInsets); + + CGSize totalSize = titleSize; totalSize.width += imageSize.width; // Get the frame based on the control alignment. @@ -951,32 +977,35 @@ - (UIImageView*)imageView { - (CGSize)intrinsicContentSize { CGSize ret = CGSizeZero; - UIImage* img = self.currentImage; - UIEdgeInsets contentInsets = self.contentEdgeInsets; - - // TODO: Should we be asking our label for its intrinsicContentSize? - // We need to round the font size to the nearest pixel value to avoid rounding errors when used in conjunction with the - // frame values that are rounded by UIView. - CGSize textSize = doPixelRound([[self currentTitle] sizeWithFont:self.font]); + //////////////////////////////////////////////////////////////////// + // Note: #1365 All size calculations here must check for nil, + // as we cannot assume getting a size from nil will return CGSizeZero + //////////////////////////////////////////////////////////////////// // Size should at least fit the image in a normal state. - if (img != nil) { - ret = [img size]; + UIImage* currentImage = self.currentImage; + if (currentImage) { + ret = [currentImage size]; } - if ([self currentTitle].length) { + // TODO: Should we be asking our label for its intrinsicContentSize? + CGSize textSize = CGSizeZero; + NSString* currentTitle = self.currentTitle; + if (currentTitle && (currentTitle.length > 0)) { + // We need to round the font size to the nearest pixel value to avoid rounding errors when used in conjunction with the + // frame values that are rounded by UIView. + textSize = doPixelRound([currentTitle sizeWithFont:self.font]); ret.width = std::max(textSize.width, ret.width); ret.height = std::max(textSize.height, ret.height); } // If we have a background, its image size dictates the smallest size. - if (self.currentBackgroundImage) { - UIImage* background = self.currentBackgroundImage; - // TODO #1365 :: Currently cannot assume getting size from nil will return CGSizeZero - CGSize size = background ? [background size] : CGSizeZero; - - ret.width = std::max(size.width, ret.width); - ret.height = std::max(size.height, ret.height); + UIEdgeInsets contentInsets = self.contentEdgeInsets; + UIImage* currentBackgroundImage = self.currentBackgroundImage; + if (currentBackgroundImage) { + CGSize imageSize = [currentBackgroundImage size]; + ret.width = std::max(imageSize.width, ret.width); + ret.height = std::max(imageSize.height, ret.height); } else if (UIEdgeInsetsEqualToEdgeInsets(contentInsets, UIEdgeInsetsZero)) { // Min values found emperically; set if no contentInsets are set. ret.width = std::max(ret.width, 30.0f); diff --git a/Frameworks/UIKit/UIImage.mm b/Frameworks/UIKit/UIImage.mm index dcba1ef6b9..47a101277b 100644 --- a/Frameworks/UIKit/UIImage.mm +++ b/Frameworks/UIKit/UIImage.mm @@ -491,8 +491,8 @@ - (void)drawAtPoint:(CGPoint)point blendMode:(CGBlendMode)mode alpha:(float)alph CGRect pos; pos.origin = point; - pos.size.width = (img_height / _scale); - pos.size.height = (img_width / _scale); + pos.size.height = (img_height / _scale); + pos.size.width = (img_width / _scale); // |1 0 0| is the transformation matrix for flipping a rect about its Y midpoint m. (m = (y + h/2)) // |0 -1 0| diff --git a/Frameworks/include/CGImageInternal.h b/Frameworks/include/CGImageInternal.h index 14904841ec..1da3541734 100644 --- a/Frameworks/include/CGImageInternal.h +++ b/Frameworks/include/CGImageInternal.h @@ -49,11 +49,13 @@ struct GuidPixelLess : public std::binary_function { } }; -static const std::map s_ValidRenderTargetPixelFormat = { { GUID_WICPixelFormat8bppAlpha, 1 }, // A8 Straight - { GUID_WICPixelFormat32bppRGB, 1 }, // RGBX - { GUID_WICPixelFormat32bppPRGBA, 1 }, // RGBA Premultiplied - { GUID_WICPixelFormat32bppBGR, 1 }, // BGRX - { GUID_WICPixelFormat32bppPBGRA, 1 } }; // BGRX Premultiplied +static const std::map s_ValidRenderTargetPixelFormat = { { GUID_WICPixelFormat8bppAlpha, 1 }, // A8 Straight + { GUID_WICPixelFormat32bppRGB, 1 }, // RGBX + { GUID_WICPixelFormat32bppPRGBA, + 1 }, // RGBA Premultiplied + { GUID_WICPixelFormat32bppBGR, 1 }, // BGRX + { GUID_WICPixelFormat32bppPBGRA, + 1 } }; // BGRX Premultiplied static const std::map s_PixelFormats = { // RGB(A) formats @@ -189,14 +191,14 @@ COREGRAPHICS_EXPORT HRESULT _CGImageGetWICImageSource(CGImageRef image, IWICBitm // Obtain a direct pointer to the data. COREGRAPHICS_EXPORT void* _CGImageGetRawBytes(CGImageRef image); +COREGRAPHICS_EXPORT CGImageRef _CGImageCreateFromDataProvider(CGDataProviderRef provider); + // Obtain the associated DisplayTexture __declspec(dllexport) std::shared_ptr _CGImageGetDisplayTexture(CGImageRef image); -HRESULT _CGImageGetWICPixelFormatFromImageProperties(unsigned int bitsPerComponent, - unsigned int bitsPerPixel, - CGColorSpaceRef colorSpace, - CGBitmapInfo bitmapInfo, - GUID* pixelFormat); +size_t _CGImageImputeBitsPerPixelFromFormat(CGColorSpaceRef colorSpace, size_t bitsPerComponent, CGBitmapInfo bitmapInfo); +HRESULT _CGImageGetWICPixelFormatFromImageProperties( + unsigned int bitsPerComponent, unsigned int bitsPerPixel, CGColorSpaceRef colorSpace, CGBitmapInfo bitmapInfo, GUID* pixelFormat); // If the image is of the same format, the image is retained and returned. COREGRAPHICS_EXPORT CGImageRef _CGImageCreateCopyWithPixelFormat(CGImageRef image, WICPixelFormatGUID pixelFormat); diff --git a/bin/xib2nib.exe b/bin/xib2nib.exe index c21fb0824b..d2bd73783a 100644 --- a/bin/xib2nib.exe +++ b/bin/xib2nib.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:28d70329d20caa244f44b4d974e6e862cc86ff3ae5ed6e32e945c8fbcf5d3234 +oid sha256:7f09eeb3a798ddb23720e7c368ada2afc9794e371f2acdf5b64331cb629a8fb4 size 294912 diff --git a/build/CoreGraphics/dll/CoreGraphics.def b/build/CoreGraphics/dll/CoreGraphics.def index 692b3e3622..9caae62c36 100644 --- a/build/CoreGraphics/dll/CoreGraphics.def +++ b/build/CoreGraphics/dll/CoreGraphics.def @@ -381,6 +381,7 @@ LIBRARY CoreGraphics ; CGImage private exports _CGImageLoadImageWithWICDecoder _CGImageGetImageFromData + _CGImageCreateFromDataProvider _CGImagePNGRepresentation _CGImageJPEGRepresentation _CGImageRepresentation diff --git a/build/winobjc.version b/build/winobjc.version index 303e175096..0f3b16da7a 100644 --- a/build/winobjc.version +++ b/build/winobjc.version @@ -1,4 +1,4 @@ # MAJOR.MINOR.BUILD.REVISION # BUILD = YYMM # REVISION = DD -0.2.1702.16 +0.2.1702.28 diff --git a/deps/3rdparty/libobjc2 b/deps/3rdparty/libobjc2 index 58a7fd2146..f2e4c5ac4b 160000 --- a/deps/3rdparty/libobjc2 +++ b/deps/3rdparty/libobjc2 @@ -1 +1 @@ -Subproject commit 58a7fd2146eaa7312bd315e9e74e45433198e91f +Subproject commit f2e4c5ac4b3ac17f413a38bbc7ee1242f9efd0f7 diff --git a/deps/prebuilt/Universal Windows/ARM/Debug/libobjc2.dll b/deps/prebuilt/Universal Windows/ARM/Debug/libobjc2.dll index 2a068a6947..049bd001ae 100644 --- a/deps/prebuilt/Universal Windows/ARM/Debug/libobjc2.dll +++ b/deps/prebuilt/Universal Windows/ARM/Debug/libobjc2.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:65c36e0092ccc944908ae09b347f2ff0e41240ec9ce1e7d7242a875ac805e559 -size 248832 +oid sha256:391206167c5467a6733a5d202c0b823558b048ce7e85607b2dcf05ced98ba596 +size 249344 diff --git a/deps/prebuilt/Universal Windows/ARM/Debug/libobjc2.lib b/deps/prebuilt/Universal Windows/ARM/Debug/libobjc2.lib index 7c2f121b74..3e78f77810 100644 --- a/deps/prebuilt/Universal Windows/ARM/Debug/libobjc2.lib +++ b/deps/prebuilt/Universal Windows/ARM/Debug/libobjc2.lib @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:098d5ed6195c83543855ac6713f4d124d811447fc7b640ddb694822b03092d16 +oid sha256:e789d3530f7dbddc7910d341b8c5ccece64e2c1238bf25e75b115a13a38a8bd1 size 41870 diff --git a/deps/prebuilt/Universal Windows/ARM/Debug/libobjc2.pdb b/deps/prebuilt/Universal Windows/ARM/Debug/libobjc2.pdb index bc25d63192..bda540cdd2 100644 --- a/deps/prebuilt/Universal Windows/ARM/Debug/libobjc2.pdb +++ b/deps/prebuilt/Universal Windows/ARM/Debug/libobjc2.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e9ae3dd6b8ec1a49830c44459884a8a7d49659fbf1d2e089d26bc06e829f4f3b +oid sha256:67a3a21ec9999efa5b697872de546d5ed12b454925750ee74f6f9f1379be00f4 size 1298432 diff --git a/deps/prebuilt/Universal Windows/ARM/Release/libobjc2.dll b/deps/prebuilt/Universal Windows/ARM/Release/libobjc2.dll index 8353533176..0c0cf8d5c5 100644 --- a/deps/prebuilt/Universal Windows/ARM/Release/libobjc2.dll +++ b/deps/prebuilt/Universal Windows/ARM/Release/libobjc2.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8224c56d91159a872f61b4abea02c575c284583cdf64580fcf0e455bf645bd46 -size 93696 +oid sha256:c81a0cf4e8df174e4924d88d2d81f9a8097369968e73696e19c6e3d138d949b4 +size 94720 diff --git a/deps/prebuilt/Universal Windows/ARM/Release/libobjc2.lib b/deps/prebuilt/Universal Windows/ARM/Release/libobjc2.lib index f8e608260b..ae1fd5e175 100644 --- a/deps/prebuilt/Universal Windows/ARM/Release/libobjc2.lib +++ b/deps/prebuilt/Universal Windows/ARM/Release/libobjc2.lib @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9598aaedf5440bd6baa25a125a465ae9d043d1b8d7d74be3bad168736e24ffd4 +oid sha256:607b82720857e5fd36abdaad58ddd276a2dc444ffc2448d99fd5614193c1709c size 41870 diff --git a/deps/prebuilt/Universal Windows/ARM/Release/libobjc2.pdb b/deps/prebuilt/Universal Windows/ARM/Release/libobjc2.pdb index 378d82d708..a1cca7c8fa 100644 --- a/deps/prebuilt/Universal Windows/ARM/Release/libobjc2.pdb +++ b/deps/prebuilt/Universal Windows/ARM/Release/libobjc2.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:51759bf5b71d0794c21fbb5a32bf0c9d9f35a9a45a873731d637fc93c65bf183 -size 1044480 +oid sha256:37ec205af083d520460c97225dd210b63646b5f6566224bb55ad68fcc2cf6932 +size 1052672 diff --git a/deps/prebuilt/Universal Windows/x86/Debug/libobjc2.dll b/deps/prebuilt/Universal Windows/x86/Debug/libobjc2.dll index 0e256ae6e2..22b73b3d61 100644 --- a/deps/prebuilt/Universal Windows/x86/Debug/libobjc2.dll +++ b/deps/prebuilt/Universal Windows/x86/Debug/libobjc2.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6421fdba5cf80654ffc7731a8d954705283f75f6725629e6156c691d95f7dce6 -size 190976 +oid sha256:aa2db996f6874880f747b256f9e3270c3fc927b25292adfb0a95877d5b8d24fe +size 191488 diff --git a/deps/prebuilt/Universal Windows/x86/Debug/libobjc2.lib b/deps/prebuilt/Universal Windows/x86/Debug/libobjc2.lib index 3a92b02776..535ce1a80e 100644 --- a/deps/prebuilt/Universal Windows/x86/Debug/libobjc2.lib +++ b/deps/prebuilt/Universal Windows/x86/Debug/libobjc2.lib @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d8fa0e7e9e6e66a4e434f78ae22a9a7dac0d33eb58af446319125abc007cb46d +oid sha256:666127145866ad705a6c227b51a3caac0c2e665da6592d441e5609d0d4ed70c4 size 42758 diff --git a/deps/prebuilt/Universal Windows/x86/Debug/libobjc2.pdb b/deps/prebuilt/Universal Windows/x86/Debug/libobjc2.pdb index 3fd1b4a4f2..cb09f238f1 100644 --- a/deps/prebuilt/Universal Windows/x86/Debug/libobjc2.pdb +++ b/deps/prebuilt/Universal Windows/x86/Debug/libobjc2.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e37f75aa55d70f3f6181a7cbd83fd9fd3c5ff60ffe93e16be153d8a1880f4ea7 -size 1265664 +oid sha256:57768f07f31b60a64f9f971d13448206970c6f65bbb542227bb5f3f67aaac51d +size 1273856 diff --git a/deps/prebuilt/Universal Windows/x86/Release/libobjc2.dll b/deps/prebuilt/Universal Windows/x86/Release/libobjc2.dll index 35d89d042b..4f98cd1d7c 100644 --- a/deps/prebuilt/Universal Windows/x86/Release/libobjc2.dll +++ b/deps/prebuilt/Universal Windows/x86/Release/libobjc2.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:92bcb3e5ac22e343b70fa4e831c2be29d1b63e320850601d3669d45cb731f113 -size 95232 +oid sha256:d4139631fa7fdcb8637d5506aa83682ec126faf247d084f66e730e6d4d16115c +size 95744 diff --git a/deps/prebuilt/Universal Windows/x86/Release/libobjc2.lib b/deps/prebuilt/Universal Windows/x86/Release/libobjc2.lib index 6251b92f53..52eb0506bb 100644 --- a/deps/prebuilt/Universal Windows/x86/Release/libobjc2.lib +++ b/deps/prebuilt/Universal Windows/x86/Release/libobjc2.lib @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:07521ec4bd28240555617d74e64823e65390cae53c0b64ef02fc52ee6c164509 +oid sha256:91a529ac5b0cbaca86afb45e08d92cafe3e2d3c7b964c86dcd342b923f341714 size 42758 diff --git a/deps/prebuilt/Universal Windows/x86/Release/libobjc2.pdb b/deps/prebuilt/Universal Windows/x86/Release/libobjc2.pdb index ba2b8e9a3c..f7792adae8 100644 --- a/deps/prebuilt/Universal Windows/x86/Release/libobjc2.pdb +++ b/deps/prebuilt/Universal Windows/x86/Release/libobjc2.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:53f4006dcdb77626bf681a22152052f0ceaeb276b9b970b7b23189c65fb9728d -size 1077248 +oid sha256:ea441a2df50b59b25101feae366c60c0811a408815ac477f27e6f4acd092862e +size 1085440 diff --git a/tests/unittests/CoreGraphics/CGBitmapContextTests.mm b/tests/unittests/CoreGraphics/CGBitmapContextTests.mm index f2dfb2ab58..b4d926a253 100644 --- a/tests/unittests/CoreGraphics/CGBitmapContextTests.mm +++ b/tests/unittests/CoreGraphics/CGBitmapContextTests.mm @@ -288,3 +288,43 @@ void _TestPixelFormat(const CGRect bounds, const CGBitmapInfo info, DWORD expect // clang-format on INSTANTIATE_TEST_CASE_P(CGBitmapContextFormat, BitmapFormats, ::testing::ValuesIn(bitmapFormatTestCases)); + +TEST(CGBitmapContext, BadStrides) { + uint32_t data = 0; + auto colorSpace = woc::MakeStrongCF(CGColorSpaceCreateDeviceRGB()); + + { + auto context = woc::MakeStrongCF(CGBitmapContextCreateWithData(&data, 1, 1, 8, 0, colorSpace, kCGImageAlphaLast, nullptr, nullptr)); + ASSERT_EQ(nullptr, context); + } + + { + auto context = woc::MakeStrongCF(CGBitmapContextCreateWithData(&data, 1, 1, 8, 1, colorSpace, kCGImageAlphaLast, nullptr, nullptr)); + ASSERT_EQ(nullptr, context); + } +} + +TEST(CGBitmapContext, MismatchedConfigurationValues) { + auto colorSpace = woc::MakeStrongCF(CGColorSpaceCreateDeviceRGB()); + + { + // Provided 1 byte per row, but using 3-component + alpha = 32bpp (4 byte/pixel) + auto context = woc::MakeStrongCF(CGBitmapContextCreateWithData(nullptr, 1, 1, 8, 1, colorSpace, kCGImageAlphaLast, nullptr, nullptr)); + ASSERT_EQ(nullptr, context); + } + + { + // Provided 2 bytes per row, requested 32bpp, but using 3-component no alpha = 24bpp (3 byte/pixel) + // Context imputes format to be 32, but provided values should not match. + auto context = woc::MakeStrongCF(CGBitmapContextCreateWithData(nullptr, 1, 1, 8, 2, colorSpace, kCGImageAlphaNone | kCGBitmapByteOrder32Big, nullptr, nullptr)); + ASSERT_EQ(nullptr, context); + } +} + +TEST(CGBitmapContext, ImputeStrideRGBA) { + auto colorSpace = woc::MakeStrongCF(CGColorSpaceCreateDeviceRGB()); + auto context = woc::MakeStrongCF(CGBitmapContextCreateWithData(nullptr, 1, 1, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast, nullptr, nullptr)); + ASSERT_NE(nullptr, context); + EXPECT_EQ(32, CGBitmapContextGetBitsPerPixel(context)); + EXPECT_LE(4, CGBitmapContextGetBytesPerRow(context)); // 4 <= stride +} \ No newline at end of file diff --git a/tools/vsimporter/xib2nib/UIButton.cpp b/tools/vsimporter/xib2nib/UIButton.cpp index 9533f8914f..1961316166 100644 --- a/tools/vsimporter/xib2nib/UIButton.cpp +++ b/tools/vsimporter/xib2nib/UIButton.cpp @@ -235,15 +235,7 @@ void UIButton::InitFromXIB(XIBObject* obj) { if (!_font) _font = (UIFont*)obj->FindMember("IBUIFont"); - switch (_buttonType) { - case 1: - obj->_outputClassName = "UIRoundedRectButton"; - break; - - default: - obj->_outputClassName = "UIButton"; - break; - } + obj->_outputClassName = "UIButton"; } void UIButton::InitFromStory(XIBObject* obj) { @@ -253,6 +245,7 @@ void UIButton::InitFromStory(XIBObject* obj) { if (type) { if (strcmp(type, "roundedRect") == 0) { getAttrAndHandle("buttonType"); + // TODO: Investigate why this value deviates from UIButtonType _buttonType = 1; } else { printf("Unknown button type <%s>\n", type); @@ -260,15 +253,7 @@ void UIButton::InitFromStory(XIBObject* obj) { } } - switch (_buttonType) { - case 1: - obj->_outputClassName = "UIRoundedRectButton"; - break; - - default: - obj->_outputClassName = "UIButton"; - break; - } + obj->_outputClassName = "UIButton"; } void UIButton::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) {