// TODO: Want to create and retain UIImage so it doesn't have to be reloaded!!!! void RenderImageBrush(CGContext context, ImageBrush imageBrush, bool isFill) { UIImage image = imageBrush.NativeBitmap as UIImage; if (image == null) { return; } System.Diagnostics.Debug.WriteLine("Image: {0} x {1}", image.CGImage.Width, image.CGImage.Height); using (CGColorSpace space = CGColorSpace.CreatePattern(null)) { if (isFill) { context.SetFillColorSpace(space); } else { context.SetStrokeColorSpace(space); } } nfloat scale = UIScreen.MainScreen.NativeScale; CGRect cell = new CGRect(0, 0, image.Size.Width / scale, image.Size.Height / scale); using (CGPattern pattern = new CGPattern(cell, CGAffineTransform.MakeIdentity(), cell.Width, cell.Height, CGPatternTiling.NoDistortion, true, (CGContext localContext) => { localContext.DrawImage(cell, image.CGImage); })) { nfloat[] alpha = { 1 }; if (isFill) { context.SetFillPattern(pattern, alpha); context.FillPath(); } else { context.SetStrokePattern(pattern, alpha); context.StrokePath(); } } }
public UIImage GetRenderedPattern() { var patternBounds = new CGRect(0, 0, 12, 12); var bounds = new CGRect(0, 0, patternBounds.Width * patternBounds.Width, patternBounds.Height * patternBounds.Height); #if __MACOS__ var img = new NSImage(bounds.Size); img.LockFocus(); var context = NSGraphicsContext.CurrentContext.GraphicsPort; #else UIGraphics.BeginImageContextWithOptions(bounds.Size, false, 0); var context = UIGraphics.GetCurrentContext(); #endif try { context.SetStrokeColor(UIColor.Blue.CGColor); context.AddEllipseInRect(bounds); using (var patternColorSpace = CGColorSpace.CreatePattern(null)) { context.SetFillColorSpace(patternColorSpace); using (var pattern = new CGPattern(patternBounds, CGAffineTransform.MakeIdentity(), patternBounds.Width, patternBounds.Height, CGPatternTiling.ConstantSpacing, true, ctx => { ctx.SetStrokeColor(UIColor.Green.CGColor); ctx.SetLineWidth(1); ctx.MoveTo(2, 6); ctx.AddLineToPoint(10, 6); ctx.MoveTo(6, 2); ctx.AddLineToPoint(6, 10); ctx.StrokePath(); })) { context.SetFillPattern(pattern, new nfloat [] { 1 }); } } context.DrawPath(CGPathDrawingMode.FillStroke); #if __MACOS__ return(img); #else return(UIGraphics.GetImageFromCurrentImageContext()); #endif } finally { #if __MACOS__ img.UnlockFocus(); #else UIGraphics.EndImageContext(); #endif } }
//======================================================================== #endregion //======================================================================== public override void ViewDidLoad() { base.ViewDidLoad(); //---- set the background color of the view to white this.View.BackgroundColor = UIColor.White; //---- instantiate a new image view that takes up the whole screen and add it to // the view hierarchy RectangleF imageViewFrame = new RectangleF(0, -this.NavigationController.NavigationBar.Frame.Height, this.View.Frame.Width, this.View.Frame.Height); this._imageView = new UIImageView(imageViewFrame); this.View.AddSubview(this._imageView); //---- create our offscreen bitmap context // size SizeF bitmapSize = new SizeF(this.View.Frame.Size); using (CGBitmapContext context = new CGBitmapContext(IntPtr.Zero , (int)bitmapSize.Width, (int)bitmapSize.Height, 8 , (int)(4 * bitmapSize.Width), CGColorSpace.CreateDeviceRGB() , CGImageAlphaInfo.PremultipliedFirst)) { //---- declare vars RectangleF patternRect = new RectangleF(0, 0, 16, 16); //---- set the color space of our fill to be the patter colorspace context.SetFillColorSpace(CGColorSpace.CreatePattern(null)); //---- create a new pattern CGPattern pattern = new CGPattern(patternRect , CGAffineTransform.MakeRotation(.3f), 16, 16, CGPatternTiling.NoDistortion , true, DrawPolkaDotPattern); //---- set our fill as our pattern, color doesn't matter because the pattern handles it context.SetFillPattern(pattern, new float[] { 1 }); //---- fill the entire view with that pattern context.FillRect(this._imageView.Frame); //---- output the drawing to the view this._imageView.Image = UIImage.FromImage(context.ToImage()); } }
public PatternDrawingView() : base() { // First we need to create a CGPattern that specifies the qualities of our pattern. using (var coloredPattern = new CGPattern( new RectangleF(0, 0, 16, 16), // the pattern coordinate space, drawing is clipped to this rectangle CGAffineTransform.MakeIdentity(), // a transform on the pattern coordinate space used before it is drawn. 16, 16, // the spacing (horizontal, vertical) of the pattern - how far to move after drawing each cell CGPatternTiling.NoDistortion, true, // this is a colored pattern, which means that you only specify an alpha value when drawing it DrawColored)){ // To draw a pattern, you need a pattern colorspace. // Since this is an colored pattern, the parent colorspace is NULL, indicating that it only has an alpha value. using (var coloredPatternColorSpace = CGColorSpace.CreatePattern(null)){ float alpha = 1; // Since this pattern is colored, we'll create a CGColor for it to make drawing it easier and more efficient. // From here on, the colored pattern is referenced entirely via the associated CGColor rather than the // originally created CGPatternRef. coloredPatternColor = new CGColor(coloredPatternColorSpace, coloredPattern, new float [] { alpha }); } } // Uncolored Pattern setup // As above, we create a CGPattern that specifies the qualities of our pattern uncoloredPattern = new CGPattern( new RectangleF(0, 0, 16, 16), // coordinate space CGAffineTransform.MakeIdentity(), // transform 16, 16, // spacing CGPatternTiling.NoDistortion, false, // this is an uncolored pattern, thus to draw it we need to specify both color and alpha DrawUncolored); // callbacks for this pattern // With an uncolored pattern we still need to create a pattern colorspace, but now we need a parent colorspace // We'll use the DeviceRGB colorspace here. We'll need this colorspace along with the CGPatternRef to draw this pattern later. using (var deviceRGB = CGColorSpace.CreateDeviceRGB()){ uncoloredPatternColorSpace = CGColorSpace.CreatePattern(deviceRGB); } }
// https://developer.apple.com/library/mac/#documentation/graphicsimaging/conceptual/drawingwithquartz2d/dq_patterns/dq_patterns.html#//apple_ref/doc/uid/TP30001066-CH206-TPXREF101 internal override void Setup(Graphics graphics, bool fill) { // if this is the same as the last that was set then return if (graphics.LastBrush == this) { return; } // obtain our width and height so we can set the pattern rectangle float hatch_width = getHatchWidth(hatchStyle); float hatch_height = getHatchHeight(hatchStyle); //choose the pattern to be filled based on the currentPattern selected var patternSpace = CGColorSpace.CreatePattern(null); graphics.context.SetFillColorSpace(patternSpace); graphics.context.SetStrokeColorSpace(patternSpace); patternSpace.Dispose(); // Pattern default work variables var patternRect = new CGRect(HALF_PIXEL_X, HALF_PIXEL_Y, hatch_width + HALF_PIXEL_X, hatch_height + HALF_PIXEL_Y); var patternTransform = CGAffineTransform.MakeIdentity(); // Since all the patterns were developed with MonoMac on Mac OS the coordinate system is // defaulted to the lower left corner being 0,0 which means for MonoTouch and any view // that is flipped we need to flip it again. Yep should have thought about it to begin with // will look into changing it later if need be. #if MONOMAC if (graphics.isFlipped) { patternTransform = new CGAffineTransform(1, 0, 0, -1, 0, hatch_height); } #endif #if MONOTOUCH if (!graphics.isFlipped) { patternTransform = new CGAffineTransform(1, 0, 0, -1, 0, hatch_height); } #endif // DrawPattern callback which will be set depending on hatch style CGPattern.DrawPattern drawPattern; switch (hatchStyle) { case HatchStyle.Horizontal: case HatchStyle.LightHorizontal: case HatchStyle.NarrowHorizontal: case HatchStyle.DarkHorizontal: drawPattern = HatchHorizontal; break; case HatchStyle.Vertical: case HatchStyle.LightVertical: case HatchStyle.NarrowVertical: case HatchStyle.DarkVertical: patternTransform = CGAffineTransform.MakeRotation(90 * (float)Math.PI / 180); drawPattern = HatchHorizontal; break; case HatchStyle.ForwardDiagonal: case HatchStyle.LightDownwardDiagonal: case HatchStyle.DarkDownwardDiagonal: case HatchStyle.WideDownwardDiagonal: // We will flip the x-axis here patternTransform = CGAffineTransform.MakeScale(-1, 1); drawPattern = HatchUpwardDiagonal; break; case HatchStyle.BackwardDiagonal: case HatchStyle.LightUpwardDiagonal: case HatchStyle.DarkUpwardDiagonal: case HatchStyle.WideUpwardDiagonal: drawPattern = HatchUpwardDiagonal; break; case HatchStyle.LargeGrid: case HatchStyle.SmallGrid: case HatchStyle.DottedGrid: drawPattern = HatchGrid; break; case HatchStyle.DiagonalCross: drawPattern = HatchDiagonalCross; break; case HatchStyle.Percent05: case HatchStyle.Percent10: case HatchStyle.Percent20: case HatchStyle.Percent25: case HatchStyle.Percent30: case HatchStyle.Percent40: case HatchStyle.Percent50: case HatchStyle.Percent60: case HatchStyle.Percent70: case HatchStyle.Percent75: case HatchStyle.Percent80: case HatchStyle.Percent90: drawPattern = HatchPercentage; break; case HatchStyle.Sphere: drawPattern = HatchSphere; break; case HatchStyle.DashedDownwardDiagonal: patternTransform = CGAffineTransform.MakeScale(-1, 1); drawPattern = HatchDashedDiagonal; break; case HatchStyle.DashedUpwardDiagonal: drawPattern = HatchDashedDiagonal; break; case HatchStyle.DashedHorizontal: drawPattern = HatchDashedHorizontal; break; case HatchStyle.DashedVertical: patternTransform = CGAffineTransform.MakeRotation(-90 * (float)Math.PI / 180); drawPattern = HatchDashedHorizontal; break; case HatchStyle.LargeConfetti: case HatchStyle.SmallConfetti: drawPattern = HatchConfetti; break; case HatchStyle.ZigZag: drawPattern = HatchZigZag; break; case HatchStyle.Wave: drawPattern = HatchWave; break; case HatchStyle.HorizontalBrick: drawPattern = HatchHorizontalBrick; break; case HatchStyle.DiagonalBrick: drawPattern = HatchDiagonalBrick; break; // case HatchStyle.Weave: // drawPattern = HatchWeave; // break; case HatchStyle.Trellis: drawPattern = HatchTrellis; break; case HatchStyle.LargeCheckerBoard: case HatchStyle.SmallCheckerBoard: drawPattern = HatchCheckered; break; case HatchStyle.OutlinedDiamond: drawPattern = HatchOutlinedDiamond; break; case HatchStyle.SolidDiamond: drawPattern = HatchSolidDiamond; break; case HatchStyle.DottedDiamond: drawPattern = HatchDottedDiamond; break; case HatchStyle.Divot: drawPattern = HatchDivot; break; case HatchStyle.Shingle: drawPattern = HatchShingle; break; case HatchStyle.Plaid: drawPattern = HatchPlaid; break; default: drawPattern = DrawPolkaDotPattern; break; } //set the pattern as the Current Context’s fill pattern var pattern = new CGPattern(patternRect, patternTransform, hatch_width, hatch_height, CGPatternTiling.NoDistortion, true, drawPattern); //we dont need to set any color, as the pattern cell itself has chosen its own color graphics.context.SetFillPattern(pattern, new nfloat[] { 1 }); graphics.context.SetStrokePattern(pattern, new nfloat[] { 1 }); graphics.LastBrush = this; // I am setting this to be used for Text coloring in DrawString graphics.lastBrushColor = foreColor; }
internal override void Setup(Graphics graphics, bool fill) { // if this is the same as the last that was set then return and no changes have been made // then return. if (graphics.LastBrush == this && !changed) { return; } // obtain our width and height so we can set the pattern rectangle float textureWidth = textureImage.Width; float textureHeight = textureImage.Height; if (wrapMode == WrapMode.TileFlipX || wrapMode == WrapMode.TileFlipY) { textureWidth *= 2; } if (wrapMode == WrapMode.TileFlipXY) { textureWidth *= 2; textureHeight *= 2; } //choose the pattern to be filled based on the currentPattern selected var patternSpace = CGColorSpace.CreatePattern(null); graphics.context.SetFillColorSpace(patternSpace); patternSpace.Dispose(); // Pattern default work variables var patternRect = new CGRect(HALF_PIXEL_X, HALF_PIXEL_Y, textureWidth + HALF_PIXEL_X, textureHeight + HALF_PIXEL_Y); var patternTransform = graphics.context.GetCTM(); patternTransform = CGAffineTransform.Multiply(textureTransform.transform, patternTransform); // DrawPattern callback which will be set depending on hatch style CGPattern.DrawPattern drawPattern; drawPattern = DrawTexture; //set the pattern as the Current Context’s fill pattern var pattern = new CGPattern(patternRect, patternTransform, textureWidth, textureHeight, //textureHeight, CGPatternTiling.NoDistortion, true, drawPattern); //we dont need to set any color, as the pattern cell itself has chosen its own color graphics.context.SetFillPattern(pattern, new nfloat[] { 1 }); changed = false; graphics.LastBrush = this; // I am setting this to be used for Text coloring in DrawString //graphics.lastBrushColor = foreColor; }