Advertisement
Guest User

Untitled

a guest
Apr 30th, 2014
347
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. @interface DrawView () {
  2.     CGPoint point0,point1,point2,point3;
  3.     CGContextRef cacheContext;
  4.     CGImageRef imageBeforeDraw;
  5.     Byte* cacheBitmap;
  6.     CGImageRef startedImage;
  7. }
  8.  
  9. - (void)allInits:(CGSize)size;
  10. - (void)drawBezierCurveWithPoint0:(CGPoint)p0 point1:(CGPoint)p1 point2:(CGPoint)p2 point3:(CGPoint)p3;
  11. - (void)drawToCache;
  12. - (void)eraseInPoint:(CGPoint)point;
  13. @end
  14.  
  15. @implementation DrawView
  16. @synthesize isErase;
  17. @synthesize brushColor;
  18. @synthesize brushSize;
  19.  
  20. - (BOOL) initContext:(CGSize)size {
  21.    
  22.     int bitmapByteCount;
  23.     int bitmapBytesPerRow;
  24.    
  25.     // Declare the number of bytes per row. Each pixel in the bitmap in this
  26.     // example is represented by 4 bytes; 8 bits each of red, green, blue, and
  27.     // alpha.
  28.     bitmapBytesPerRow = (size.width * 4);
  29.     bitmapByteCount = (bitmapBytesPerRow * size.height);
  30.    
  31.     // Allocate memory for image data. This is the destination in memory
  32.     // where any drawing to the bitmap context will be rendered.
  33.     cacheBitmap = malloc( bitmapByteCount );
  34.     if (cacheBitmap == NULL){
  35.         return NO;
  36.     }
  37.     for (int i=0; i<bitmapByteCount; i++) {
  38.         cacheBitmap[i]=255;
  39.     }
  40.     cacheContext = CGBitmapContextCreate (cacheBitmap, size.width, size.height, 8, bitmapBytesPerRow, CGColorSpaceCreateDeviceRGB(), (CGBitmapInfo)kCGImageAlphaNoneSkipFirst);
  41.     return YES;
  42. }
  43.  
  44. - (void) drawRect:(CGRect)rect {
  45.     // draw from cacheContext
  46.     CGContextRef context = UIGraphicsGetCurrentContext();
  47.     CGImageRef cacheImage = CGBitmapContextCreateImage(cacheContext);
  48.     CGContextDrawImage(context, self.bounds, cacheImage);
  49.     CGImageRelease(cacheImage);
  50. }
  51.  
  52. - (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
  53.     [self drawBezierCurveWithPoint0:nilPoint point1:nilPoint point2:nilPoint point3:[[touches anyObject] locationInView:self]];
  54. }
  55.  
  56. - (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
  57.     [self drawBezierCurveWithPoint0:point1 point1:point2 point2:point3 point3:[[touches anyObject] locationInView:self]];
  58. }
  59.  
  60. - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
  61.     [self drawBezierCurveWithPoint0:point1 point1:point2 point2:point3 point3:[[touches anyObject] locationInView:self]];
  62. }
  63.  
  64. - (void)drawBezierCurveWithPoint0:(CGPoint)p0 point1:(CGPoint)p1 point2:(CGPoint)p2 point3:(CGPoint)p3 {
  65.     point0 = p0;
  66.     point1 = p1;
  67.     point2 = p2;
  68.     point3 = p3;
  69.  
  70.     if (isErase) {
  71.         [self eraseInPoint:point3];
  72.     } else {
  73.         [self drawToCache];
  74.     }
  75. }
  76.  
  77. - (void) drawToCache {
  78.    
  79.     CGContextSetStrokeColorWithColor(cacheContext, [brushColor CGColor]);
  80.     CGContextSetLineCap(cacheContext, kCGLineCapRound);
  81.     CGContextSetLineWidth(cacheContext, brushSize);
  82.    
  83.     CGRect dirtyRect;
  84.    
  85.     if (point1.x > -1) {
  86.         // create cubic Bezier curve
  87.         double x0 = (point0.x > -1) ? point0.x : point1.x;
  88.         double y0 = (point0.y > -1) ? point0.y : point1.y;
  89.         double x1 = point1.x;
  90.         double y1 = point1.y;
  91.         double x2 = point2.x;
  92.         double y2 = point2.y;
  93.         double x3 = point3.x;
  94.         double y3 = point3.y;
  95.        
  96.         double xc1 = (x0 + x1) / 2.0;
  97.         double yc1 = (y0 + y1) / 2.0;
  98.         double xc2 = (x1 + x2) / 2.0;
  99.         double yc2 = (y1 + y2) / 2.0;
  100.         double xc3 = (x2 + x3) / 2.0;
  101.         double yc3 = (y2 + y3) / 2.0;
  102.        
  103.         double len1 = sqrt((x1-x0) * (x1-x0) + (y1-y0) * (y1-y0));
  104.         double len2 = sqrt((x2-x1) * (x2-x1) + (y2-y1) * (y2-y1));
  105.         double len3 = sqrt((x3-x2) * (x3-x2) + (y3-y2) * (y3-y2));
  106.        
  107.         double k1 = len1 / (len1 + len2);
  108.         double k2 = len2 / (len2 + len3);
  109.        
  110.         double xm1 = xc1 + (xc2 - xc1) * k1;
  111.         double ym1 = yc1 + (yc2 - yc1) * k1;
  112.         double xm2 = xc2 + (xc3 - xc2) * k2;
  113.         double ym2 = yc2 + (yc3 - yc2) * k2;
  114.        
  115.         double smooth_value = 0.5;
  116.         float ctrl1_x = xm1 + (xc2 - xm1) * smooth_value + x1 - xm1;
  117.         float ctrl1_y = ym1 + (yc2 - ym1) * smooth_value + y1 - ym1;
  118.         float ctrl2_x = xm2 + (xc2 - xm2) * smooth_value + x2 - xm2;
  119.         float ctrl2_y = ym2 + (yc2 - ym2) * smooth_value + y2 - ym2;
  120.        
  121.         CGContextMoveToPoint(cacheContext, point1.x, point1.y);
  122.         CGContextAddCurveToPoint(cacheContext, ctrl1_x, ctrl1_y, ctrl2_x, ctrl2_y, point2.x, point2.y);
  123.         CGContextStrokePath(cacheContext);
  124.        
  125.         int DRx,DRy,DRw,DRh;
  126.         DRx = (point1.x<point2.x?point1.x:point2.x) - brushSize;
  127.         DRy = (point1.y<point2.y?point1.y:point2.y) - brushSize;
  128.         DRw = abs(point1.x-point2.x)+2*brushSize;
  129.         DRh = abs(point1.y - point2.y) + 2*brushSize;
  130.         dirtyRect = CGRectMake(DRx, DRy, DRw, DRh);
  131.     } else {
  132.         //draw point
  133.         dirtyRect = CGRectMake(point3.x-brushSize/2, point3.y-brushSize/2, brushSize, brushSize);
  134.         CGContextMoveToPoint(cacheContext, point3.x, point3.y);
  135.         CGContextAddLineToPoint(cacheContext, point3.x, point3.y);
  136.         CGContextStrokePath(cacheContext);
  137.     }
  138.     [self setNeedsDisplayInRect:dirtyRect];
  139. }
  140.  
  141. - (void)eraseInPoint:(CGPoint)point {
  142.     float x = point.x-brushSize/2, y = point.y-brushSize/2;
  143.     float width = brushSize, height = brushSize;
  144.  
  145.     CGRect dirtyRect = CGRectMake(x, y, width, height);
  146.     CGRect drawRect = dirtyRect;
  147.     drawRect.origin.y = self.bounds.size.height-drawRect.origin.y-drawRect.size.height;
  148.     CGImageRef erase = CGImageCreateWithImageInRect(startedImage, drawRect);
  149.     CGContextDrawImage(cacheContext, dirtyRect, erase);
  150.     CGImageRelease(erase);
  151.    
  152.     [self setNeedsDisplayInRect:dirtyRect];
  153. }
  154.  
  155. - (void)setStartedImage:(CGImageRef)image {
  156.     [undoArray removeAllObjects];
  157.     [redoArray removeAllObjects];
  158.    
  159.     CGContextDrawImage(cacheContext, [self bounds], image);
  160.    
  161.     // change image origin point
  162.     int height = self.bounds.size.height;
  163.     int width = self.bounds.size.width;
  164.     int bitmapBytesPerRow = (width * 4);
  165.     int tmp;
  166.     for (int i=0; i<height/2+height%2; i++) {
  167.         for (int j=0; j<bitmapBytesPerRow; j++) {
  168.             tmp = cacheBitmap[i*bitmapBytesPerRow + j];;
  169.             cacheBitmap[i*bitmapBytesPerRow + j] = cacheBitmap[j+ bitmapBytesPerRow*(height-i-1)];
  170.             cacheBitmap[j+bitmapBytesPerRow*(height-i-1)]=tmp;
  171.         }
  172.     }
  173.    
  174.     CGImageRelease(startedImage);
  175.     startedImage = CGBitmapContextCreateImage(cacheContext);
  176.     [self setNeedsDisplay];
  177. }
  178. @end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement