// // PDFSignatureDrawView.m // PDFReader // // Copyright © 2014-2022 PDF Technologies, Inc. All Rights Reserved. // // The PDF Reader Sample applications are licensed with a modified BSD license. // Please see License for details. This notice may not be removed from this file. // #import "PDFSignatureDrawView.h" static CGPoint _points[5]; static NSInteger _index; @interface PDFSignatureDrawView () @property (nonatomic,retain) UIBezierPath *bezierPath; @end @implementation PDFSignatureDrawView #pragma mark - Init Methods - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { _bezierPath = [[UIBezierPath alloc] init]; _color = [[UIColor blackColor] retain]; _lineWidth = 5; } return self; } - (instancetype)initWithCoder:(NSCoder *)aDecoder { if (self = [super initWithCoder:aDecoder]) { _bezierPath = [[UIBezierPath alloc] init]; _color = [[UIColor blackColor] retain]; _lineWidth = 5; } return self; } - (void)dealloc { [_image release]; [_color release]; [_bezierPath release]; [super dealloc]; } #pragma mark - Draw Methods - (void)layoutSubviews { [super layoutSubviews]; [self setNeedsDisplay]; } - (void)drawRect:(CGRect)rect { [super drawRect:rect]; if (self.image) { CGRect imageFrame = [self imageFrameInRect:rect]; [self.image drawInRect:imageFrame]; } [self.color set]; [self.bezierPath setLineWidth:self.lineWidth]; [self.bezierPath setLineCapStyle:kCGLineCapRound]; [self.bezierPath setLineJoinStyle:kCGLineJoinRound]; [self.bezierPath stroke]; } - (CGRect)imageFrameInRect:(CGRect)rect { CGRect imageRect; if (self.image.size.width < rect.size.width && self.image.size.height < rect.size.height) { imageRect.origin.x = (rect.size.width-self.image.size.width)/2.0; imageRect.origin.y = (rect.size.height-self.image.size.height)/2.0; imageRect.size = self.image.size; } else { if (self.image.size.width/self.image.size.height > rect.size.width/rect.size.height) { imageRect.size.width = rect.size.width; imageRect.size.height = rect.size.width*self.image.size.height/self.image.size.width; } else { imageRect.size.height = rect.size.height; imageRect.size.width = rect.size.height*self.image.size.width/self.image.size.height; } imageRect.origin.x = (rect.size.width-imageRect.size.width)/2.0; imageRect.origin.y = (rect.size.height-imageRect.size.height)/2.0; } return imageRect; } #pragma mark - Public Mehtods - (UIImage *)signatureImage { CGRect rect = CGRectZero; CGRect imageFrame = [self imageFrameInRect:self.frame]; if (self.image) { if (self.bezierPath.empty) { rect = imageFrame; } else { CGRect pathFrame = self.bezierPath.bounds; rect.origin.x = MIN(CGRectGetMinX(imageFrame), CGRectGetMinX(pathFrame)); rect.origin.y = MIN(CGRectGetMinY(imageFrame), CGRectGetMinY(pathFrame)); rect.size.width = MAX(CGRectGetMaxX(imageFrame), CGRectGetMaxX(pathFrame))-rect.origin.x; rect.size.height = MAX(CGRectGetMaxY(imageFrame), CGRectGetMaxY(pathFrame))-rect.origin.y; } } else { if (self.bezierPath.empty) { return nil; } else { rect = self.bezierPath.bounds; } } CGSize size = CGSizeMake(rect.size.width+self.bezierPath.lineWidth, rect.size.height+self.bezierPath.lineWidth); UIGraphicsBeginImageContext(size); CGContextRef context = UIGraphicsGetCurrentContext(); CGAffineTransform transform = CGAffineTransformMakeTranslation(-rect.origin.x+self.bezierPath.lineWidth/2.0, -rect.origin.y+self.bezierPath.lineWidth/2.0); CGContextConcatCTM(context, transform); if (self.image) { [self.image drawInRect:imageFrame]; } if (!self.bezierPath.empty) { CGContextSetStrokeColorWithColor(context, self.color.CGColor); CGContextSetLineWidth(context, self.bezierPath.lineWidth); CGContextSetLineCap(context, self.bezierPath.lineCapStyle); CGContextSetLineJoin(context, self.bezierPath.lineJoinStyle); CGContextAddPath(context, self.bezierPath.CGPath); CGContextStrokePath(context); } UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; } - (void)clear { self.image = nil; [self.bezierPath removeAllPoints]; [self setNeedsDisplay]; } - (void)setColor:(UIColor *)color { if (_color != color) { [_color release]; _color = [color retain]; } [self setNeedsDisplay]; } - (void)setLineWidth:(CGFloat)lineWidth { _lineWidth = lineWidth; [self setNeedsDisplay]; } - (void)setImage:(UIImage *)image { if (_image != image) { [_image release]; _image = [image retain]; } [self setNeedsDisplay]; } #pragma mark - Touch Methods - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [super touchesBegan:touches withEvent:event]; CGPoint point = [[touches anyObject] locationInView:self]; _index = 0; _points[0] = point; } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { [super touchesMoved:touches withEvent:event]; CGPoint point = [[touches anyObject] locationInView:self]; _index++; _points[_index] = point; if (_index == 4) { _points[3] = CGPointMake((_points[2].x + _points[4].x)/2.0, (_points[2].y + _points[4].y)/2.0); [self.bezierPath moveToPoint:_points[0]]; [self.bezierPath addCurveToPoint:_points[3] controlPoint1:_points[1] controlPoint2:_points[2]]; _points[0] = _points[3]; _points[1] = _points[4]; _index = 1; [self setNeedsDisplay]; } } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { [super touchesEnded:touches withEvent:event]; if (_index < 4) { for (int i=0; i<_index; i++) { [self.bezierPath moveToPoint:_points[i]]; } [self setNeedsDisplay]; } } @end