diff --git a/Frameworks/CoreGraphics/CGContext.mm b/Frameworks/CoreGraphics/CGContext.mm
index 0bd842cfab..87432a9bbf 100644
--- a/Frameworks/CoreGraphics/CGContext.mm
+++ b/Frameworks/CoreGraphics/CGContext.mm
@@ -93,11 +93,10 @@ void CGContextSetFillPattern(CGContextRef ctx, CGPatternRef pattern, const float
}
/**
- @Status Stub
+ @Status Interoperable
*/
void CGContextSetPatternPhase(CGContextRef ctx, CGSize phase) {
- UNIMPLEMENTED();
- TraceWarning(TAG, L"CGContextSetPatternPhase not implemented");
+ return ctx->Backing()->CGContextSetPatternPhase(phase);
}
/**
diff --git a/Frameworks/CoreGraphics/CGContextImpl.mm b/Frameworks/CoreGraphics/CGContextImpl.mm
index 37d481790c..6f7190953b 100644
--- a/Frameworks/CoreGraphics/CGContextImpl.mm
+++ b/Frameworks/CoreGraphics/CGContextImpl.mm
@@ -400,6 +400,16 @@
}
}
+void CGContextImpl::CGContextSetPatternPhase(CGSize phase) {
+ if ([curState->curFillColorObject isKindOfClass:[CGPattern class]]) {
+ CGPattern* pattern = curState->curFillColorObject;
+ CGAffineTransform matrix = pattern->matrix;
+ matrix.tx += phase.width;
+ matrix.ty += phase.height;
+ pattern->matrix = matrix;
+ }
+}
+
void CGContextImpl::CGContextSelectFont(char* name, float size, DWORD encoding) {
// curState->curFont = [UIFont class]("fontWithName:size:", @name, size);
curState->fontSize = size;
diff --git a/Frameworks/include/CGContextImpl.h b/Frameworks/include/CGContextImpl.h
index ca3f030eb1..8ad28fd6b3 100644
--- a/Frameworks/include/CGContextImpl.h
+++ b/Frameworks/include/CGContextImpl.h
@@ -15,6 +15,11 @@
//******************************************************************************
#pragma once
+
+#ifndef __CGCONTEXTIMPL_TEST_FRIENDS
+#define __CGCONTEXTIMPL_TEST_FRIENDS
+#endif
+
#include "CGContextInternal.h"
#include "CoreGraphics/CGPath.h"
@@ -53,6 +58,7 @@ typedef struct {
#define MAX_CG_STATES 16
class CGContextImpl {
+__CGCONTEXTIMPL_TEST_FRIENDS;
protected:
CGContextRef _rootContext;
CGImageRef _imgDest;
@@ -107,6 +113,7 @@ class CGContextImpl {
virtual void CGContextSetStrokeColorWithColor(id color);
virtual void CGContextSetFillColorWithColor(id color);
virtual void CGContextSetFillColor(float* components);
+ virtual void CGContextSetPatternPhase(CGSize phase);
virtual void CGContextSetFillPattern(CGPatternRef pattern, const float* components);
virtual void CGContextSelectFont(char* name, float size, DWORD encoding);
virtual void CGContextGetTextPosition(CGPoint* pos);
diff --git a/build/CoreGraphics/dll/CoreGraphics.def b/build/CoreGraphics/dll/CoreGraphics.def
index 36571acfd2..aa155313b0 100644
--- a/build/CoreGraphics/dll/CoreGraphics.def
+++ b/build/CoreGraphics/dll/CoreGraphics.def
@@ -215,6 +215,7 @@ LIBRARY CoreGraphics
CGContextIsDirty
CGContextReleaseLock
CGContextSetDirty
+ CGContextGetBacking
EbrCenterTextInRectVertically
; CGDataConsumer.mm
diff --git a/build/Tests/UnitTests/CoreGraphics/CoreGraphics.UnitTests.vcxproj b/build/Tests/UnitTests/CoreGraphics/CoreGraphics.UnitTests.vcxproj
index 12481c1d5e..4138cdc88a 100644
--- a/build/Tests/UnitTests/CoreGraphics/CoreGraphics.UnitTests.vcxproj
+++ b/build/Tests/UnitTests/CoreGraphics/CoreGraphics.UnitTests.vcxproj
@@ -28,8 +28,8 @@
{0AC27ECF-E2AB-420B-9359-4843FFF4CBFA}
-
- {26da08da-d0b9-4579-b168-e7f0a5f20e57}
+
+ {6293444C-1461-4CC7-9634-44AB90B8BBC3}
{8E79930B-7EF6-4A4E-B46C-EFC0A49C55D9}
diff --git a/include/CoreGraphics/CGContext.h b/include/CoreGraphics/CGContext.h
index 7029dfe730..c256cbab69 100644
--- a/include/CoreGraphics/CGContext.h
+++ b/include/CoreGraphics/CGContext.h
@@ -95,7 +95,7 @@ COREGRAPHICS_EXPORT void CGContextSetLineJoin(CGContextRef c, CGLineJoin join);
COREGRAPHICS_EXPORT void CGContextSetLineWidth(CGContextRef c, CGFloat width);
COREGRAPHICS_EXPORT void CGContextSetMiterLimit(CGContextRef c, CGFloat limit);
-COREGRAPHICS_EXPORT void CGContextSetPatternPhase(CGContextRef c, CGSize phase) STUB_METHOD;
+COREGRAPHICS_EXPORT void CGContextSetPatternPhase(CGContextRef c, CGSize phase);
COREGRAPHICS_EXPORT void CGContextSetFillPattern(CGContextRef c, CGPatternRef pattern, const CGFloat* components);
COREGRAPHICS_EXPORT void CGContextSetRenderingIntent(CGContextRef c, CGColorRenderingIntent intent) STUB_METHOD;
diff --git a/samples/CGCatalog/CGCatalog/Samples/CGCCGContextSetPatternPhase.m b/samples/CGCatalog/CGCatalog/Samples/CGCCGContextSetPatternPhase.m
index c244d6c803..519a015087 100644
--- a/samples/CGCatalog/CGCatalog/Samples/CGCCGContextSetPatternPhase.m
+++ b/samples/CGCatalog/CGCatalog/Samples/CGCCGContextSetPatternPhase.m
@@ -33,12 +33,6 @@ - (void)drawRect:(CGRect)rect {
CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
CGContextFillRect(context, CGRectMake(0, 0, maxWidth, maxHeight));
- // Create a base pattern color space
- CGContextSaveGState(context);
- CGColorSpaceRef colorSpace = CGColorSpaceCreatePattern(NULL);
- CGContextSetFillColorSpace(context, colorSpace);
- CGColorSpaceRelease(colorSpace);
-
// Create the pattern
static const CGPatternCallbacks callbacks = { 0, &_DrawCustomPattern, NULL };
CGFloat alpha = 1;
@@ -52,7 +46,6 @@ - (void)drawRect:(CGRect)rect {
// Fill using the pattern
CGContextFillRect(context, rect);
- CGContextRestoreGState(context);
}
void _DrawCustomPattern(void* info, CGContextRef context) {
diff --git a/tests/unittests/CoreGraphics/CGContextTests.mm b/tests/unittests/CoreGraphics/CGContextTests.mm
index 55f53899fc..8627ddfa3f 100644
--- a/tests/unittests/CoreGraphics/CGContextTests.mm
+++ b/tests/unittests/CoreGraphics/CGContextTests.mm
@@ -15,6 +15,107 @@
//******************************************************************************
#import
+
+#define __CGCONTEXTIMPL_TEST_FRIENDS \
+ FRIEND_TEST(CGContext, CGContextSetPatternPhasePatternIsNil); \
+ FRIEND_TEST(CGContext, CGContextSetPatternPhaseColorObjectIsFillColor); \
+ FRIEND_TEST(CGContext, CGContextSetPatternPhasePositiveChange); \
+ FRIEND_TEST(CGContext, CGContextSetPatternPhaseNegativeChange);
+
#import
+#import "CGPatternInternal.h"
#import
+#import "CGContextInternal.h"
+#import "CGContextImpl.h"
#import
+#import
+
+void _DrawCustomPattern(void* info, CGContextRef context) {
+ // Draw a circle inset from the pattern size
+ CGRect circleRect = CGRectMake(0, 0, 50, 50);
+ circleRect = CGRectInset(circleRect, 4, 4);
+ CGContextFillEllipseInRect(context, circleRect);
+ CGContextStrokeEllipseInRect(context, circleRect);
+}
+
+TEST(CGContext, CGContextSetPatternPhasePatternIsNil) {
+ // Given
+ CGContextRef ctx = CGBitmapContextCreate24(1000, 1000);
+ CGContextImpl* backing = CGContextGetBacking(ctx);
+
+ backing->curState->curFillColorObject = nil;
+
+ // When
+ CGContextSetPatternPhase(ctx, CGSizeMake(100, 100));
+
+ // Then
+ ASSERT_EQ(0, backing->curState->curFillColorObject);
+
+ CGContextRelease(ctx);
+}
+
+TEST(CGContext, CGContextSetPatternPhaseColorObjectIsFillColor) {
+ // Given
+ CGContextRef ctx = CGBitmapContextCreate24(1000, 1000);
+ CGContextImpl* backing = CGContextGetBacking(ctx);
+
+ CGContextSetFillColorWithColor(ctx, [UIColor blueColor].CGColor);
+
+ // When
+ CGContextSetPatternPhase(ctx, CGSizeMake(100, 100));
+
+ // Then
+ ASSERT_EQ(0, (CGColorRef)backing->curState->curFillColorObject);
+
+ CGContextRelease(ctx);
+}
+
+/*TEST(CGContext, CGContextSetPatternPhasePositiveChange) {
+ // Given
+ CGContextRef ctx = CGBitmapContextCreate24(1000, 1000);
+ CGContextImpl* backing = CGContextGetBacking(ctx);
+
+ CGRect boundsRect = CGRectMake(0, 0,1000, 1000);
+ const CGPatternCallbacks callbacks = { 0, &_DrawCustomPattern, NULL };
+ CGFloat alpha = 1;
+ CGAffineTransform transform = CGAffineTransformMakeTranslation(10, 10);
+ CGPatternRef pattern = CGPatternCreate(
+ NULL, boundsRect, transform, 50, 50, kCGPatternTilingConstantSpacing, true, &callbacks);
+ CGContextSetFillPattern(ctx, pattern, &alpha);
+ CGPatternRelease(pattern);
+
+ // When
+ CGContextSetPatternPhase(ctx, CGSizeMake(100, 200));
+
+ // Then
+ CGPattern* actualPattern = (CGPattern*)backing->curState->curFillColorObject;
+ ASSERT_EQ(110, actualPattern->matrix.tx);
+ ASSERT_EQ(210, actualPattern->matrix.ty);
+
+ CGContextRelease(ctx);
+}
+
+TEST(CGContext, CGContextSetPatternPhaseNegativeChange) {
+ // Given
+ CGContextRef ctx = CGBitmapContextCreate24(1000, 1000);
+ CGContextImpl* backing = CGContextGetBacking(ctx);
+
+ CGRect boundsRect = CGRectMake(0, 0,1000, 1000);
+ const CGPatternCallbacks callbacks = { 0, &_DrawCustomPattern, NULL };
+ CGFloat alpha = 1;
+ CGAffineTransform transform = CGAffineTransformMakeTranslation(300, 500);
+ CGPatternRef pattern = CGPatternCreate(
+ NULL, boundsRect, transform, 50, 50, kCGPatternTilingConstantSpacing, true, &callbacks);
+ CGContextSetFillPattern(ctx, pattern, &alpha);
+ CGPatternRelease(pattern);
+
+ // When
+ CGContextSetPatternPhase(ctx, CGSizeMake(-100, -200));
+
+ // Then
+ CGPattern* actualPattern = (CGPattern*)backing->curState->curFillColorObject;
+ ASSERT_EQ(200, actualPattern->matrix.tx);
+ ASSERT_EQ(300, actualPattern->matrix.ty);
+
+ CGContextRelease(ctx);
+}*/