// // KMPDFPrintManageWindowController.m // PDF Reader // // Created by 蒋志鹏 on 2018/6/19. // Copyright © 2018年 Kdan Mobile. All rights reserved. // #import "KMPDFPrintManageWindowController.h" #import "NSMutableArray+KMOddEvenPartFetch.h" #import "KMPDFMultiplePrintWindowController.h" #import "KMPDFPosterPrintWindowController.h" #import "KMPDFBookletWindowController.h" //#import "NSWindowController_SKExtensions.h" //#import "KMBookletMaskView.h" //#import "KMFileAttribute.h" #import "PDF_Reader_Pro-Swift.h" #import #define kPrintFolderPath [[NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:[NSBundle mainBundle].bundleIdentifier] #define kPrintManageFileSavePath [[[NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:[NSBundle mainBundle].bundleIdentifier] stringByAppendingPathComponent:@"printManage.pdf"] #define kPreviewMaxWidth 207.0 #define kPreviewMaxHeight 289.0 typedef NS_ENUM(NSUInteger, kPrintStyle) { kPrintStyle_DocumentOnly = 0, kPrintStyle_DocumentAndMarkups, kPrintStyle_DocumentAndStamps, kPrintStyle_FormsOnly }; typedef NS_ENUM(NSUInteger, kPageSelectStyle) { kPageSelectStyle_AllPage = 0, kPageSelectStyle_OddPage, kPageSelectStyle_EvenPage, kPageSelectStyle_CurrentPage, kPageSelectStyle_HandInput }; @interface KMPrintParameter :NSObject @property (nonatomic, assign) kPrintStyle printStyle; @property (nonatomic, assign) BOOL reversePages; @property (nonatomic, assign) kPageSelectStyle pageSelectStyle; @end @implementation KMPrintParameter - (void)dealloc { } @end @interface KMPDFPrintManageWindowController () //当前文档 @property (nonatomic, retain) PDFDocument *pdfDocument; @property (nonatomic, retain) PDFPage *currentPage; //model 管理 @property (nonatomic, assign) NSModalSession modalSession; @property (assign) IBOutlet NSTextField *pagesSettingLabel; @property (assign) IBOutlet NSButton *allPageButton; @property (assign) IBOutlet NSButton *oddPageButton; @property (assign) IBOutlet NSButton *evenPageButton; @property (assign) IBOutlet NSButton *currentPageButton; @property (assign) IBOutlet NSButton *handInputPageButton; @property (assign) IBOutlet NSTextField *intputPageRangeTextField; @property (assign) IBOutlet NSButton *reversePageButton; @property (assign) IBOutlet NSTextField *printSettingLabel; @property (assign) IBOutlet NSButton *printDocumentButton; @property (assign) IBOutlet NSButton *printDocumentAndMarkupsButton; @property (assign) IBOutlet NSButton *printDocumentAndStampsButton; @property (assign) IBOutlet NSButton *printFormOnlyButton; @property (assign) IBOutlet NSButton *printButton; @property (assign) IBOutlet NSButton *cancelButton; @property (assign) IBOutlet NSButton *posterButton; @property (assign) IBOutlet NSButton *mutilpleButton; @property (assign) IBOutlet NSButton *bookletButton; @property (assign) IBOutlet NSTextField *currentPageNumberTextField; @property (assign) IBOutlet NSTextField *totalPageNumberLabel; @property (assign) IBOutlet NSLayoutConstraint *previewHeightContraint; @property (assign) IBOutlet NSLayoutConstraint *previewWidthContraint; @property (assign) IBOutlet PDFView *preview; @property (nonatomic, retain) KMPrintParameter *printParameter; @property (nonatomic, retain) NSMutableArray *selectPagesIndexArray; @property (nonatomic, retain) KMBookletMaskView *maskView; @property (nonatomic, copy) printCallBack callBack; @property (retain) NSArray *pageButtons; @property(nonatomic, strong) KMPDFPosterPrintWindowController *posterVC; @property(nonatomic, strong) KMPDFMultiplePrintWindowController *multipleVC; @property(nonatomic, strong) KMPDFBookletWindowController *bookletVC; @end @implementation KMPDFPrintManageWindowController - (void)dealloc { } #pragma mark - init Method - (instancetype)initWithPDFDocument:(PDFDocument *)pdfDocument currentPage:(PDFPage *)currentpage completeHandler:(printCallBack)printHandler { self = [super initWithWindowNibName:@"KMPDFPrintManageWindowController"]; if (self) { [self showWaitting]; dispatch_async(dispatch_get_global_queue(0, 0), ^{ if (![[NSFileManager defaultManager] fileExistsAtPath:kPrintFolderPath]) { if (![[NSFileManager defaultManager] createDirectoryAtPath:kPrintFolderPath withIntermediateDirectories:NO attributes:nil error:nil]) { return; } } self.callBack = printHandler; [pdfDocument writeToURL:[NSURL fileURLWithPath:kPrintManageFileSavePath]]; self.pdfDocument = [[PDFDocument alloc] initWithURL:[NSURL fileURLWithPath:kPrintManageFileSavePath]]; dispatch_async(dispatch_get_main_queue(), ^{ [self hideWaitting]; if (self.pdfDocument) { // if([self.pdfDocument isLocked]) { // [self.pdfDocument unlockWithPassword:pdfDocument.password]; // } [self setTextFieldDelegate]; [self initFormatter]; [self configuInitializationParameter]; [self produceNewPDFForPreview]; }else{ [self close]; } }); }); } return self; } #pragma mark - 生命周期 - (void)windowDidLoad { [super windowDidLoad]; [self localizedLanguage]; [self configuInitializationParameter]; if (!self.pdfDocument) { return; } [self setTextFieldDelegate]; [self initFormatter]; [self produceNewPDFForPreview]; } - (BOOL)windowShouldClose:(id)sender { return YES; } #pragma mark - Private Methods - (void)localizedLanguage { self.window.title = NSLocalizedString(@"Pages to Print", nil); self.pagesSettingLabel.stringValue = NSLocalizedString(@"Page Range:", nil); self.allPageButton.title = NSLocalizedString(@"All Pages", nil); self.oddPageButton.title = NSLocalizedString(@"Odd Pages Only", nil); self.evenPageButton.title = NSLocalizedString(@"Even Pages Only", nil); self.reversePageButton.title = NSLocalizedString(@"Reverse pages", nil); self.printSettingLabel.stringValue = NSLocalizedString(@"Comments & Forms:", nil); self.printDocumentButton.title = NSLocalizedString(@"Document", nil); self.printDocumentAndMarkupsButton.title = NSLocalizedString(@"Document and Markups", nil); self.printDocumentAndStampsButton.title = NSLocalizedString(@"Document and Stamps", nil); self.printFormOnlyButton.title = NSLocalizedString(@"Form fields only", nil); self.posterButton.title = NSLocalizedString(@"Poster", nil); self.mutilpleButton.title = NSLocalizedString(@"Multiple", nil); self.bookletButton.title = NSLocalizedString(@"Booklet", nil); self.cancelButton.title = NSLocalizedString(@"Cancel", nil); self.printButton.title = NSLocalizedString(@"Printer", nil); self.currentPageButton.title= NSLocalizedString(@"Current Page", nil); [self.intputPageRangeTextField.cell setPlaceholderString:NSLocalizedString(@"e.g. 1,3-5,10", nil)]; } - (void)setTextFieldDelegate { self.intputPageRangeTextField.delegate = self; self.currentPageNumberTextField.delegate = self; } - (void)initFormatter { NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init]; formatter.numberStyle = NSNumberFormatterNoStyle; self.currentPageNumberTextField.formatter = formatter; } - (void)configuInitializationParameter { if (!self.printParameter) { self.printParameter = [[KMPrintParameter alloc] init]; self.printParameter.reversePages = NO; self.printParameter.printStyle = kPrintStyle_DocumentAndMarkups; self.printParameter.pageSelectStyle = kPageSelectStyle_AllPage; } self.preview.autoScales = YES; self.preview.backgroundColor = [NSColor whiteColor]; self.preview.wantsLayer = YES; self.preview.layer.borderColor = [NSColor blackColor].CGColor; self.preview.layer.borderWidth = 2; self.intputPageRangeTextField.enabled = NO; } - (void)adjustPreviewSizeWithPage:(PDFPage *)page { CGSize pageSize = [page boundsForBox:kPDFDisplayBoxMediaBox].size; if (page.rotation %180) { pageSize = CGSizeMake(pageSize.height, pageSize.width); } // NSLog(@"pageSize:%f,%f",pageSize.width,pageSize.height); CGFloat wRatio = kPreviewMaxWidth/pageSize.width; CGFloat hRatio = kPreviewMaxHeight/pageSize.height; CGFloat ratio = MIN(wRatio, hRatio); if (ratio == hRatio) { self.previewHeightContraint.constant = kPreviewMaxHeight; self.previewWidthContraint.constant = kPreviewMaxHeight * pageSize.width/pageSize.height; } else { self.previewWidthContraint.constant = kPreviewMaxWidth; self.previewHeightContraint.constant = kPreviewMaxWidth * pageSize.height/pageSize.width; } } - (NSMutableArray *)fetchPagesArrayWithParameter:(kPageSelectStyle)selectStyle { NSMutableArray *pagesArray = [NSMutableArray array]; for (NSInteger i = 0; i < self.pdfDocument.pageCount; i ++) { PDFPage *page = [[self.pdfDocument pageAtIndex:i] copy]; [pagesArray addObject:page]; self.currentPage = self.preview.currentPage; } switch (selectStyle) { case kPageSelectStyle_AllPage: break; case kPageSelectStyle_OddPage: [pagesArray subArrayWithType:KMSubArrayTypeOdd]; break; case kPageSelectStyle_EvenPage: [pagesArray subArrayWithType:KMSubArrayTypeEven]; break; case kPageSelectStyle_CurrentPage: { [pagesArray removeAllObjects]; PDFPage *page = [self.currentPage copy]; [pagesArray addObject:page]; } break; case kPageSelectStyle_HandInput: { [pagesArray removeAllObjects]; for (NSNumber *pageIndexNum in self.selectPagesIndexArray) { PDFPage *page = [[self.pdfDocument pageAtIndex:[pageIndexNum integerValue] - 1] copy]; [pagesArray addObject:page]; } } break; default: break; } return pagesArray; } - (void)pageRangeSelectWithCurrentSelectStyle:(NSButton *)sender { self.allPageButton.state = NO; self.oddPageButton.state = NO; self.evenPageButton.state = NO; self.currentPageButton.state = NO; self.handInputPageButton.state = NO; if (sender) { sender.state = YES; } } - (void)printStyleSelectWithCurrentSelectStyle:(NSButton *)sender { self.printDocumentButton.state = NO; self.printDocumentAndMarkupsButton.state = NO; self.printDocumentAndStampsButton.state = NO; self.printFormOnlyButton.state = NO; if (sender) { sender.state = YES; } } - (void)produceNewPDFForPreview { NSMutableArray *pagesArray = [self fetchPagesArrayWithParameter:self.printParameter.pageSelectStyle]; if (pagesArray.count < 1) { return; } if (self.printParameter.reversePages) { NSMutableArray *tempArray = [NSMutableArray array]; for (NSInteger i = 0; i < pagesArray.count; i ++) { [tempArray addObject:[pagesArray objectAtIndex:pagesArray.count - i -1]]; } [pagesArray removeAllObjects]; [pagesArray addObjectsFromArray:tempArray]; } [self handleAnnotationWithPrintParameter:pagesArray printStyle:self.printParameter.printStyle]; PDFDocument *document = [[PDFDocument alloc] init]; for (NSInteger i = 0; i < pagesArray.count; i++) { PDFPage *page = [pagesArray objectAtIndex:i]; [document insertPage:page atIndex:document.pageCount]; } self.preview.document = document; [self.preview goToFirstPage:nil]; [self adjustPreviewSizeWithPage:[document pageAtIndex:0]]; self.currentPageNumberTextField.stringValue = @"1"; self.totalPageNumberLabel.stringValue = [NSString stringWithFormat:@" / %ld",pagesArray.count]; } - (void)handleAnnotationWithPrintParameter:(NSMutableArray *)pagesArray printStyle:(kPrintStyle)printStyle { for (PDFPage *page in pagesArray) { NSMutableArray *annotationArray = [NSMutableArray new]; for (PDFAnnotation *annotation in page.annotations) { [annotationArray addObject:annotation]; } switch (printStyle) { case kPrintStyle_DocumentOnly: { for (PDFAnnotation *annotation in annotationArray) { [annotation.page removeAnnotation:annotation]; } } break; case kPrintStyle_DocumentAndStamps: { for (PDFAnnotation *annotation in annotationArray) { if (![annotation isKindOfClass:[PDFAnnotationStamp class]]) { [annotation.page removeAnnotation:annotation]; } } } break; default: break; } } } - (void)showCriticalAlert:(NSString *)alertMsg { NSAlert *alert = [[NSAlert alloc] init]; [alert setAlertStyle:NSCriticalAlertStyle]; if (alertMsg) { [alert setInformativeText:alertMsg]; } else { [alert setMessageText:[NSString stringWithFormat:@"%@ %@",self.pdfDocument.documentURL.path.lastPathComponent,NSLocalizedString(@"Invalid page range or the page number is out of range. Please try again.", nil)]]; } [alert runModal]; } #pragma mark - 按钮点击方法 //所有页 - (IBAction)buttonItemClicked_AllPages:(NSButton *)sender { if (sender.state) { if (self.printParameter.pageSelectStyle == kPageSelectStyle_AllPage) { return; } self.intputPageRangeTextField.stringValue = @""; self.intputPageRangeTextField.enabled = NO; [self pageRangeSelectWithCurrentSelectStyle:sender]; self.printParameter.pageSelectStyle = kPageSelectStyle_AllPage; if (self.printParameter.printStyle == kPrintStyle_FormsOnly) { [self createOnlyFormDocument]; } else { [self produceNewPDFForPreview]; } } } //奇数页 - (IBAction)buttonItemClicked_OddPages:(NSButton *)sender { if (sender.state) { if (self.printParameter.pageSelectStyle == kPageSelectStyle_OddPage) { return; } self.intputPageRangeTextField.stringValue = @""; self.intputPageRangeTextField.enabled = NO; [self pageRangeSelectWithCurrentSelectStyle:sender]; self.printParameter.pageSelectStyle = kPageSelectStyle_OddPage; if (self.printParameter.printStyle == kPrintStyle_FormsOnly) { [self createOnlyFormDocument]; } else { [self produceNewPDFForPreview]; } } } //偶数页 - (IBAction)buttonItemClicked_EvenPages:(NSButton *)sender { if (sender.state) { if (self.printParameter.pageSelectStyle == kPageSelectStyle_EvenPage) { return; } self.intputPageRangeTextField.stringValue = @""; self.intputPageRangeTextField.enabled = NO; [self pageRangeSelectWithCurrentSelectStyle:sender]; self.printParameter.pageSelectStyle = kPageSelectStyle_EvenPage; if (self.printParameter.printStyle == kPrintStyle_FormsOnly) { [self createOnlyFormDocument]; } else { [self produceNewPDFForPreview]; } } } //当前页面 - (IBAction)buttonItemClicked_CurrentPage:(NSButton *)sender { if (sender.state) { if (self.printParameter.pageSelectStyle == kPageSelectStyle_CurrentPage) { return; } self.intputPageRangeTextField.stringValue = @""; self.intputPageRangeTextField.enabled = NO; [self pageRangeSelectWithCurrentSelectStyle:sender]; self.printParameter.pageSelectStyle = kPageSelectStyle_CurrentPage; if (self.printParameter.printStyle == kPrintStyle_FormsOnly) { [self createOnlyFormDocument]; } else { [self produceNewPDFForPreview]; } } } //手动输入页码 - (IBAction)buttonItemClicked_handInputPages:(NSButton *)sender { if (sender.state) { if (self.printParameter.pageSelectStyle == kPageSelectStyle_HandInput) { return; } self.intputPageRangeTextField.enabled = YES; self.intputPageRangeTextField.stringValue = @""; [self.window makeFirstResponder:self.intputPageRangeTextField]; [self pageRangeSelectWithCurrentSelectStyle:sender]; self.printParameter.pageSelectStyle = kPageSelectStyle_HandInput; } } //反排序 - (IBAction)buttonItemClicked_Reversepages:(NSButton *)sender { self.printParameter.reversePages = sender.state; if (self.printParameter.printStyle == kPrintStyle_FormsOnly) { [self createOnlyFormDocument]; } else { [self produceNewPDFForPreview]; } } //只打印Document - (IBAction)buttonItemClicked_PrintDocumentOnly:(NSButton *)sender { if (sender.state) { if (self.printParameter.printStyle == kPrintStyle_DocumentOnly) { return; } [self printStyleSelectWithCurrentSelectStyle:sender]; self.printParameter.printStyle = kPrintStyle_DocumentOnly; [self produceNewPDFForPreview]; } } //打印Document和注释 - (IBAction)buttonItemClicked_PrintDocumentAndMarkups:(NSButton *)sender { if (sender.state) { if (self.printParameter.printStyle == kPrintStyle_DocumentAndMarkups) { return; } [self printStyleSelectWithCurrentSelectStyle:sender]; self.printParameter.printStyle = kPrintStyle_DocumentAndMarkups; [self produceNewPDFForPreview]; } } //打印Document和Stamp类型注释 - (IBAction)buttonItemClicked_PrintDocumentAndStamps:(NSButton *)sender { if (sender.state) { if (self.printParameter.printStyle == kPrintStyle_DocumentAndStamps) { return; } [self printStyleSelectWithCurrentSelectStyle:sender]; self.printParameter.printStyle = kPrintStyle_DocumentAndStamps; [self produceNewPDFForPreview]; } } - (IBAction)buttonItemClicked_PrintFormOnly:(NSButton *)sender { if (sender.state) { if (self.printParameter.printStyle == kPrintStyle_FormsOnly) { return; } [self printStyleSelectWithCurrentSelectStyle:sender]; self.printParameter.printStyle = kPrintStyle_FormsOnly; [self createOnlyFormDocument]; } } //Preview上一页 - (IBAction)buttonItemClicked_PreviousPage:(NSButton *)sender { if ([self.preview canGoToPreviousPage]) { [self.preview goToPreviousPage:nil]; self.currentPageNumberTextField.stringValue = [NSString stringWithFormat:@"%ld",[self.preview.document indexForPage:[self.preview currentPage]] + 1]; [self adjustPreviewSizeWithPage:[self.preview currentPage]]; } } //PreView下一页 - (IBAction)buttonItemClicked_NextPage:(NSButton *)sender { if ([self.preview canGoToNextPage]) { [self.preview goToNextPage:nil]; self.currentPageNumberTextField.stringValue = [NSString stringWithFormat:@"%ld",[self.preview.document indexForPage:[self.preview currentPage]] + 1]; [self adjustPreviewSizeWithPage:[self.preview currentPage]]; } } //Poster - (IBAction)buttonItemClicked_Poster:(NSButton *)sender { if (![KMMemberInfo shared].isMemberAllFunction) { [self close]; NSWindowController *winC = [KMProductCompareWC shared]; winC.kEventName = @"MenuBar_PrintPoster_BuyNow"; [[KMMemberInfo shared] advancedFunctionUsage]; return; } [self close]; _posterVC = [[KMPDFPosterPrintWindowController alloc] initWithPDFDocument:self.pdfDocument]; [[NSApp mainWindow] beginSheet:_posterVC.window completionHandler:^(NSModalResponse returnCode) { }]; // [posterVC beginSheetModalForWindow:[NSApp mainWindow] completionHandler:nil]; } //Multiple - (IBAction)buttonItemClicked_Multiple:(NSButton *)sender { if (![KMMemberInfo shared].isMemberAllFunction) { [self close]; NSWindowController *winC = [KMProductCompareWC shared]; winC.kEventName = @"MenuBar_PrintMultiple_BuyNow"; [[KMMemberInfo shared] advancedFunctionUsage]; return; } [self close]; _multipleVC = [[KMPDFMultiplePrintWindowController alloc] initWithPDFDocument:self.pdfDocument]; // [multipleVC beginSheetModalForWindow:[NSApp mainWindow] completionHandler:nil]; [[NSApp mainWindow] beginSheet:_multipleVC.window completionHandler:^(NSModalResponse returnCode) { }]; } //Booklet - (IBAction)buttonItemClicked_Booklet:(NSButton *)sender { if (![KMMemberInfo shared].isMemberAllFunction) { [self close]; NSWindowController *winC = [KMProductCompareWC shared]; winC.kEventName = @"MenuBar_PrintBooklet_BuyNow"; [[KMMemberInfo shared] advancedFunctionUsage]; return; } [self close]; _bookletVC = [[KMPDFBookletWindowController alloc] initWithDocument:self.pdfDocument]; // [bookletVC beginSheetModalForWindow:[NSApp mainWindow] completionHandler:nil]; [[NSApp mainWindow] beginSheet:_bookletVC.window completionHandler:^(NSModalResponse returnCode) { }]; } //取消 - (IBAction)buttonItemClicked_Cancel:(NSButton *)sender { [self close]; } - (void)close{ if (self.window.isSheet) { [self.window.sheetParent endSheet:self.window]; // [self dismissSheet:nil]; } else { [super close]; } } //打印 - (IBAction)buttonItemClicked_Print:(NSButton *)sender { [self.window makeFirstResponder:self.preview]; if (self.callBack) { [self close]; self.callBack(self.preview.document); } } #pragma mark - NSTextField Delegate - (void)controlTextDidEndEditing:(NSNotification *)notification { NSTextField *textField = notification.object; if ([textField isEqual:self.intputPageRangeTextField]) { if (!self.selectPagesIndexArray) { self.selectPagesIndexArray = [NSMutableArray array]; }else{ [self.selectPagesIndexArray removeAllObjects]; } KMFileAttribute *fileAttribute = [[KMFileAttribute alloc] init]; fileAttribute.filePath = [self.pdfDocument.documentURL path]; fileAttribute.bAllPage = NO; fileAttribute.pagesString = self.intputPageRangeTextField.stringValue; if ([fileAttribute fetchSelectPages]) { [self.selectPagesIndexArray addObjectsFromArray: [fileAttribute fetchSelectPages]]; if (self.printParameter.printStyle == kPrintStyle_FormsOnly) { [self createOnlyFormDocument]; } else { [self produceNewPDFForPreview]; } }else{ [self showCriticalAlert:nil]; } }else if ([textField isEqual:self.currentPageNumberTextField]){ PDFPage *targetPage = [self.preview.document pageAtIndex:[self.currentPageNumberTextField.stringValue integerValue] - 1]; if (targetPage) { [self.preview goToPage:targetPage]; } } } - (void)controlTextDidChange:(NSNotification *)notification { NSTextField *textField = notification.object; if ([textField isEqual:self.currentPageNumberTextField]) { NSString *string = [self.currentPageNumberTextField.formatter stringFromNumber:[NSNumber numberWithFloat:[self.currentPageNumberTextField.stringValue integerValue]]]; if ([string integerValue] > self.preview.document.pageCount) { string = [NSString stringWithFormat:@"%ld",self.preview.document.pageCount]; }else if ([string integerValue] <= 0){ string = @"1"; } self.currentPageNumberTextField.stringValue = string; } } #pragma mark - 开始转圈,隐藏转圈提示 - (void)showWaitting { if (!_maskView) { _maskView = [[KMBookletMaskView alloc] initWithFrame:NSMakeRect(0, 0, self.window.frame.size.width, self.window.frame.size.height)]; } [self.window.contentView addSubview:_maskView]; } - (void)hideWaitting { [_maskView removeFromSuperview]; } //创建一个新的空白只打印formPDF - (void)createOnlyFormDocument { NSMutableArray *pagesArray = [self fetchPagesArrayWithParameter:self.printParameter.pageSelectStyle]; if (pagesArray.count < 1) { NSBeep(); return; } if (self.printParameter.reversePages) { pagesArray = [NSMutableArray arrayWithArray:[[pagesArray reverseObjectEnumerator] allObjects]]; } //取最大宽高作为画布大小 CGFloat maxWidth = 0; CGFloat maxHeight = 0; for (NSInteger i = 0; i < pagesArray.count; i++) { PDFPage *page = [pagesArray objectAtIndex:i]; CGRect rect = [page boundsForBox:kPDFDisplayBoxMediaBox]; maxWidth = MAX(maxWidth, CGRectGetWidth(rect)); maxHeight = MAX(maxHeight, CGRectGetHeight(rect)); } //生成画布 CGContextRef myPDFContext = NULL; CGRect mediaBox = CGRectMake(0, 0, maxWidth, maxHeight); NSString *newFieldName = [[[self.pdfDocument.documentURL.lastPathComponent stringByDeletingPathExtension] stringByAppendingString:@"_FormOnly"] stringByAppendingPathExtension:@"pdf"]; NSString *newPDFPath = [[[NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:[NSBundle mainBundle].bundleIdentifier] stringByAppendingPathComponent:newFieldName]; CFStringRef ref = (__bridge CFStringRef)newPDFPath; myPDFContext = PDFContextCreate(&mediaBox, ref); for (NSInteger i = 0; i < pagesArray.count; i++) { PDFPage *page = [pagesArray objectAtIndex:i]; mediaBox.size.width = [page boundsForBox:kPDFDisplayBoxMediaBox].size.width; mediaBox.size.height = [page boundsForBox:kPDFDisplayBoxMediaBox].size.height; CFStringRef myKeys[1]; CFTypeRef myValues[1]; myKeys[0] = kCGPDFContextMediaBox; myValues[0] = (CFTypeRef) CFDataCreate(NULL,(const UInt8 *)&mediaBox, sizeof (CGRect)); CFDictionaryRef pageDictionary = CFDictionaryCreate(NULL, (const void **) myKeys, (const void **) myValues, 1, &kCFTypeDictionaryKeyCallBacks, & kCFTypeDictionaryValueCallBacks); CGPDFContextBeginPage(myPDFContext, pageDictionary); /*-------------绘制页开始---------------------**/ NSMutableArray *array = [NSMutableArray array]; for (NSInteger i = 0; i < page.annotations.count; i++) { PDFAnnotation *annotation = [page.annotations objectAtIndex:i]; if ([annotation isKindOfClass:[PDFAnnotationButtonWidget class]] || [annotation isKindOfClass:[PDFAnnotationTextWidget class]] || [annotation isKindOfClass:[PDFAnnotationChoiceWidget class]]) { [array addObject:annotation]; } } for (NSInteger i = 0; i < array.count; i++) { PDFAnnotation *annotation = [array objectAtIndex:i]; CGRect newPosition = annotation.bounds; // if (page.rotation == 90) { // newPosition = CGRectMake(CGRectGetMinY(annotation.bounds), CGRectGetHeight(mediaBox) - CGRectGetMaxX(annotation.bounds), CGRectGetHeight(annotation.bounds), CGRectGetWidth(annotation.bounds)); // } else if (page.rotation == 180) { // newPosition = CGRectMake(CGRectGetMaxX(mediaBox) - CGRectGetMaxX(annotation.bounds), CGRectGetMaxY(mediaBox) - CGRectGetMaxY(annotation.bounds), CGRectGetWidth(annotation.bounds), CGRectGetHeight(annotation.bounds)); // } else if (page.rotation == 270) { // newPosition = CGRectMake(CGRectGetMaxX(mediaBox) - CGRectGetMaxY(annotation.bounds), CGRectGetMinX(annotation.bounds), CGRectGetHeight(annotation.bounds), CGRectGetWidth(annotation.bounds)); // } if ([annotation isKindOfClass:[PDFAnnotationButtonWidget class]]) { PDFAnnotationButtonWidget *actulWidget = (PDFAnnotationButtonWidget *)annotation; if (actulWidget.controlType == kPDFWidgetCheckBoxControl) { CGContextSaveGState(myPDFContext); /* 如果没有签署,那么不画 CGContextAddRect(myPDFContext, newPosition); CGContextStrokePath(myPDFContext);*/ if (actulWidget.state) { CGFloat originalWidth = CGRectGetWidth(newPosition); CGFloat originalHeight = CGRectGetHeight(newPosition); CGFloat min = MIN(CGRectGetWidth(newPosition), CGRectGetHeight(newPosition)); newPosition.size.width = min; newPosition.size.height = min; CGContextTranslateCTM(myPDFContext, newPosition.origin.x + (originalWidth - newPosition.size.width)/2.0, newPosition.origin.y + (originalHeight - newPosition.size.height /2.0)); CGFloat x = newPosition.size.width/7; CGFloat y = newPosition.size.height/5; CGContextMoveToPoint(myPDFContext, x,newPosition.size.height/2.0); CGContextAddLineToPoint(myPDFContext,(newPosition.size.width-2*x)/3.0+x, y); CGContextAddLineToPoint(myPDFContext, newPosition.size.width-x, newPosition.size.height-y); CGContextStrokePath(myPDFContext); } CGContextRestoreGState(myPDFContext); } else if (actulWidget.controlType == kPDFWidgetRadioButtonControl) { CGContextSaveGState(myPDFContext); /*如果没有签署,那么不画 CGContextStrokeEllipseInRect(myPDFContext, newPosition);*/ if (actulWidget.state) { CGContextSetStrokeColorWithColor(myPDFContext, [NSColor blackColor].CGColor); CGContextSetFillColorWithColor(myPDFContext, [NSColor blackColor].CGColor); CGFloat x = newPosition.size.width/9; CGContextFillEllipseInRect(myPDFContext, CGRectInset(newPosition, x, x)); } CGContextRestoreGState(myPDFContext); } else { CGContextSaveGState(myPDFContext); CGContextAddRect(myPDFContext, newPosition); CGContextSetFillColorWithColor(myPDFContext, [NSColor colorWithRed:220/255.0 green:220/255.0 blue:220/255.0 alpha:1.0].CGColor); CGContextFillPath(myPDFContext); CGContextRestoreGState(myPDFContext); if (actulWidget.caption.length > 0) { [NSGraphicsContext saveGraphicsState]; NSGraphicsContext *context = [NSGraphicsContext graphicsContextWithGraphicsPort:myPDFContext flipped:NO]; [NSGraphicsContext setCurrentContext:context]; NSDictionary *attributeDic = @{NSFontAttributeName:actulWidget.font,NSForegroundColorAttributeName:[(PDFAnnotationTextWidget *)actulWidget fontColor]}; CGSize size = [actulWidget.caption sizeWithAttributes:attributeDic]; CGRect drawRect = newPosition; if (CGRectGetWidth(drawRect) > size.width) { drawRect.origin.x += (CGRectGetWidth(drawRect) - size.width)/2.0; } if (CGRectGetHeight(drawRect) > size.height) { drawRect.origin.y += (CGRectGetHeight(drawRect) - size.height)/2.0; } drawRect.size.height = size.height; [actulWidget.caption drawInRect:drawRect withAttributes:@{NSFontAttributeName:actulWidget.font,NSForegroundColorAttributeName:[(PDFAnnotationTextWidget *)actulWidget fontColor]}]; [NSGraphicsContext restoreGraphicsState]; } } } else if ([annotation isKindOfClass:[PDFAnnotationTextWidget class]]) { PDFAnnotationTextWidget *actualWidget = (PDFAnnotationTextWidget *)annotation; if ([actualWidget stringValue] > 0) { [NSGraphicsContext saveGraphicsState]; NSGraphicsContext *context = [NSGraphicsContext graphicsContextWithGraphicsPort:myPDFContext flipped:NO]; [NSGraphicsContext setCurrentContext:context]; NSDictionary *attributeDic = @{NSFontAttributeName:actualWidget.font,NSForegroundColorAttributeName:[actualWidget fontColor]}; if (actualWidget.isMultiline) { NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:actualWidget.stringValue]; [attributeString setAlignment:actualWidget.alignment range:NSMakeRange(0, attributeString.length)]; [attributeString addAttributes:attributeDic range:NSMakeRange(0, attributeString.length)]; [attributeString drawInRect:newPosition]; } else { CGSize size = [actualWidget.stringValue sizeWithAttributes:attributeDic]; if (size.height < newPosition.size.height) { newPosition.origin.y = CGRectGetMaxY(newPosition) - size.height; newPosition.size.height = size.height; } NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:actualWidget.stringValue]; [attributeString addAttributes:attributeDic range:NSMakeRange(0, attributeString.length)]; [attributeString setAlignment:actualWidget.alignment range:NSMakeRange(0, attributeString.length)]; [attributeString drawInRect:newPosition]; } [NSGraphicsContext restoreGraphicsState]; } } else if([annotation isKindOfClass:[PDFAnnotationChoiceWidget class]]){ PDFAnnotationChoiceWidget *actualWidget = (PDFAnnotationChoiceWidget *)annotation; if (actualWidget.isListChoice) { NSDictionary *attributeDict = @{NSFontAttributeName:actualWidget.font,NSForegroundColorAttributeName:[actualWidget fontColor]}; CGFloat fontHeight = [actualWidget.stringValue sizeWithAttributes:attributeDict].height; NSGraphicsContext *context = [NSGraphicsContext graphicsContextWithGraphicsPort:myPDFContext flipped:NO]; [NSGraphicsContext setCurrentContext:context]; for (NSInteger i = 0; i < actualWidget.choices.count; i++) { CGRect drawRect = CGRectZero; CGFloat drawedHeight = i * fontHeight; CGFloat drawingHeight = fontHeight; drawRect.origin.y = MAX(CGRectGetMaxY(newPosition) - drawedHeight - drawingHeight,CGRectGetMinY(newPosition)); drawRect.origin.x = newPosition.origin.x; drawRect.size.width = CGRectGetWidth(newPosition); drawRect.size.height = MIN(fontHeight, CGRectGetHeight(newPosition) - drawedHeight); NSString *drawString = [actualWidget.choices objectAtIndex:i]; if ([drawString isEqualToString:actualWidget.stringValue]) { CGContextAddRect(myPDFContext, drawRect); CGContextSetFillColorWithColor(myPDFContext, [NSColor colorWithRed:155/255.0 green:155/255.0 blue:155/255.0 alpha:1.0].CGColor); CGContextFillPath(myPDFContext); } [drawString drawInRect:drawRect withAttributes:attributeDict]; } [NSGraphicsContext restoreGraphicsState]; } else { CGContextSaveGState(myPDFContext); [NSGraphicsContext saveGraphicsState]; NSGraphicsContext *context = [NSGraphicsContext graphicsContextWithGraphicsPort:myPDFContext flipped:NO]; [NSGraphicsContext setCurrentContext:context]; NSDictionary *attributeDic = @{NSFontAttributeName:actualWidget.font,NSForegroundColorAttributeName:[actualWidget fontColor]}; CGSize size = [actualWidget.stringValue sizeWithAttributes:attributeDic]; CGRect drawRect = newPosition; if (CGRectGetWidth(drawRect) > size.width) { drawRect.origin.x += (CGRectGetWidth(drawRect) - size.width)/2.0; } if (CGRectGetHeight(drawRect) > size.height) { drawRect.origin.y += (CGRectGetHeight(drawRect) - size.height)/2.0; } drawRect.size.height = size.height; [[actualWidget stringValue] drawInRect:drawRect withAttributes:attributeDic]; [NSGraphicsContext restoreGraphicsState]; CGContextRestoreGState(myPDFContext); } } else { CGContextSaveGState(myPDFContext); CGContextAddRect(myPDFContext, newPosition); CGContextSetFillColorWithColor(myPDFContext, [NSColor yellowColor].CGColor); CGContextFillPath(myPDFContext); CGContextRestoreGState(myPDFContext); } } /*-------------绘制页结束---------------------**/ CGPDFContextEndPage(myPDFContext); CFRelease(pageDictionary); CFRelease(myValues[0]); } CGPDFContextClose(myPDFContext); CGContextRelease(myPDFContext); self.preview.document = [[PDFDocument alloc] initWithURL:[NSURL fileURLWithPath:newPDFPath]]; [self.preview goToFirstPage:nil]; [self adjustPreviewSizeWithPage:[self.preview.document pageAtIndex:0]]; self.currentPageNumberTextField.stringValue = @"1"; self.totalPageNumberLabel.stringValue = [NSString stringWithFormat:@" / %ld",pagesArray.count]; } //创建一个图形上下文对象 CGContextRef PDFContextCreate (const CGRect *inMediaBox, CFStringRef path) { CGContextRef myOutContext = NULL; CFURLRef url; url = CFURLCreateWithFileSystemPath (NULL, // 1 path, kCFURLPOSIXPathStyle, false); if (url != NULL) { myOutContext = CGPDFContextCreateWithURL (url,// 2 inMediaBox, NULL); CFRelease(url);// 3 } return myOutContext;// 4 } @end