2 * Copyright (C) 2002 Apple Computer, Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
26 #import <WebKit/WebImageRendererFactory.h>
27 #import <WebKit/WebImageRenderer.h>
29 #import <WebKit/WebAssertions.h>
30 #import <Foundation/NSURLFileTypeMappings.h>
32 @implementation WebImageRendererFactory
34 + (void)createSharedFactory
36 if (![self sharedFactory]) {
37 [[[self alloc] init] release];
39 ASSERT([[self sharedFactory] isKindOfClass:self]);
42 + (WebImageRendererFactory *)sharedFactory
44 return (WebImageRendererFactory *)[super sharedFactory];
47 - (id <WebCoreImageRenderer>)imageRendererWithMIMEType:(NSString *)MIMEType
49 WebImageRenderer *imageRenderer = [[WebImageRenderer alloc] initWithMIMEType:MIMEType];
51 #ifndef USE_CGIMAGEREF
52 NSImage *image = [imageRenderer image];
54 if (![MIMEType isEqual:@"application/pdf"]) {
55 NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initForIncrementalLoad];
56 [image addRepresentation:rep];
60 [image setFlipped:YES];
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];
68 [image setScalesWhenResized:NO];
71 return [imageRenderer autorelease];
74 - (id <WebCoreImageRenderer>)imageRenderer
76 return [self imageRendererWithMIMEType:nil];
79 - (id <WebCoreImageRenderer>)imageRendererWithData:(NSData*)data MIMEType:(NSString *)MIMEType
81 WebImageRenderer *imageRenderer = [[WebImageRenderer alloc] initWithData:data MIMEType:MIMEType];
83 #ifndef USE_CGIMAGEREF
84 NSImage *image = [imageRenderer image];
86 NSArray *reps = [image representations];
87 if ([reps count] == 0){
88 [imageRenderer release];
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];
101 [image setFlipped:YES];
104 return [imageRenderer autorelease];
107 - (id <WebCoreImageRenderer>)imageRendererWithBytes:(const void *)bytes length:(unsigned)length MIMEType:(NSString *)MIMEType
109 NSData *data = [[NSData alloc] initWithBytes:(void *)bytes length:length];
110 WebImageRenderer *imageRenderer = [self imageRendererWithData:data MIMEType:MIMEType];
112 return imageRenderer;
115 - (id <WebCoreImageRenderer>)imageRendererWithBytes:(const void *)bytes length:(unsigned)length
117 return [self imageRendererWithBytes:bytes length:length MIMEType:nil];
120 - (id <WebCoreImageRenderer>)imageRendererWithSize:(NSSize)s
122 WebImageRenderer *imageRenderer = [[[WebImageRenderer alloc] initWithSize:s] autorelease];
123 #ifndef USE_CGIMAGEREF
124 [[imageRenderer image] setScalesWhenResized:NO];
126 return imageRenderer;
129 - (id <WebCoreImageRenderer>)imageRendererWithName:(NSString *)name
131 WebImageRenderer *imageRenderer = [[[WebImageRenderer alloc] initWithContentsOfFile:name] autorelease];
132 #ifndef USE_CGIMAGEREF
133 [[imageRenderer image] setScalesWhenResized:NO];
134 [[imageRenderer image] setFlipped:YES];
136 return imageRenderer;
139 struct CompositeOperator
142 NSCompositingOperation value;
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
163 - (int)CGCompositeOperationInContext:(CGContextRef)context
165 return [[NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:NO] compositingOperation];
168 - (void)setCGCompositeOperation:(int)op inContext:(CGContextRef)context
170 [[NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:NO] setCompositingOperation:op];
173 - (void)setCGCompositeOperationFromString:(NSString *)operatorString inContext:(CGContextRef)context
175 NSCompositingOperation op = NSCompositeSourceOver;
177 if (operatorString) {
180 for (i = 0; i < NUM_COMPOSITE_OPERATORS; i++) {
181 if ([operatorString caseInsensitiveCompare:NSCompositingOperations[i].name] == NSOrderedSame) {
182 op = NSCompositingOperations[i].value;
188 [[NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:NO] setCompositingOperation:op];
192 - (NSArray *)supportedMIMETypes
194 static NSArray *imageMIMETypes = nil;
196 if (imageMIMETypes == nil) {
197 NSEnumerator *enumerator = [[NSImage imageFileTypes] objectEnumerator];
198 NSURLFileTypeMappings *mappings = [NSURLFileTypeMappings sharedMappings];
199 NSMutableSet *mimes = [NSMutableSet set];
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];
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"];
213 imageMIMETypes = [[mimes allObjects] retain];
216 return imageMIMETypes;