Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- @interface DrawView () {
- CGPoint point0,point1,point2,point3;
- CGContextRef cacheContext;
- CGImageRef imageBeforeDraw;
- Byte* cacheBitmap;
- CGImageRef startedImage;
- }
- - (void)allInits:(CGSize)size;
- - (void)drawBezierCurveWithPoint0:(CGPoint)p0 point1:(CGPoint)p1 point2:(CGPoint)p2 point3:(CGPoint)p3;
- - (void)drawToCache;
- - (void)eraseInPoint:(CGPoint)point;
- @end
- @implementation DrawView
- @synthesize isErase;
- @synthesize brushColor;
- @synthesize brushSize;
- - (BOOL) initContext:(CGSize)size {
- int bitmapByteCount;
- int bitmapBytesPerRow;
- // Declare the number of bytes per row. Each pixel in the bitmap in this
- // example is represented by 4 bytes; 8 bits each of red, green, blue, and
- // alpha.
- bitmapBytesPerRow = (size.width * 4);
- bitmapByteCount = (bitmapBytesPerRow * size.height);
- // Allocate memory for image data. This is the destination in memory
- // where any drawing to the bitmap context will be rendered.
- cacheBitmap = malloc( bitmapByteCount );
- if (cacheBitmap == NULL){
- return NO;
- }
- for (int i=0; i<bitmapByteCount; i++) {
- cacheBitmap[i]=255;
- }
- cacheContext = CGBitmapContextCreate (cacheBitmap, size.width, size.height, 8, bitmapBytesPerRow, CGColorSpaceCreateDeviceRGB(), (CGBitmapInfo)kCGImageAlphaNoneSkipFirst);
- return YES;
- }
- - (void) drawRect:(CGRect)rect {
- // draw from cacheContext
- CGContextRef context = UIGraphicsGetCurrentContext();
- CGImageRef cacheImage = CGBitmapContextCreateImage(cacheContext);
- CGContextDrawImage(context, self.bounds, cacheImage);
- CGImageRelease(cacheImage);
- }
- - (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
- [self drawBezierCurveWithPoint0:nilPoint point1:nilPoint point2:nilPoint point3:[[touches anyObject] locationInView:self]];
- }
- - (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
- [self drawBezierCurveWithPoint0:point1 point1:point2 point2:point3 point3:[[touches anyObject] locationInView:self]];
- }
- - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
- [self drawBezierCurveWithPoint0:point1 point1:point2 point2:point3 point3:[[touches anyObject] locationInView:self]];
- }
- - (void)drawBezierCurveWithPoint0:(CGPoint)p0 point1:(CGPoint)p1 point2:(CGPoint)p2 point3:(CGPoint)p3 {
- point0 = p0;
- point1 = p1;
- point2 = p2;
- point3 = p3;
- if (isErase) {
- [self eraseInPoint:point3];
- } else {
- [self drawToCache];
- }
- }
- - (void) drawToCache {
- CGContextSetStrokeColorWithColor(cacheContext, [brushColor CGColor]);
- CGContextSetLineCap(cacheContext, kCGLineCapRound);
- CGContextSetLineWidth(cacheContext, brushSize);
- CGRect dirtyRect;
- if (point1.x > -1) {
- // create cubic Bezier curve
- double x0 = (point0.x > -1) ? point0.x : point1.x;
- double y0 = (point0.y > -1) ? point0.y : point1.y;
- double x1 = point1.x;
- double y1 = point1.y;
- double x2 = point2.x;
- double y2 = point2.y;
- double x3 = point3.x;
- double y3 = point3.y;
- double xc1 = (x0 + x1) / 2.0;
- double yc1 = (y0 + y1) / 2.0;
- double xc2 = (x1 + x2) / 2.0;
- double yc2 = (y1 + y2) / 2.0;
- double xc3 = (x2 + x3) / 2.0;
- double yc3 = (y2 + y3) / 2.0;
- double len1 = sqrt((x1-x0) * (x1-x0) + (y1-y0) * (y1-y0));
- double len2 = sqrt((x2-x1) * (x2-x1) + (y2-y1) * (y2-y1));
- double len3 = sqrt((x3-x2) * (x3-x2) + (y3-y2) * (y3-y2));
- double k1 = len1 / (len1 + len2);
- double k2 = len2 / (len2 + len3);
- double xm1 = xc1 + (xc2 - xc1) * k1;
- double ym1 = yc1 + (yc2 - yc1) * k1;
- double xm2 = xc2 + (xc3 - xc2) * k2;
- double ym2 = yc2 + (yc3 - yc2) * k2;
- double smooth_value = 0.5;
- float ctrl1_x = xm1 + (xc2 - xm1) * smooth_value + x1 - xm1;
- float ctrl1_y = ym1 + (yc2 - ym1) * smooth_value + y1 - ym1;
- float ctrl2_x = xm2 + (xc2 - xm2) * smooth_value + x2 - xm2;
- float ctrl2_y = ym2 + (yc2 - ym2) * smooth_value + y2 - ym2;
- CGContextMoveToPoint(cacheContext, point1.x, point1.y);
- CGContextAddCurveToPoint(cacheContext, ctrl1_x, ctrl1_y, ctrl2_x, ctrl2_y, point2.x, point2.y);
- CGContextStrokePath(cacheContext);
- int DRx,DRy,DRw,DRh;
- DRx = (point1.x<point2.x?point1.x:point2.x) - brushSize;
- DRy = (point1.y<point2.y?point1.y:point2.y) - brushSize;
- DRw = abs(point1.x-point2.x)+2*brushSize;
- DRh = abs(point1.y - point2.y) + 2*brushSize;
- dirtyRect = CGRectMake(DRx, DRy, DRw, DRh);
- } else {
- //draw point
- dirtyRect = CGRectMake(point3.x-brushSize/2, point3.y-brushSize/2, brushSize, brushSize);
- CGContextMoveToPoint(cacheContext, point3.x, point3.y);
- CGContextAddLineToPoint(cacheContext, point3.x, point3.y);
- CGContextStrokePath(cacheContext);
- }
- [self setNeedsDisplayInRect:dirtyRect];
- }
- - (void)eraseInPoint:(CGPoint)point {
- float x = point.x-brushSize/2, y = point.y-brushSize/2;
- float width = brushSize, height = brushSize;
- CGRect dirtyRect = CGRectMake(x, y, width, height);
- CGRect drawRect = dirtyRect;
- drawRect.origin.y = self.bounds.size.height-drawRect.origin.y-drawRect.size.height;
- CGImageRef erase = CGImageCreateWithImageInRect(startedImage, drawRect);
- CGContextDrawImage(cacheContext, dirtyRect, erase);
- CGImageRelease(erase);
- [self setNeedsDisplayInRect:dirtyRect];
- }
- - (void)setStartedImage:(CGImageRef)image {
- [undoArray removeAllObjects];
- [redoArray removeAllObjects];
- CGContextDrawImage(cacheContext, [self bounds], image);
- // change image origin point
- int height = self.bounds.size.height;
- int width = self.bounds.size.width;
- int bitmapBytesPerRow = (width * 4);
- int tmp;
- for (int i=0; i<height/2+height%2; i++) {
- for (int j=0; j<bitmapBytesPerRow; j++) {
- tmp = cacheBitmap[i*bitmapBytesPerRow + j];;
- cacheBitmap[i*bitmapBytesPerRow + j] = cacheBitmap[j+ bitmapBytesPerRow*(height-i-1)];
- cacheBitmap[j+bitmapBytesPerRow*(height-i-1)]=tmp;
- }
- }
- CGImageRelease(startedImage);
- startedImage = CGBitmapContextCreateImage(cacheContext);
- [self setNeedsDisplay];
- }
- @end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement