DRAW_TEST_F(CGImageDrawing, DrawAContextIntoAnImage, UIKitMimicTest<>) { // This test will create a bitmap context, draw some entity into the context, then create a image out of the bitmap context. // Thereafter it will draw the image into the Canvas context static woc::unique_cf<CGColorSpaceRef> rgbColorSpace(CGColorSpaceCreateDeviceRGB()); // Create a bitmap context to draw the Image into woc::unique_cf<CGContextRef> contextImage(CGBitmapContextCreate( nullptr, 10, 10, 8, 4 * 10 /* bytesPerRow = bytesPerPixel*width*/, rgbColorSpace.get(), kCGImageAlphaPremultipliedFirst)); ASSERT_NE(contextImage, nullptr); CGContextSetRGBFillColor(contextImage.get(), 1.0, 0.0, 0.0, 1.0); CGContextFillRect(contextImage.get(), { 0, 0, 10, 10 }); // Create the image out of the bitmap context woc::unique_cf<CGImageRef> image(CGBitmapContextCreateImage(contextImage.get())); ASSERT_NE(image, nullptr); CGContextRef context = GetDrawingContext(); CGRect bounds = GetDrawingBounds(); CGAffineTransform flip = CGAffineTransformMakeScale(1, -1); CGAffineTransform shift = CGAffineTransformTranslate(flip, 0, bounds.size.height * -1); CGContextConcatCTM(context, shift); // draw the image CGContextDrawImage(context, bounds, image.get()); }
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); CGContextSetRGBStrokeColor(context, 1, 0, 0, 1); CGContextDrawPath(context, fillMode); CGPathRelease(leftCircles); CGPathRelease(rightCircles); }
DRAW_TEST_F(CGContextFlush, FillFlushMultipleDrawingCounters, WhiteBackgroundTest<>) { CGContextRef context = GetDrawingContext(); CGRect bounds = GetDrawingBounds(); static int sDrawCount = 5; for (int i = 0; i < sDrawCount; ++i) { _CGContextPushBeginDraw(context); } CGContextSetRGBFillColor(context, 1, 0, 0, 1); CGContextFillRect(context, bounds); for (int i = 0; i < sDrawCount; ++i) { // Multiple flushes should work. CGContextFlush(context); } // Add some extra drawings CGContextClearRect(context, bounds); // We should still have red & clear should not of been executed. unsigned char* dataPtr = static_cast<unsigned char*>(CGBitmapContextGetData(context)); ASSERT_NE(dataPtr, nullptr); // Validate only the red fill rect is executed. EXPECT_EQ(dataPtr[0], 0x00); EXPECT_EQ(dataPtr[1], 0x00); EXPECT_EQ(dataPtr[2], 0xff); EXPECT_EQ(dataPtr[3], 0xff); for (int i = 0; i < 3; ++i) { // Multiple flushes should work. CGContextFlush(context); } // validate clear EXPECT_EQ(dataPtr[0], 0x00); EXPECT_EQ(dataPtr[1], 0x00); EXPECT_EQ(dataPtr[2], 0x00); EXPECT_EQ(dataPtr[3], 0x00); CGContextSetRGBStrokeColor(context, 0, 1, 0, 1); CGContextStrokeRect(context, CGRectMake(100, 100, 200, 300)); // Still should be clear. EXPECT_EQ(dataPtr[0], 0x00); EXPECT_EQ(dataPtr[1], 0x00); EXPECT_EQ(dataPtr[2], 0x00); EXPECT_EQ(dataPtr[3], 0x00); for (int i = 0; i < sDrawCount; ++i) { _CGContextPopEndDraw(context); } }
DRAW_TEST_F(CGContextFlush, FillFlush, WhiteBackgroundTest<>) { CGContextRef context = GetDrawingContext(); CGRect bounds = GetDrawingBounds(); _CGContextPushBeginDraw(context); CGContextSetRGBFillColor(context, 1, 0, 0, 1); CGContextFillRect(context, bounds); // Flush the red fill rect CGContextFlush(context); CGContextSetRGBFillColor(context, 0, 0, 1, 1); CGContextFillRect(context, CGRectMake(0, 0, 300, 300)); // We should still have red & blue rectangle should not show up. unsigned char* dataPtr = static_cast<unsigned char*>(CGBitmapContextGetData(context)); ASSERT_NE(dataPtr, nullptr); // Validate only the red fill rect is executed. EXPECT_EQ(dataPtr[0], 0x00); EXPECT_EQ(dataPtr[1], 0x00); EXPECT_EQ(dataPtr[2], 0xff); EXPECT_EQ(dataPtr[3], 0xff); CGContextFlush(context); // We should now see the blue fill rect EXPECT_EQ(dataPtr[0], 0xff); EXPECT_EQ(dataPtr[1], 0x00); EXPECT_EQ(dataPtr[2], 0x00); EXPECT_EQ(dataPtr[3], 0xff); // Add some extra drawings CGContextClearRect(context, CGRectMake(100, 100, 200, 300)); CGPoint center = _CGRectGetCenter(bounds); CGMutablePathRef concentricCirclesPath = CGPathCreateMutable(); CGPathAddEllipseInRect(concentricCirclesPath, nullptr, _CGRectCenteredOnPoint({ 50, 50 }, center)); CGPathAddEllipseInRect(concentricCirclesPath, nullptr, _CGRectCenteredOnPoint({ 100, 100 }, center)); CGPathAddEllipseInRect(concentricCirclesPath, nullptr, _CGRectCenteredOnPoint({ 150, 150 }, center)); CGPathAddEllipseInRect(concentricCirclesPath, nullptr, _CGRectCenteredOnPoint({ 200, 200 }, center)); CGContextSetRGBFillColor(context, 1.0, 0.0, 0.0, 0.5); CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0); CGContextAddPath(context, concentricCirclesPath); CGContextDrawPath(context, kCGPathFillStroke); CGPathRelease(concentricCirclesPath); _CGContextPopEndDraw(context); }
DRAW_TEST_F(CGContext, DrawAnImageWithInterpolationQualityAndAlpha, UIKitMimicTest<>) { auto drawingConfig = DrawingTestConfig::Get(); woc::unique_cf<CFStringRef> testFilename{ _CFStringCreateWithStdString(drawingConfig->GetResourcePath("png1.9.png")) }; woc::unique_cf<CGImageRef> image{ _CGImageCreateFromPNGFile(testFilename.get()) }; ASSERT_NE(image, nullptr); CGContextRef context = GetDrawingContext(); CGRect bounds = GetDrawingBounds(); CGContextSetAlpha(context, 0.25); CGContextSetInterpolationQuality(context, kCGInterpolationHigh); CGContextDrawImage(context, bounds, image.get()); }
DISABLED_DRAW_TEST_F(CGContext, Shadow, WhiteBackgroundTest) { CGContextRef context = GetDrawingContext(); CGRect bounds = GetDrawingBounds(); CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0); CGContextSetLineWidth(context, 5); CGContextSetShadow(context, CGSize{ 10.f, 10.f }, 1.0); CGPoint center = _CGRectGetCenter(bounds); CGRect rect = _CGRectCenteredOnPoint({ 150, 150 }, center); CGContextStrokeRect(context, rect); }
DRAW_TEST_F(CGImageDrawing, DrawAnImage, UIKitMimicTest<>) { // Load an Image and draw it into the canvas context auto drawingConfig = DrawingTestConfig::Get(); woc::unique_cf<CFStringRef> testFilename{ _CFStringCreateWithStdString(drawingConfig->GetResourcePath("jpg1.jpg")) }; woc::unique_cf<CGImageRef> image{ _CGImageCreateFromJPEGFile(testFilename.get()) }; ASSERT_NE(image, nullptr); CGContextRef context = GetDrawingContext(); CGRect bounds = GetDrawingBounds(); CGAffineTransform flip = CGAffineTransformMakeScale(1, -1); CGAffineTransform shift = CGAffineTransformTranslate(flip, 0, bounds.size.height * -1); CGContextConcatCTM(context, shift); CGContextDrawImage(context, bounds, image.get()); }
DISABLED_DRAW_TEST_F(CGContext, ShadowWithRotatedCTM, WhiteBackgroundTest) { CGContextRef context = GetDrawingContext(); CGRect bounds = GetDrawingBounds(); CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0); CGContextSetLineWidth(context, 5); CGContextSetShadow(context, CGSize{ 10.f, 10.f }, 1.0); CGPoint center = _CGRectGetCenter(bounds); CGRect rect = _CGRectCenteredOnPoint({ 150, 150 }, center); CGPoint rectCenter = _CGRectGetCenter(rect); CGContextTranslateCTM(context, rectCenter.x, rectCenter.y); CGContextRotateCTM(context, 15.f * M_PI / 180.f); CGContextTranslateCTM(context, -rectCenter.x, -rectCenter.y); CGContextStrokeRect(context, rect); }
DISABLED_DRAW_TEST_F(CGImageDrawing, DrawIntoRect, UIKitMimicTest<>) { // Draw a portion of an image into a different region. auto drawingConfig = DrawingTestConfig::Get(); woc::unique_cf<CFStringRef> testFilename{ _CFStringCreateWithStdString(drawingConfig->GetResourcePath("png3.9.png")) }; woc::unique_cf<CGImageRef> image{ _CGImageCreateFromPNGFile(testFilename.get()) }; ASSERT_NE(image, nullptr); CGContextRef context = GetDrawingContext(); CGRect bounds = GetDrawingBounds(); CGAffineTransform flip = CGAffineTransformMakeScale(1, -1); CGAffineTransform shift = CGAffineTransformTranslate(flip, 0, bounds.size.height * -1); CGContextConcatCTM(context, shift); _CGContextDrawImageRect(context, image.get(), { 0, 0, bounds.size.width / 4, bounds.size.height / 4 }, { 0, 0, bounds.size.width, bounds.size.height }); }