From 613b2769f3e7dc0e9b68fdba1ed6e62665615a3e Mon Sep 17 00:00:00 2001 From: Jeyaram Jeyaraj Date: Tue, 20 Dec 2016 18:25:16 -0800 Subject: [PATCH 1/5] Implementation of Linear gradients with full optional support --- Frameworks/CoreGraphics/CGContext.mm | 99 +++++++++- Frameworks/CoreGraphics/CGGradient.mm | 22 ++- Frameworks/include/CGGradientInternal.h | 14 +- .../CGContextDrawingTests.cpp | 178 ++++++++++++++++++ .../TestImage.CGContext.LinearGradient2.png | 3 + .../TestImage.CGContext.LinearGradient3.png | 3 + ...e.CGContext.LinearGradientInvalidCount.png | 3 + ...CGContext.LinearGradientShortBothSides.png | 3 + ...LinearGradientShortBothSides_Options_0.png | 3 + ...tions_kCGGradientDrawsAfterEndLocation.png | 3 + ...ns_kCGGradientDrawsBeforeStartLocation.png | 3 + ...mage.CGContext.LinearGradientWithAlpha.png | 3 + ...CGContext.LinearGradientWithLowOpacity.png | 3 + ...text.LinearGradientWithLowOpacityShort.png | 3 + 14 files changed, 337 insertions(+), 6 deletions(-) create mode 100644 tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradient2.png create mode 100644 tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradient3.png create mode 100644 tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientInvalidCount.png create mode 100644 tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientShortBothSides.png create mode 100644 tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientShortBothSides_Options_0.png create mode 100644 tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientShortBothSides_Options_kCGGradientDrawsAfterEndLocation.png create mode 100644 tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientShortBothSides_Options_kCGGradientDrawsBeforeStartLocation.png create mode 100644 tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientWithAlpha.png create mode 100644 tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientWithLowOpacity.png create mode 100644 tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientWithLowOpacityShort.png diff --git a/Frameworks/CoreGraphics/CGContext.mm b/Frameworks/CoreGraphics/CGContext.mm index 302b8c9405..534b3e7e00 100644 --- a/Frameworks/CoreGraphics/CGContext.mm +++ b/Frameworks/CoreGraphics/CGContext.mm @@ -30,6 +30,7 @@ #import "CGPathInternal.h" #import "CGIWICBitmap.h" #import "CGPatternInternal.h" +#import "CGGradientInternal.h" #import @@ -49,6 +50,9 @@ static const wchar_t* TAG = L"CGContext"; +// Coordinate offset to support CGGradientDrawingOptions +static const float s_CGGradientStartPoint = 1E-45; + enum _CGCoordinateMode : unsigned int { _kCGCoordinateModeDeviceSpace = 0, _kCGCoordinateModeUserSpace }; // A drawing context is represented by a number of layers, each with their own drawing state: @@ -2356,14 +2360,105 @@ void CGContextDrawTiledImage(CGContextRef context, CGRect rect, CGImageRef image #pragma region Drawing Operations - Gradient + Shading /** - @Status Stub +* Insert a transparent color at the specified 'location'. +* This will also move the color at the specified 'location' to the supplied 'position' +*/ +static inline void __CGGradientInsertTransparentColor(std::vector& gradientStops, int location, float position) { + gradientStops[location].position = position; + // set the edge location to be transparent + D2D1_GRADIENT_STOP transparent; + transparent.color = D2D1::ColorF(0, 0, 0, 0); + transparent.position = location; + gradientStops.push_back(transparent); +} + +/* +* Convert CGGradient to D2D1_GRADIENT_STOP +*/ +static std::vector __CGGradientToD2D1GradientStop(CGContextRef context, + CGGradientRef gradient, + CGGradientDrawingOptions options) { + unsigned long gradientCount = _CGGradientGetCount(gradient); + std::vector gradientStops(gradientCount); + + CGFloat* colorComponents = _CGGradientGetColorComponents(gradient); + CGFloat* locations = _CGGradientGetStopLocation(gradient); + for (unsigned long i = 0; i < gradientCount; ++i) { + unsigned int colorIndex = (i * 4); + gradientStops[i].color = D2D1::ColorF(colorComponents[colorIndex], + colorComponents[colorIndex + 1], + colorComponents[colorIndex + 2], + colorComponents[colorIndex + 3]); + gradientStops[i].position = locations[i]; + } + + // we want to support CGGradientDrawingOptions, but by default d2d will extend the region via repeating the brush (or other + // effect based on the extend mode). We support that by inserting a point (with transparent color) close to the start/end points, such + // that d2d will automatically extend the transparent color, thus we obtain the desired effect for CGGradientDrawingOptions. + + switch (options) { + case 0: + __CGGradientInsertTransparentColor(gradientStops, 0, s_CGGradientStartPoint); + __CGGradientInsertTransparentColor(gradientStops, 1, 1 - s_CGGradientStartPoint); + break; + + case kCGGradientDrawsAfterEndLocation: + __CGGradientInsertTransparentColor(gradientStops, 0, s_CGGradientStartPoint); + break; + + case kCGGradientDrawsBeforeStartLocation: + __CGGradientInsertTransparentColor(gradientStops, 1, 1 - s_CGGradientStartPoint); + break; + default: + break; + } + + return gradientStops; +} + +/** + @Status Interoperable */ void CGContextDrawLinearGradient( CGContextRef context, CGGradientRef gradient, CGPoint startPoint, CGPoint endPoint, CGGradientDrawingOptions options) { NOISY_RETURN_IF_NULL(context); + NOISY_RETURN_IF_NULL(gradient); RETURN_IF(!context->ShouldDraw()); - UNIMPLEMENTED(); + RETURN_IF(_CGGradientGetCount(gradient) == 0); + + std::vector gradientStops = __CGGradientToD2D1GradientStop(context, gradient, options); + + ComPtr gradientStopCollection; + + ComPtr deviceContext = context->DeviceContext(); + FAIL_FAST_IF_FAILED(deviceContext->CreateGradientStopCollection(gradientStops.data(), + gradientStops.size(), + D2D1_GAMMA_2_2, + D2D1_EXTEND_MODE_CLAMP, + &gradientStopCollection)); + + ComPtr linearGradientBrush; + FAIL_FAST_IF_FAILED(deviceContext->CreateLinearGradientBrush( + D2D1::LinearGradientBrushProperties(_CGPointToD2D_F(startPoint), _CGPointToD2D_F(endPoint)), + D2D1::BrushProperties(context->CurrentGState().alpha, + __CGAffineTransformToD2D_F(CGContextGetUserSpaceToDeviceSpaceTransform(context))), + gradientStopCollection.Get(), + &linearGradientBrush)); + + // Area to fill + D2D1_SIZE_F targetSize = deviceContext->GetSize(); + D2D1_RECT_F region = D2D1::RectF(0, 0, targetSize.width, targetSize.height); + + ComPtr commandList; + FAIL_FAST_IF_FAILED(context->DrawToCommandList(_kCGCoordinateModeDeviceSpace, + nullptr, + &commandList, + [&](CGContextRef context, ID2D1DeviceContext* deviceContext) { + deviceContext->FillRectangle(®ion, linearGradientBrush.Get()); + return S_OK; + })); + FAIL_FAST_IF_FAILED(context->DrawImage(commandList.Get())); } /** diff --git a/Frameworks/CoreGraphics/CGGradient.mm b/Frameworks/CoreGraphics/CGGradient.mm index 4b81574e2e..0b5d0869cc 100644 --- a/Frameworks/CoreGraphics/CGGradient.mm +++ b/Frameworks/CoreGraphics/CGGradient.mm @@ -36,7 +36,7 @@ - (void)dealloc { @end __CGGradient::__CGGradient() : _components(NULL), _locations(NULL) { - object_setClass((id) this, [CGNSGradient class]); + object_setClass((id)this, [CGNSGradient class]); } __CGGradient::~__CGGradient() { @@ -181,3 +181,23 @@ CFTypeID CGGradientGetTypeID() { UNIMPLEMENTED(); return StubReturn(); } + +CGFloat* _CGGradientGetStopLocation(CGGradientRef gradient) { + RETURN_NULL_IF(!gradient); + return gradient->_locations; +} + +CGFloat* _CGGradientGetColorComponents(CGGradientRef gradient) { + RETURN_NULL_IF(!gradient); + return gradient->_components; +} + +unsigned long _CGGradientGetCount(CGGradientRef gradient) { + RETURN_RESULT_IF_NULL(gradient, 0); + return gradient->_count; +} + +CGColorSpaceModel _CGGradientGetColorSpaceModel(CGGradientRef gradient) { + RETURN_RESULT_IF_NULL(gradient, kCGColorSpaceModelRGB); + return gradient->_colorSpaceModel; +} \ No newline at end of file diff --git a/Frameworks/include/CGGradientInternal.h b/Frameworks/include/CGGradientInternal.h index 021cd6bb13..a8680d0921 100644 --- a/Frameworks/include/CGGradientInternal.h +++ b/Frameworks/include/CGGradientInternal.h @@ -1,7 +1,7 @@ //****************************************************************************** // // Copyright (c) 2016 Intel Corporation. All rights reserved. -// Copyright (c) 2015 Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft. All rights reserved. // // This code is licensed under the MIT License (MIT). // @@ -17,8 +17,8 @@ #pragma once -#include "CoreGraphics/CGGradient.h" -#include "CoreGraphicsInternal.h" +#import +#import "CoreGraphicsInternal.h" #include class __CGGradient : private objc_object { @@ -34,3 +34,11 @@ class __CGGradient : private objc_object { void initWithColorComponents(const float* components, const float* locations, size_t count, CGColorSpaceRef colorspace); void initWithColors(CFArrayRef components, const float* locations, CGColorSpaceRef colorspace); }; + +unsigned long _CGGradientGetCount(CGGradientRef gradient); + +CGFloat* _CGGradientGetStopLocation(CGGradientRef gradient); + +CGFloat* _CGGradientGetColorComponents(CGGradientRef gradient); + +CGColorSpaceModel _CGGradientGetColorSpaceModel(CGGradientRef gradient); \ No newline at end of file diff --git a/tests/UnitTests/CoreGraphics.drawing/CGContextDrawingTests.cpp b/tests/UnitTests/CoreGraphics.drawing/CGContextDrawingTests.cpp index c7338651a3..a5e6623d28 100644 --- a/tests/UnitTests/CoreGraphics.drawing/CGContextDrawingTests.cpp +++ b/tests/UnitTests/CoreGraphics.drawing/CGContextDrawingTests.cpp @@ -589,3 +589,181 @@ DRAW_TEST(CGContext, PremultipliedAlphaImage) { CGContextSetRGBFillColor(context, 1.0, 0.0, 0.0, 0.5); CGContextFillRect(context, { 0, 0, 100, 100 }); } + +#pragma region LinearGradient +DRAW_TEST_F(CGContext, LinearGradient, UIKitMimicTest) { + CGContextRef context = GetDrawingContext(); + + CGFloat locations[2] = { 0, 1 }; + CGFloat components[8] = { 0.0, 0.0, 1, 1.0, 1.0, 0, 0, 1.0 }; + CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); + CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, 2); + + CGPoint startPoint = CGPointMake(0, 0); + CGPoint endPoint = CGPointMake(512, 1024); + + CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsBeforeStartLocation); + CFRelease(colorspace); + CFRelease(gradient); +} + +static void _drawShortLinearGradientWithOptions(CGContextRef context, CGRect bounds, CGGradientDrawingOptions option) { + CGFloat locations[2] = { 0, 1 }; + CGFloat components[8] = { 0.0, 1, 0.0, 1.0, 1.0, 0, 0, 1.0 }; + + CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); + CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, 2); + + CGRect borderRect = CGRectInset(bounds, 30, 50); + + CGContextDrawLinearGradient(context, gradient, borderRect.origin, CGPointMake(borderRect.size.width, borderRect.size.height), option); + + CFRelease(colorspace); + CFRelease(gradient); +} + +DRAW_TEST_F(CGContext, LinearGradientShortBothSides_Options_0, UIKitMimicTest) { + _drawShortLinearGradientWithOptions(GetDrawingContext(), GetDrawingBounds(), 0); +} + +DRAW_TEST_F(CGContext, LinearGradientShortBothSides_Options_kCGGradientDrawsBeforeStartLocation, UIKitMimicTest) { + _drawShortLinearGradientWithOptions(GetDrawingContext(), GetDrawingBounds(), kCGGradientDrawsBeforeStartLocation); +} + +DRAW_TEST_F(CGContext, LinearGradientShortBothSides_Options_kCGGradientDrawsAfterEndLocation, UIKitMimicTest) { + _drawShortLinearGradientWithOptions(GetDrawingContext(), GetDrawingBounds(), kCGGradientDrawsAfterEndLocation); +} + +DRAW_TEST_F(CGContext, LinearGradientInvalidCount, UIKitMimicTest) { + CGContextRef context = GetDrawingContext(); + + CGFloat locations[] = { 0.0 }; + + CGFloat components[] = { + 0.85, 0, 0, 1.0, + }; + + CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); + CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, 0); + CGPoint startPoint = CGPointMake(0, 0); + CGPoint endPoint = CGPointMake(512, 1024); + + CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsBeforeStartLocation); + CFRelease(colorspace); + CFRelease(gradient); +} + +DRAW_TEST_F(CGContext, LinearGradient2, UIKitMimicTest) { + CGContextRef context = GetDrawingContext(); + + CGFloat locations[] = { 0.0, 0.33, 0.66, 1.0 }; + + CGFloat components[] = { + 0.85, 0, 0, 1.0, 1, 0, 0, 1.0, 0.85, 0.3, 0, 1.0, 0.1, 0, 0.9, 1.0, + }; + + CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); + CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, 4); + CGPoint startPoint = CGPointMake(0, 0); + CGPoint endPoint = CGPointMake(512, 1024); + + CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsBeforeStartLocation); + CFRelease(colorspace); + CFRelease(gradient); +} + +DRAW_TEST_F(CGContext, LinearGradient2Short, UIKitMimicTest) { + CGContextRef context = GetDrawingContext(); + + CGFloat locations[] = { 0.0, 0.33, 1.0 }; + + CGFloat components[] = { 0.85, 0, 0, 1.0, 1, 0, 0, 1.0, 0.85, 0.3, 0, 1.0 }; + + CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); + CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, 3); + CGPoint startPoint = CGPointMake(120, 200); + CGPoint endPoint = CGPointMake(350, 800); + + CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsBeforeStartLocation); + CFRelease(colorspace); + CFRelease(gradient); +} + +DRAW_TEST_F(CGContext, LinearGradient3, UIKitMimicTest) { + CGContextRef context = GetDrawingContext(); + + CGFloat locations[] = { 0.0, 0.5, 1 }; + + CGFloat components[] = { + 1, 0, 0, 1.0, 0, 1, 0, 1.0, 0, 0, 1, 1.0, + }; + + CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); + CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, 3); + CGPoint startPoint = CGPointMake(0, 0); + CGPoint endPoint = CGPointMake(512, 1024); + + CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsBeforeStartLocation); + CFRelease(colorspace); + CFRelease(gradient); +} + +DRAW_TEST_F(CGContext, LinearGradientWithLowOpacity, UIKitMimicTest) { + CGContextRef context = GetDrawingContext(); + + CGFloat locations[] = { 0.0, 0.5, 1 }; + + CGFloat components[] = { + 1, 0, 0, 0.1, 0, 1, 0, 0.9, 0, 0, 1, 0.8, + }; + + CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); + CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, 3); + CGPoint startPoint = CGPointMake(300, 750); + CGPoint endPoint = CGPointMake(0, 0); + + CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsBeforeStartLocation); + CFRelease(colorspace); + CFRelease(gradient); +} + +DRAW_TEST_F(CGContext, LinearGradientWithAlpha, UIKitMimicTest) { + CGContextRef context = GetDrawingContext(); + + CGFloat locations[] = { 0.0, 0.25, 0.5, 0.6, 0.8, 0.9, 1 }; + + CGFloat components[] = { + 1, 0, 0, 1, 0.4, 0.1, 0.5, 1, 0.50, 0.2, 0.99, 1, 0.41, 0.56, 0, 1, 0.12, 0.12, .3, 1, 0.9, 0.4, 1, 1, 0.2, 0.3, 0.8, 1, + }; + + CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); + CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, 7); + CGPoint startPoint = CGPointMake(512, 1024); + CGPoint endPoint = CGPointMake(0, 0); + + CGContextSetAlpha(context, 0.75); + CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsBeforeStartLocation); + CFRelease(colorspace); + CFRelease(gradient); +} + +DRAW_TEST_F(CGContext, LinearGradientWithLowOpacityShort, UIKitMimicTest) { + CGContextRef context = GetDrawingContext(); + + CGFloat locations[] = { 0.0, 0.5, 1 }; + + CGFloat components[] = { + 1, 0, 0, 0.8, 0, 1, 0, 0.9, 0, 0, 1, 0.1, + }; + + CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); + CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, 3); + CGPoint startPoint = CGPointMake(250, 300); + CGPoint endPoint = CGPointMake(0, 0); + CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsAfterEndLocation); + + CFRelease(colorspace); + CFRelease(gradient); +} + +#pragma endregion LinearGradient \ No newline at end of file diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradient2.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradient2.png new file mode 100644 index 0000000000..e06811f608 --- /dev/null +++ b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradient2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:082d34c1be4f421ed9e701662200431cd65cfb3618dea93dd438aa2054d72c0b +size 249515 diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradient3.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradient3.png new file mode 100644 index 0000000000..25214c5fa5 --- /dev/null +++ b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradient3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3c792db607bdbdb1f9def63c4392c68d92bdd1de3ffaeb9bf0062074fbce2177 +size 361452 diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientInvalidCount.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientInvalidCount.png new file mode 100644 index 0000000000..0d49c63b48 --- /dev/null +++ b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientInvalidCount.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3ff5638aa5ef680221b0ecdbf32b625662d6720dae7e0ed2be3d4aaa43e24995 +size 10309 diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientShortBothSides.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientShortBothSides.png new file mode 100644 index 0000000000..a6b75e9d54 --- /dev/null +++ b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientShortBothSides.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:23439ef625639281d2cc914a1055994b499fb813dc7c28b8ed56a14f54fc548e +size 292501 diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientShortBothSides_Options_0.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientShortBothSides_Options_0.png new file mode 100644 index 0000000000..fd413dd8b6 --- /dev/null +++ b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientShortBothSides_Options_0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:17368771d59238306c3d613f898211a24983b9d382055c6ccb719346e3ebf07b +size 293568 diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientShortBothSides_Options_kCGGradientDrawsAfterEndLocation.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientShortBothSides_Options_kCGGradientDrawsAfterEndLocation.png new file mode 100644 index 0000000000..8c3e3bd97e --- /dev/null +++ b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientShortBothSides_Options_kCGGradientDrawsAfterEndLocation.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dd17fb5bb48fde1a0068dd80a26b06dd9b90360b16f5d02d0d2d0fb39a45b293 +size 292629 diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientShortBothSides_Options_kCGGradientDrawsBeforeStartLocation.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientShortBothSides_Options_kCGGradientDrawsBeforeStartLocation.png new file mode 100644 index 0000000000..9ac7583cad --- /dev/null +++ b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientShortBothSides_Options_kCGGradientDrawsBeforeStartLocation.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6cac94bfd0661b0b4b3581dc76b0d4a4c578e6509879da14e786d413f995687d +size 292451 diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientWithAlpha.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientWithAlpha.png new file mode 100644 index 0000000000..4ab5964a87 --- /dev/null +++ b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientWithAlpha.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:88669c0894dd30ec71c09f0148cd3e3ac19c2db4fbf83abf6c399a7eca20cab7 +size 485405 diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientWithLowOpacity.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientWithLowOpacity.png new file mode 100644 index 0000000000..8582e7057a --- /dev/null +++ b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientWithLowOpacity.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4f3e7e6cefb31ab3835372859461fc0e524c58f18569d3058f02e0b5c6dbb088 +size 500289 diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientWithLowOpacityShort.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientWithLowOpacityShort.png new file mode 100644 index 0000000000..698271f24e --- /dev/null +++ b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientWithLowOpacityShort.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f53e5e9ba48cbcf5f825ad72dcda2eeaa188f69efc3b4c4e559115923e0cc5ae +size 483536 From bfdf4790b7f0df0d48ee2720788e605be096d6da Mon Sep 17 00:00:00 2001 From: Jeyaram Jeyaraj Date: Wed, 21 Dec 2016 07:45:04 -0800 Subject: [PATCH 2/5] cr feedback and moving tests to file --- Frameworks/CoreGraphics/CGContext.mm | 23 +-- .../CoreGraphics.Drawing.UnitTests.vcxproj | 1 + .../CGContextDrawingTests.cpp | 180 +--------------- .../CGContextDrawing_GradientTests.cpp | 195 ++++++++++++++++++ ...TestImage.CGGradient..LinearGradient2.png} | 0 ...TestImage.CGGradient..LinearGradient3.png} | 0 ...radient..LinearGradientShortBothSides.png} | 0 ...inearGradientShortBothSides_Options_0.png} | 0 .../TestImage.CGGradient.LinearGradient.png | 3 + ...CGGradient.LinearGradientInvalidCount.png} | 0 ...LinearGradientShortBothSides_Options_0.png | 3 + ...ions_kCGGradientDrawsAfterEndLocation.png} | 0 ...s_kCGGradientDrawsBeforeStartLocation.png} | 0 ...ge.CGGradient.LinearGradientWithAlpha.png} | 0 ...Gradient.LinearGradientWithLowOpacity.png} | 0 ...ent.LinearGradientWithLowOpacityShort.png} | 0 16 files changed, 210 insertions(+), 195 deletions(-) create mode 100644 tests/unittests/CoreGraphics.drawing/CGContextDrawing_GradientTests.cpp rename tests/unittests/CoreGraphics.drawing/data/reference/{TestImage.CGContext.LinearGradient2.png => TestImage.CGGradient..LinearGradient2.png} (100%) rename tests/unittests/CoreGraphics.drawing/data/reference/{TestImage.CGContext.LinearGradient3.png => TestImage.CGGradient..LinearGradient3.png} (100%) rename tests/unittests/CoreGraphics.drawing/data/reference/{TestImage.CGContext.LinearGradientShortBothSides.png => TestImage.CGGradient..LinearGradientShortBothSides.png} (100%) rename tests/unittests/CoreGraphics.drawing/data/reference/{TestImage.CGContext.LinearGradientShortBothSides_Options_0.png => TestImage.CGGradient..LinearGradientShortBothSides_Options_0.png} (100%) create mode 100644 tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGGradient.LinearGradient.png rename tests/unittests/CoreGraphics.drawing/data/reference/{TestImage.CGContext.LinearGradientInvalidCount.png => TestImage.CGGradient.LinearGradientInvalidCount.png} (100%) create mode 100644 tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGGradient.LinearGradientShortBothSides_Options_0.png rename tests/unittests/CoreGraphics.drawing/data/reference/{TestImage.CGContext.LinearGradientShortBothSides_Options_kCGGradientDrawsAfterEndLocation.png => TestImage.CGGradient.LinearGradientShortBothSides_Options_kCGGradientDrawsAfterEndLocation.png} (100%) rename tests/unittests/CoreGraphics.drawing/data/reference/{TestImage.CGContext.LinearGradientShortBothSides_Options_kCGGradientDrawsBeforeStartLocation.png => TestImage.CGGradient.LinearGradientShortBothSides_Options_kCGGradientDrawsBeforeStartLocation.png} (100%) rename tests/unittests/CoreGraphics.drawing/data/reference/{TestImage.CGContext.LinearGradientWithAlpha.png => TestImage.CGGradient.LinearGradientWithAlpha.png} (100%) rename tests/unittests/CoreGraphics.drawing/data/reference/{TestImage.CGContext.LinearGradientWithLowOpacity.png => TestImage.CGGradient.LinearGradientWithLowOpacity.png} (100%) rename tests/unittests/CoreGraphics.drawing/data/reference/{TestImage.CGContext.LinearGradientWithLowOpacityShort.png => TestImage.CGGradient.LinearGradientWithLowOpacityShort.png} (100%) diff --git a/Frameworks/CoreGraphics/CGContext.mm b/Frameworks/CoreGraphics/CGContext.mm index 534b3e7e00..9bc4912735 100644 --- a/Frameworks/CoreGraphics/CGContext.mm +++ b/Frameworks/CoreGraphics/CGContext.mm @@ -51,7 +51,7 @@ static const wchar_t* TAG = L"CGContext"; // Coordinate offset to support CGGradientDrawingOptions -static const float s_CGGradientStartPoint = 1E-45; +static const float s_CGGradientOffsetPoint = 1E-45; enum _CGCoordinateMode : unsigned int { _kCGCoordinateModeDeviceSpace = 0, _kCGCoordinateModeUserSpace }; @@ -2384,6 +2384,7 @@ static inline void __CGGradientInsertTransparentColor(std::vector + diff --git a/tests/UnitTests/CoreGraphics.drawing/CGContextDrawingTests.cpp b/tests/UnitTests/CoreGraphics.drawing/CGContextDrawingTests.cpp index a5e6623d28..f000ec6b0b 100644 --- a/tests/UnitTests/CoreGraphics.drawing/CGContextDrawingTests.cpp +++ b/tests/UnitTests/CoreGraphics.drawing/CGContextDrawingTests.cpp @@ -588,182 +588,4 @@ DRAW_TEST(CGContext, PremultipliedAlphaImage) { CGContextSetRGBFillColor(context, 1.0, 0.0, 0.0, 0.5); CGContextFillRect(context, { 0, 0, 100, 100 }); -} - -#pragma region LinearGradient -DRAW_TEST_F(CGContext, LinearGradient, UIKitMimicTest) { - CGContextRef context = GetDrawingContext(); - - CGFloat locations[2] = { 0, 1 }; - CGFloat components[8] = { 0.0, 0.0, 1, 1.0, 1.0, 0, 0, 1.0 }; - CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); - CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, 2); - - CGPoint startPoint = CGPointMake(0, 0); - CGPoint endPoint = CGPointMake(512, 1024); - - CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsBeforeStartLocation); - CFRelease(colorspace); - CFRelease(gradient); -} - -static void _drawShortLinearGradientWithOptions(CGContextRef context, CGRect bounds, CGGradientDrawingOptions option) { - CGFloat locations[2] = { 0, 1 }; - CGFloat components[8] = { 0.0, 1, 0.0, 1.0, 1.0, 0, 0, 1.0 }; - - CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); - CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, 2); - - CGRect borderRect = CGRectInset(bounds, 30, 50); - - CGContextDrawLinearGradient(context, gradient, borderRect.origin, CGPointMake(borderRect.size.width, borderRect.size.height), option); - - CFRelease(colorspace); - CFRelease(gradient); -} - -DRAW_TEST_F(CGContext, LinearGradientShortBothSides_Options_0, UIKitMimicTest) { - _drawShortLinearGradientWithOptions(GetDrawingContext(), GetDrawingBounds(), 0); -} - -DRAW_TEST_F(CGContext, LinearGradientShortBothSides_Options_kCGGradientDrawsBeforeStartLocation, UIKitMimicTest) { - _drawShortLinearGradientWithOptions(GetDrawingContext(), GetDrawingBounds(), kCGGradientDrawsBeforeStartLocation); -} - -DRAW_TEST_F(CGContext, LinearGradientShortBothSides_Options_kCGGradientDrawsAfterEndLocation, UIKitMimicTest) { - _drawShortLinearGradientWithOptions(GetDrawingContext(), GetDrawingBounds(), kCGGradientDrawsAfterEndLocation); -} - -DRAW_TEST_F(CGContext, LinearGradientInvalidCount, UIKitMimicTest) { - CGContextRef context = GetDrawingContext(); - - CGFloat locations[] = { 0.0 }; - - CGFloat components[] = { - 0.85, 0, 0, 1.0, - }; - - CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); - CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, 0); - CGPoint startPoint = CGPointMake(0, 0); - CGPoint endPoint = CGPointMake(512, 1024); - - CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsBeforeStartLocation); - CFRelease(colorspace); - CFRelease(gradient); -} - -DRAW_TEST_F(CGContext, LinearGradient2, UIKitMimicTest) { - CGContextRef context = GetDrawingContext(); - - CGFloat locations[] = { 0.0, 0.33, 0.66, 1.0 }; - - CGFloat components[] = { - 0.85, 0, 0, 1.0, 1, 0, 0, 1.0, 0.85, 0.3, 0, 1.0, 0.1, 0, 0.9, 1.0, - }; - - CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); - CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, 4); - CGPoint startPoint = CGPointMake(0, 0); - CGPoint endPoint = CGPointMake(512, 1024); - - CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsBeforeStartLocation); - CFRelease(colorspace); - CFRelease(gradient); -} - -DRAW_TEST_F(CGContext, LinearGradient2Short, UIKitMimicTest) { - CGContextRef context = GetDrawingContext(); - - CGFloat locations[] = { 0.0, 0.33, 1.0 }; - - CGFloat components[] = { 0.85, 0, 0, 1.0, 1, 0, 0, 1.0, 0.85, 0.3, 0, 1.0 }; - - CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); - CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, 3); - CGPoint startPoint = CGPointMake(120, 200); - CGPoint endPoint = CGPointMake(350, 800); - - CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsBeforeStartLocation); - CFRelease(colorspace); - CFRelease(gradient); -} - -DRAW_TEST_F(CGContext, LinearGradient3, UIKitMimicTest) { - CGContextRef context = GetDrawingContext(); - - CGFloat locations[] = { 0.0, 0.5, 1 }; - - CGFloat components[] = { - 1, 0, 0, 1.0, 0, 1, 0, 1.0, 0, 0, 1, 1.0, - }; - - CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); - CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, 3); - CGPoint startPoint = CGPointMake(0, 0); - CGPoint endPoint = CGPointMake(512, 1024); - - CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsBeforeStartLocation); - CFRelease(colorspace); - CFRelease(gradient); -} - -DRAW_TEST_F(CGContext, LinearGradientWithLowOpacity, UIKitMimicTest) { - CGContextRef context = GetDrawingContext(); - - CGFloat locations[] = { 0.0, 0.5, 1 }; - - CGFloat components[] = { - 1, 0, 0, 0.1, 0, 1, 0, 0.9, 0, 0, 1, 0.8, - }; - - CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); - CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, 3); - CGPoint startPoint = CGPointMake(300, 750); - CGPoint endPoint = CGPointMake(0, 0); - - CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsBeforeStartLocation); - CFRelease(colorspace); - CFRelease(gradient); -} - -DRAW_TEST_F(CGContext, LinearGradientWithAlpha, UIKitMimicTest) { - CGContextRef context = GetDrawingContext(); - - CGFloat locations[] = { 0.0, 0.25, 0.5, 0.6, 0.8, 0.9, 1 }; - - CGFloat components[] = { - 1, 0, 0, 1, 0.4, 0.1, 0.5, 1, 0.50, 0.2, 0.99, 1, 0.41, 0.56, 0, 1, 0.12, 0.12, .3, 1, 0.9, 0.4, 1, 1, 0.2, 0.3, 0.8, 1, - }; - - CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); - CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, 7); - CGPoint startPoint = CGPointMake(512, 1024); - CGPoint endPoint = CGPointMake(0, 0); - - CGContextSetAlpha(context, 0.75); - CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsBeforeStartLocation); - CFRelease(colorspace); - CFRelease(gradient); -} - -DRAW_TEST_F(CGContext, LinearGradientWithLowOpacityShort, UIKitMimicTest) { - CGContextRef context = GetDrawingContext(); - - CGFloat locations[] = { 0.0, 0.5, 1 }; - - CGFloat components[] = { - 1, 0, 0, 0.8, 0, 1, 0, 0.9, 0, 0, 1, 0.1, - }; - - CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); - CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, 3); - CGPoint startPoint = CGPointMake(250, 300); - CGPoint endPoint = CGPointMake(0, 0); - CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsAfterEndLocation); - - CFRelease(colorspace); - CFRelease(gradient); -} - -#pragma endregion LinearGradient \ No newline at end of file +} \ No newline at end of file diff --git a/tests/unittests/CoreGraphics.drawing/CGContextDrawing_GradientTests.cpp b/tests/unittests/CoreGraphics.drawing/CGContextDrawing_GradientTests.cpp new file mode 100644 index 0000000000..6120754943 --- /dev/null +++ b/tests/unittests/CoreGraphics.drawing/CGContextDrawing_GradientTests.cpp @@ -0,0 +1,195 @@ +//****************************************************************************** +// +// Copyright (c) Microsoft. All rights reserved. +// +// This code is licensed under the MIT License (MIT). +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//****************************************************************************** + +#include "DrawingTest.h" + +#pragma region LinearGradient +DRAW_TEST_F(CGGradient, LinearGradient, UIKitMimicTest) { + CGContextRef context = GetDrawingContext(); + + CGFloat locations[2] = { 0, 1 }; + CGFloat components[8] = { 0.0, 0.0, 1, 1.0, 1.0, 0, 0, 1.0 }; + CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); + CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, 2); + + CGPoint startPoint = CGPointMake(0, 0); + CGPoint endPoint = CGPointMake(512, 1024); + + CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsBeforeStartLocation); + CFRelease(colorspace); + CFRelease(gradient); +} + +static void _drawShortLinearGradientWithOptions(CGContextRef context, CGRect bounds, CGGradientDrawingOptions option) { + CGFloat locations[2] = { 0, 1 }; + CGFloat components[8] = { 0.0, 1, 0.0, 1.0, 1.0, 0, 0, 1.0 }; + + CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); + CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, 2); + + CGRect borderRect = CGRectInset(bounds, 30, 50); + + CGContextDrawLinearGradient(context, gradient, borderRect.origin, CGPointMake(borderRect.size.width, borderRect.size.height), option); + + CFRelease(colorspace); + CFRelease(gradient); +} + +DRAW_TEST_F(CGGradient, LinearGradientShortBothSides_Options_0, UIKitMimicTest) { + _drawShortLinearGradientWithOptions(GetDrawingContext(), GetDrawingBounds(), 0); +} + +DRAW_TEST_F(CGGradient, LinearGradientShortBothSides_Options_kCGGradientDrawsBeforeStartLocation, UIKitMimicTest) { + _drawShortLinearGradientWithOptions(GetDrawingContext(), GetDrawingBounds(), kCGGradientDrawsBeforeStartLocation); +} + +DRAW_TEST_F(CGGradient, LinearGradientShortBothSides_Options_kCGGradientDrawsAfterEndLocation, UIKitMimicTest) { + _drawShortLinearGradientWithOptions(GetDrawingContext(), GetDrawingBounds(), kCGGradientDrawsAfterEndLocation); +} + +DRAW_TEST_F(CGGradient, LinearGradientInvalidCount, UIKitMimicTest) { + CGContextRef context = GetDrawingContext(); + + CGFloat locations[] = { 0.0 }; + + CGFloat components[] = { + 0.85, 0, 0, 1.0, + }; + + CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); + CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, 0); + CGPoint startPoint = CGPointMake(0, 0); + CGPoint endPoint = CGPointMake(512, 1024); + + CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsBeforeStartLocation); + CFRelease(colorspace); + CFRelease(gradient); +} + +DRAW_TEST_F(CGGradient, LinearGradient2, UIKitMimicTest) { + CGContextRef context = GetDrawingContext(); + + CGFloat locations[] = { 0.0, 0.33, 0.66, 1.0 }; + + CGFloat components[] = { + 0.85, 0, 0, 1.0, 1, 0, 0, 1.0, 0.85, 0.3, 0, 1.0, 0.1, 0, 0.9, 1.0, + }; + + CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); + CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, 4); + CGPoint startPoint = CGPointMake(0, 0); + CGPoint endPoint = CGPointMake(512, 1024); + + CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsBeforeStartLocation); + CFRelease(colorspace); + CFRelease(gradient); +} + +DRAW_TEST_F(CGGradient, LinearGradient2Short, UIKitMimicTest) { + CGContextRef context = GetDrawingContext(); + + CGFloat locations[] = { 0.0, 0.33, 1.0 }; + + CGFloat components[] = { 0.85, 0, 0, 1.0, 1, 0, 0, 1.0, 0.85, 0.3, 0, 1.0 }; + + CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); + CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, 3); + CGPoint startPoint = CGPointMake(120, 200); + CGPoint endPoint = CGPointMake(350, 800); + + CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsBeforeStartLocation); + CFRelease(colorspace); + CFRelease(gradient); +} + +DRAW_TEST_F(CGGradient, LinearGradient3, UIKitMimicTest) { + CGContextRef context = GetDrawingContext(); + + CGFloat locations[] = { 0.0, 0.5, 1 }; + + CGFloat components[] = { + 1, 0, 0, 1.0, 0, 1, 0, 1.0, 0, 0, 1, 1.0, + }; + + CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); + CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, 3); + CGPoint startPoint = CGPointMake(0, 0); + CGPoint endPoint = CGPointMake(512, 1024); + + CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsBeforeStartLocation); + CFRelease(colorspace); + CFRelease(gradient); +} + +DRAW_TEST_F(CGGradient, LinearGradientWithLowOpacity, UIKitMimicTest) { + CGContextRef context = GetDrawingContext(); + + CGFloat locations[] = { 0.0, 0.5, 1 }; + + CGFloat components[] = { + 1, 0, 0, 0.1, 0, 1, 0, 0.9, 0, 0, 1, 0.8, + }; + + CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); + CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, 3); + CGPoint startPoint = CGPointMake(300, 750); + CGPoint endPoint = CGPointMake(0, 0); + + CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsBeforeStartLocation); + CFRelease(colorspace); + CFRelease(gradient); +} + +DRAW_TEST_F(CGGradient, LinearGradientWithAlpha, UIKitMimicTest) { + CGContextRef context = GetDrawingContext(); + + CGFloat locations[] = { 0.0, 0.25, 0.5, 0.6, 0.8, 0.9, 1 }; + + CGFloat components[] = { + 1, 0, 0, 1, 0.4, 0.1, 0.5, 1, 0.50, 0.2, 0.99, 1, 0.41, 0.56, 0, 1, 0.12, 0.12, .3, 1, 0.9, 0.4, 1, 1, 0.2, 0.3, 0.8, 1, + }; + + CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); + CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, 7); + CGPoint startPoint = CGPointMake(512, 1024); + CGPoint endPoint = CGPointMake(0, 0); + + CGContextSetAlpha(context, 0.75); + CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsBeforeStartLocation); + CFRelease(colorspace); + CFRelease(gradient); +} + +DRAW_TEST_F(CGGradient, LinearGradientWithLowOpacityShort, UIKitMimicTest) { + CGContextRef context = GetDrawingContext(); + + CGFloat locations[] = { 0.0, 0.5, 1 }; + + CGFloat components[] = { + 1, 0, 0, 0.8, 0, 1, 0, 0.9, 0, 0, 1, 0.1, + }; + + CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); + CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, 3); + CGPoint startPoint = CGPointMake(250, 300); + CGPoint endPoint = CGPointMake(0, 0); + CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsAfterEndLocation); + + CFRelease(colorspace); + CFRelease(gradient); +} + +#pragma endregion LinearGradient \ No newline at end of file diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradient2.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGGradient..LinearGradient2.png similarity index 100% rename from tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradient2.png rename to tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGGradient..LinearGradient2.png diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradient3.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGGradient..LinearGradient3.png similarity index 100% rename from tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradient3.png rename to tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGGradient..LinearGradient3.png diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientShortBothSides.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGGradient..LinearGradientShortBothSides.png similarity index 100% rename from tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientShortBothSides.png rename to tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGGradient..LinearGradientShortBothSides.png diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientShortBothSides_Options_0.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGGradient..LinearGradientShortBothSides_Options_0.png similarity index 100% rename from tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientShortBothSides_Options_0.png rename to tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGGradient..LinearGradientShortBothSides_Options_0.png diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGGradient.LinearGradient.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGGradient.LinearGradient.png new file mode 100644 index 0000000000..39902702cf --- /dev/null +++ b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGGradient.LinearGradient.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d1ebed1412be8f4b436ed215764017185bc8da4d9da79e69bb224f0b2d00b668 +size 248700 diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientInvalidCount.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGGradient.LinearGradientInvalidCount.png similarity index 100% rename from tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientInvalidCount.png rename to tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGGradient.LinearGradientInvalidCount.png diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGGradient.LinearGradientShortBothSides_Options_0.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGGradient.LinearGradientShortBothSides_Options_0.png new file mode 100644 index 0000000000..fd413dd8b6 --- /dev/null +++ b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGGradient.LinearGradientShortBothSides_Options_0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:17368771d59238306c3d613f898211a24983b9d382055c6ccb719346e3ebf07b +size 293568 diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientShortBothSides_Options_kCGGradientDrawsAfterEndLocation.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGGradient.LinearGradientShortBothSides_Options_kCGGradientDrawsAfterEndLocation.png similarity index 100% rename from tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientShortBothSides_Options_kCGGradientDrawsAfterEndLocation.png rename to tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGGradient.LinearGradientShortBothSides_Options_kCGGradientDrawsAfterEndLocation.png diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientShortBothSides_Options_kCGGradientDrawsBeforeStartLocation.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGGradient.LinearGradientShortBothSides_Options_kCGGradientDrawsBeforeStartLocation.png similarity index 100% rename from tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientShortBothSides_Options_kCGGradientDrawsBeforeStartLocation.png rename to tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGGradient.LinearGradientShortBothSides_Options_kCGGradientDrawsBeforeStartLocation.png diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientWithAlpha.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGGradient.LinearGradientWithAlpha.png similarity index 100% rename from tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientWithAlpha.png rename to tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGGradient.LinearGradientWithAlpha.png diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientWithLowOpacity.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGGradient.LinearGradientWithLowOpacity.png similarity index 100% rename from tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientWithLowOpacity.png rename to tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGGradient.LinearGradientWithLowOpacity.png diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientWithLowOpacityShort.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGGradient.LinearGradientWithLowOpacityShort.png similarity index 100% rename from tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.LinearGradientWithLowOpacityShort.png rename to tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGGradient.LinearGradientWithLowOpacityShort.png From 01b435ecb3afd427d9c77572a31b6fcfccaa8ff3 Mon Sep 17 00:00:00 2001 From: Jeyaram Jeyaraj Date: Wed, 21 Dec 2016 10:03:20 -0800 Subject: [PATCH 3/5] some nit picks --- Frameworks/CoreGraphics/CGContext.mm | 10 +- Frameworks/CoreGraphics/CGGradient.mm | 2 +- .../CGContextDrawing_GradientTests.cpp | 161 ++++++++---------- 3 files changed, 77 insertions(+), 96 deletions(-) diff --git a/Frameworks/CoreGraphics/CGContext.mm b/Frameworks/CoreGraphics/CGContext.mm index 9bc4912735..1ec424ffa9 100644 --- a/Frameworks/CoreGraphics/CGContext.mm +++ b/Frameworks/CoreGraphics/CGContext.mm @@ -51,7 +51,7 @@ static const wchar_t* TAG = L"CGContext"; // Coordinate offset to support CGGradientDrawingOptions -static const float s_CGGradientOffsetPoint = 1E-45; +static const float s_kCGGradientOffsetPoint = 1E-45; enum _CGCoordinateMode : unsigned int { _kCGCoordinateModeDeviceSpace = 0, _kCGCoordinateModeUserSpace }; @@ -2366,9 +2366,7 @@ void CGContextDrawTiledImage(CGContextRef context, CGRect rect, CGImageRef image static inline void __CGGradientInsertTransparentColor(std::vector& gradientStops, int location, float position) { gradientStops[location].position = position; // set the edge location to be transparent - D2D1_GRADIENT_STOP transparent; - transparent.color = D2D1::ColorF(0, 0, 0, 0); - transparent.position = location; + D2D1_GRADIENT_STOP transparent = { location, D2D1::ColorF(0, 0, 0, 0) }; gradientStops.push_back(transparent); } @@ -2398,11 +2396,11 @@ static inline void __CGGradientInsertTransparentColor(std::vector Date: Wed, 21 Dec 2016 10:31:56 -0800 Subject: [PATCH 4/5] more nits --- .../CGContextDrawing_GradientTests.cpp | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/tests/unittests/CoreGraphics.drawing/CGContextDrawing_GradientTests.cpp b/tests/unittests/CoreGraphics.drawing/CGContextDrawing_GradientTests.cpp index 84089e2232..6e268dd44e 100644 --- a/tests/unittests/CoreGraphics.drawing/CGContextDrawing_GradientTests.cpp +++ b/tests/unittests/CoreGraphics.drawing/CGContextDrawing_GradientTests.cpp @@ -21,12 +21,12 @@ static void _drawLinearGradient(CGContextRef context, CGPoint startPoint, CGPoint endPoint, - CGFloat* components, - CGFloat* locations, - size_t count, + CGFloat components[], + CGFloat locations[], CGGradientDrawingOptions options) { CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); - CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, count); + CGGradientRef gradient = + CGGradientCreateWithColorComponents(colorspace, components, locations, std::extent::value); CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, options); CFRelease(colorspace); @@ -44,7 +44,6 @@ static void _drawShortLinearGradientWithOptions(CGContextRef context, CGRect bou CGPointMake(borderRect.size.width, borderRect.size.height), components, locations, - _countof(locations), option); } @@ -56,7 +55,6 @@ DRAW_TEST_F(CGGradient, LinearGradient, UIKitMimicTest) { CGPointMake(512, 1024), components, locations, - _countof(locations), kCGGradientDrawsBeforeStartLocation); } @@ -78,8 +76,17 @@ DRAW_TEST_F(CGGradient, LinearGradientInvalidCount, UIKitMimicTest) { CGFloat components[] = { 0.85, 0, 0, 1.0, }; - _drawLinearGradient( - GetDrawingContext(), CGPointMake(0, 0), CGPointMake(512, 1024), components, locations, 0, kCGGradientDrawsBeforeStartLocation); + + CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); + CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, 0); + + CGContextDrawLinearGradient(GetDrawingContext(), + gradient, + CGPointMake(0, 0), + CGPointMake(512, 1024), + kCGGradientDrawsBeforeStartLocation); + CFRelease(colorspace); + CFRelease(gradient); } DRAW_TEST_F(CGGradient, LinearGradient2, UIKitMimicTest) { @@ -94,7 +101,6 @@ DRAW_TEST_F(CGGradient, LinearGradient2, UIKitMimicTest) { CGPointMake(512, 1024), components, locations, - _countof(locations), kCGGradientDrawsBeforeStartLocation); } @@ -107,7 +113,6 @@ DRAW_TEST_F(CGGradient, LinearGradient2Short, UIKitMimicTest) { CGPointMake(350, 800), components, locations, - _countof(locations), kCGGradientDrawsBeforeStartLocation); } @@ -122,7 +127,6 @@ DRAW_TEST_F(CGGradient, LinearGradient3, UIKitMimicTest) { CGPointMake(512, 1024), components, locations, - _countof(locations), kCGGradientDrawsBeforeStartLocation); } @@ -138,7 +142,6 @@ DRAW_TEST_F(CGGradient, LinearGradientWithLowOpacity, UIKitMimicTest) { CGPointMake(0, 0), components, locations, - _countof(locations), kCGGradientDrawsBeforeStartLocation); } @@ -155,7 +158,6 @@ DRAW_TEST_F(CGGradient, LinearGradientWithAlpha, UIKitMimicTest) { CGPointMake(512, 1024), components, locations, - _countof(locations), kCGGradientDrawsBeforeStartLocation); } @@ -171,7 +173,6 @@ DRAW_TEST_F(CGGradient, LinearGradientWithLowOpacityShort, UIKitMimicTest) { CGPointMake(0, 0), components, locations, - _countof(locations), kCGGradientDrawsAfterEndLocation); } From 28a0a8c446fd8194a994ee7e216d626c91b5c89d Mon Sep 17 00:00:00 2001 From: Jeyaram Jeyaraj Date: Wed, 21 Dec 2016 10:40:38 -0800 Subject: [PATCH 5/5] disabling tests --- .../CGContextDrawing_GradientTests.cpp | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/unittests/CoreGraphics.drawing/CGContextDrawing_GradientTests.cpp b/tests/unittests/CoreGraphics.drawing/CGContextDrawing_GradientTests.cpp index 6e268dd44e..c737b08103 100644 --- a/tests/unittests/CoreGraphics.drawing/CGContextDrawing_GradientTests.cpp +++ b/tests/unittests/CoreGraphics.drawing/CGContextDrawing_GradientTests.cpp @@ -47,7 +47,7 @@ static void _drawShortLinearGradientWithOptions(CGContextRef context, CGRect bou option); } -DRAW_TEST_F(CGGradient, LinearGradient, UIKitMimicTest) { +DISABLED_DRAW_TEST_F(CGGradient, LinearGradient, UIKitMimicTest) { CGFloat locations[2] = { 0, 1 }; CGFloat components[8] = { 0.0, 0.0, 1, 1.0, 1.0, 0, 0, 1.0 }; _drawLinearGradient(GetDrawingContext(), @@ -58,15 +58,15 @@ DRAW_TEST_F(CGGradient, LinearGradient, UIKitMimicTest) { kCGGradientDrawsBeforeStartLocation); } -DRAW_TEST_F(CGGradient, LinearGradientShortBothSides_Options_0, UIKitMimicTest) { +DISABLED_DRAW_TEST_F(CGGradient, LinearGradientShortBothSides_Options_0, UIKitMimicTest) { _drawShortLinearGradientWithOptions(GetDrawingContext(), GetDrawingBounds(), 0); } -DRAW_TEST_F(CGGradient, LinearGradientShortBothSides_Options_kCGGradientDrawsBeforeStartLocation, UIKitMimicTest) { +DISABLED_DRAW_TEST_F(CGGradient, LinearGradientShortBothSides_Options_kCGGradientDrawsBeforeStartLocation, UIKitMimicTest) { _drawShortLinearGradientWithOptions(GetDrawingContext(), GetDrawingBounds(), kCGGradientDrawsBeforeStartLocation); } -DRAW_TEST_F(CGGradient, LinearGradientShortBothSides_Options_kCGGradientDrawsAfterEndLocation, UIKitMimicTest) { +DISABLED_DRAW_TEST_F(CGGradient, LinearGradientShortBothSides_Options_kCGGradientDrawsAfterEndLocation, UIKitMimicTest) { _drawShortLinearGradientWithOptions(GetDrawingContext(), GetDrawingBounds(), kCGGradientDrawsAfterEndLocation); } @@ -89,7 +89,7 @@ DRAW_TEST_F(CGGradient, LinearGradientInvalidCount, UIKitMimicTest) { CFRelease(gradient); } -DRAW_TEST_F(CGGradient, LinearGradient2, UIKitMimicTest) { +DISABLED_DRAW_TEST_F(CGGradient, LinearGradient2, UIKitMimicTest) { CGFloat locations[] = { 0.0, 0.33, 0.66, 1.0 }; CGFloat components[] = { @@ -104,7 +104,7 @@ DRAW_TEST_F(CGGradient, LinearGradient2, UIKitMimicTest) { kCGGradientDrawsBeforeStartLocation); } -DRAW_TEST_F(CGGradient, LinearGradient2Short, UIKitMimicTest) { +DISABLED_DRAW_TEST_F(CGGradient, LinearGradient2Short, UIKitMimicTest) { CGFloat locations[] = { 0.0, 0.33, 1.0 }; CGFloat components[] = { 0.85, 0, 0, 1.0, 1, 0, 0, 1.0, 0.85, 0.3, 0, 1.0 }; @@ -116,7 +116,7 @@ DRAW_TEST_F(CGGradient, LinearGradient2Short, UIKitMimicTest) { kCGGradientDrawsBeforeStartLocation); } -DRAW_TEST_F(CGGradient, LinearGradient3, UIKitMimicTest) { +DISABLED_DRAW_TEST_F(CGGradient, LinearGradient3, UIKitMimicTest) { CGFloat locations[] = { 0.0, 0.5, 1 }; CGFloat components[] = { @@ -130,7 +130,7 @@ DRAW_TEST_F(CGGradient, LinearGradient3, UIKitMimicTest) { kCGGradientDrawsBeforeStartLocation); } -DRAW_TEST_F(CGGradient, LinearGradientWithLowOpacity, UIKitMimicTest) { +DISABLED_DRAW_TEST_F(CGGradient, LinearGradientWithLowOpacity, UIKitMimicTest) { CGFloat locations[] = { 0.0, 0.5, 1 }; CGFloat components[] = { @@ -145,7 +145,7 @@ DRAW_TEST_F(CGGradient, LinearGradientWithLowOpacity, UIKitMimicTest) { kCGGradientDrawsBeforeStartLocation); } -DRAW_TEST_F(CGGradient, LinearGradientWithAlpha, UIKitMimicTest) { +DISABLED_DRAW_TEST_F(CGGradient, LinearGradientWithAlpha, UIKitMimicTest) { CGFloat locations[] = { 0.0, 0.25, 0.5, 0.6, 0.8, 0.9, 1 }; CGFloat components[] = { @@ -161,7 +161,7 @@ DRAW_TEST_F(CGGradient, LinearGradientWithAlpha, UIKitMimicTest) { kCGGradientDrawsBeforeStartLocation); } -DRAW_TEST_F(CGGradient, LinearGradientWithLowOpacityShort, UIKitMimicTest) { +DISABLED_DRAW_TEST_F(CGGradient, LinearGradientWithLowOpacityShort, UIKitMimicTest) { CGFloat locations[] = { 0.0, 0.5, 1 }; CGFloat components[] = {