PDFListView.m 69 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462
  1. //
  2. // PDFListView.m
  3. // PDFReader
  4. //
  5. // Copyright © 2014-2022 PDF Technologies, Inc. All Rights Reserved.
  6. //
  7. // The PDF Reader Sample applications are licensed with a modified BSD license.
  8. // Please see License for details. This notice may not be removed from this file.
  9. //
  10. #import "PDFListView.h"
  11. #import <MobileCoreServices/UTCoreTypes.h>
  12. #import "PDFMagnifierView.h"
  13. typedef NS_ENUM(NSInteger, PDFAnnotationDraggingType) {
  14. PDFAnnotationDraggingNone = 0,
  15. PDFAnnotationDraggingCenter,
  16. PDFAnnotationDraggingTopLeft,
  17. PDFAnnotationDraggingTopRight,
  18. PDFAnnotationDraggingBottomLeft,
  19. PDFAnnotationDraggingBottomRight,
  20. PDFAnnotationDraggingStart,
  21. PDFAnnotationDraggingEnd
  22. };
  23. @interface PDFListView ()
  24. @property (nonatomic,assign) PDFAnnotationDraggingType draggingType;
  25. @property (nonatomic,assign) CGPoint draggingPoint;
  26. @property (nonatomic,assign) CGRect topLeftRect;
  27. @property (nonatomic,assign) CGRect bottomLeftRect;
  28. @property (nonatomic,assign) CGRect topRightRect;
  29. @property (nonatomic,assign) CGRect bottomRightRect;
  30. @property (nonatomic,assign) CGRect startPointRect;
  31. @property (nonatomic,assign) CGRect endPointRect;
  32. @property (nonatomic,assign) CGPoint addLinkPoint;
  33. @property (nonatomic,assign) CGRect addLinkRect;
  34. @property (nonatomic,retain) CPDFAnnotation *menuAnnotation;
  35. @property (nonatomic,assign) CGPoint menuPoint;
  36. @property (nonatomic,assign) CPDFPage *menuPage;
  37. @property (nonatomic,retain) PDFMagnifierView *magnifierView;
  38. @end
  39. @implementation PDFListView
  40. #pragma mark - Initializers
  41. - (instancetype)initWithFrame:(CGRect)frame {
  42. if (self = [super initWithFrame:frame]) {
  43. }
  44. return self;
  45. }
  46. - (void)dealloc {
  47. [_magnifierView release];
  48. [_activeAnnotation release];
  49. [_menuAnnotation release];
  50. [_addAnnotation release];
  51. [super dealloc];
  52. }
  53. #pragma mark - Accessors
  54. - (void)setAnnotationMode:(PDFViewAnnotationMode)annotationMode {
  55. _annotationMode = annotationMode;
  56. if (PDFViewAnnotationModeHighlight == annotationMode ||
  57. PDFViewAnnotationModeUnderline == annotationMode ||
  58. PDFViewAnnotationModeStrikeout == annotationMode ||
  59. PDFViewAnnotationModeSquiggly == annotationMode) {
  60. self.textSelectionMode = YES;
  61. } else {
  62. self.textSelectionMode = NO;
  63. }
  64. if (PDFViewAnnotationModeLink == annotationMode) {
  65. self.scrollEnabled = NO;
  66. [self endDrawing];
  67. } else if (PDFViewAnnotationModeInk == annotationMode) {
  68. self.scrollEnabled = NO;
  69. [self beginDrawing];
  70. } else {
  71. if (self.activeAnnotation) {
  72. self.scrollEnabled = NO;
  73. } else {
  74. self.scrollEnabled = YES;
  75. }
  76. [self endDrawing];
  77. [self becomeFirstResponder];
  78. }
  79. // 取消注释选中状态
  80. if (PDFViewAnnotationModeNone != annotationMode) {
  81. CPDFPage *page = self.activeAnnotation.page;
  82. self.activeAnnotation = nil;
  83. [self setNeedsDisplayForPage:page];
  84. }
  85. }
  86. - (void)updateScrollEnabled {
  87. if (self.activeAnnotation) {
  88. self.scrollEnabled = NO;
  89. } else {
  90. if (PDFViewAnnotationModeLink == self.annotationMode) {
  91. self.scrollEnabled = NO;
  92. } else {
  93. self.scrollEnabled = YES;
  94. }
  95. }
  96. }
  97. - (NSString *)annotationUserName {
  98. NSString *annotationUserName = CPDFKitShareConfig.annotationAuthor;
  99. if (!annotationUserName || [annotationUserName length] <= 0) {
  100. annotationUserName = [[UIDevice currentDevice] name];
  101. }
  102. return annotationUserName ? : @"";
  103. }
  104. - (UIImage *)compressImage:(UIImage *)image size:(CGSize)size {
  105. CGFloat imageScale = 1.0;
  106. if (image.size.width > size.width || image.size.height > size.height) {
  107. imageScale = MIN(size.width / image.size.width, size.height / image.size.height);
  108. }
  109. CGSize newSize = CGSizeMake(image.size.width * imageScale, image.size.height * imageScale);
  110. UIGraphicsBeginImageContext(newSize);
  111. [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
  112. UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
  113. UIGraphicsEndImageContext();
  114. return newImage;
  115. }
  116. - (void)goToPageIndex:(NSInteger)pageIndex animated:(BOOL)animated {
  117. if ([self.performDelegate respondsToSelector:@selector(PDFViewPerformWillGoTo:pageIndex:)]) {
  118. [self.performDelegate PDFViewPerformWillGoTo:self pageIndex:pageIndex];
  119. }
  120. [super goToPageIndex:pageIndex animated:animated];
  121. }
  122. #pragma mark - Magnifier
  123. - (void)addMagnifierAtPoint:(CGPoint)point forPage:(CPDFPage *)page {
  124. if (!_magnifierView) {
  125. _magnifierView = [[PDFMagnifierView alloc] init];
  126. _magnifierView.style = PDFMagnifierViewStyleCircle;
  127. }
  128. point = [self convertPoint:point fromPage:page];
  129. CGPoint center = [self convertPoint:point toView:self.superview];
  130. self.magnifierView.scale = 1.0;
  131. self.magnifierView.pointToMagnify = point;
  132. self.magnifierView.viewToMagnify = self;
  133. self.magnifierView.center = CGPointMake(center.x, center.y - self.magnifierView.frame.size.height/2.0 - 20);
  134. if ([self.magnifierView superview]) {
  135. [self.magnifierView setNeedsDisplay];
  136. } else {
  137. [self.superview addSubview:self.magnifierView];
  138. }
  139. }
  140. - (void)removeMagnifier {
  141. [self.magnifierView removeFromSuperview];
  142. self.magnifierView = nil;
  143. }
  144. #pragma mark - Rendering
  145. - (void)drawPage:(CPDFPage *)page toContext:(CGContextRef)context {
  146. if (PDFViewAnnotationModeLink == self.annotationMode) {
  147. CGContextSetLineWidth(context, 1.0);
  148. CGContextSetStrokeColorWithColor(context, [UIColor colorWithRed:255.0/255.f green:255.0/255.f blue:255.0/255.f alpha:0.8].CGColor);
  149. CGContextSetFillColorWithColor(context, [UIColor colorWithRed:100.0/255.f green:149.0/255.f blue:237.0/255.f alpha:0.4].CGColor);
  150. CGContextAddRect(context, self.addLinkRect);
  151. CGContextDrawPath(context, kCGPathFillStroke);
  152. }
  153. if (self.activeAnnotation.page != page) {
  154. return;
  155. }
  156. CGSize dragDotSize = CGSizeMake(30, 30);
  157. CGContextSetStrokeColorWithColor(context, [UIColor colorWithRed:72.0/255.0 green:183.0/255.0 blue:247.0/255.0 alpha:1.0].CGColor);
  158. if ([self.activeAnnotation isKindOfClass:[CPDFLineAnnotation class]]) {
  159. CPDFLineAnnotation *line = (CPDFLineAnnotation *)self.activeAnnotation;
  160. CGPoint startPoint = line.startPoint;
  161. CGPoint endPoint = line.endPoint;
  162. CGPoint tStartPoint = startPoint;
  163. CGPoint tEndPoint = endPoint;
  164. float final = 40;
  165. if (fabs(tStartPoint.x - tEndPoint.x) < 0.00001) {
  166. if (tStartPoint.y > tEndPoint.y) {
  167. tStartPoint.y += final;
  168. tEndPoint.y -= final;
  169. } else {
  170. tStartPoint.y -= final;
  171. tEndPoint.y += final;
  172. }
  173. } else if (fabs(tStartPoint.y - tEndPoint.y) < 0.00001) {
  174. if (tStartPoint.x > tEndPoint.x) {
  175. tStartPoint.x += final;
  176. tEndPoint.x -= final;
  177. } else {
  178. tStartPoint.x -= final;
  179. tEndPoint.x += final;
  180. }
  181. } else {
  182. double k = (tEndPoint.y - tStartPoint.y)/(tEndPoint.x - tStartPoint.x);
  183. double atank = atan(k);
  184. if (endPoint.x > startPoint.x) {
  185. tEndPoint.x += cos(atank) * final;
  186. tEndPoint.y += sin(atank) * final;
  187. tStartPoint.x -= cos(atank) * final;
  188. tStartPoint.y -= sin(atank) * final;
  189. } else {
  190. tEndPoint.x -= cos(atank) * final;
  191. tEndPoint.y -= sin(atank) * final;
  192. tStartPoint.x += cos(atank) * final;
  193. tStartPoint.y += sin(atank) * final;
  194. }
  195. }
  196. CGContextSetLineWidth(context, 1.0);
  197. CGFloat dashArray[] = {3,3};
  198. CGContextSetLineDash(context, 0, dashArray, 2);
  199. CGContextMoveToPoint(context, tStartPoint.x, tStartPoint.y);
  200. CGContextAddLineToPoint(context, startPoint.x, startPoint.y);
  201. CGContextStrokePath(context);
  202. CGContextMoveToPoint(context, tEndPoint.x, tEndPoint.y);
  203. CGContextAddLineToPoint(context, endPoint.x, endPoint.y);
  204. CGContextStrokePath(context);
  205. CGRect startPointRect = CGRectMake(tStartPoint.x - dragDotSize.width/2.0,
  206. tStartPoint.y - dragDotSize.height/2.0,
  207. dragDotSize.width, dragDotSize.height);
  208. CGRect endPointRect = CGRectMake(tEndPoint.x - dragDotSize.width/2.0,
  209. tEndPoint.y - dragDotSize.height/2.0,
  210. dragDotSize.width, dragDotSize.height);
  211. UIImage *image = [UIImage imageNamed:@"annotation_drag_dot.png" inBundle:[NSBundle bundleForClass:self.class] compatibleWithTraitCollection:nil];
  212. CGImageRef dragDotImage = image.CGImage;
  213. CGContextDrawImage(context, startPointRect, dragDotImage);
  214. CGContextDrawImage(context, endPointRect, dragDotImage);
  215. self.startPointRect = startPointRect;
  216. self.endPointRect = endPointRect;
  217. } else if ([self.activeAnnotation isKindOfClass:[CPDFFreeTextAnnotation class]]) {
  218. CGRect rect = CGRectInset(self.activeAnnotation.bounds, -dragDotSize.width/2.0, -dragDotSize.height/2.0);
  219. CGContextSetLineWidth(context, 1.0);
  220. CGFloat lengths[] = {6, 6};
  221. CGContextSetLineDash(context, 0, lengths, 2);
  222. CGContextStrokeRect(context, rect);
  223. CGContextStrokePath(context);
  224. CGAffineTransform transform = [page transform];
  225. if (CPDFKitShareConfig.enableAnnotationNoRotate) {
  226. rect = CGRectApplyAffineTransform(rect, transform);
  227. }
  228. CGRect leftCenterRect = CGRectMake(CGRectGetMinX(rect)-dragDotSize.width/2.0,
  229. CGRectGetMidY(rect)-dragDotSize.height/2.0,
  230. dragDotSize.width, dragDotSize.height);
  231. CGRect rightCenterRect = CGRectMake(CGRectGetMaxX(rect)-dragDotSize.width/2.0,
  232. CGRectGetMidY(rect)-dragDotSize.height/2.0,
  233. dragDotSize.width, dragDotSize.height);
  234. if (CPDFKitShareConfig.enableAnnotationNoRotate) {
  235. leftCenterRect = CGRectApplyAffineTransform(leftCenterRect, CGAffineTransformInvert(transform));
  236. rightCenterRect = CGRectApplyAffineTransform(rightCenterRect, CGAffineTransformInvert(transform));
  237. }
  238. UIImage *image = [UIImage imageNamed:@"annotation_drag_dot.png" inBundle:[NSBundle bundleForClass:self.class] compatibleWithTraitCollection:nil];
  239. CGImageRef dragDotImage = image.CGImage;
  240. CGContextDrawImage(context, leftCenterRect, dragDotImage);
  241. CGContextDrawImage(context, rightCenterRect, dragDotImage);
  242. self.startPointRect = leftCenterRect;
  243. self.endPointRect = rightCenterRect;
  244. } else {
  245. CGRect rect = CGRectInset(self.activeAnnotation.bounds, -dragDotSize.width/2.0, -dragDotSize.height/2.0);
  246. CGContextSetLineWidth(context, 1.0);
  247. CGFloat lengths[] = {6, 6};
  248. CGContextSetLineDash(context, 0, lengths, 2);
  249. CGContextStrokeRect(context, rect);
  250. CGContextStrokePath(context);
  251. if ([self.activeAnnotation isKindOfClass:[CPDFSoundAnnotation class]] ||
  252. [self.activeAnnotation isKindOfClass:[CPDFMovieAnnotation class]]) {
  253. return;
  254. }
  255. CGRect topLeftRect = CGRectMake(CGRectGetMinX(rect)-dragDotSize.width/2.0,
  256. CGRectGetMaxY(rect)-dragDotSize.height/2.0,
  257. dragDotSize.width, dragDotSize.height);
  258. CGRect bottomLeftRect = CGRectMake(CGRectGetMinX(rect)-dragDotSize.width/2.0,
  259. CGRectGetMinY(rect)-dragDotSize.height/2.0,
  260. dragDotSize.width, dragDotSize.height);
  261. CGRect topRightRect = CGRectMake(CGRectGetMaxX(rect)-dragDotSize.width/2.0,
  262. CGRectGetMaxY(rect)-dragDotSize.height/2.0,
  263. dragDotSize.width, dragDotSize.height);
  264. CGRect bottomRightRect = CGRectMake(CGRectGetMaxX(rect)-dragDotSize.width/2.0,
  265. CGRectGetMinY(rect)-dragDotSize.height/2.0,
  266. dragDotSize.width, dragDotSize.height);
  267. UIImage *image = [UIImage imageNamed:@"annotation_drag_dot.png" inBundle:[NSBundle bundleForClass:self.class] compatibleWithTraitCollection:nil];
  268. CGImageRef dragDotImage = image.CGImage;
  269. CGContextDrawImage(context, topLeftRect, dragDotImage);
  270. CGContextDrawImage(context, bottomLeftRect, dragDotImage);
  271. CGContextDrawImage(context, topRightRect, dragDotImage);
  272. CGContextDrawImage(context, bottomRightRect, dragDotImage);
  273. self.topLeftRect = topLeftRect;
  274. self.bottomLeftRect = bottomLeftRect;
  275. self.topRightRect = topRightRect;
  276. self.bottomRightRect = bottomRightRect;
  277. }
  278. }
  279. #pragma mark - Touch
  280. - (void)touchBeganAtPoint:(CGPoint)point forPage:(CPDFPage *)page {
  281. if (self.textSelectionMode) {
  282. // 文本选取模式
  283. } else {
  284. self.addLinkPoint = point;
  285. self.addLinkRect = CGRectZero;
  286. self.draggingType = PDFAnnotationDraggingNone;
  287. if (!self.activeAnnotation || self.activeAnnotation.page != page) {
  288. return;
  289. }
  290. CGRect topLeftRect = CGRectInset(self.topLeftRect, -5, -5);
  291. CGRect bottomLeftRect = CGRectInset(self.bottomLeftRect, -5, -5);
  292. CGRect topRightRect = CGRectInset(self.topRightRect, -5, -5);
  293. CGRect bottomRightRect = CGRectInset(self.bottomRightRect, -5, -5);
  294. CGRect startPointRect = CGRectInset(self.startPointRect, -5, -5);
  295. CGRect endPointRect = CGRectInset(self.endPointRect, -5, -5);
  296. if (CGRectContainsPoint(topLeftRect, point)) {
  297. self.draggingType = PDFAnnotationDraggingTopLeft;
  298. } else if (CGRectContainsPoint(bottomLeftRect, point)) {
  299. self.draggingType = PDFAnnotationDraggingBottomLeft;
  300. } else if (CGRectContainsPoint(topRightRect, point)) {
  301. self.draggingType = PDFAnnotationDraggingTopRight;
  302. } else if (CGRectContainsPoint(bottomRightRect, point)) {
  303. self.draggingType = PDFAnnotationDraggingBottomRight;
  304. } else if (CGRectContainsPoint(startPointRect, point)) {
  305. self.draggingType = PDFAnnotationDraggingStart;
  306. } else if (CGRectContainsPoint(endPointRect, point)) {
  307. self.draggingType = PDFAnnotationDraggingEnd;
  308. } else if ([page annotation:self.activeAnnotation atPoint:point]) {
  309. self.draggingType = PDFAnnotationDraggingCenter;
  310. }
  311. self.draggingPoint = point;
  312. if (PDFAnnotationDraggingCenter == self.draggingType) {
  313. if ([self.activeAnnotation isKindOfClass:[CPDFFreeTextAnnotation class]] ||
  314. [self.activeAnnotation isKindOfClass:[CPDFSignatureAnnotation class]]) {
  315. [self addMagnifierAtPoint:point forPage:page];
  316. }
  317. }
  318. }
  319. }
  320. - (void)touchMovedAtPoint:(CGPoint)point forPage:(CPDFPage *)page {
  321. if (self.textSelectionMode) {
  322. // 文本选取模式
  323. } else if (PDFAnnotationDraggingNone != self.draggingType) {
  324. [self moveAnnotation:self.activeAnnotation fromPoint:self.draggingPoint toPoint:point forType:self.draggingType];
  325. [self setNeedsDisplayForPage:page];
  326. self.draggingPoint = point;
  327. if (PDFAnnotationDraggingCenter == self.draggingType) {
  328. if ([self.activeAnnotation isKindOfClass:[CPDFFreeTextAnnotation class]] ||
  329. [self.activeAnnotation isKindOfClass:[CPDFSignatureAnnotation class]]) {
  330. [self addMagnifierAtPoint:point forPage:page];
  331. }
  332. }
  333. } else if (PDFViewAnnotationModeLink == self.annotationMode) {
  334. CGRect rect = CGRectZero;
  335. if (point.x > self.addLinkPoint.x) {
  336. rect.origin.x = self.addLinkPoint.x;
  337. rect.size.width = point.x-self.addLinkPoint.x;
  338. } else {
  339. rect.origin.x = point.x;
  340. rect.size.width = self.addLinkPoint.x-point.x;
  341. }
  342. if (point.y > self.addLinkPoint.y) {
  343. rect.origin.y = self.addLinkPoint.y;
  344. rect.size.height = point.y-self.addLinkPoint.y;
  345. } else {
  346. rect.origin.y = point.y;
  347. rect.size.height = self.addLinkPoint.y-point.y;
  348. }
  349. self.addLinkRect = rect;
  350. [self setNeedsDisplayForPage:page];
  351. }
  352. }
  353. - (void)touchEndedAtPoint:(CGPoint)point forPage:(CPDFPage *)page {
  354. if (self.textSelectionMode) {
  355. // 文本选取模式,添加Markup注释
  356. if (self.currentSelection) {
  357. [self addAnnotation:self.annotationMode atPoint:point forPage:page];
  358. } else {
  359. CPDFAnnotation *annotation = [page annotationAtPoint:point];
  360. if ([annotation isKindOfClass:[CPDFMarkupAnnotation class]]) {
  361. [self showMenuForAnnotation:annotation];
  362. }
  363. }
  364. } else if (PDFAnnotationDraggingNone == self.draggingType) {
  365. if (self.activeAnnotation) {
  366. CPDFPage *previousPage = self.activeAnnotation.page;
  367. self.activeAnnotation = nil;
  368. [self setNeedsDisplayForPage:previousPage];
  369. [self updateScrollEnabled];
  370. } else {
  371. if (PDFViewAnnotationModeNone == self.annotationMode) {
  372. CPDFAnnotation *annotation = [page annotationAtPoint:point];
  373. if ([annotation isKindOfClass:[CPDFTextAnnotation class]]) {
  374. if ([self.performDelegate respondsToSelector:@selector(PDFViewPerformOpenNote:forAnnotation:)]) {
  375. [self.performDelegate PDFViewPerformOpenNote:self forAnnotation:annotation];
  376. }
  377. } else if ([annotation isKindOfClass:[CPDFMarkupAnnotation class]]) {
  378. if (CGRectContainsPoint(annotation.bounds, point)) {
  379. [self showMenuForAnnotation:annotation];
  380. } else {
  381. if ([self.performDelegate respondsToSelector:@selector(PDFViewPerformPopup:forAnnotation:)]) {
  382. [self.performDelegate PDFViewPerformPopup:self forAnnotation:(CPDFMarkupAnnotation *)annotation];
  383. }
  384. }
  385. } else if ([annotation isKindOfClass:[CPDFLinkAnnotation class]]) {
  386. [super touchEndedAtPoint:point forPage:page];
  387. } else if ([annotation isKindOfClass:[CPDFMovieAnnotation class]]) {
  388. [super touchEndedAtPoint:point forPage:page];
  389. } else if ([annotation isKindOfClass:[CPDFWidgetAnnotation class]]) {
  390. if ([annotation isKindOfClass:[CPDFSignatureWidgetAnnotation class]]) {
  391. if ([(CPDFSignatureWidgetAnnotation *)annotation isSigned]) {
  392. [self showMenuForAnnotation:annotation];
  393. } else {
  394. if ([self.performDelegate respondsToSelector:@selector(PDFViewPerformSignatureWidget:forAnnotation:)]) {
  395. [self.performDelegate PDFViewPerformSignatureWidget:self forAnnotation:(CPDFSignatureWidgetAnnotation *)annotation];
  396. }
  397. }
  398. } else {
  399. [super touchEndedAtPoint:point forPage:page];
  400. }
  401. } else {
  402. self.activeAnnotation = annotation;
  403. [self setNeedsDisplayForPage:page];
  404. [self updateScrollEnabled];
  405. [self showMenuForAnnotation:annotation];
  406. if (!self.activeAnnotation) {
  407. if ([self.performDelegate respondsToSelector:@selector(PDFViewPerformTouchEnded:)]) {
  408. [self.performDelegate PDFViewPerformTouchEnded:self];
  409. }
  410. }
  411. }
  412. } else if (PDFViewAnnotationModeLink == self.annotationMode) {
  413. if (CGRectIsEmpty(self.addLinkRect)) {
  414. CPDFAnnotation *annotation = [page annotationAtPoint:point];
  415. if ([annotation isKindOfClass:[CPDFLinkAnnotation class]]) {
  416. self.activeAnnotation = annotation;
  417. [self setNeedsDisplayForPage:page];
  418. [self updateScrollEnabled];
  419. [self showMenuForAnnotation:annotation];
  420. }
  421. } else {
  422. [self addAnnotationLinkAtPoint:point forPage:page];
  423. }
  424. } else if (PDFViewAnnotationModeFreeText == self.annotationMode) {
  425. [self addAnnotationFreeTextAtPoint:point forPage:page];
  426. } else if (PDFViewAnnotationModeStamp == self.annotationMode) {
  427. [self addAnnotationAtPoint:point forPage:page];
  428. if ([self.performDelegate respondsToSelector:@selector(PDFViewPerformTouchEnded:)]) {
  429. [self.performDelegate PDFViewPerformTouchEnded:self];
  430. }
  431. } else if (PDFViewAnnotationModeImage == self.annotationMode) {
  432. [self addAnnotationAtPoint:point forPage:page];
  433. if ([self.performDelegate respondsToSelector:@selector(PDFViewPerformTouchEnded:)]) {
  434. [self.performDelegate PDFViewPerformTouchEnded:self];
  435. }
  436. } else {
  437. [self addAnnotation:self.annotationMode atPoint:point forPage:page];
  438. }
  439. }
  440. } else {
  441. // 注释修改大小后,重新生成外观
  442. if (PDFAnnotationDraggingCenter != self.draggingType) {
  443. if ([self.activeAnnotation isKindOfClass:[CPDFFreeTextAnnotation class]] ||
  444. [self.activeAnnotation isKindOfClass:[CPDFStampAnnotation class]] ||
  445. [self.activeAnnotation isKindOfClass:[CPDFSignatureAnnotation class]]) {
  446. [self.activeAnnotation updateAppearanceStream];
  447. [self setNeedsDisplayForPage:page];
  448. }
  449. }
  450. self.draggingType = PDFAnnotationDraggingNone;
  451. [self showMenuForAnnotation:self.activeAnnotation];
  452. }
  453. [self removeMagnifier];
  454. }
  455. - (void)touchCancelledAtPoint:(CGPoint)point forPage:(CPDFPage *)page {
  456. self.draggingType = PDFAnnotationDraggingNone;
  457. [self removeMagnifier];
  458. }
  459. #pragma mark - Annotation
  460. - (void)moveAnnotation:(CPDFAnnotation *)annotation fromPoint:(CGPoint)fromPoint toPoint:(CGPoint)toPoint forType:(PDFAnnotationDraggingType)draggingType {
  461. CGRect bounds = annotation.bounds;
  462. CGPoint offsetPoint = CGPointMake(toPoint.x - fromPoint.x, toPoint.y - fromPoint.y);
  463. CGFloat scale = bounds.size.height/bounds.size.width;
  464. if ([annotation isKindOfClass:[CPDFLineAnnotation class]]) {
  465. CPDFLineAnnotation *line = (CPDFLineAnnotation *)annotation;
  466. CGPoint startPoint = line.startPoint;
  467. CGPoint endPoint = line.endPoint;
  468. switch (draggingType) {
  469. case PDFAnnotationDraggingCenter:
  470. {
  471. startPoint.x += offsetPoint.x;
  472. startPoint.y += offsetPoint.y;
  473. endPoint.x += offsetPoint.x;
  474. endPoint.y += offsetPoint.y;
  475. }
  476. break;
  477. case PDFAnnotationDraggingStart:
  478. {
  479. startPoint.x += offsetPoint.x;
  480. startPoint.y += offsetPoint.y;
  481. }
  482. break;
  483. case PDFAnnotationDraggingEnd:
  484. {
  485. endPoint.x += offsetPoint.x;
  486. endPoint.y += offsetPoint.y;
  487. }
  488. break;
  489. default:
  490. break;
  491. }
  492. line.startPoint = startPoint;
  493. line.endPoint = endPoint;
  494. bounds = line.bounds;
  495. } else if ([annotation isKindOfClass:[CPDFFreeTextAnnotation class]]) {
  496. CGAffineTransform transform = [annotation.page transform];
  497. if (CPDFKitShareConfig.enableAnnotationNoRotate) {
  498. bounds = CGRectApplyAffineTransform(bounds, transform);
  499. toPoint = CGPointApplyAffineTransform(toPoint, transform);
  500. fromPoint = CGPointApplyAffineTransform(fromPoint, transform);
  501. offsetPoint = CGPointMake(toPoint.x - fromPoint.x, toPoint.y - fromPoint.y);
  502. }
  503. CPDFFreeTextAnnotation *freeText = (CPDFFreeTextAnnotation *)annotation;
  504. NSDictionary *attributes = @{NSFontAttributeName : freeText.font};
  505. switch (draggingType) {
  506. case PDFAnnotationDraggingCenter:
  507. {
  508. bounds.origin.x += offsetPoint.x;
  509. bounds.origin.y += offsetPoint.y;
  510. }
  511. break;
  512. case PDFAnnotationDraggingStart:
  513. {
  514. CGFloat x = CGRectGetMaxX(bounds);
  515. bounds.size.width -= offsetPoint.x;
  516. bounds.size.width = MAX(bounds.size.width, 5.0);
  517. bounds.origin.x = x - bounds.size.width;
  518. CGRect rect = [freeText.contents boundingRectWithSize:CGSizeMake(bounds.size.width, CGFLOAT_MAX)
  519. options:NSStringDrawingUsesLineFragmentOrigin
  520. attributes:attributes
  521. context:nil];
  522. bounds.origin.y = CGRectGetMaxY(bounds) - rect.size.height;
  523. bounds.size.height = rect.size.height;
  524. }
  525. break;
  526. case PDFAnnotationDraggingEnd:
  527. {
  528. bounds.size.width += offsetPoint.x;
  529. bounds.size.width = MAX(bounds.size.width, 5.0);
  530. CGRect rect = [freeText.contents boundingRectWithSize:CGSizeMake(bounds.size.width, CGFLOAT_MAX)
  531. options:NSStringDrawingUsesLineFragmentOrigin
  532. attributes:attributes
  533. context:nil];
  534. bounds.origin.y = CGRectGetMaxY(bounds) - rect.size.height;
  535. bounds.size.height = rect.size.height;
  536. }
  537. break;
  538. default:
  539. break;
  540. }
  541. if (CPDFKitShareConfig.enableAnnotationNoRotate) {
  542. bounds = CGRectApplyAffineTransform(bounds, CGAffineTransformInvert(transform));
  543. }
  544. } else {
  545. switch (draggingType) {
  546. case PDFAnnotationDraggingCenter:
  547. {
  548. bounds.origin.x += offsetPoint.x;
  549. bounds.origin.y += offsetPoint.y;
  550. }
  551. break;
  552. case PDFAnnotationDraggingTopLeft:
  553. {
  554. CGFloat x = CGRectGetMaxX(bounds);
  555. bounds.size.width -= offsetPoint.x;
  556. bounds.size.height += offsetPoint.y;
  557. if ([annotation isKindOfClass:[CPDFStampAnnotation class]] ||
  558. [annotation isKindOfClass:[CPDFSignatureAnnotation class]] ||
  559. [annotation isKindOfClass:[CPDFInkAnnotation class]]) {
  560. bounds.size.height = bounds.size.width*scale;
  561. bounds.size.width = MAX(bounds.size.width, 5.0);
  562. bounds.size.height = MAX(bounds.size.height, 5.0*scale);
  563. } else {
  564. bounds.size.width = MAX(bounds.size.width, 5.0);
  565. bounds.size.height = MAX(bounds.size.height, 5.0);
  566. }
  567. bounds.origin.x = x - bounds.size.width;
  568. }
  569. break;
  570. case PDFAnnotationDraggingBottomLeft:
  571. {
  572. CGFloat x = CGRectGetMaxX(bounds);
  573. CGFloat y = CGRectGetMaxY(bounds);
  574. bounds.size.width -= offsetPoint.x;
  575. bounds.size.height -= offsetPoint.y;
  576. if ([annotation isKindOfClass:[CPDFStampAnnotation class]] ||
  577. [annotation isKindOfClass:[CPDFSignatureAnnotation class]] ||
  578. [annotation isKindOfClass:[CPDFInkAnnotation class]]) {
  579. bounds.size.height = bounds.size.width*scale;
  580. bounds.size.width = MAX(bounds.size.width, 5.0);
  581. bounds.size.height = MAX(bounds.size.height, 5.0*scale);
  582. } else {
  583. bounds.size.width = MAX(bounds.size.width, 5.0);
  584. bounds.size.height = MAX(bounds.size.height, 5.0);
  585. }
  586. bounds.origin.x = x - bounds.size.width;
  587. bounds.origin.y = y - bounds.size.height;
  588. }
  589. break;
  590. case PDFAnnotationDraggingTopRight:
  591. {
  592. bounds.size.width += offsetPoint.x;
  593. bounds.size.height += offsetPoint.y;
  594. if ([annotation isKindOfClass:[CPDFStampAnnotation class]] ||
  595. [annotation isKindOfClass:[CPDFSignatureAnnotation class]] ||
  596. [annotation isKindOfClass:[CPDFInkAnnotation class]]) {
  597. bounds.size.height = bounds.size.width*scale;
  598. bounds.size.width = MAX(bounds.size.width, 5.0);
  599. bounds.size.height = MAX(bounds.size.height, 5.0*scale);
  600. } else {
  601. bounds.size.width = MAX(bounds.size.width, 5.0);
  602. bounds.size.height = MAX(bounds.size.height, 5.0);
  603. }
  604. }
  605. break;
  606. case PDFAnnotationDraggingBottomRight:
  607. {
  608. CGFloat y = CGRectGetMaxY(bounds);
  609. bounds.size.width += offsetPoint.x;
  610. bounds.size.height -= offsetPoint.y;
  611. if ([annotation isKindOfClass:[CPDFStampAnnotation class]] ||
  612. [annotation isKindOfClass:[CPDFSignatureAnnotation class]] ||
  613. [annotation isKindOfClass:[CPDFInkAnnotation class]]) {
  614. bounds.size.height = bounds.size.width*scale;
  615. bounds.size.width = MAX(bounds.size.width, 5.0);
  616. bounds.size.height = MAX(bounds.size.height, 5.0*scale);
  617. } else {
  618. bounds.size.width = MAX(bounds.size.width, 5.0);
  619. bounds.size.height = MAX(bounds.size.height, 5.0);
  620. }
  621. bounds.origin.y = y - bounds.size.height;
  622. }
  623. break;
  624. default:
  625. break;
  626. }
  627. if (CGRectGetMinX(bounds) < 0) {
  628. bounds.origin.x = 0;
  629. }
  630. if (CGRectGetMaxX(bounds) > CGRectGetWidth(annotation.page.bounds)) {
  631. bounds.origin.x = CGRectGetWidth(annotation.page.bounds) - CGRectGetWidth(bounds);
  632. }
  633. if (CGRectGetMinY(bounds) < 0) {
  634. bounds.origin.y = 0;
  635. }
  636. if (CGRectGetMaxY(bounds) > CGRectGetHeight(annotation.page.bounds)) {
  637. bounds.origin.y = CGRectGetHeight(annotation.page.bounds) - CGRectGetHeight(bounds);
  638. }
  639. }
  640. annotation.bounds = bounds;
  641. }
  642. - (void)addAnnotation:(PDFViewAnnotationMode)mode atPoint:(CGPoint)point forPage:(CPDFPage *)page {
  643. CPDFAnnotation *annotation = nil;
  644. switch (mode) {
  645. case PDFViewAnnotationModeNote:
  646. {
  647. CGFloat width = 57.0/1.5;
  648. annotation = [[[CPDFTextAnnotation alloc] initWithDocument:self.document] autorelease];
  649. annotation.bounds = CGRectMake(point.x-width/2.0, point.y-width/2.0, width, width);
  650. }
  651. break;
  652. case PDFViewAnnotationModeHighlight:
  653. {
  654. if (!self.currentSelection) {
  655. return;
  656. }
  657. NSMutableArray *quadrilateralPoints = [NSMutableArray array];
  658. annotation = [[[CPDFMarkupAnnotation alloc] initWithDocument:self.document markupType:CPDFMarkupTypeHighlight] autorelease];
  659. for (CPDFSelection *selection in self.currentSelection.selectionsByLine) {
  660. CGRect bounds = selection.bounds;
  661. [quadrilateralPoints addObject:[NSValue valueWithCGPoint:CGPointMake(CGRectGetMinX(bounds), CGRectGetMaxY(bounds))]];
  662. [quadrilateralPoints addObject:[NSValue valueWithCGPoint:CGPointMake(CGRectGetMaxX(bounds), CGRectGetMaxY(bounds))]];
  663. [quadrilateralPoints addObject:[NSValue valueWithCGPoint:CGPointMake(CGRectGetMinX(bounds), CGRectGetMinY(bounds))]];
  664. [quadrilateralPoints addObject:[NSValue valueWithCGPoint:CGPointMake(CGRectGetMaxX(bounds), CGRectGetMinY(bounds))]];
  665. }
  666. [(CPDFMarkupAnnotation *)annotation setQuadrilateralPoints:quadrilateralPoints];
  667. [(CPDFMarkupAnnotation *)annotation setMarkupText:self.currentSelection.string];
  668. [self clearSelection];
  669. }
  670. break;
  671. case PDFViewAnnotationModeUnderline:
  672. {
  673. if (!self.currentSelection) {
  674. return;
  675. }
  676. NSMutableArray *quadrilateralPoints = [NSMutableArray array];
  677. annotation = [[[CPDFMarkupAnnotation alloc] initWithDocument:self.document markupType:CPDFMarkupTypeUnderline] autorelease];
  678. for (CPDFSelection *selection in self.currentSelection.selectionsByLine) {
  679. CGRect bounds = selection.bounds;
  680. [quadrilateralPoints addObject:[NSValue valueWithCGPoint:CGPointMake(CGRectGetMinX(bounds), CGRectGetMaxY(bounds))]];
  681. [quadrilateralPoints addObject:[NSValue valueWithCGPoint:CGPointMake(CGRectGetMaxX(bounds), CGRectGetMaxY(bounds))]];
  682. [quadrilateralPoints addObject:[NSValue valueWithCGPoint:CGPointMake(CGRectGetMinX(bounds), CGRectGetMinY(bounds))]];
  683. [quadrilateralPoints addObject:[NSValue valueWithCGPoint:CGPointMake(CGRectGetMaxX(bounds), CGRectGetMinY(bounds))]];
  684. }
  685. [(CPDFMarkupAnnotation *)annotation setQuadrilateralPoints:quadrilateralPoints];
  686. [(CPDFMarkupAnnotation *)annotation setMarkupText:self.currentSelection.string];
  687. [self clearSelection];
  688. }
  689. break;
  690. case PDFViewAnnotationModeStrikeout:
  691. {
  692. if (!self.currentSelection) {
  693. return;
  694. }
  695. NSMutableArray *quadrilateralPoints = [NSMutableArray array];
  696. annotation = [[[CPDFMarkupAnnotation alloc] initWithDocument:self.document markupType:CPDFMarkupTypeStrikeOut] autorelease];
  697. for (CPDFSelection *selection in self.currentSelection.selectionsByLine) {
  698. CGRect bounds = selection.bounds;
  699. [quadrilateralPoints addObject:[NSValue valueWithCGPoint:CGPointMake(CGRectGetMinX(bounds), CGRectGetMaxY(bounds))]];
  700. [quadrilateralPoints addObject:[NSValue valueWithCGPoint:CGPointMake(CGRectGetMaxX(bounds), CGRectGetMaxY(bounds))]];
  701. [quadrilateralPoints addObject:[NSValue valueWithCGPoint:CGPointMake(CGRectGetMinX(bounds), CGRectGetMinY(bounds))]];
  702. [quadrilateralPoints addObject:[NSValue valueWithCGPoint:CGPointMake(CGRectGetMaxX(bounds), CGRectGetMinY(bounds))]];
  703. }
  704. [(CPDFMarkupAnnotation *)annotation setQuadrilateralPoints:quadrilateralPoints];
  705. [(CPDFMarkupAnnotation *)annotation setMarkupText:self.currentSelection.string];
  706. [self clearSelection];
  707. }
  708. break;
  709. case PDFViewAnnotationModeSquiggly:
  710. {
  711. if (!self.currentSelection) {
  712. return;
  713. }
  714. NSMutableArray *quadrilateralPoints = [NSMutableArray array];
  715. annotation = [[[CPDFMarkupAnnotation alloc] initWithDocument:self.document markupType:CPDFMarkupTypeSquiggly] autorelease];
  716. for (CPDFSelection *selection in self.currentSelection.selectionsByLine) {
  717. CGRect bounds = selection.bounds;
  718. [quadrilateralPoints addObject:[NSValue valueWithCGPoint:CGPointMake(CGRectGetMinX(bounds), CGRectGetMaxY(bounds))]];
  719. [quadrilateralPoints addObject:[NSValue valueWithCGPoint:CGPointMake(CGRectGetMaxX(bounds), CGRectGetMaxY(bounds))]];
  720. [quadrilateralPoints addObject:[NSValue valueWithCGPoint:CGPointMake(CGRectGetMinX(bounds), CGRectGetMinY(bounds))]];
  721. [quadrilateralPoints addObject:[NSValue valueWithCGPoint:CGPointMake(CGRectGetMaxX(bounds), CGRectGetMinY(bounds))]];
  722. }
  723. [(CPDFMarkupAnnotation *)annotation setQuadrilateralPoints:quadrilateralPoints];
  724. [(CPDFMarkupAnnotation *)annotation setMarkupText:self.currentSelection.string];
  725. [self clearSelection];
  726. }
  727. break;
  728. case PDFViewAnnotationModeCircle:
  729. {
  730. annotation = [[[CPDFCircleAnnotation alloc] initWithDocument:self.document] autorelease];
  731. annotation.bounds = CGRectMake(point.x-50, point.y-50, 100, 100);
  732. }
  733. break;
  734. case PDFViewAnnotationModeSquare:
  735. {
  736. annotation = [[[CPDFSquareAnnotation alloc] initWithDocument:self.document] autorelease];
  737. annotation.bounds = CGRectMake(point.x-50, point.y-50, 100, 100);
  738. }
  739. break;
  740. case PDFViewAnnotationModeArrow:
  741. {
  742. annotation = [[[CPDFLineAnnotation alloc] initWithDocument:self.document] autorelease];
  743. [(CPDFLineAnnotation *)annotation setStartPoint:CGPointMake(point.x-50, point.y)];
  744. [(CPDFLineAnnotation *)annotation setEndPoint:CGPointMake(point.x+50, point.y)];
  745. [(CPDFLineAnnotation *)annotation setEndLineStyle:CPDFLineStyleClosedArrow];
  746. }
  747. break;
  748. case PDFViewAnnotationModeLine:
  749. {
  750. annotation = [[[CPDFLineAnnotation alloc] initWithDocument:self.document] autorelease];
  751. [(CPDFLineAnnotation *)annotation setStartPoint:CGPointMake(point.x-50, point.y)];
  752. [(CPDFLineAnnotation *)annotation setEndPoint:CGPointMake(point.x+50, point.y)];
  753. }
  754. break;
  755. default:
  756. break;
  757. }
  758. if (!annotation) {
  759. return;
  760. }
  761. [annotation setModificationDate:[NSDate date]];
  762. [annotation setUserName:[self annotationUserName]];
  763. [page addAnnotation:annotation];
  764. if ([annotation isKindOfClass:[CPDFTextAnnotation class]]) {
  765. [self setNeedsDisplayForPage:page];
  766. if ([self.performDelegate respondsToSelector:@selector(PDFViewPerformOpenNote:forAnnotation:)]) {
  767. [self.performDelegate PDFViewPerformOpenNote:self forAnnotation:annotation];
  768. }
  769. } else if ([annotation isKindOfClass:[CPDFMarkupAnnotation class]]) {
  770. [self setNeedsDisplayForPage:page];
  771. } else {
  772. self.activeAnnotation = annotation;
  773. [self setNeedsDisplayForPage:page];
  774. [self updateScrollEnabled];
  775. [self showMenuForAnnotation:annotation];
  776. }
  777. }
  778. - (void)addAnnotationLinkAtPoint:(CGPoint)point forPage:(CPDFPage *)page {
  779. CPDFLinkAnnotation *annotation = [[[CPDFLinkAnnotation alloc] initWithDocument:self.document] autorelease];
  780. annotation.bounds = self.addLinkRect;
  781. [annotation setModificationDate:[NSDate date]];
  782. [annotation setUserName:[self annotationUserName]];
  783. [page addAnnotation:annotation];
  784. self.addLinkPoint = CGPointZero;
  785. self.addLinkRect = CGRectZero;
  786. [self setNeedsDisplayForPage:page];
  787. if ([self.performDelegate respondsToSelector:@selector(PDFViewPerformEditLink:forAnnotation:)]) {
  788. [self.performDelegate PDFViewPerformEditLink:self forAnnotation:annotation];
  789. }
  790. }
  791. - (void)addAnnotationFreeTextAtPoint:(CGPoint)point forPage:(CPDFPage *)page {
  792. CPDFFreeTextAnnotation *annotation = [[[CPDFFreeTextAnnotation alloc] initWithDocument:self.document] autorelease];
  793. if (CPDFKitShareConfig.enableAnnotationNoRotate) {
  794. CGFloat width;
  795. CGAffineTransform transform = [page transform];
  796. point = CGPointApplyAffineTransform(point, transform);
  797. if (page.rotation == 90 ||
  798. page.rotation == 270) {
  799. width = CGRectGetMaxY(page.bounds) - point.x - 20;
  800. } else {
  801. width = CGRectGetMaxX(page.bounds) - point.x - 20;
  802. }
  803. CGRect bounds = CGRectMake(point.x, point.y, width, annotation.font.pointSize);
  804. bounds = CGRectApplyAffineTransform(bounds, CGAffineTransformInvert(transform));
  805. annotation.bounds = bounds;
  806. } else {
  807. CGFloat width = CGRectGetMaxX(page.bounds) - point.x - 20;
  808. annotation.bounds = CGRectMake(point.x, point.y, width, annotation.font.pointSize);
  809. }
  810. [annotation setModificationDate:[NSDate date]];
  811. [annotation setUserName:[self annotationUserName]];
  812. [page addAnnotation:annotation];
  813. [self editAnnotationFreeText:annotation];
  814. }
  815. - (void)addAnnotationAtPoint:(CGPoint)point forPage:(CPDFPage *)page {
  816. CPDFAnnotation *annotation = self.addAnnotation;
  817. if (!annotation) {
  818. return;
  819. }
  820. annotation.bounds = CGRectMake(point.x-annotation.bounds.size.width/2.0,
  821. point.y-annotation.bounds.size.height/2.0,
  822. annotation.bounds.size.width, annotation.bounds.size.height);
  823. [annotation setModificationDate:[NSDate date]];
  824. [annotation setUserName:[self annotationUserName]];
  825. [page addAnnotation:annotation];
  826. self.activeAnnotation = annotation;
  827. [self setNeedsDisplayForPage:page];
  828. [self updateScrollEnabled];
  829. [self showMenuForAnnotation:annotation];
  830. self.addAnnotation = nil;
  831. }
  832. - (void)addAnnotation:(CPDFAnnotation *)annotation forPage:(CPDFPage *)page {
  833. if (!annotation || !page) {
  834. return;
  835. }
  836. [annotation setModificationDate:[NSDate date]];
  837. [annotation setUserName:[self annotationUserName]];
  838. [page addAnnotation:annotation];
  839. self.activeAnnotation = annotation;
  840. [self setNeedsDisplayForPage:page];
  841. [self updateScrollEnabled];
  842. [self showMenuForAnnotation:annotation];
  843. }
  844. - (void)addAnnotation:(CPDFAnnotation *)annotation {
  845. CPDFPage *page = [self.document pageAtIndex:self.currentPageIndex];
  846. CGPoint center = [self convertPoint:self.center toPage:page];
  847. if (CGPointEqualToPoint(center, CGPointZero)) {
  848. return;
  849. }
  850. CGRect bounds = annotation.bounds;
  851. bounds.origin.x = center.x-bounds.size.width/2.0;
  852. bounds.origin.y = center.y-bounds.size.height/2.0;
  853. bounds.origin.y = MIN(MAX(0, bounds.origin.y), page.bounds.size.height-bounds.size.height);
  854. annotation.bounds = bounds;
  855. [self addAnnotation:annotation forPage:page];
  856. }
  857. #pragma mark - Annotation Menu
  858. - (BOOL)canBecomeFirstResponder {
  859. return YES;
  860. }
  861. - (void)showMenuForAnnotation:(CPDFAnnotation *)annotation {
  862. self.menuAnnotation = annotation;
  863. if (!annotation) {
  864. [UIMenuController sharedMenuController].menuItems = nil;
  865. [[UIMenuController sharedMenuController] setMenuVisible:NO animated:YES];
  866. return;
  867. }
  868. NSMutableArray *menuItems = [NSMutableArray array];
  869. UIMenuItem *colorItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Color", nil)
  870. action:@selector(colorItemAction:)] autorelease];
  871. UIMenuItem *opacityItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Opacity", nil)
  872. action:@selector(opacityItemAction:)] autorelease];
  873. UIMenuItem *copyItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Copy", nil)
  874. action:@selector(copyItemAction:)] autorelease];
  875. UIMenuItem *noteItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Note", nil)
  876. action:@selector(noteItemAction:)] autorelease];
  877. UIMenuItem *deleteItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Delete", nil)
  878. action:@selector(deleteItemAction:)] autorelease];
  879. if ([annotation isKindOfClass:[CPDFMarkupAnnotation class]]) {
  880. UIMenuItem *shareItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Share", nil)
  881. action:@selector(shareItemAction:)] autorelease];
  882. [menuItems addObject:colorItem];
  883. [menuItems addObject:opacityItem];
  884. [menuItems addObject:copyItem];
  885. [menuItems addObject:shareItem];
  886. [menuItems addObject:noteItem];
  887. [menuItems addObject:deleteItem];
  888. } else if ([annotation isKindOfClass:[CPDFStampAnnotation class]]) {
  889. if (CPDFStampTypeImage == [(CPDFStampAnnotation *)annotation stampType]) {
  890. UIMenuItem *saveItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Save", nil)
  891. action:@selector(saveItemAction:)] autorelease];
  892. [menuItems addObject:saveItem];
  893. [menuItems addObject:copyItem];
  894. }
  895. [menuItems addObject:deleteItem];
  896. } else if ([annotation isKindOfClass:[CPDFLinkAnnotation class]]) {
  897. UIMenuItem *editItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Edit", nil)
  898. action:@selector(editItemAction:)] autorelease];
  899. [menuItems addObject:editItem];
  900. [menuItems addObject:deleteItem];
  901. } else if ([annotation isKindOfClass:[CPDFFreeTextAnnotation class]]) {
  902. UIMenuItem *editItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Edit", nil)
  903. action:@selector(editItemAction:)] autorelease];
  904. [menuItems addObject:editItem];
  905. [menuItems addObject:copyItem];
  906. [menuItems addObject:deleteItem];
  907. } else if ([annotation isKindOfClass:[CPDFSoundAnnotation class]] ||
  908. [annotation isKindOfClass:[CPDFMovieAnnotation class]]) {
  909. [menuItems addObject:deleteItem];
  910. } else if ([annotation isKindOfClass:[CPDFSignatureAnnotation class]]) {
  911. UIMenuItem *cancelItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Cancel", nil)
  912. action:@selector(deleteItemAction:)] autorelease];
  913. UIMenuItem *addHereItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Add here", nil)
  914. action:@selector(addHereItemAction:)] autorelease];
  915. [menuItems addObject:cancelItem];
  916. [menuItems addObject:addHereItem];
  917. } else if ([annotation isKindOfClass:[CPDFLineAnnotation class]] ||
  918. [annotation isKindOfClass:[CPDFSquareAnnotation class]] ||
  919. [annotation isKindOfClass:[CPDFCircleAnnotation class]] ||
  920. [annotation isKindOfClass:[CPDFInkAnnotation class]]) {
  921. UIMenuItem *thicknessItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Thickness", nil)
  922. action:@selector(thicknessItemAction:)] autorelease];
  923. [menuItems addObject:noteItem];
  924. [menuItems addObject:colorItem];
  925. [menuItems addObject:thicknessItem];
  926. [menuItems addObject:opacityItem];
  927. [menuItems addObject:deleteItem];
  928. } else if ([annotation isKindOfClass:[CPDFSignatureWidgetAnnotation class]]) {
  929. UIMenuItem *deleteItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Delete", nil)
  930. action:@selector(signatureWidgetDeleteItemAction:)] autorelease];
  931. [menuItems addObject:deleteItem];
  932. }
  933. if (menuItems.count <= 0) {
  934. return;
  935. }
  936. CGRect bounds = annotation.bounds;
  937. bounds = CGRectInset(bounds, -15, -15);
  938. CGRect rect = [self convertRect:bounds fromPage:annotation.page];
  939. [self becomeFirstResponder];
  940. [UIMenuController sharedMenuController].menuItems = menuItems;
  941. [[UIMenuController sharedMenuController] setTargetRect:rect inView:self];
  942. [[UIMenuController sharedMenuController] setMenuVisible:YES animated:YES];
  943. }
  944. - (void)signatureWidgetDeleteItemAction:(id)sender {
  945. if ([self.menuAnnotation isKindOfClass:[CPDFSignatureWidgetAnnotation class]]) {
  946. [(CPDFSignatureWidgetAnnotation *)self.menuAnnotation reset];
  947. [self setNeedsDisplayForPage:self.menuAnnotation.page];
  948. }
  949. }
  950. - (void)colorItemAction:(id)sender {
  951. if ([self.performDelegate respondsToSelector:@selector(PDFViewPerformChangeColor:forAnnotation:)]) {
  952. [self.performDelegate PDFViewPerformChangeColor:self forAnnotation:self.menuAnnotation];
  953. }
  954. }
  955. - (void)opacityItemAction:(id)sender {
  956. NSMutableArray *menuItems = [NSMutableArray array];
  957. UIMenuItem *opacity25Item = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"25%", nil)
  958. action:@selector(opacity25ItemAction:)] autorelease];
  959. UIMenuItem *opacity50Item = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"50%", nil)
  960. action:@selector(opacity50ItemAction:)] autorelease];
  961. UIMenuItem *opacity75Item = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"75%", nil)
  962. action:@selector(opacity75ItemAction:)] autorelease];
  963. UIMenuItem *opacity100Item = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"100%", nil)
  964. action:@selector(opacity100ItemAction:)] autorelease];
  965. [menuItems addObject:opacity25Item];
  966. [menuItems addObject:opacity50Item];
  967. [menuItems addObject:opacity75Item];
  968. [menuItems addObject:opacity100Item];
  969. CGRect bounds = self.menuAnnotation.bounds;
  970. bounds = CGRectInset(bounds, -15, -15);
  971. CGRect rect = [self convertRect:bounds fromPage:self.menuAnnotation.page];
  972. [self becomeFirstResponder];
  973. [UIMenuController sharedMenuController].menuItems = menuItems;
  974. [[UIMenuController sharedMenuController] setTargetRect:rect inView:self];
  975. [[UIMenuController sharedMenuController] setMenuVisible:YES animated:YES];
  976. }
  977. - (void)opacity25ItemAction:(id)sender {
  978. self.menuAnnotation.opacity = 0.25;
  979. [self setNeedsDisplayForPage:self.menuAnnotation.page];
  980. [self showMenuForAnnotation:self.menuAnnotation];
  981. }
  982. - (void)opacity50ItemAction:(id)sender {
  983. self.menuAnnotation.opacity = 0.50;
  984. [self setNeedsDisplayForPage:self.menuAnnotation.page];
  985. [self showMenuForAnnotation:self.menuAnnotation];
  986. }
  987. - (void)opacity75ItemAction:(id)sender {
  988. self.menuAnnotation.opacity = 0.75;
  989. [self setNeedsDisplayForPage:self.menuAnnotation.page];
  990. [self showMenuForAnnotation:self.menuAnnotation];
  991. }
  992. - (void)opacity100ItemAction:(id)sender {
  993. self.menuAnnotation.opacity = 1.0;
  994. [self setNeedsDisplayForPage:self.menuAnnotation.page];
  995. [self showMenuForAnnotation:self.menuAnnotation];
  996. }
  997. - (void)copyItemAction:(id)sender {
  998. if ([self.menuAnnotation isKindOfClass:[CPDFMarkupAnnotation class]]) {
  999. NSString *string = [(CPDFMarkupAnnotation *)self.menuAnnotation markupText];
  1000. [[UIPasteboard generalPasteboard] setString:string];
  1001. } else if ([self.menuAnnotation isKindOfClass:[CPDFStampAnnotation class]]) {
  1002. UIImage *image = [(CPDFStampAnnotation *)self.menuAnnotation stampImage];
  1003. [UIPasteboard generalPasteboard].image = image;
  1004. } else if ([self.menuAnnotation isKindOfClass:[CPDFFreeTextAnnotation class]]) {
  1005. NSString *string = self.menuAnnotation.contents;
  1006. [[UIPasteboard generalPasteboard] setString:string];
  1007. }
  1008. }
  1009. - (void)noteItemAction:(id)sender {
  1010. if ([self.performDelegate respondsToSelector:@selector(PDFViewPerformOpenNote:forAnnotation:)]) {
  1011. [self.performDelegate PDFViewPerformOpenNote:self forAnnotation:self.menuAnnotation];
  1012. }
  1013. }
  1014. - (void)deleteItemAction:(id)sender {
  1015. self.activeAnnotation = nil;
  1016. [self.menuAnnotation.page removeAnnotation:self.menuAnnotation];
  1017. [self setNeedsDisplayForPage:self.menuAnnotation.page];
  1018. [self updateScrollEnabled];
  1019. }
  1020. - (void)shareItemAction:(id)sender {
  1021. if ([self.menuAnnotation isKindOfClass:[CPDFMarkupAnnotation class]]) {
  1022. if ([self.performDelegate respondsToSelector:@selector(PDFViewPerformShare:forAnnotation:)]) {
  1023. [self.performDelegate PDFViewPerformShare:self forAnnotation:(CPDFMarkupAnnotation *)self.menuAnnotation];
  1024. }
  1025. }
  1026. }
  1027. - (void)saveItemAction:(id)sender {
  1028. if ([self.menuAnnotation isKindOfClass:[CPDFStampAnnotation class]]) {
  1029. if ([self.performDelegate respondsToSelector:@selector(PDFViewPerformSave:forAnnotation:)]) {
  1030. [self.performDelegate PDFViewPerformSave:self forAnnotation:(CPDFStampAnnotation *)self.menuAnnotation];
  1031. }
  1032. }
  1033. }
  1034. - (void)editItemAction:(id)sender {
  1035. if ([self.menuAnnotation isKindOfClass:[CPDFLinkAnnotation class]]) {
  1036. if ([self.performDelegate respondsToSelector:@selector(PDFViewPerformEditLink:forAnnotation:)]) {
  1037. [self.performDelegate PDFViewPerformEditLink:self forAnnotation:(CPDFLinkAnnotation *)self.menuAnnotation];
  1038. }
  1039. } else if ([self.menuAnnotation isKindOfClass:[CPDFFreeTextAnnotation class]]) {
  1040. self.activeAnnotation = nil;
  1041. [self editAnnotationFreeText:(CPDFFreeTextAnnotation *)self.menuAnnotation];
  1042. }
  1043. }
  1044. - (void)addHereItemAction:(id)sender {
  1045. if ([self.menuAnnotation isKindOfClass:[CPDFSignatureAnnotation class]]) {
  1046. [(CPDFSignatureAnnotation *)self.menuAnnotation signature];
  1047. self.activeAnnotation = nil;
  1048. [self setNeedsDisplayForPage:self.menuAnnotation.page];
  1049. [self updateScrollEnabled];
  1050. }
  1051. }
  1052. - (void)thicknessItemAction:(id)sender {
  1053. NSMutableArray *menuItems = [NSMutableArray array];
  1054. UIMenuItem *thickness0_5Item = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"0.5pt", nil)
  1055. action:@selector(thickness0_5ItemAction:)] autorelease];
  1056. UIMenuItem *thickness1Item = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"1pt", nil)
  1057. action:@selector(thickness1ItemAction:)] autorelease];
  1058. UIMenuItem *thickness1_5Item = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"1.5pt", nil)
  1059. action:@selector(thickness1_5ItemAction:)] autorelease];
  1060. UIMenuItem *thickness2Item = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"2pt", nil)
  1061. action:@selector(thickness2ItemAction:)] autorelease];
  1062. UIMenuItem *thickness3Item = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"3pt", nil)
  1063. action:@selector(thickness3ItemAction:)] autorelease];
  1064. UIMenuItem *thickness5Item = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"5pt", nil)
  1065. action:@selector(thickness5ItemAction:)] autorelease];
  1066. UIMenuItem *thickness9Item = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"9pt", nil)
  1067. action:@selector(thickness9ItemAction:)] autorelease];
  1068. [menuItems addObject:thickness0_5Item];
  1069. [menuItems addObject:thickness1Item];
  1070. [menuItems addObject:thickness1_5Item];
  1071. [menuItems addObject:thickness2Item];
  1072. [menuItems addObject:thickness3Item];
  1073. [menuItems addObject:thickness5Item];
  1074. [menuItems addObject:thickness9Item];
  1075. CGRect bounds = self.menuAnnotation.bounds;
  1076. bounds = CGRectInset(bounds, -15, -15);
  1077. CGRect rect = [self convertRect:bounds fromPage:self.menuAnnotation.page];
  1078. [self becomeFirstResponder];
  1079. [UIMenuController sharedMenuController].menuItems = menuItems;
  1080. [[UIMenuController sharedMenuController] setTargetRect:rect inView:self];
  1081. [[UIMenuController sharedMenuController] setMenuVisible:YES animated:YES];
  1082. }
  1083. - (void)thickness0_5ItemAction:(id)sender {
  1084. self.menuAnnotation.borderWidth = 0.5;
  1085. [self setNeedsDisplayForPage:self.menuAnnotation.page];
  1086. [self showMenuForAnnotation:self.menuAnnotation];
  1087. }
  1088. - (void)thickness1ItemAction:(id)sender {
  1089. self.menuAnnotation.borderWidth = 1.0;
  1090. [self setNeedsDisplayForPage:self.menuAnnotation.page];
  1091. [self showMenuForAnnotation:self.menuAnnotation];
  1092. }
  1093. - (void)thickness1_5ItemAction:(id)sender {
  1094. self.menuAnnotation.borderWidth = 1.5;
  1095. [self setNeedsDisplayForPage:self.menuAnnotation.page];
  1096. [self showMenuForAnnotation:self.menuAnnotation];
  1097. }
  1098. - (void)thickness2ItemAction:(id)sender {
  1099. self.menuAnnotation.borderWidth = 2.0;
  1100. [self setNeedsDisplayForPage:self.menuAnnotation.page];
  1101. [self showMenuForAnnotation:self.menuAnnotation];
  1102. }
  1103. - (void)thickness3ItemAction:(id)sender {
  1104. self.menuAnnotation.borderWidth = 3.0;
  1105. [self setNeedsDisplayForPage:self.menuAnnotation.page];
  1106. [self showMenuForAnnotation:self.menuAnnotation];
  1107. }
  1108. - (void)thickness5ItemAction:(id)sender {
  1109. self.menuAnnotation.borderWidth = 5.0;
  1110. [self setNeedsDisplayForPage:self.menuAnnotation.page];
  1111. [self showMenuForAnnotation:self.menuAnnotation];
  1112. }
  1113. - (void)thickness9ItemAction:(id)sender {
  1114. self.menuAnnotation.borderWidth = 9.0;
  1115. [self setNeedsDisplayForPage:self.menuAnnotation.page];
  1116. [self showMenuForAnnotation:self.menuAnnotation];
  1117. }
  1118. #pragma mark - Menu
  1119. - (NSArray<UIMenuItem *> *)menuItemsAtPoint:(CGPoint)point forPage:(CPDFPage *)page {
  1120. if (PDFViewAnnotationModeNone != self.annotationMode) {
  1121. return nil;
  1122. }
  1123. NSArray *items = [super menuItemsAtPoint:point forPage:page];
  1124. self.menuPoint = point;
  1125. self.menuPage = page;
  1126. NSMutableArray *menuItems = [NSMutableArray arrayWithArray:items];
  1127. if (self.currentSelection) {
  1128. UIMenuItem *textNoteItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Note", nil)
  1129. action:@selector(textNoteItemAction:)] autorelease];
  1130. UIMenuItem *textShareItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Share", nil)
  1131. action:@selector(textShareItemAction:)] autorelease];
  1132. UIMenuItem *defineItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Define", nil)
  1133. action:@selector(defineItemAction:)] autorelease];
  1134. UIMenuItem *linkItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Link", nil)
  1135. action:@selector(linkItemAction:)] autorelease];
  1136. UIMenuItem *searchItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Search", nil)
  1137. action:@selector(searchItemAction:)] autorelease];
  1138. [menuItems insertObject:textNoteItem atIndex:0];
  1139. [menuItems addObject:textShareItem];
  1140. [menuItems addObject:defineItem];
  1141. [menuItems addObject:linkItem];
  1142. [menuItems addObject:searchItem];
  1143. } else {
  1144. UIMenuItem *textNoteItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Note", nil)
  1145. action:@selector(textNoteItemAction:)] autorelease];
  1146. UIMenuItem *textItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Text", nil)
  1147. action:@selector(textItemAction:)] autorelease];
  1148. UIMenuItem *signatureItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Signature", nil)
  1149. action:@selector(signatureItemAction:)] autorelease];
  1150. UIMenuItem *stampItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Stamp", nil)
  1151. action:@selector(stampItemAction:)] autorelease];
  1152. UIMenuItem *imageItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Image", nil)
  1153. action:@selector(imageItemAction:)] autorelease];
  1154. UIMenuItem *pasteItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Paste", nil)
  1155. action:@selector(pasteItemAction:)] autorelease];
  1156. [menuItems addObject:textNoteItem];
  1157. [menuItems addObject:textItem];
  1158. [menuItems addObject:signatureItem];
  1159. [menuItems addObject:stampItem];
  1160. [menuItems addObject:imageItem];
  1161. if ([self isPasteboardValid]) {
  1162. [menuItems addObject:pasteItem];
  1163. }
  1164. }
  1165. return menuItems;
  1166. }
  1167. - (BOOL)isPasteboardValid {
  1168. NSString *textType = (NSString *)kUTTypeText;
  1169. NSString *urlType = (NSString*)kUTTypeURL;
  1170. NSString *urlFileType = (NSString*)kUTTypeFileURL;
  1171. NSString *jpegImageType = (NSString *)kUTTypeJPEG;
  1172. NSString *pngImageType = (NSString *)kUTTypePNG;
  1173. NSString *rawImageType = @"com.apple.uikit.image";
  1174. return [[UIPasteboard generalPasteboard] containsPasteboardTypes:[NSArray arrayWithObjects:textType, urlType, urlFileType, jpegImageType, pngImageType, rawImageType, nil]];
  1175. }
  1176. - (void)textNoteItemAction:(id)sender {
  1177. if (self.currentSelection) {
  1178. NSMutableArray *quadrilateralPoints = [NSMutableArray array];
  1179. CPDFMarkupAnnotation *annotation = [[[CPDFMarkupAnnotation alloc] initWithDocument:self.document markupType:CPDFMarkupTypeHighlight] autorelease];
  1180. for (CPDFSelection *selection in self.currentSelection.selectionsByLine) {
  1181. CGRect bounds = selection.bounds;
  1182. [quadrilateralPoints addObject:[NSValue valueWithCGPoint:CGPointMake(CGRectGetMinX(bounds), CGRectGetMaxY(bounds))]];
  1183. [quadrilateralPoints addObject:[NSValue valueWithCGPoint:CGPointMake(CGRectGetMaxX(bounds), CGRectGetMaxY(bounds))]];
  1184. [quadrilateralPoints addObject:[NSValue valueWithCGPoint:CGPointMake(CGRectGetMinX(bounds), CGRectGetMinY(bounds))]];
  1185. [quadrilateralPoints addObject:[NSValue valueWithCGPoint:CGPointMake(CGRectGetMaxX(bounds), CGRectGetMinY(bounds))]];
  1186. }
  1187. [annotation setQuadrilateralPoints:quadrilateralPoints];
  1188. [annotation setMarkupText:self.currentSelection.string];
  1189. [annotation setModificationDate:[NSDate date]];
  1190. [annotation setUserName:[self annotationUserName]];
  1191. [self.currentSelection.page addAnnotation:annotation];
  1192. [annotation createPopup];
  1193. [self clearSelection];
  1194. [self setNeedsDisplayForPage:annotation.page];
  1195. if ([self.performDelegate respondsToSelector:@selector(PDFViewPerformPopup:forAnnotation:)]) {
  1196. [self.performDelegate PDFViewPerformPopup:self forAnnotation:annotation];
  1197. }
  1198. } else {
  1199. [self addAnnotation:PDFViewAnnotationModeNote atPoint:self.menuPoint forPage:self.menuPage];
  1200. }
  1201. }
  1202. - (void)textShareItemAction:(id)sender {
  1203. if ([self.performDelegate respondsToSelector:@selector(PDFViewPerformShare:forSelection:)]) {
  1204. [self.performDelegate PDFViewPerformShare:self forSelection:self.currentSelection];
  1205. }
  1206. }
  1207. - (void)defineItemAction:(id)sender {
  1208. if ([self.performDelegate respondsToSelector:@selector(PDFViewPerformDefine:forSelection:)]) {
  1209. [self.performDelegate PDFViewPerformDefine:self forSelection:self.currentSelection];
  1210. }
  1211. }
  1212. - (void)linkItemAction:(id)sender {
  1213. if (self.currentSelection) {
  1214. CPDFLinkAnnotation *annotation = [[[CPDFLinkAnnotation alloc] initWithDocument:self.document] autorelease];
  1215. annotation.bounds = self.currentSelection.bounds;
  1216. [annotation setModificationDate:[NSDate date]];
  1217. [annotation setUserName:[self annotationUserName]];
  1218. [self.currentSelection.page addAnnotation:annotation];
  1219. [self clearSelection];
  1220. [self setNeedsDisplayForPage:annotation.page];
  1221. if ([self.performDelegate respondsToSelector:@selector(PDFViewPerformEditLink:forAnnotation:)]) {
  1222. [self.performDelegate PDFViewPerformEditLink:self forAnnotation:annotation];
  1223. }
  1224. }
  1225. }
  1226. - (void)searchItemAction:(id)sender {
  1227. NSMutableArray *menuItems = [NSMutableArray array];
  1228. UIMenuItem *googleSearchItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Google", nil)
  1229. action:@selector(googleSearchItemAction:)] autorelease];
  1230. UIMenuItem *wikiSearchItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Wiki", nil)
  1231. action:@selector(wikiSearchItemAction:)] autorelease];
  1232. [menuItems addObject:googleSearchItem];
  1233. [menuItems addObject:wikiSearchItem];
  1234. CGRect rect = [self convertRect:self.currentSelection.bounds fromPage:self.currentSelection.page];
  1235. [self becomeFirstResponder];
  1236. [UIMenuController sharedMenuController].menuItems = menuItems;
  1237. [[UIMenuController sharedMenuController] setTargetRect:rect inView:self];
  1238. [[UIMenuController sharedMenuController] setMenuVisible:YES animated:YES];
  1239. }
  1240. - (void)googleSearchItemAction:(id)sender {
  1241. if ([self.performDelegate respondsToSelector:@selector(PDFViewPerformGoogleSearch:forSelection:)]) {
  1242. [self.performDelegate PDFViewPerformGoogleSearch:self forSelection:self.currentSelection];
  1243. }
  1244. }
  1245. - (void)wikiSearchItemAction:(id)sender {
  1246. if ([self.performDelegate respondsToSelector:@selector(PDFViewPerformWikiSearch:forSelection:)]) {
  1247. [self.performDelegate PDFViewPerformWikiSearch:self forSelection:self.currentSelection];
  1248. }
  1249. }
  1250. - (void)textItemAction:(id)sender {
  1251. [self addAnnotationFreeTextAtPoint:self.menuPoint forPage:self.menuPage];
  1252. }
  1253. - (void)signatureItemAction:(id)sender {
  1254. if ([self.performDelegate respondsToSelector:@selector(PDFViewPerformAddSignture:atPoint:forPage:)]) {
  1255. [self.performDelegate PDFViewPerformAddSignture:self atPoint:self.menuPoint forPage:self.menuPage];
  1256. }
  1257. }
  1258. - (void)stampItemAction:(id)sender {
  1259. if ([self.performDelegate respondsToSelector:@selector(PDFViewPerformAddStamp:atPoint:forPage:)]) {
  1260. [self.performDelegate PDFViewPerformAddStamp:self atPoint:self.menuPoint forPage:self.menuPage];
  1261. }
  1262. }
  1263. - (void)imageItemAction:(id)sender {
  1264. if ([self.performDelegate respondsToSelector:@selector(PDFViewPerformAddImage:atPoint:forPage:)]) {
  1265. [self.performDelegate PDFViewPerformAddImage:self atPoint:self.menuPoint forPage:self.menuPage];
  1266. }
  1267. }
  1268. - (void)pasteItemAction:(id)sender {
  1269. NSString *textType = (NSString *)kUTTypeText;
  1270. NSString *utf8TextType = (NSString *)kUTTypeUTF8PlainText;
  1271. NSString *urlType = (NSString*)kUTTypeURL;
  1272. NSString *urlFileType = (NSString*)kUTTypeFileURL;
  1273. NSString *jpegImageType = (NSString *)kUTTypeJPEG;
  1274. NSString *pngImageType = (NSString *)kUTTypePNG;
  1275. NSString *rawImageType = @"com.apple.uikit.image";
  1276. NSArray *pasteArray = [UIPasteboard generalPasteboard].items;
  1277. for (NSDictionary* dic in pasteArray) {
  1278. if ([dic objectForKey:textType] ||
  1279. [dic objectForKey:utf8TextType] ||
  1280. [dic objectForKey:urlType] ||
  1281. [dic objectForKey:urlFileType]) {
  1282. NSString *contents = nil;
  1283. if ([dic objectForKey:textType] ||
  1284. [dic objectForKey:utf8TextType]) {
  1285. contents = [UIPasteboard generalPasteboard].string;
  1286. } else {
  1287. contents = [[UIPasteboard generalPasteboard].URL absoluteString];
  1288. }
  1289. UIFont *font = [UIFont systemFontOfSize:12.0];
  1290. NSDictionary *attributes = @{NSFontAttributeName : font};
  1291. CGRect bounds = [contents boundingRectWithSize:CGSizeMake(280, MAXFLOAT)
  1292. options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading)
  1293. attributes:attributes
  1294. context:nil];
  1295. CPDFFreeTextAnnotation *annotation = [[[CPDFFreeTextAnnotation alloc] initWithDocument:self.document] autorelease];
  1296. [annotation setContents:contents];
  1297. [annotation setModificationDate:[NSDate date]];
  1298. [annotation setUserName:[self annotationUserName]];
  1299. annotation.bounds = CGRectMake(self.menuPoint.x-bounds.size.width/2.0,
  1300. self.menuPoint.y-bounds.size.height/2.0,
  1301. bounds.size.width, bounds.size.height);
  1302. [self.menuPage addAnnotation:annotation];
  1303. [self setNeedsDisplayForPage:self.menuPage];
  1304. } else if ([dic objectForKey:jpegImageType] ||
  1305. [dic objectForKey:pngImageType] ||
  1306. [dic objectForKey:rawImageType]) {
  1307. UIImage *image = [UIPasteboard generalPasteboard].image;
  1308. UIImage *compressImage = [self compressImage:image size:CGSizeMake(240.0, 240.0)];
  1309. CPDFStampAnnotation *annotation = [[[CPDFStampAnnotation alloc] initWithDocument:self.document image:compressImage] autorelease];
  1310. [annotation setModificationDate:[NSDate date]];
  1311. [annotation setUserName:[self annotationUserName]];
  1312. annotation.bounds = CGRectMake(self.menuPoint.x-compressImage.size.width/2.0,
  1313. self.menuPoint.y-compressImage.size.height/2.0,
  1314. compressImage.size.width, compressImage.size.height);
  1315. [self.menuPage addAnnotation:annotation];
  1316. [self setNeedsDisplayForPage:self.menuPage];
  1317. }
  1318. }
  1319. }
  1320. @end