CSignatureDrawView.m 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. //
  2. // CSignatureDrawView.m
  3. // compdfkit-tools
  4. //
  5. // Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
  6. //
  7. // THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
  8. // AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
  9. // UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
  10. // This notice may not be removed from this file.
  11. //
  12. #import "CSignatureDrawView.h"
  13. static CGPoint _points[5];
  14. static NSInteger _index;
  15. @interface CSignatureDrawView ()
  16. @property (nonatomic, strong) UIBezierPath *bezierPath;
  17. @end
  18. @implementation CSignatureDrawView
  19. #pragma mark - Initializers
  20. - (instancetype)initWithFrame:(CGRect)frame {
  21. if (self = [super initWithFrame:frame]) {
  22. self.bezierPath = [[UIBezierPath alloc] init];
  23. self.lineWidth = 1;
  24. self.backgroundColor = [UIColor whiteColor];
  25. }
  26. return self;
  27. }
  28. - (void)layoutSubviews {
  29. [super layoutSubviews];
  30. [self setNeedsDisplayInRect:self.bounds];
  31. }
  32. - (void)drawRect:(CGRect)rect {
  33. [super drawRect:rect];
  34. if (CSignatureDrawText == self.selectIndex) {
  35. [self.color set];
  36. [self.bezierPath setLineWidth:self.lineWidth];
  37. [self.bezierPath setLineCapStyle:kCGLineCapRound];
  38. [self.bezierPath setLineJoinStyle:kCGLineJoinRound];
  39. [self.bezierPath stroke];
  40. } else if (CSignatureDrawImage) {
  41. if (self.image) {
  42. CGRect imageFrame = [self imageFrameInRect:rect];
  43. [self.image drawInRect:imageFrame];
  44. }
  45. }
  46. }
  47. #pragma mark - Draw Methods
  48. - (CGRect)imageFrameInRect:(CGRect)rect {
  49. CGRect imageRect;
  50. if (self.image.size.width < rect.size.width &&
  51. self.image.size.height < rect.size.height) {
  52. imageRect.origin.x = (rect.size.width-self.image.size.width)/2.0;
  53. imageRect.origin.y = (rect.size.height-self.image.size.height)/2.0;
  54. imageRect.size = self.image.size;
  55. } else {
  56. if (self.image.size.width/self.image.size.height >
  57. rect.size.width/rect.size.height) {
  58. imageRect.size.width = rect.size.width;
  59. imageRect.size.height = rect.size.width*self.image.size.height/self.image.size.width;
  60. } else {
  61. imageRect.size.height = rect.size.height;
  62. imageRect.size.width = rect.size.height*self.image.size.width/self.image.size.height;
  63. }
  64. imageRect.origin.x = (rect.size.width-imageRect.size.width)/2.0;
  65. imageRect.origin.y = (rect.size.height-imageRect.size.height)/2.0;
  66. }
  67. return imageRect;
  68. }
  69. #pragma mark - Public Methods
  70. - (UIImage *)signatureImage {
  71. CGRect rect = CGRectZero;
  72. CGRect imageFrame = [self imageFrameInRect:self.frame];
  73. if (self.image) {
  74. if (self.bezierPath.empty) {
  75. rect = imageFrame;
  76. } else {
  77. CGRect pathFrame = self.bezierPath.bounds;
  78. rect.origin.x = MIN(CGRectGetMinX(imageFrame), CGRectGetMinX(pathFrame));
  79. rect.origin.y = MIN(CGRectGetMinY(imageFrame), CGRectGetMinY(pathFrame));
  80. rect.size.width = MAX(CGRectGetMaxX(imageFrame), CGRectGetMaxX(pathFrame))-rect.origin.x;
  81. rect.size.height = MAX(CGRectGetMaxY(imageFrame), CGRectGetMaxY(pathFrame))-rect.origin.y;
  82. }
  83. } else {
  84. if (self.bezierPath.empty) {
  85. return nil;
  86. } else {
  87. rect = self.bezierPath.bounds;
  88. }
  89. }
  90. CGSize size = CGSizeMake(rect.size.width+self.bezierPath.lineWidth,
  91. rect.size.height+self.bezierPath.lineWidth);
  92. UIGraphicsBeginImageContext(size);
  93. CGContextRef context = UIGraphicsGetCurrentContext();
  94. CGAffineTransform transform = CGAffineTransformMakeTranslation(-rect.origin.x+self.bezierPath.lineWidth/2.0, -rect.origin.y+self.bezierPath.lineWidth/2.0);
  95. CGContextConcatCTM(context, transform);
  96. if (self.image) {
  97. [self.image drawInRect:imageFrame];
  98. }
  99. if (!self.bezierPath.empty) {
  100. CGContextSetStrokeColorWithColor(context, self.color.CGColor);
  101. CGContextSetLineWidth(context, self.bezierPath.lineWidth);
  102. CGContextSetLineCap(context, self.bezierPath.lineCapStyle);
  103. CGContextSetLineJoin(context, self.bezierPath.lineJoinStyle);
  104. CGContextAddPath(context, self.bezierPath.CGPath);
  105. CGContextStrokePath(context);
  106. }
  107. UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
  108. UIGraphicsEndImageContext();
  109. return image;
  110. }
  111. #pragma mark - Public Methods
  112. - (void)signatureClear {
  113. self.image = nil;
  114. [self.bezierPath removeAllPoints];
  115. [self setNeedsDisplay];
  116. }
  117. #pragma mark - Action
  118. - (void)buttonItemClicked_clear:(UIButton *)button {
  119. self.image = nil;
  120. [self.bezierPath removeAllPoints];
  121. [self setNeedsDisplay];
  122. }
  123. #pragma mark - Touch Methods
  124. - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
  125. [super touchesBegan:touches withEvent:event];
  126. CGPoint point = [[touches anyObject] locationInView:self];
  127. _index = 0;
  128. _points[0] = point;
  129. }
  130. - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
  131. [super touchesMoved:touches withEvent:event];
  132. CGPoint point = [[touches anyObject] locationInView:self];
  133. _index++;
  134. _points[_index] = point;
  135. if (_index == 4) {
  136. _points[3] = CGPointMake((_points[2].x + _points[4].x)/2.0,
  137. (_points[2].y + _points[4].y)/2.0);
  138. [self.bezierPath moveToPoint:_points[0]];
  139. [self.bezierPath addCurveToPoint:_points[3]
  140. controlPoint1:_points[1]
  141. controlPoint2:_points[2]];
  142. _points[0] = _points[3];
  143. _points[1] = _points[4];
  144. _index = 1;
  145. [self setNeedsDisplay];
  146. }
  147. }
  148. - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
  149. [super touchesEnded:touches withEvent:event];
  150. if (_index < 4) {
  151. for (int i=0; i<_index; i++) {
  152. [self.bezierPath moveToPoint:_points[i]];
  153. }
  154. [self setNeedsDisplay];
  155. }
  156. }
  157. @end