From 7d2a3a4625581a7d5941b44967909c9d5f1038e9 Mon Sep 17 00:00:00 2001 From: Aaron Brager Date: Sun, 30 Sep 2018 02:27:45 -0700 Subject: [PATCH] Add PDF support --- cartool/main.m | 88 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 66 insertions(+), 22 deletions(-) mode change 100644 => 100755 cartool/main.m diff --git a/cartool/main.m b/cartool/main.m old mode 100644 new mode 100755 index 6aaf27b..28b494b --- a/cartool/main.m +++ b/cartool/main.m @@ -7,6 +7,7 @@ // #import +#import typedef enum _kCoreThemeIdiom { kCoreThemeIdiomUniversal, @@ -50,22 +51,18 @@ -(CGImageRef)image; @interface CUIRenditionKey : NSObject @end -@interface CUIThemeFacet : NSObject - -+(CUIThemeFacet *)themeWithContentsOfURL:(NSURL *)u error:(NSError **)e; - -@end - @interface CUICatalog : NSObject @property(readonly) bool isVectorBased; +-(id)initWithURL:(id)arg1 error:(id*)arg2; -(id)initWithName:(NSString *)n fromBundle:(NSBundle *)b; -(id)allKeys; -(id)allImageNames; -(CUINamedImage *)imageWithName:(NSString *)n scaleFactor:(CGFloat)s; -(CUINamedImage *)imageWithName:(NSString *)n scaleFactor:(CGFloat)s deviceIdiom:(int)idiom; -(NSArray *)imagesWithName:(NSString *)n; +- (struct CGPDFDocument { }*)pdfDocumentWithName:(id)arg1; @end @@ -134,32 +131,65 @@ void CGImageWriteToFile(CGImageRef image, NSString *path) { NSMutableArray *images = [[NSMutableArray alloc] initWithCapacity:5]; - for (NSNumber *scaleFactor in @[@1, @2, @3]) - { - CUINamedImage *image = [catalog imageWithName:key scaleFactor:scaleFactor.doubleValue]; + + struct CGPDFDocument *pdfDocument = [catalog pdfDocumentWithName:key]; + + if (pdfDocument) { + [images addObject:(__bridge id _Nonnull)(pdfDocument)]; + } else { + for (NSNumber *scaleFactor in @[@1, @2, @3]) + { + CUINamedImage *image = [catalog imageWithName:key scaleFactor:scaleFactor.doubleValue]; - if (image && image.scale == scaleFactor.floatValue) [images addObject:image]; + if (image && image.scale == scaleFactor.floatValue) [images addObject:image]; + } } - return images; } +void writePDFtoFile(struct CGPDFDocument *pdfDocument, NSString *path, NSString *key) { + unsigned long pageCount = CGPDFDocumentGetNumberOfPages(pdfDocument); + CGPDFPageRef pageRef = CGPDFDocumentGetPage(pdfDocument, 1); + CGRect pageRect = CGPDFPageGetBoxRect(pageRef, kCGPDFMediaBox); + float pageHeight = pageRect.size.height; + pageRect.size.height = pageRect.size.height * pageCount; + + NSMutableData* pdfData = [[NSMutableData alloc] init]; + CGDataConsumerRef pdfConsumer = CGDataConsumerCreateWithCFData((CFMutableDataRef)pdfData); + CGContextRef pdfContext = CGPDFContextCreate(pdfConsumer, &pageRect, NULL); + + CGPDFContextBeginPage(pdfContext, NULL); + CGContextTranslateCTM(pdfContext, 0, pageRect.size.height); + for (int i = 1; i <= pageCount; i++) { + @autoreleasepool { + pageRef = CGPDFDocumentGetPage(pdfDocument, i); + CGContextTranslateCTM(pdfContext, 0, -pageHeight); + CGContextDrawPDFPage(pdfContext, pageRef); + } + } + CGPDFContextEndPage(pdfContext); + CGPDFContextClose(pdfContext); + + NSString *filename = [NSString stringWithFormat:@"%@.pdf", key]; + NSString *pdfFile = [path stringByAppendingPathComponent:filename]; + + [pdfData writeToFile: pdfFile atomically: NO]; + printf("\t%s\n", [filename UTF8String]); +} + void exportCarFileAtPath(NSString * carPath, NSString *outputDirectoryPath) { NSError *error = nil; outputDirectoryPath = [outputDirectoryPath stringByExpandingTildeInPath]; - - CUIThemeFacet *facet = [CUIThemeFacet themeWithContentsOfURL:[NSURL fileURLWithPath:carPath] error:&error]; - - CUICatalog *catalog = [[CUICatalog alloc] init]; - - /* Override CUICatalog to point to a file rather than a bundle */ - [catalog setValue:facet forKey:@"_storageRef"]; - + carPath = [carPath stringByExpandingTildeInPath]; + + NSURL *carPathURL = [NSURL fileURLWithPath:carPath.stringByExpandingTildeInPath]; + CUICatalog *catalog = [[CUICatalog alloc] initWithURL:carPathURL error:&error]; + /* CUICommonAssetStorage won't link */ CUICommonAssetStorage *storage = [[NSClassFromString(@"CUICommonAssetStorage") alloc] initWithPath:carPath]; - + for (NSString *key in [storage allRenditionNames]) { printf("%s\n", [key UTF8String]); @@ -185,8 +215,19 @@ void exportCarFileAtPath(NSString * carPath, NSString *outputDirectoryPath) NSMutableArray *images = getImagesArray(catalog, key); for( CUINamedImage *image in images ) { - if( CGSizeEqualToSize(image.size, CGSizeZero) ) + if ( ![image respondsToSelector:@selector(size)]) { + // image is really a CGPDFDocument + struct CGPDFDocument *pdfDocument = (__bridge struct CGPDFDocument *)(image); + printf("\t looks like a PDF!!\n"); + if (outputDirectoryPath) { + writePDFtoFile(pdfDocument, outputDirectoryPath, key); + } else { + printf("\t not saving since an output path wasn't provided\n"); + } + } + else if( CGSizeEqualToSize(image.size, CGSizeZero) ) { printf("\tnil image?\n"); + } else { CGImageRef cgImage = [image image]; @@ -202,8 +243,11 @@ void exportCarFileAtPath(NSString * carPath, NSString *outputDirectoryPath) NSString *scale = image.scale > 1.0 ? [NSString stringWithFormat:@"@%dx", (int)floor(image.scale)] : @""; NSString *name = [NSString stringWithFormat:@"%@%@%@%@.png", key, idiomSuffix, sizeClassSuffix, scale]; printf("\t%s\n", [name UTF8String]); - if( outputDirectoryPath ) + if( outputDirectoryPath ) { CGImageWriteToFile(cgImage, [outputDirectoryPath stringByAppendingPathComponent:name]); + } else { + printf("\t not saving since an output path wasn't provided\n"); + } } } }