1/* 2 * Copyright (C) 2005, 2006 Apple 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 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#if !PLATFORM(IOS) 30 31#import "WebPDFRepresentation.h" 32 33#import "WebDataSourcePrivate.h" 34#import "WebFrame.h" 35#import "WebJSPDFDoc.h" 36#import "WebPDFDocumentExtras.h" 37#import "WebPDFView.h" 38#import "WebTypesInternal.h" 39#import <wtf/Assertions.h> 40#import <wtf/ObjcRuntimeExtras.h> 41#import <JavaScriptCore/JSContextRef.h> 42#import <JavaScriptCore/JSStringRef.h> 43#import <JavaScriptCore/JSStringRefCF.h> 44 45@implementation WebPDFRepresentation 46 47+ (NSArray *)postScriptMIMETypes 48{ 49 return [NSArray arrayWithObjects: 50 @"application/postscript", 51 nil]; 52} 53 54+ (NSArray *)supportedMIMETypes 55{ 56 return [[[self class] postScriptMIMETypes] arrayByAddingObjectsFromArray: 57 [NSArray arrayWithObjects: 58 @"text/pdf", 59 @"application/pdf", 60 nil]]; 61} 62 63+ (Class)PDFDocumentClass 64{ 65 static Class PDFDocumentClass = nil; 66 if (PDFDocumentClass == nil) { 67 PDFDocumentClass = [[WebPDFView PDFKitBundle] classNamed:@"PDFDocument"]; 68 if (PDFDocumentClass == nil) { 69 LOG_ERROR("Couldn't find PDFDocument class in PDFKit.framework"); 70 } 71 } 72 return PDFDocumentClass; 73} 74 75- (void)setDataSource:(WebDataSource *)dataSource 76{ 77} 78 79- (void)receivedData:(NSData *)data withDataSource:(WebDataSource *)dataSource 80{ 81} 82 83- (void)receivedError:(NSError *)error withDataSource:(WebDataSource *)dataSource 84{ 85} 86 87- (NSData *)convertPostScriptDataSourceToPDF:(NSData *)data 88{ 89 // Convert PostScript to PDF using Quartz 2D API 90 // http://developer.apple.com/documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_ps_convert/chapter_16_section_1.html 91 92 CGPSConverterCallbacks callbacks = { 0, 0, 0, 0, 0, 0, 0, 0 }; 93 CGPSConverterRef converter = CGPSConverterCreate(0, &callbacks, 0); 94 ASSERT(converter); 95 96 CGDataProviderRef provider = CGDataProviderCreateWithCFData((CFDataRef)data); 97 ASSERT(provider); 98 99 CFMutableDataRef result = CFDataCreateMutable(kCFAllocatorDefault, 0); 100 ASSERT(result); 101 102 CGDataConsumerRef consumer = CGDataConsumerCreateWithCFData(result); 103 ASSERT(consumer); 104 105 // Error handled by detecting zero-length 'result' in caller 106 CGPSConverterConvert(converter, provider, consumer, 0); 107 108 CFRelease(converter); 109 CFRelease(provider); 110 CFRelease(consumer); 111 112 return CFBridgingRelease(result); 113} 114 115- (void)finishedLoadingWithDataSource:(WebDataSource *)dataSource 116{ 117 NSData *data = [dataSource data]; 118 119 NSArray *postScriptMIMETypes = [[self class] postScriptMIMETypes]; 120 NSString *mimeType = [dataSource _responseMIMEType]; 121 if ([postScriptMIMETypes containsObject:mimeType]) { 122 data = [self convertPostScriptDataSourceToPDF:data]; 123 if ([data length] == 0) 124 return; 125 } 126 127 WebPDFView *view = (WebPDFView *)[[[dataSource webFrame] frameView] documentView]; 128 PDFDocument *doc = [[[[self class] PDFDocumentClass] alloc] initWithData:data]; 129 [view setPDFDocument:doc]; 130 131 NSArray *scripts = allScriptsInPDFDocument(doc); 132 [doc release]; 133 doc = nil; 134 135 NSUInteger scriptCount = [scripts count]; 136 if (!scriptCount) 137 return; 138 139 JSGlobalContextRef ctx = JSGlobalContextCreate(0); 140 JSObjectRef jsPDFDoc = makeJSPDFDoc(ctx, dataSource); 141 142 for (NSUInteger i = 0; i < scriptCount; ++i) { 143 JSStringRef script = JSStringCreateWithCFString((CFStringRef)[scripts objectAtIndex:i]); 144 JSEvaluateScript(ctx, script, jsPDFDoc, 0, 0, 0); 145 JSStringRelease(script); 146 } 147 148 JSGlobalContextRelease(ctx); 149} 150 151- (BOOL)canProvideDocumentSource 152{ 153 return NO; 154} 155 156 157- (NSString *)documentSource 158{ 159 return nil; 160} 161 162 163- (NSString *)title 164{ 165 return nil; 166} 167 168@end 169 170#endif // !PLATFORM(IOS) 171