Reviewed by NOBODY (OOPS!).
[WebKit-https.git] / WebKit / WebCoreSupport.subproj / WebImageRendererFactory.m
1 /*
2  * Copyright (C) 2002 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  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #import <WebKit/WebImageRendererFactory.h>
27 #import <WebKit/WebImageRenderer.h>
28
29 #import <WebKit/WebAssertions.h>
30 #import <Foundation/NSURLFileTypeMappings.h>
31
32 @implementation WebImageRendererFactory
33
34 + (void)createSharedFactory
35 {
36     if (![self sharedFactory]) {
37         [[[self alloc] init] release];
38     }
39     ASSERT([[self sharedFactory] isKindOfClass:self]);
40 }
41
42 + (WebImageRendererFactory *)sharedFactory
43 {
44     return (WebImageRendererFactory *)[super sharedFactory];
45 }
46
47 - (id <WebCoreImageRenderer>)imageRendererWithMIMEType:(NSString *)MIMEType
48 {
49     WebImageRenderer *imageRenderer = [[WebImageRenderer alloc] initWithMIMEType:MIMEType];
50
51 #ifndef USE_CGIMAGEREF
52     NSImage *image = [imageRenderer image];
53
54     if (![MIMEType isEqual:@"application/pdf"]) {
55         NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initForIncrementalLoad];
56         [image addRepresentation:rep];
57         [rep autorelease];
58     }
59
60     [image setFlipped:YES];
61     
62     // Turn the default caching mode back on when the image has completed load.
63     // Caching intermediate progressive representations causes problems for
64     // progressive loads.  We also rely on the NSBitmapImageRep surviving during
65     // incremental loads.  See 3165631 and 3262592.
66     [image setCacheMode: NSImageCacheNever];
67
68     [image setScalesWhenResized:NO];
69 #endif
70         
71     return [imageRenderer autorelease];
72 }
73
74 - (id <WebCoreImageRenderer>)imageRenderer
75 {
76     return [self imageRendererWithMIMEType:nil];
77 }
78
79 - (id <WebCoreImageRenderer>)imageRendererWithData:(NSData*)data MIMEType:(NSString *)MIMEType
80 {
81     WebImageRenderer *imageRenderer = [[WebImageRenderer alloc] initWithData:data MIMEType:MIMEType];
82
83 #ifndef USE_CGIMAGEREF
84     NSImage *image = [imageRenderer image];
85
86     NSArray *reps = [image representations];
87     if ([reps count] == 0){
88         [imageRenderer release];
89         return nil;
90     }
91     
92     // Force the image to use the pixel size and ignore the dpi.
93     [image setScalesWhenResized:NO];
94     if ([reps count] > 0){
95         NSImageRep *rep = [reps objectAtIndex:0];
96         [rep setSize:NSMakeSize([rep pixelsWide], [rep pixelsHigh])];
97         if ([imageRenderer frameCount] > 1)
98             [imageRenderer setOriginalData:data];
99     }
100     
101     [image setFlipped:YES];
102 #endif
103
104     return [imageRenderer autorelease];
105 }
106
107 - (id <WebCoreImageRenderer>)imageRendererWithBytes:(const void *)bytes length:(unsigned)length MIMEType:(NSString *)MIMEType
108 {
109     NSData *data = [[NSData alloc] initWithBytes:(void *)bytes length:length];
110     WebImageRenderer *imageRenderer = [self imageRendererWithData:data MIMEType:MIMEType];
111     [data autorelease];
112     return imageRenderer;
113 }
114
115 - (id <WebCoreImageRenderer>)imageRendererWithBytes:(const void *)bytes length:(unsigned)length
116 {
117     return [self imageRendererWithBytes:bytes length:length MIMEType:nil];
118 }
119
120 - (id <WebCoreImageRenderer>)imageRendererWithSize:(NSSize)s
121 {
122     WebImageRenderer *imageRenderer = [[[WebImageRenderer alloc] initWithSize:s] autorelease];
123 #ifndef USE_CGIMAGEREF
124     [[imageRenderer image] setScalesWhenResized:NO];
125 #endif
126     return imageRenderer;
127 }
128
129 - (id <WebCoreImageRenderer>)imageRendererWithName:(NSString *)name
130 {
131     WebImageRenderer *imageRenderer = [[[WebImageRenderer alloc] initWithContentsOfFile:name] autorelease];
132 #ifndef USE_CGIMAGEREF
133     [[imageRenderer image] setScalesWhenResized:NO];
134     [[imageRenderer image] setFlipped:YES];
135 #endif
136     return imageRenderer;
137 }
138
139 struct CompositeOperator
140 {
141     NSString *name;
142     NSCompositingOperation value;
143 };
144
145 #define NUM_COMPOSITE_OPERATORS 14
146 struct CompositeOperator NSCompositingOperations[NUM_COMPOSITE_OPERATORS] = {
147     { @"clear", NSCompositeClear },
148     { @"copy", NSCompositeCopy },
149     { @"source-over", NSCompositeSourceOver },
150     { @"source-in", NSCompositeSourceIn },
151     { @"source-out", NSCompositeSourceOut },
152     { @"source-atop", NSCompositeSourceAtop },
153     { @"destination-over", NSCompositeDestinationOver },
154     { @"destination-in", NSCompositeDestinationIn },
155     { @"destination-out", NSCompositeDestinationOut },
156     { @"destination-atop", NSCompositeDestinationAtop },
157     { @"xor", NSCompositeXOR },
158     { @"darker", NSCompositePlusDarker },
159     { @"highlight", NSCompositeHighlight },
160     { @"lighter", NSCompositeHighlight }    // Per AppKit
161 };
162
163 - (int)CGCompositeOperationInContext:(CGContextRef)context
164 {
165         return [[NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:NO] compositingOperation];
166 }
167
168 - (void)setCGCompositeOperation:(int)op inContext:(CGContextRef)context
169 {
170         [[NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:NO] setCompositingOperation:op];
171 }
172
173 - (void)setCGCompositeOperationFromString:(NSString *)operatorString inContext:(CGContextRef)context
174 {
175     NSCompositingOperation op = NSCompositeSourceOver;
176     
177     if (operatorString) {
178         int i;
179         
180         for (i = 0; i < NUM_COMPOSITE_OPERATORS; i++) {
181             if ([operatorString caseInsensitiveCompare:NSCompositingOperations[i].name] == NSOrderedSame) {
182                 op = NSCompositingOperations[i].value;
183                 break;
184             }
185         }
186     }
187     
188         [[NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:NO] setCompositingOperation:op];
189 }
190
191
192 - (NSArray *)supportedMIMETypes
193 {
194     static NSArray *imageMIMETypes = nil;
195
196     if (imageMIMETypes == nil) {
197         NSEnumerator *enumerator = [[NSImage imageFileTypes] objectEnumerator];
198         NSURLFileTypeMappings *mappings = [NSURLFileTypeMappings sharedMappings];
199         NSMutableSet *mimes = [NSMutableSet set];
200         NSString *type;
201
202         while ((type = [enumerator nextObject]) != nil) {
203             NSString *mime = [mappings MIMETypeForExtension:type];
204             if (mime != nil && ![mime isEqualToString:@"application/octet-stream"]) {
205                 [mimes addObject:mime];
206             }
207         }
208
209         // image/pjpeg is the MIME type for progressive jpeg. These files have the jpg file extension.
210         // This is workaround of NSURLFileTypeMappings's limitation of only providing 1 MIME type for an extension.
211         [mimes addObject:@"image/pjpeg"];
212         
213         imageMIMETypes = [[mimes allObjects] retain];
214     }
215
216     return imageMIMETypes;
217 }
218
219
220 @end