From 00473b6496a2cf37799e2ef5d6f1fcfe0a29d449 Mon Sep 17 00:00:00 2001 From: Hank Fox Date: Mon, 13 Feb 2017 14:10:53 -0800 Subject: [PATCH 1/5] Avoid D2D1Group fill mode conversion for CGPath and other simple geometries. Fill mode conversion removed from CGContext. --- Frameworks/CoreGraphics/CGContext.mm | 16 +++----- Frameworks/CoreGraphics/CGPath.mm | 26 +++++++++++-- Frameworks/CoreGraphics/D2DWrapper.mm | 15 -------- Frameworks/include/CGPathInternal.h | 2 +- Frameworks/include/CoreGraphics/D2DWrapper.h | 2 - .../CGPathDrawingTests.cpp | 38 ++++++++++++++++++- ...estImage.CGPath.FillModeDefaultCircles.png | 3 ++ ...=> TestImage.CGPath.FillModeEOCircles.png} | 0 8 files changed, 69 insertions(+), 33 deletions(-) create mode 100644 tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGPath.FillModeDefaultCircles.png rename tests/unittests/CoreGraphics.drawing/data/reference/{TestImage.CGPath.FillModeCircles.png => TestImage.CGPath.FillModeEOCircles.png} (100%) diff --git a/Frameworks/CoreGraphics/CGContext.mm b/Frameworks/CoreGraphics/CGContext.mm index 33699216dc..00a86e9254 100644 --- a/Frameworks/CoreGraphics/CGContext.mm +++ b/Frameworks/CoreGraphics/CGContext.mm @@ -156,8 +156,9 @@ inline HRESULT IntersectClippingGeometry(ID2D1Geometry* incomingGeometry, CGPath D2D1_FILL_MODE d2dFillMode = (pathMode & kCGPathEOFill) == kCGPathEOFill ? D2D1_FILL_MODE_ALTERNATE : D2D1_FILL_MODE_WINDING; if (!clippingGeometry) { - // If we don't have a clipping geometry, we are free to take this one wholesale (after EO/Winding conversion.) - return _CGConvertD2DGeometryToFillMode(incomingGeometry, d2dFillMode, &clippingGeometry); + // If we don't have a clipping geometry, we are free to take this one wholesale. + clippingGeometry = incomingGeometry; + return S_OK; } ComPtr factory; @@ -1053,7 +1054,7 @@ bool CGContextPathContainsPoint(CGContextRef context, CGPoint point, CGPathDrawi } ComPtr additionalClippingGeometry; - RETURN_IF_FAILED(_CGPathGetGeometry(Path(), &additionalClippingGeometry)); + RETURN_IF_FAILED(_CGPathGetGeometryWithFillMode(Path(), pathMode, &additionalClippingGeometry)); ClearPath(); auto& state = CurrentGState(); @@ -2383,12 +2384,7 @@ void CGContextClearRect(CGContextRef context, CGRect rect) { auto& state = context->CurrentGState(); if (drawMode & kCGPathFill) { state.fillBrush->SetOpacity(state.alpha); - - ComPtr geometryToFill; - D2D1_FILL_MODE d2dFillMode = (drawMode & kCGPathEOFill) == kCGPathEOFill ? D2D1_FILL_MODE_ALTERNATE : D2D1_FILL_MODE_WINDING; - RETURN_IF_FAILED(_CGConvertD2DGeometryToFillMode(geometry, d2dFillMode, &geometryToFill)); - - deviceContext->FillGeometry(geometryToFill.Get(), state.fillBrush.Get()); + deviceContext->FillGeometry(geometry, state.fillBrush.Get()); } if (drawMode & kCGPathStroke && std::fpclassify(state.lineWidth) != FP_ZERO) { @@ -2551,7 +2547,7 @@ void CGContextDrawPath(CGContextRef context, CGPathDrawingMode mode) { if (context->HasPath()) { ComPtr pGeometry; - FAIL_FAST_IF_FAILED(_CGPathGetGeometry(context->Path(), &pGeometry)); + FAIL_FAST_IF_FAILED(_CGPathGetGeometryWithFillMode(context->Path(), mode, &pGeometry)); FAIL_FAST_IF_FAILED(context->DrawGeometry(_kCGCoordinateModeDeviceSpace, pGeometry.Get(), mode)); context->ClearPath(); } diff --git a/Frameworks/CoreGraphics/CGPath.mm b/Frameworks/CoreGraphics/CGPath.mm index 1874870011..a79630302c 100644 --- a/Frameworks/CoreGraphics/CGPath.mm +++ b/Frameworks/CoreGraphics/CGPath.mm @@ -46,7 +46,7 @@ return m_geometrySink.Get(); } - _CGPathCustomSink(_In_ ID2D1GeometrySink* sink) : m_geometrySink(sink), m_lastPoint{0, 0}, m_isFigureOpen(false) { + _CGPathCustomSink(_In_ ID2D1GeometrySink* sink) : m_geometrySink(sink), m_lastPoint{ 0, 0 }, m_isFigureOpen(false) { } STDMETHOD_(void, SetFillMode)(D2D1_FILL_MODE fillMode) { @@ -271,11 +271,29 @@ HRESULT AddGeometryToPathWithTransformation(const ID2D1Geometry* geometry, const } }; -HRESULT _CGPathGetGeometry(CGPathRef path, ID2D1Geometry** pGeometry) { - RETURN_HR_IF_NULL(E_POINTER, pGeometry); +HRESULT _CGPathGetGeometryWithFillMode(CGPathRef path, CGPathDrawingMode fillMode, ID2D1Geometry** pNewGeometry) { + RETURN_HR_IF_NULL(E_POINTER, pNewGeometry); RETURN_HR_IF_NULL(E_POINTER, path); + RETURN_IF_FAILED(path->ClosePath()); - path->pathGeometry.CopyTo(pGeometry); + if (fillMode == kCGPathEOFill || fillMode == kCGPathEOFillStroke) { + ID2D1Geometry* geometry = path->GetPathGeometry(); + ComPtr factory; + geometry->GetFactory(&factory); + + ComPtr geometryGroup; + RETURN_IF_FAILED(factory->CreateGeometryGroup(fillMode == kCGPathEOFill ? D2D1_FILL_MODE_ALTERNATE : D2D1_FILL_MODE_WINDING, + &geometry, + 1, + &geometryGroup)); + + ComPtr outGeometry; + RETURN_IF_FAILED(geometryGroup.As(&outGeometry)); + + *pNewGeometry = outGeometry.Detach(); + } else { + path->pathGeometry.CopyTo(pNewGeometry); + } return S_OK; } diff --git a/Frameworks/CoreGraphics/D2DWrapper.mm b/Frameworks/CoreGraphics/D2DWrapper.mm index e7c7940e54..026dd83671 100644 --- a/Frameworks/CoreGraphics/D2DWrapper.mm +++ b/Frameworks/CoreGraphics/D2DWrapper.mm @@ -31,19 +31,4 @@ HRESULT _CGGetWICFactory(IWICImagingFactory** factory) { static HRESULT sHr = CoCreateInstance(CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&sWicFactory)); sWicFactory.CopyTo(factory); RETURN_HR(sHr); -} - -// TODO GH#1375: Remove this when CGPath's fill mode has been worked out. -HRESULT _CGConvertD2DGeometryToFillMode(ID2D1Geometry* geometry, D2D1_FILL_MODE fillMode, ID2D1Geometry** pNewGeometry) { - ComPtr factory; - geometry->GetFactory(&factory); - - ComPtr geometryGroup; - RETURN_IF_FAILED(factory->CreateGeometryGroup(fillMode, &geometry, 1, &geometryGroup)); - - ComPtr outGeometry; - RETURN_IF_FAILED(geometryGroup.As(&outGeometry)); - - *pNewGeometry = outGeometry.Detach(); - return S_OK; } \ No newline at end of file diff --git a/Frameworks/include/CGPathInternal.h b/Frameworks/include/CGPathInternal.h index 31410b770e..e92e70de8f 100644 --- a/Frameworks/include/CGPathInternal.h +++ b/Frameworks/include/CGPathInternal.h @@ -68,8 +68,8 @@ struct CGPathElementInternal : CGPathElement { }; typedef struct CGPathElementInternal CGPathElementInternal; -HRESULT _CGPathGetGeometry(CGPathRef path, ID2D1Geometry** pGeometry); HRESULT _CGPathApplyInternal(ID2D1PathGeometry* pathGeometry, void* info, CGPathApplierFunction function); +HRESULT _CGPathGetGeometryWithFillMode(CGPathRef path, CGPathDrawingMode fillMode, ID2D1Geometry** pNewGeometry); #if defined __clang__ #pragma clang diagnostic pop diff --git a/Frameworks/include/CoreGraphics/D2DWrapper.h b/Frameworks/include/CoreGraphics/D2DWrapper.h index f4f61ed53e..11ff98697e 100644 --- a/Frameworks/include/CoreGraphics/D2DWrapper.h +++ b/Frameworks/include/CoreGraphics/D2DWrapper.h @@ -30,8 +30,6 @@ HRESULT _CGGetD2DFactory(ID2D1Factory** factory); HRESULT _CGGetWICFactory(IWICImagingFactory** factory); -HRESULT _CGConvertD2DGeometryToFillMode(ID2D1Geometry* geometry, D2D1_FILL_MODE fillMode, ID2D1Geometry** pNewGeometry); - inline D2D_POINT_2F _CGPointToD2D_F(CGPoint point) { return { point.x, point.y }; } diff --git a/tests/unittests/CoreGraphics.Drawing/CGPathDrawingTests.cpp b/tests/unittests/CoreGraphics.Drawing/CGPathDrawingTests.cpp index da43b33027..7425564e04 100644 --- a/tests/unittests/CoreGraphics.Drawing/CGPathDrawingTests.cpp +++ b/tests/unittests/CoreGraphics.Drawing/CGPathDrawingTests.cpp @@ -500,7 +500,7 @@ DRAW_TEST_F(CGPath, FillStraightLines, UIKitMimicTest<>) { CGPathRelease(thepath); } -DRAW_TEST_F(CGPath, FillModeCircles, UIKitMimicTest<>) { +DRAW_TEST_F(CGPath, FillModeEOCircles, UIKitMimicTest<>) { CGContextRef context = GetDrawingContext(); CGRect bounds = GetDrawingBounds(); CGFloat width = bounds.size.width; @@ -533,5 +533,41 @@ DRAW_TEST_F(CGPath, FillModeCircles, UIKitMimicTest<>) { CGContextEOFillPath(context); CGContextStrokePath(context); + CGPathRelease(thepath); +} + +DRAW_TEST_F(CGPath, FillModeDefaultCircles, UIKitMimicTest<>) { + CGContextRef context = GetDrawingContext(); + CGRect bounds = GetDrawingBounds(); + CGFloat width = bounds.size.width; + CGFloat height = bounds.size.height; + CGFloat xstart = bounds.origin.x; + CGFloat ystart = bounds.origin.y; + + CGMutablePathRef thepath = CGPathCreateMutable(); + + CGPathMoveToPoint(thepath, NULL, xstart + .5 * width + .4 * height, ystart + .5 * height); + CGPathAddArc(thepath, NULL, xstart + .5 * width, ystart + .5 * height, .4 * height, 0, M_PI, true); + CGPathAddArc(thepath, NULL, xstart + .5 * width, ystart + .5 * height, .4 * height, M_PI, 0, true); + + CGPathMoveToPoint(thepath, NULL, xstart + .5 * width + .3 * height, ystart + .5 * height); + CGPathAddArc(thepath, NULL, xstart + .5 * width, ystart + .5 * height, .3 * height, 0, M_PI, true); + CGPathAddArc(thepath, NULL, xstart + .5 * width, ystart + .5 * height, .3 * height, M_PI, 0, true); + + CGPathMoveToPoint(thepath, NULL, xstart + .5 * width + .2 * height, ystart + .5 * height); + CGPathAddArc(thepath, NULL, xstart + .5 * width, ystart + .5 * height, .2 * height, 0, M_PI, true); + CGPathAddArc(thepath, NULL, xstart + .5 * width, ystart + .5 * height, .2 * height, M_PI, 0, true); + + CGPathMoveToPoint(thepath, NULL, xstart + .5 * width + .1 * height, ystart + .5 * height); + CGPathAddArc(thepath, NULL, xstart + .5 * width, ystart + .5 * height, .1 * height, 0, M_PI, true); + CGPathAddArc(thepath, NULL, xstart + .5 * width, ystart + .5 * height, .1 * height, M_PI, 0, true); + + CGPathCloseSubpath(thepath); + + CGContextAddPath(context, thepath); + CGContextSetRGBFillColor(context, 0, 0, 1, 1); + CGContextFillPath(context); + CGContextStrokePath(context); + CGPathRelease(thepath); } \ No newline at end of file diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGPath.FillModeDefaultCircles.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGPath.FillModeDefaultCircles.png new file mode 100644 index 0000000000..3f678ba42c --- /dev/null +++ b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGPath.FillModeDefaultCircles.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:357fb54394bed3eb785da2b032c6ce5939c38e420bcc051a77d3df6a645f60a2 +size 10261 diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGPath.FillModeCircles.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGPath.FillModeEOCircles.png similarity index 100% rename from tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGPath.FillModeCircles.png rename to tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGPath.FillModeEOCircles.png From 31cfaf970e3bcf6917c5d57a5bac3041b322fb75 Mon Sep 17 00:00:00 2001 From: Hank Fox Date: Wed, 15 Feb 2017 11:08:21 -0800 Subject: [PATCH 2/5] Remove unnecessary check for proper fill mode since only one fill mode will ever be converted to. --- Frameworks/CoreGraphics/CGPath.mm | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Frameworks/CoreGraphics/CGPath.mm b/Frameworks/CoreGraphics/CGPath.mm index a79630302c..189da54a55 100644 --- a/Frameworks/CoreGraphics/CGPath.mm +++ b/Frameworks/CoreGraphics/CGPath.mm @@ -282,10 +282,7 @@ HRESULT _CGPathGetGeometryWithFillMode(CGPathRef path, CGPathDrawingMode fillMod geometry->GetFactory(&factory); ComPtr geometryGroup; - RETURN_IF_FAILED(factory->CreateGeometryGroup(fillMode == kCGPathEOFill ? D2D1_FILL_MODE_ALTERNATE : D2D1_FILL_MODE_WINDING, - &geometry, - 1, - &geometryGroup)); + RETURN_IF_FAILED(factory->CreateGeometryGroup(D2D1_FILL_MODE_ALTERNATE, &geometry, 1, &geometryGroup)); ComPtr outGeometry; RETURN_IF_FAILED(geometryGroup.As(&outGeometry)); From 4b45085d1b2b664adf4efa6ddc4772910f9e94e9 Mon Sep 17 00:00:00 2001 From: Hank Fox Date: Wed, 15 Feb 2017 15:49:44 -0800 Subject: [PATCH 3/5] Parameterized test for fill modes with embedded circles with alternating arc directions. --- .../CoreGraphics.Drawing.UnitTests.vcxproj | 4 +- .../CGContextDrawing_FillModeTests.cpp | 124 ++++++++++++++++++ .../TestImage.CGContext.FillMode.EOFill.png | 3 + ...tImage.CGContext.FillMode.EOFillStroke.png | 3 + .../TestImage.CGContext.FillMode.Fill.png | 3 + ...estImage.CGContext.FillMode.FillStroke.png | 3 + 6 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 tests/unittests/CoreGraphics.drawing/CGContextDrawing_FillModeTests.cpp create mode 100644 tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.FillMode.EOFill.png create mode 100644 tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.FillMode.EOFillStroke.png create mode 100644 tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.FillMode.Fill.png create mode 100644 tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.FillMode.FillStroke.png diff --git a/build/Tests/UnitTests/CoreGraphics.Drawing/CoreGraphics.Drawing.UnitTests.vcxproj b/build/Tests/UnitTests/CoreGraphics.Drawing/CoreGraphics.Drawing.UnitTests.vcxproj index 9277523361..0b97b02ee7 100644 --- a/build/Tests/UnitTests/CoreGraphics.Drawing/CoreGraphics.Drawing.UnitTests.vcxproj +++ b/build/Tests/UnitTests/CoreGraphics.Drawing/CoreGraphics.Drawing.UnitTests.vcxproj @@ -231,8 +231,8 @@ - + @@ -266,4 +266,4 @@ - + \ No newline at end of file diff --git a/tests/unittests/CoreGraphics.drawing/CGContextDrawing_FillModeTests.cpp b/tests/unittests/CoreGraphics.drawing/CGContextDrawing_FillModeTests.cpp new file mode 100644 index 0000000000..6f8fa1b46b --- /dev/null +++ b/tests/unittests/CoreGraphics.drawing/CGContextDrawing_FillModeTests.cpp @@ -0,0 +1,124 @@ +//****************************************************************************** +// +// 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" + +CGPathDrawingMode fillModes[] = { kCGPathFill, kCGPathFillStroke, kCGPathEOFill, kCGPathEOFillStroke }; + +class CGContextFillMode : public WhiteBackgroundTest<>, public ::testing::WithParamInterface { + CFStringRef CreateOutputFilename() { + CGPathDrawingMode fillMode = GetParam(); + + char* fillModeName; + switch (fillMode) { + case kCGPathFill: + fillModeName = "Fill"; + break; + case kCGPathFillStroke: + fillModeName = "FillStroke"; + break; + case kCGPathEOFill: + fillModeName = "EOFill"; + break; + case kCGPathEOFillStroke: + fillModeName = "EOFillStroke"; + break; + default: + break; + } + + return CFStringCreateWithFormat(nullptr, nullptr, CFSTR("TestImage.CGContext.FillMode.%s.png"), fillModeName); + } +}; + +DRAW_TEST_P(CGContextFillMode, OverlappedEllipses) { + CGContextRef context = GetDrawingContext(); + CGRect bounds = GetDrawingBounds(); + bounds = CGRectInset(bounds, 16.f, 16.f); + CGFloat width = bounds.size.width; + CGFloat height = bounds.size.height; + CGFloat xstart = bounds.origin.x; + CGFloat ystart = bounds.origin.y; + + CGPathDrawingMode fillMode = GetParam(); + + CGMutablePathRef leftCircles = CGPathCreateMutable(); + + CGPathMoveToPoint(leftCircles, NULL, xstart + .25 * width + .4 * height, ystart + .5 * height); + CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .4 * height, 0, M_PI, true); + CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .4 * height, M_PI, 0, true); + + CGPathMoveToPoint(leftCircles, NULL, xstart + .25 * width + .3 * height, ystart + .5 * height); + CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .3 * height, 0, M_PI, true); + CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .3 * height, M_PI, 0, true); + + CGPathMoveToPoint(leftCircles, NULL, xstart + .25 * width + .2 * height, ystart + .5 * height); + CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .2 * height, 0, M_PI, true); + CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .2 * height, M_PI, 0, true); + + CGPathMoveToPoint(leftCircles, NULL, xstart + .25 * width + .1 * height, ystart + .5 * height); + CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .1 * height, 0, M_PI, true); + CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .1 * height, M_PI, 0, true); + + CGPathCloseSubpath(leftCircles); + + CGMutablePathRef rightCircles = CGPathCreateMutable(); + + CGPathMoveToPoint(rightCircles, NULL, xstart + .75 * width + .4 * height, ystart + .5 * height); + CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .4 * height, 0, M_PI, false); + CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .4 * height, M_PI, 0, false); + + CGPathMoveToPoint(rightCircles, NULL, xstart + .75 * width + .3 * height, ystart + .5 * height); + CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .3 * height, 0, M_PI, true); + CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .3 * height, M_PI, 0, true); + + CGPathMoveToPoint(rightCircles, NULL, xstart + .75 * width + .2 * height, ystart + .5 * height); + CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .2 * height, 0, M_PI, false); + CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .2 * height, M_PI, 0, false); + + CGPathMoveToPoint(rightCircles, NULL, xstart + .75 * width + .1 * height, ystart + .5 * height); + CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .1 * height, 0, M_PI, true); + CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .1 * height, M_PI, 0, true); + + CGPathCloseSubpath(rightCircles); + + CGContextAddPath(context, leftCircles); + CGContextAddPath(context, rightCircles); + CGContextSetRGBFillColor(context, 0, 0, 1, 1); + switch (fillMode) { + case kCGPathFill: + CGContextFillPath(context); + break; + case kCGPathFillStroke: + CGContextFillPath(context); + CGContextStrokePath(context); + break; + case kCGPathEOFill: + CGContextEOFillPath(context); + break; + case kCGPathEOFillStroke: + CGContextEOFillPath(context); + CGContextStrokePath(context); + break; + default: + break; + } + + CGPathRelease(leftCircles); + CGPathRelease(rightCircles); +} + +INSTANTIATE_TEST_CASE_P(FillModes, CGContextFillMode, ::testing::ValuesIn(fillModes)); \ No newline at end of file diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.FillMode.EOFill.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.FillMode.EOFill.png new file mode 100644 index 0000000000..787d3d9844 --- /dev/null +++ b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.FillMode.EOFill.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:51e7d8d7f7191bc10b105bbfee3bb1848bbb83765cf953f739f2ddf131e9cbe5 +size 9010 diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.FillMode.EOFillStroke.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.FillMode.EOFillStroke.png new file mode 100644 index 0000000000..787d3d9844 --- /dev/null +++ b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.FillMode.EOFillStroke.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:51e7d8d7f7191bc10b105bbfee3bb1848bbb83765cf953f739f2ddf131e9cbe5 +size 9010 diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.FillMode.Fill.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.FillMode.Fill.png new file mode 100644 index 0000000000..e996e12e5f --- /dev/null +++ b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.FillMode.Fill.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0fd904926a6ba1e00589bc216130c3b273a1a90b846c444dc373a1a58028a8c8 +size 8326 diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.FillMode.FillStroke.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.FillMode.FillStroke.png new file mode 100644 index 0000000000..e996e12e5f --- /dev/null +++ b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.FillMode.FillStroke.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0fd904926a6ba1e00589bc216130c3b273a1a90b846c444dc373a1a58028a8c8 +size 8326 From 868f0ad9698427d78100486f38211456e8fb7247 Mon Sep 17 00:00:00 2001 From: Hank Fox Date: Wed, 15 Feb 2017 17:00:37 -0800 Subject: [PATCH 4/5] Fix Fill/Stroke tests and remove redundant tests. --- .../CGPathDrawingTests.cpp | 72 ------------------- .../CGContextDrawing_FillModeTests.cpp | 20 +----- ...tImage.CGContext.FillMode.EOFillStroke.png | 4 +- ...estImage.CGContext.FillMode.FillStroke.png | 4 +- ...estImage.CGPath.FillModeDefaultCircles.png | 3 - .../TestImage.CGPath.FillModeEOCircles.png | 3 - 6 files changed, 6 insertions(+), 100 deletions(-) delete mode 100644 tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGPath.FillModeDefaultCircles.png delete mode 100644 tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGPath.FillModeEOCircles.png diff --git a/tests/unittests/CoreGraphics.Drawing/CGPathDrawingTests.cpp b/tests/unittests/CoreGraphics.Drawing/CGPathDrawingTests.cpp index 7425564e04..d6727e1de5 100644 --- a/tests/unittests/CoreGraphics.Drawing/CGPathDrawingTests.cpp +++ b/tests/unittests/CoreGraphics.Drawing/CGPathDrawingTests.cpp @@ -497,77 +497,5 @@ DRAW_TEST_F(CGPath, FillStraightLines, UIKitMimicTest<>) { CGContextFillPath(context); CGContextStrokePath(context); - CGPathRelease(thepath); -} - -DRAW_TEST_F(CGPath, FillModeEOCircles, UIKitMimicTest<>) { - CGContextRef context = GetDrawingContext(); - CGRect bounds = GetDrawingBounds(); - CGFloat width = bounds.size.width; - CGFloat height = bounds.size.height; - CGFloat xstart = bounds.origin.x; - CGFloat ystart = bounds.origin.y; - - CGMutablePathRef thepath = CGPathCreateMutable(); - - CGPathMoveToPoint(thepath, NULL, xstart + .5 * width + .4 * height, ystart + .5 * height); - CGPathAddArc(thepath, NULL, xstart + .5 * width, ystart + .5 * height, .4 * height, 0, M_PI, true); - CGPathAddArc(thepath, NULL, xstart + .5 * width, ystart + .5 * height, .4 * height, M_PI, 0, true); - - CGPathMoveToPoint(thepath, NULL, xstart + .5 * width + .3 * height, ystart + .5 * height); - CGPathAddArc(thepath, NULL, xstart + .5 * width, ystart + .5 * height, .3 * height, 0, M_PI, true); - CGPathAddArc(thepath, NULL, xstart + .5 * width, ystart + .5 * height, .3 * height, M_PI, 0, true); - - CGPathMoveToPoint(thepath, NULL, xstart + .5 * width + .2 * height, ystart + .5 * height); - CGPathAddArc(thepath, NULL, xstart + .5 * width, ystart + .5 * height, .2 * height, 0, M_PI, true); - CGPathAddArc(thepath, NULL, xstart + .5 * width, ystart + .5 * height, .2 * height, M_PI, 0, true); - - CGPathMoveToPoint(thepath, NULL, xstart + .5 * width + .1 * height, ystart + .5 * height); - CGPathAddArc(thepath, NULL, xstart + .5 * width, ystart + .5 * height, .1 * height, 0, M_PI, true); - CGPathAddArc(thepath, NULL, xstart + .5 * width, ystart + .5 * height, .1 * height, M_PI, 0, true); - - CGPathCloseSubpath(thepath); - - CGContextAddPath(context, thepath); - CGContextSetRGBFillColor(context, 0, 0, 1, 1); - CGContextEOFillPath(context); - CGContextStrokePath(context); - - CGPathRelease(thepath); -} - -DRAW_TEST_F(CGPath, FillModeDefaultCircles, UIKitMimicTest<>) { - CGContextRef context = GetDrawingContext(); - CGRect bounds = GetDrawingBounds(); - CGFloat width = bounds.size.width; - CGFloat height = bounds.size.height; - CGFloat xstart = bounds.origin.x; - CGFloat ystart = bounds.origin.y; - - CGMutablePathRef thepath = CGPathCreateMutable(); - - CGPathMoveToPoint(thepath, NULL, xstart + .5 * width + .4 * height, ystart + .5 * height); - CGPathAddArc(thepath, NULL, xstart + .5 * width, ystart + .5 * height, .4 * height, 0, M_PI, true); - CGPathAddArc(thepath, NULL, xstart + .5 * width, ystart + .5 * height, .4 * height, M_PI, 0, true); - - CGPathMoveToPoint(thepath, NULL, xstart + .5 * width + .3 * height, ystart + .5 * height); - CGPathAddArc(thepath, NULL, xstart + .5 * width, ystart + .5 * height, .3 * height, 0, M_PI, true); - CGPathAddArc(thepath, NULL, xstart + .5 * width, ystart + .5 * height, .3 * height, M_PI, 0, true); - - CGPathMoveToPoint(thepath, NULL, xstart + .5 * width + .2 * height, ystart + .5 * height); - CGPathAddArc(thepath, NULL, xstart + .5 * width, ystart + .5 * height, .2 * height, 0, M_PI, true); - CGPathAddArc(thepath, NULL, xstart + .5 * width, ystart + .5 * height, .2 * height, M_PI, 0, true); - - CGPathMoveToPoint(thepath, NULL, xstart + .5 * width + .1 * height, ystart + .5 * height); - CGPathAddArc(thepath, NULL, xstart + .5 * width, ystart + .5 * height, .1 * height, 0, M_PI, true); - CGPathAddArc(thepath, NULL, xstart + .5 * width, ystart + .5 * height, .1 * height, M_PI, 0, true); - - CGPathCloseSubpath(thepath); - - CGContextAddPath(context, thepath); - CGContextSetRGBFillColor(context, 0, 0, 1, 1); - CGContextFillPath(context); - CGContextStrokePath(context); - CGPathRelease(thepath); } \ No newline at end of file diff --git a/tests/unittests/CoreGraphics.drawing/CGContextDrawing_FillModeTests.cpp b/tests/unittests/CoreGraphics.drawing/CGContextDrawing_FillModeTests.cpp index 6f8fa1b46b..1b73e44228 100644 --- a/tests/unittests/CoreGraphics.drawing/CGContextDrawing_FillModeTests.cpp +++ b/tests/unittests/CoreGraphics.drawing/CGContextDrawing_FillModeTests.cpp @@ -98,24 +98,8 @@ DRAW_TEST_P(CGContextFillMode, OverlappedEllipses) { CGContextAddPath(context, leftCircles); CGContextAddPath(context, rightCircles); CGContextSetRGBFillColor(context, 0, 0, 1, 1); - switch (fillMode) { - case kCGPathFill: - CGContextFillPath(context); - break; - case kCGPathFillStroke: - CGContextFillPath(context); - CGContextStrokePath(context); - break; - case kCGPathEOFill: - CGContextEOFillPath(context); - break; - case kCGPathEOFillStroke: - CGContextEOFillPath(context); - CGContextStrokePath(context); - break; - default: - break; - } + CGContextSetRGBStrokeColor(context, 1, 0, 0, 1); + CGContextDrawPath(context, fillMode); CGPathRelease(leftCircles); CGPathRelease(rightCircles); diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.FillMode.EOFillStroke.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.FillMode.EOFillStroke.png index 787d3d9844..ff1403db01 100644 --- a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.FillMode.EOFillStroke.png +++ b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.FillMode.EOFillStroke.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:51e7d8d7f7191bc10b105bbfee3bb1848bbb83765cf953f739f2ddf131e9cbe5 -size 9010 +oid sha256:76bad121aa3f04269f6795f0aacdaf8f1576d44c18f5b1ded084ff009bd13fa6 +size 15722 diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.FillMode.FillStroke.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.FillMode.FillStroke.png index e996e12e5f..8351197107 100644 --- a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.FillMode.FillStroke.png +++ b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGContext.FillMode.FillStroke.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0fd904926a6ba1e00589bc216130c3b273a1a90b846c444dc373a1a58028a8c8 -size 8326 +oid sha256:86d7892766a42f6355a8bda1f7ca92edc84f3b75dd135f4eb62f122e659aef47 +size 17892 diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGPath.FillModeDefaultCircles.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGPath.FillModeDefaultCircles.png deleted file mode 100644 index 3f678ba42c..0000000000 --- a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGPath.FillModeDefaultCircles.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:357fb54394bed3eb785da2b032c6ce5939c38e420bcc051a77d3df6a645f60a2 -size 10261 diff --git a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGPath.FillModeEOCircles.png b/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGPath.FillModeEOCircles.png deleted file mode 100644 index db6d7d1930..0000000000 --- a/tests/unittests/CoreGraphics.drawing/data/reference/TestImage.CGPath.FillModeEOCircles.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3f8cba6c6fe60b8a40784cd8bdec2145a0c66855dc7ce1d53f9b8f6c414e1c72 -size 18952 From 29280ec7bc9be8ac4a4d42ed01d6f8144f8f10ac Mon Sep 17 00:00:00 2001 From: Hank Fox Date: Wed, 15 Feb 2017 17:07:21 -0800 Subject: [PATCH 5/5] Fix relative project path --- .../CoreGraphics.Drawing/CoreGraphics.Drawing.UnitTests.vcxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/Tests/UnitTests/CoreGraphics.Drawing/CoreGraphics.Drawing.UnitTests.vcxproj b/build/Tests/UnitTests/CoreGraphics.Drawing/CoreGraphics.Drawing.UnitTests.vcxproj index 0b97b02ee7..a98ac6a4ed 100644 --- a/build/Tests/UnitTests/CoreGraphics.Drawing/CoreGraphics.Drawing.UnitTests.vcxproj +++ b/build/Tests/UnitTests/CoreGraphics.Drawing/CoreGraphics.Drawing.UnitTests.vcxproj @@ -232,7 +232,6 @@ - @@ -246,6 +245,7 @@ +