I am working with a drawing app, I am using CGlayers for drawing. On touches ended, I get image out of the layer and store it in a Array, which I use to undo operation.
My touches ended function
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"Touches ended");
UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0.0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextDrawLayerInRect(context, self.bounds, self.drawingLayer);
m_curImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[m_undoArray addObject: m_curImage];
}
My Drawing View expands dynamically on user demand, So suppose user can draw say, a line with drawView size 200*200, then expand it to 200*300 and draw one more line, then expand it to 200*300 and draw one more line.
Here is the image of the app
So now I have 3 images with different sizes in UndoArray.
Whenever I increase/decrese the canvas size. I have written this code
On increase and decrease of the drawingView, I am writing this function
(void)increaseDecreaseDrawingView
{
self.currentDrawingLayer = nil;
if(self.permanentDrawingLayer)
{
rectSize = self.bounds;
NSLog(@"Size%@", NSStringFromCGRect(self.bounds));
CGContextRef context = UIGraphicsGetCurrentContext();
//self.newDrawingLayer = CGLayerCreateWithContext(context, self.bounds.size, NULL);
CGFloat scale = self.contentScaleFactor;
CGRect bounds = CGRectMake(0, 0, self.bounds.size.width * scale, self.bounds.size.height * scale);
CGLayerRef layer = CGLayerCreateWithContext(context, bounds.size, NULL);
CGContextRef layerContext = CGLayerGetContext(layer);
CGContextScaleCTM(layerContext, scale, scale);
self.newDrawingLayer = layer;
CGContextDrawLayerInRect(layerContext, self.bounds, self.permanentDrawingLayer );
self.permanentDrawingLayer = nil;
}
And for doing undo I have written this code
- (void)Undo
{
//Destroy the layer and create it once again with the image you get from undoArray.
self.currentDrawingLayer = Nil;
CGContextRef layerContext1 = CGLayerGetContext(self.permanentDrawingLayer );
CGContextClearRect(layerContext1, self.bounds);
CGContextRef context = UIGraphicsGetCurrentContext();
for(int i =0; i<[m_rectArrayUndo count];i++)
{
CGRect rect = [[m_rectArrayUndo objectAtIndex:i]CGRectValue];
CGLayerRef undoLayer = CGLayerCreateWithContext(context, rect.size, NULL);
CGContextRef layerContext = CGLayerGetContext(undoLayer );
CGContextTranslateCTM(layerContext, 0.0, rect.size.height);
CGContextScaleCTM(layerContext, 1.0, -1.0);
CGRect imageFrame;
NSDictionary *lineInfo = [m_undoArray objectAtIndex:i];
m_curImage = [lineInfo valueForKey:@"IMAGE"];
imageFrame = CGRectMake(0 ,0,m_curImage.size.width,m_curImage.size.height);
CGContextDrawImage(layerContext, imageFrame, m_curImage.CGImage);
CGContextDrawLayerInRect(context, rect, undoLayer );
CGContextDrawLayerInRect(layerContext1, rect, undoLayer);
}
}
In my drawRect function, I have written this code
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();//Get a reference to current context(The context to draw)
if(self.currentDrawingLayer == nil)
{
CGLayerRef layer = CGLayerCreateWithContext(context, bounds.size, NULL);
self.currentDrawingLayer = layer;
}
if(self.permanentDrawingLayer == nil)
{
CGLayerRef layer = CGLayerCreateWithContext(context, bounds.size, NULL);
self.permanentDrawingLayer = layer;
}
if(self.newDrawingLayer == nil)
{
CGLayerRef layer = CGLayerCreateWithContext(context, bounds.size, NULL);
self.newDrawingLayer = layer;
}
CGPoint mid1 = midPoint(m_previousPoint1, m_previousPoint2);
CGPoint mid2 = midPoint(m_currentPoint, m_previousPoint1);
CGContextRef layerContext = CGLayerGetContext(self.currentDrawingLayer);
CGContextSetLineCap(layerContext, kCGLineCapRound);
CGContextSetBlendMode(layerContext, kCGBlendModeNormal);
CGContextSetLineJoin(layerContext, kCGLineJoinRound);
CGContextSetLineWidth(layerContext, self.lineWidth);
CGContextSetStrokeColorWithColor(layerContext, self.lineColor.CGColor);
CGContextSetShouldAntialias(layerContext, YES);
CGContextSetAllowsAntialiasing(layerContext, YES);
CGContextSetAlpha(layerContext, self.lineAlpha);
CGContextSetFlatness(layerContext, 1.0f);
CGContextBeginPath(layerContext);
CGContextMoveToPoint(layerContext, mid1.x, mid1.y);//Position the current point
CGContextAddQuadCurveToPoint(layerContext, m_previousPoint1.x, m_previousPoint1.y, mid2.x, mid2.y);
CGContextStrokePath(layerContext);//paints(fills) the line along the current path.
CGContextDrawLayerInRect(context, self.bounds, self.newDrawingLayer);
CGContextDrawLayerInRect(context, self.bounds, self.permanentDrawingLayer);
CGContextDrawLayerInRect(context, self.bounds, self.currentDrawingLayer);
[super drawRect:rect];
}
I have few doubts
Is this the correct way to do? Or is their any better approach.
Here What happens is that, my images from undo array are not respecting the rects and are drawn at any random position on the new Layer.
So I want to know how we can draw them properly so that images are drawn properly on CGlayers at specific position.