123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531 |
- //
- // KMPDFMorePagePrintManager.m
- // PDF Reader Pro Edition
- //
- // Created by 丁林圭 on 2018/5/17.
- //
- #import "KMPDFMultipleManager.h"
- #pragma mark - KMPDFMultiple
- @interface KMEachPageProperties()
- @end
- @implementation KMEachPageProperties
- -(void)dealloc {
- }
- @end
- #pragma mark - KMPDFMultipleManager
- @interface KMPDFMultipleManager()
- @end
- @implementation KMPDFMultipleManager
- - (void)dealloc {
- }
- #pragma mark Private Action
- - (void)PDFKitDrawPageToContext:(CGContextRef)context eachPages:(NSArray *)pages multipleOption:(KMEachPageProperties *)properties
- {
- CGSize size = properties.pageSize;
- CGFloat width = size.width;
- CGFloat height =size.height;
-
- if (kKMPDFMultiplePageDirection_Landscape == properties.direction) {
- width = size.height;
- height = size.width;
- }
-
- CGFloat contextWidth = width- properties.edgeInsets.left - properties.edgeInsets.right;//实际画page的总宽度
- CGFloat contextHeight = height - properties.edgeInsets.bottom - properties.edgeInsets.top;//实际画page的总高度
-
- NSInteger columnCout = properties.columnCout;
- NSInteger rowCount = properties.rowCount;
-
- CGFloat columnSpace = properties.columnSpace;
- NSInteger rowSpace = properties.rowSpace;
-
- CGFloat drawPageMaxW = (contextWidth - (columnCout - 1) * columnSpace)/ columnCout; //page的能画的最大宽度
- CGFloat drawPageMaxH = (contextHeight - (rowCount -1) * rowSpace) / rowCount;//page能画的最大高度
-
- CGFloat scanl = 1.0;
- CGFloat xTransform = 0;
- CGFloat yTransform = 0;
-
- if (kKMPDFMultiplePageOrder_LongitudinalAntitone == properties.order || kKMPDFMultiplePageOrder_Longitudinal == properties.order) {
- rowCount = properties.columnCout;
- columnCout = properties.rowCount;
- }
-
- for (NSInteger i = 0; i < rowCount; i++) {
- for (NSInteger j = 0;j < columnCout; j++) {
- NSUInteger index = j + i * columnCout;
-
- if (index >= pages.count) {
- break;
- }
- PDFPage *drawPage = pages[index];
- NSRect pageBounds = [drawPage boundsForBox:kPDFDisplayBoxCropBox];
- CGFloat orgPageWidth = pageBounds.size.width;//原始page的宽度(不管有没有旋转,都是旋转度数等于0)
- CGFloat orgPageHeight = pageBounds.size.height;//原始page的高度
-
- NSMutableArray *annotations = [NSMutableArray array];
- for (PDFAnnotation *annotation in drawPage.annotations) {
- [annotations addObject:annotation];
- }
- if (kKMPDFCommentsForms_Documents == properties.commentsForms) {
- for (PDFAnnotation *annotation in annotations) {
- [annotation.page removeAnnotation:annotation];
- }
- } else if (kKMPDFCommentsForms_DocumentStamps == properties.commentsForms) {
- for (PDFAnnotation *annotation in annotations) {
- if (![annotation isKindOfClass:[PDFAnnotationStamp class]]) {
- [annotation.page removeAnnotation:annotation];
- }
- }
- }
-
- NSInteger rotate = drawPage.rotation;
- if (90 == rotate || 270 == rotate) {
- orgPageWidth = pageBounds.size.height;
- orgPageHeight = pageBounds.size.width;
- }
- scanl = MIN(drawPageMaxW/orgPageWidth,drawPageMaxH/orgPageHeight);
- //取出page横竖时能显示的最大Rect
- if (properties.isAutoRotate) {
- CGFloat tScanl1 = MIN(drawPageMaxW/pageBounds.size.width,drawPageMaxH/pageBounds.size.height);//page旋转度数为0度或者180度时,在指定的大小内,能显示的比例
- CGFloat tScanl2 = MIN(drawPageMaxW/pageBounds.size.height,drawPageMaxH/pageBounds.size.width);//page旋转度数为90度或者270度时,在指定的大小内,能显示的比例
-
- scanl = MAX(tScanl1, tScanl2);
-
- if (tScanl1 > tScanl2) {
- //高为竖直排列时,显示最大,则需将page时90度或者270度需要进行旋转
- if (rotate == 90 || rotate == 270) {
- [drawPage setRotation:rotate - 90];
- }
- } else {
- //宽为竖直排列时,显示最大,则需将page时0度或者180度需要进行旋转
- if (rotate == 0 || rotate == 180) {
- [drawPage setRotation:rotate - 90];
- }
- }
-
- if ( 90 == drawPage.rotation || 270 == drawPage.rotation) {
- orgPageWidth = pageBounds.size.height;
- orgPageHeight = pageBounds.size.width;
- } else {
- orgPageWidth = pageBounds.size.width;
- orgPageHeight = pageBounds.size.height;
- }
- }
-
- if (scanl >1) {
- scanl = 1;
- }
- //每一页都是它居中;
- CGFloat spaceX = (drawPageMaxW - orgPageWidth * scanl)/2;
- CGFloat spaceY = (drawPageMaxH - orgPageHeight* scanl)/2;
-
- if (kKMPDFMultiplePageOrder_Transverse == properties.order) {
- xTransform = (drawPageMaxW + columnSpace) * j + properties.edgeInsets.left + spaceX;
- //页面内容高度 + 下边的行间距 - 第几个cell的高度 +居中
- yTransform = contextHeight + properties.edgeInsets.bottom - (drawPageMaxH + rowSpace) * (i+1) + spaceY + rowSpace;
- } else if (kKMPDFMultiplePageOrder_TransverseAntitone == properties.order) {
- xTransform = contextWidth + properties.edgeInsets.left - (drawPageMaxW + columnSpace) * (j + 1) + spaceX + columnSpace;
- yTransform = contextHeight - (drawPageMaxH + rowSpace) * (i+1) + spaceY + properties.edgeInsets.bottom + rowSpace;
- } else if (kKMPDFMultiplePageOrder_Longitudinal == properties.order) {
- xTransform = (drawPageMaxW + columnSpace) * i + properties.edgeInsets.left + spaceX;
- yTransform = contextHeight - (drawPageMaxH + rowSpace) * (j+1) + spaceY + properties.edgeInsets.bottom + rowSpace;
- } else if (kKMPDFMultiplePageOrder_LongitudinalAntitone == properties.order) {
- xTransform = contextWidth + properties.edgeInsets.left - (drawPageMaxW + columnSpace) * (i + 1) + spaceX + columnSpace;
- yTransform = contextHeight - (drawPageMaxH + rowSpace) * (j+1) + spaceY + properties.edgeInsets.bottom + rowSpace;
- }
-
- [NSGraphicsContext saveGraphicsState];
-
- //平移
- CGContextTranslateCTM(context, xTransform,yTransform);
-
- //缩放
- CGContextScaleCTM(context, scanl, scanl);
- if (@available(macOS 10.12, *)) {
- [drawPage drawWithBox:kPDFDisplayBoxCropBox toContext:context];
- [drawPage transformContext:context forBox:kPDFDisplayBoxCropBox];
- } else {
- [NSGraphicsContext saveGraphicsState];
- [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:YES]];
- [drawPage drawWithBox:kPDFDisplayBoxCropBox];
- [NSGraphicsContext restoreGraphicsState];
- [drawPage transformContextForBox:kPDFDisplayBoxCropBox];
- }
- if (properties.isHasBorder) {
-
- CGFloat borderWidth = pageBounds.size.width;
- CGFloat borderHeight = pageBounds.size.height;
- if ( 90 == drawPage.rotation || 270 == drawPage.rotation) {
- borderWidth = pageBounds.size.height;
- borderWidth = pageBounds.size.width;
- }
-
- CGRect dirtyRect = CGRectMake(pageBounds.origin.x, pageBounds.origin.y, borderWidth, borderHeight);
- CGContextAddRect(context, dirtyRect);
- CGContextSetRGBStrokeColor(context, 0.0, 0.0, 0.0, 1.0);
- CGContextStrokePath(context);
- }
-
- [NSGraphicsContext restoreGraphicsState];
- }
- }
- }
- - (void)CGDrawPageToContext:(CGContextRef)context eachPages:(NSArray *)pages multipleOption:(KMEachPageProperties *)properties
- {
- CGSize size = properties.pageSize;
- CGFloat width = size.width;
- CGFloat height =size.height;
-
- if (kKMPDFMultiplePageDirection_Landscape == properties.direction) {
- width = size.height;
- height = size.width;
- }
-
- CGFloat contextWidth = width- properties.edgeInsets.left - properties.edgeInsets.right;
- CGFloat contextHeight = height - properties.edgeInsets.bottom - properties.edgeInsets.top;
-
- NSInteger columnCout = properties.columnCout;
- NSInteger rowCount = properties.rowCount;
- CGFloat columnSpace = properties.columnSpace;
- NSInteger rowSpace = properties.rowSpace;
-
- CGFloat drawPageW = (contextWidth - (columnCout - 1) * columnSpace)/ columnCout; //画page的宽度
- CGFloat drawPageH = (contextHeight - (rowCount -1) * rowSpace) / rowCount;//画page的高度
-
- CGFloat scanl = 1.0;
- CGFloat xTransform = 0;
- CGFloat yTransform = 0;
-
- if (kKMPDFMultiplePageOrder_LongitudinalAntitone == properties.order || kKMPDFMultiplePageOrder_Longitudinal == properties.order) {
- rowCount = properties.columnCout;
- columnCout = properties.rowCount;
- }
- for (NSInteger i = 0; i < rowCount; i++) {
- for (NSInteger j = 0;j < columnCout; j++) {
- NSUInteger index = j + i * columnCout;
-
- if (index >= pages.count) {
- break;
- }
- PDFPage *drawPage = pages[index];
- NSRect pageBounds = [drawPage boundsForBox:kPDFDisplayBoxCropBox];
- CGFloat orgPageWidth = pageBounds.size.width;//原始page的宽度
- CGFloat orgPageHeight = pageBounds.size.height;//原始page的高度
-
- NSInteger rotate = drawPage.rotation;
-
- if (90 == rotate || 270 == rotate) {
- orgPageWidth = pageBounds.size.height;
- orgPageHeight = pageBounds.size.width;
- }
-
- if (properties.isAutoRotate) {
- CGFloat tScanl1 = MIN(drawPageW/pageBounds.size.width,drawPageH/pageBounds.size.height);
- CGFloat tScanl2 = MIN(drawPageW/pageBounds.size.height,drawPageH/pageBounds.size.width);
-
- scanl = MAX(tScanl1, tScanl2);
-
- if (tScanl1 > tScanl2) {
- if (rotate == 90 || rotate == 270) {
- rotate = rotate - 90;
- }
- } else {
- if (rotate != 90 || rotate != 270) {
- rotate = rotate - 90;
- }
- }
-
- if (rotate == -90) {
- rotate = 270;
- }
- }
-
-
- if ( 90 == rotate || 270 == rotate) {
- orgPageWidth = pageBounds.size.height;
- orgPageHeight = pageBounds.size.width;
- } else {
- orgPageWidth = pageBounds.size.width;
- orgPageHeight = pageBounds.size.height;
- }
- scanl = MIN(drawPageW/orgPageWidth,drawPageH/orgPageHeight);
- if (scanl >1) {
- scanl = 1;
- }
- // //每一页都是它居中;
- CGFloat spaceX = (drawPageW - orgPageWidth * scanl)/2;
- CGFloat spaceY = (drawPageH - orgPageHeight* scanl)/2;
-
- CGFloat offsetX = 0;
- CGFloat offsetY = 0;
- if (kKMPDFMultiplePageOrder_Transverse == properties.order) {
- if (rotate == 270) {
- offsetX = (properties.edgeInsets.bottom+ spaceY)/scanl;
- offsetY = - pageBounds.size.height - (properties.edgeInsets.left + spaceX)/scanl;
-
- xTransform = offsetX + (drawPageH + rowSpace)/scanl * (rowCount - i -1) ;
- yTransform = offsetY - (drawPageW + columnSpace)/scanl * j;
- } else if (rotate == 180) {
- offsetX = -(pageBounds.size.width + properties.edgeInsets.left/scanl + spaceX/scanl);
- offsetY = -(pageBounds.size.height + properties.edgeInsets.bottom/scanl + spaceY/scanl);
- xTransform = offsetX - (drawPageW + columnSpace)/scanl * j ;
- yTransform = offsetY - (drawPageH + rowSpace)/scanl * (rowCount - i -1);
- } else if (rotate == 90) {
-
- offsetX = - (pageBounds.size.width + (properties.edgeInsets.bottom+ spaceY)/scanl);
- offsetY = (properties.edgeInsets.left + spaceX)/scanl;
- xTransform = offsetX - (drawPageH + rowSpace)/scanl * (rowCount - i -1) ;
- yTransform = offsetY + (drawPageW + columnSpace)/scanl * j;
- } else {
- offsetX = (properties.edgeInsets.left + spaceX)/scanl;
- offsetY = (properties.edgeInsets.bottom+spaceY)/scanl;
-
- xTransform = offsetX + (drawPageW + columnSpace)/scanl * j ;
- yTransform = (offsetY + (drawPageH + rowSpace)/scanl * (rowCount - i -1));
- }
- } else if (kKMPDFMultiplePageOrder_TransverseAntitone == properties.order) {
- if (rotate == 270) {
- offsetX = (properties.edgeInsets.bottom+ spaceY)/scanl;
- offsetY = - pageBounds.size.height - (properties.edgeInsets.left + spaceX)/scanl;
-
- xTransform = offsetX + (drawPageH + rowSpace)/scanl * (rowCount - i -1) ;
- yTransform = offsetY - (drawPageW + columnSpace)/scanl * (columnCout - 1 - j);
-
- } else if (rotate == 180) {
- offsetX = -(pageBounds.size.width + properties.edgeInsets.left/scanl + spaceX/scanl);
- offsetY = -(pageBounds.size.height + properties.edgeInsets.bottom/scanl + spaceY/scanl);
-
- xTransform = offsetX - (drawPageW + columnSpace)/scanl * (columnCout - 1 - j) ;
- yTransform = offsetY - (drawPageH + rowSpace)/scanl * (rowCount - i -1);
-
- } else if (rotate == 90) {
-
- offsetX = - (pageBounds.size.width + (properties.edgeInsets.bottom+ spaceY)/scanl);
- offsetY = (properties.edgeInsets.left + spaceX)/scanl;
-
- xTransform = offsetX - (drawPageH + rowSpace)/scanl * (rowCount - i -1) ;
- yTransform = offsetY + (drawPageW + columnSpace)/scanl * (columnCout - 1 - j);
-
- } else {
- offsetX = (properties.edgeInsets.left + spaceX)/scanl;
- offsetY = (properties.edgeInsets.bottom+spaceY)/scanl;
-
- xTransform = offsetX + (drawPageW + columnSpace)/scanl * (columnCout - 1 - j) ;
- yTransform = (offsetY + (drawPageH + rowSpace)/scanl * (rowCount - i -1));
- }
- } else if (kKMPDFMultiplePageOrder_Longitudinal == properties.order) {
- if (rotate == 270) {
- offsetX = (properties.edgeInsets.bottom+ spaceY)/scanl;
- offsetY = - pageBounds.size.height - (properties.edgeInsets.left + spaceX)/scanl;
-
- xTransform = offsetX + (drawPageH + rowSpace)/scanl * (rowCount - j -1) ;
- yTransform = offsetY - (drawPageW + columnSpace)/scanl * i;
-
- } else if (rotate == 180) {
- offsetX = -(pageBounds.size.width + properties.edgeInsets.left/scanl + spaceX/scanl);
- offsetY = -(pageBounds.size.height + properties.edgeInsets.bottom/scanl + spaceY/scanl);
-
- xTransform = offsetX - (drawPageW + columnSpace)/scanl * i ;
- yTransform = offsetY - (drawPageH + rowSpace)/scanl * (rowCount - j -1);
-
- } else if (rotate == 90) {
-
- offsetX = - (pageBounds.size.width + (properties.edgeInsets.bottom+ spaceY)/scanl);
- offsetY = (properties.edgeInsets.left + spaceX)/scanl;
-
- xTransform = offsetX - (drawPageH + rowSpace)/scanl * (rowCount - j -1) ;
- yTransform = offsetY + (drawPageW + columnSpace)/scanl * i;
-
- } else {
- offsetX = (properties.edgeInsets.left + spaceX)/scanl;
- offsetY = (properties.edgeInsets.bottom+spaceY)/scanl;
-
- xTransform = offsetX + (drawPageW + columnSpace)/scanl * i ;
- yTransform = (offsetY + (drawPageH + rowSpace)/scanl * (rowCount - j -1));
- }
- } else if (kKMPDFMultiplePageOrder_LongitudinalAntitone == properties.order) {
- if (rotate == 270) {
- offsetX = (properties.edgeInsets.bottom+ spaceY)/scanl;
- offsetY = - pageBounds.size.height - (properties.edgeInsets.left + spaceX)/scanl;
-
- xTransform = offsetX + (drawPageH + rowSpace)/scanl * (rowCount - j -1) ;
- yTransform = offsetY - (drawPageW + columnSpace)/scanl * (columnCout - 1 - i);
-
- } else if (rotate == 180) {
- offsetX = -(pageBounds.size.width + properties.edgeInsets.left/scanl + spaceX/scanl);
- offsetY = -(pageBounds.size.height + properties.edgeInsets.bottom/scanl + spaceY/scanl);
-
- xTransform = offsetX - (drawPageW + columnSpace)/scanl * (columnCout - 1 - i) ;
- yTransform = offsetY - (drawPageH + rowSpace)/scanl * (rowCount - j -1);
-
- } else if (rotate == 90) {
-
- offsetX = - (pageBounds.size.width + (properties.edgeInsets.bottom+ spaceY)/scanl);
- offsetY = (properties.edgeInsets.left + spaceX)/scanl;
-
- xTransform = offsetX - (drawPageH + rowSpace)/scanl * (rowCount - j -1) ;
- yTransform = offsetY + (drawPageW + columnSpace)/scanl * (columnCout - 1 - i);
-
- } else {
- offsetX = (properties.edgeInsets.left + spaceX)/scanl;
- offsetY = (properties.edgeInsets.bottom+spaceY)/scanl;
-
- xTransform = offsetX + (drawPageW + columnSpace)/scanl * (columnCout - 1 - i) ;
- yTransform = (offsetY + (drawPageH + rowSpace)/scanl * (rowCount - j -1));
- }
- }
-
- [NSGraphicsContext saveGraphicsState];
-
- //缩放
- CGContextScaleCTM(context, scanl, scanl);
- CGContextRotateCTM(context, -rotate*M_PI/180);
-
- CGContextTranslateCTM(context,xTransform,yTransform);
- CGContextDrawPDFPage(context,drawPage.pageRef);
- if (properties.isHasBorder) {
- CGFloat borderWidth = pageBounds.size.width;
- CGFloat borderHeight = pageBounds.size.height;
- CGRect dirtyRect = CGRectMake(0, 0, borderWidth, borderHeight);
- CGContextAddRect(context, dirtyRect);
- CGContextSetRGBStrokeColor(context, 0.0, 0.0, 0.0, 1.0);
- CGContextStrokePath(context);
- }
- [NSGraphicsContext restoreGraphicsState];
- }
- }
- }
- #pragma mark Publick Action
- + (KMPDFMultipleManager *)defaultManager
- {
- static KMPDFMultipleManager *singleton = nil;
- static dispatch_once_t pred;
- dispatch_once(&pred, ^{
- singleton = [[KMPDFMultipleManager alloc] init];
- });
- return singleton;
- }
- - (void)savePDFDocumentPath:(NSString *)path drawPages:(NSArray *)pages multipleOption:(KMEachPageProperties *)properties completionHandler:(void (^)(BOOL isSuccessfully))handler
- {
- CFStringRef filePath = (__bridge CFStringRef)path;
- CFURLRef url = CFURLCreateWithFileSystemPath(NULL, filePath, kCFURLPOSIXPathStyle, 0);
- CFMutableDictionaryRef myDictionary = CFDictionaryCreateMutable(NULL,
- 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- CFDictionarySetValue(myDictionary, kCGPDFContextCreator, CFSTR("PDF Reader Pro"));
-
- CGContextRef pdfContext = CGPDFContextCreateWithURL(url, &CGRectZero, myDictionary);
-
- CFRelease(myDictionary);
- CFRelease(url);
-
- if (!pdfContext) {
- handler(NO);
- return;
- }
- [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:pdfContext flipped:NO]];
- NSInteger eachPageCount = (properties.columnCout * properties.rowCount);
- NSInteger numPages = 0;
- if (pages.count % eachPageCount == 0) {
- numPages = pages.count / eachPageCount;
- } else {
- numPages = pages.count / eachPageCount +1;
- }
-
- for (NSInteger index = 0; index < numPages; index ++) {
- NSMutableArray * eachPages = [NSMutableArray array];
- for (NSInteger i = 0; i<eachPageCount; i++) {
- NSUInteger currentIndex = i + eachPageCount * index;
- if (properties.isReversePage) {
- currentIndex = i + eachPageCount * (numPages - index - 1);
- }
- if (currentIndex >= pages.count) {
- break;
- }
- PDFPage * page = [pages[currentIndex] copy];
- [eachPages addObject:page];
- }
-
- if (eachPages.count < 1) {
- break;
- }
- CGSize size = properties.pageSize;
- CGFloat width = size.width;
- CGFloat height =size.height;
-
- if (kKMPDFMultiplePageDirection_Landscape == properties.direction) {
- width = size.height;
- height = size.width;
- }
-
- CGRect mediaBox = CGRectMake(0, 0, width,height);
-
- CGContextBeginPage(pdfContext, &mediaBox);
-
- [self drawPageToContext:pdfContext eachPages:eachPages multipleOption:properties];
- CGContextEndPage(pdfContext);
- }
-
- CGPDFContextClose(pdfContext);
- CGContextRelease (pdfContext);
-
- handler(YES);
-
- }
- - (void)drawPageToContext:(CGContextRef)context eachPages:(NSArray *)pages multipleOption:(KMEachPageProperties *)properties
- {
- /****
- *可以统一使用CG类来进行缩放、平移、旋转
- *PDFkit 自带画page的方法,这样能够保留注释存在
- if (@available(macOS 10.12, *)) {
- [self PDFKitDrawPageToContext:context eachPages:pages multipleOption:properties];
- } else {
- [self CGDrawPageToContext:context eachPages:pages multipleOption:properties];
- }
- *****/
- [self PDFKitDrawPageToContext:context eachPages:pages multipleOption:properties];
- }
- @end
|