1/* 2 * Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 14 * its contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#import "WebPDFRepresentation.h" 30 31#import "WebDataSourcePrivate.h" 32#import "WebFrame.h" 33#import "WebJSPDFDoc.h" 34#import "WebNSObjectExtras.h" 35#import "WebPDFDocumentExtras.h" 36#import "WebPDFView.h" 37#import "WebTypesInternal.h" 38#import <JavaScriptCore/Assertions.h> 39#import <JavaScriptCore/JSContextRef.h> 40#import <JavaScriptCore/JSStringRef.h> 41#import <JavaScriptCore/JSStringRefCF.h> 42 43@implementation WebPDFRepresentation 44 45+ (NSArray *)postScriptMIMETypes 46{ 47 return [NSArray arrayWithObjects: 48 @"application/postscript", 49 nil]; 50} 51 52+ (NSArray *)supportedMIMETypes 53{ 54 return [[[self class] postScriptMIMETypes] arrayByAddingObjectsFromArray: 55 [NSArray arrayWithObjects: 56 @"text/pdf", 57 @"application/pdf", 58 nil]]; 59} 60 61+ (Class)PDFDocumentClass 62{ 63 static Class PDFDocumentClass = nil; 64 if (PDFDocumentClass == nil) { 65 PDFDocumentClass = [[WebPDFView PDFKitBundle] classNamed:@"PDFDocument"]; 66 if (PDFDocumentClass == nil) { 67 LOG_ERROR("Couldn't find PDFDocument class in PDFKit.framework"); 68 } 69 } 70 return PDFDocumentClass; 71} 72 73- (void)setDataSource:(WebDataSource *)dataSource; 74{ 75} 76 77- (void)receivedData:(NSData *)data withDataSource:(WebDataSource *)dataSource; 78{ 79} 80 81- (void)receivedError:(NSError *)error withDataSource:(WebDataSource *)dataSource; 82{ 83} 84 85- (NSData *)convertPostScriptDataSourceToPDF:(NSData *)data 86{ 87 // Convert PostScript to PDF using Quartz 2D API 88 // http://developer.apple.com/documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_ps_convert/chapter_16_section_1.html 89 90 CGPSConverterCallbacks callbacks = { 0, 0, 0, 0, 0, 0, 0, 0 }; 91 CGPSConverterRef converter = CGPSConverterCreate(0, &callbacks, 0); 92 ASSERT(converter); 93 94 CGDataProviderRef provider = CGDataProviderCreateWithCFData((CFDataRef)data); 95 ASSERT(provider); 96 97 CFMutableDataRef result = CFDataCreateMutable(kCFAllocatorDefault, 0); 98 ASSERT(result); 99 100 CGDataConsumerRef consumer = CGDataConsumerCreateWithCFData(result); 101 ASSERT(consumer); 102 103 // Error handled by detecting zero-length 'result' in caller 104 CGPSConverterConvert(converter, provider, consumer, 0); 105 106 CFRelease(converter); 107 CFRelease(provider); 108 CFRelease(consumer); 109 110 return WebCFAutorelease(result); 111} 112 113- (void)finishedLoadingWithDataSource:(WebDataSource *)dataSource 114{ 115 NSData *data = [dataSource data]; 116 117 NSArray *postScriptMIMETypes = [[self class] postScriptMIMETypes]; 118 NSString *mimeType = [dataSource _responseMIMEType]; 119 if ([postScriptMIMETypes containsObject:mimeType]) { 120 data = [self convertPostScriptDataSourceToPDF:data]; 121 if ([data length] == 0) 122 return; 123 } 124 125 WebPDFView *view = (WebPDFView *)[[[dataSource webFrame] frameView] documentView]; 126 PDFDocument *doc = [[[[self class] PDFDocumentClass] alloc] initWithData:data]; 127 [view setPDFDocument:doc]; 128 129 NSArray *scripts = allScriptsInPDFDocument(doc); 130 [doc release]; 131 doc = nil; 132 133 NSUInteger scriptCount = [scripts count]; 134 if (!scriptCount) 135 return; 136 137 JSGlobalContextRef ctx = JSGlobalContextCreate(0); 138 JSObjectRef jsPDFDoc = makeJSPDFDoc(ctx, dataSource); 139 140 for (NSUInteger i = 0; i < scriptCount; ++i) { 141 JSStringRef script = JSStringCreateWithCFString((CFStringRef)[scripts objectAtIndex:i]); 142 JSEvaluateScript(ctx, script, jsPDFDoc, 0, 0, 0); 143 JSStringRelease(script); 144 } 145 146 JSGlobalContextRelease(ctx); 147} 148 149- (BOOL)canProvideDocumentSource 150{ 151 return NO; 152} 153 154 155- (NSString *)documentSource 156{ 157 return nil; 158} 159 160 161- (NSString *)title 162{ 163 return nil; 164} 165 166@end 167