10.6 compatibility: Fix some new compiler warnings, and work around apparent regressions in NSTask and -stringByStandardizingPath.
5 // Copyright 2008 Jens Alfke. All rights reserved.
8 #import "GraphicsUtils.h"
10 #import <ApplicationServices/ApplicationServices.h>
13 @implementation NSImage (MYUtilities)
16 - (NSBitmapImageRep*) my_bitmapRep
19 NSBitmapImageRep *bestRep = nil;
20 for( NSImageRep *rep in self.representations )
21 if( [rep isKindOfClass: [NSBitmapImageRep class]] ) {
22 NSSize size = [rep size];
23 if( size.width > max.width || size.height > max.height ) {
24 bestRep = (NSBitmapImageRep*)rep;
29 NSImage *tiffImage = [[NSImage alloc] initWithData:[self TIFFRepresentation]];
30 bestRep = [[tiffImage representations] objectAtIndex:0];
31 [tiffImage autorelease];
37 - (NSSize) my_sizeOfLargestRep
39 NSArray *reps = [self representations];
42 for( i=[reps count]-1; i>=0; i-- ) {
43 NSImageRep *rep = [reps objectAtIndex: i];
44 NSSize size = [rep size];
45 if( size.width > max.width || size.height > max.height ) {
53 - (NSImage*) my_shrunkToFitIn: (NSSize) maxSize
55 NSSize size = self.size;
56 float scale = MIN( maxSize.width/size.width, maxSize.height/size.height );
60 NSSize newSize = {roundf(size.width*scale), roundf(size.height*scale)};
61 NSImage *newImage = [[NSImage alloc] initWithSize: newSize];
63 NSGraphicsContext *context = [NSGraphicsContext currentContext];
64 [context saveGraphicsState];
65 [context setImageInterpolation: NSImageInterpolationHigh];
66 [self drawInRect: NSMakeRect(0,0,newSize.width,newSize.height)
67 fromRect: NSMakeRect(0,0,size.width,size.height)
68 operation: NSCompositeCopy fraction: 1.0f];
69 [context restoreGraphicsState];
70 [newImage unlockFocus];
71 return [newImage autorelease];
75 - (NSData*) my_JPEGData
77 return [self my_dataInFormat: NSJPEGFileType quality: 0.75f];
81 - (NSData*) my_dataInFormat: (NSBitmapImageFileType)format quality: (float)quality
83 NSBitmapImageRep *rep = self.my_bitmapRep;
84 NSDictionary *props = [NSDictionary dictionaryWithObjectsAndKeys:
85 [NSNumber numberWithFloat: quality], NSImageCompressionFactor, nil];
86 return [rep representationUsingType: format properties: props];
92 // Adapted from Apple's CocoaCreateMovie sample
93 // <http://developer.apple.com/samplecode/Sample_Code/QuickTime/Basics/CocoaCreateMovie/MyController.m.htm>
94 static void CopyNSImageRepToGWorld(NSBitmapImageRep *imageRepresentation, GWorldPtr gWorldPtr)
96 PixMapHandle pixMapHandle;
97 unsigned char* pixBaseAddr;
100 pixMapHandle = GetGWorldPixMap(gWorldPtr);
101 LockPixels (pixMapHandle);
102 pixBaseAddr = (unsigned char*) GetPixBaseAddr(pixMapHandle);
104 const unsigned char* bitMapDataPtr = [imageRepresentation bitmapData];
106 if ((bitMapDataPtr != nil) && (pixBaseAddr != nil))
109 int pixmapRowBytes = GetPixRowBytes(pixMapHandle);
110 NSSize imageSize = [imageRepresentation size];
111 for (i=0; i< imageSize.height; i++)
113 const unsigned char *src = bitMapDataPtr + i * [imageRepresentation bytesPerRow];
114 unsigned char *dst = pixBaseAddr + i * pixmapRowBytes;
115 for (j = 0; j < imageSize.width; j++)
117 *dst++ = 0; // X - our src is 24-bit only
118 *dst++ = *src++; // Red component
119 *dst++ = *src++; // Green component
120 *dst++ = *src++; // Blue component
124 UnlockPixels(pixMapHandle);
128 - (NSData*) my_PICTData
130 // Locate the bitmap image rep:
131 NSBitmapImageRep *rep;
132 NSEnumerator *e = [[self representations] objectEnumerator];
133 while( (rep=[e nextObject]) != nil ) {
134 if( [rep isKindOfClass: [NSBitmapImageRep class]] )
138 Warn(@"No bitmap image rep in image");
142 // Copy the image data into a GWorld:
144 SetRect(&bounds, 0,0,[rep pixelsWide],[rep pixelsHigh]);
146 OSStatus err = NewGWorld(&gworld, 32, &bounds, NULL, NULL, 0);
148 Warn(@"NewGWorld failed with err %i",err);
151 CopyNSImageRepToGWorld(rep,gworld);
153 // Draw the GWorld into a PicHandle:
156 GetGWorld(&oldPort,&oldDevice);
157 SetGWorld(gworld,NULL);
159 PicHandle pic = OpenPicture(&bounds);
160 CopyBits(GetPortBitMapForCopyBits(gworld),
161 GetPortBitMapForCopyBits(gworld),
162 &bounds,&bounds,srcCopy,NULL);
165 SetGWorld(oldPort,oldDevice);
166 DisposeGWorld(gworld);
169 Warn(@"Couldn't convert to PICT: error %i",err);
173 // Copy the PicHandle into an NSData:
175 //Test to put PICT on clipboard:
177 GetCurrentScrap(&scrap);
179 PutScrapFlavor(scrap,'PICT',0,GetHandleSize((Handle)pic),*pic);*/
180 NSData *data = [NSData dataWithBytes: *pic length: GetHandleSize((Handle)pic)];
181 DisposeHandle((Handle)pic);
182 Log(@"Converted image to %i bytes of PICT data",[data length]);
193 @implementation NSBezierPath (MYUtilities)
195 + (NSBezierPath*) my_bezierPathWithRoundRect: (NSRect)rect radius: (float)radius
197 radius = MIN(radius, floorf(rect.size.width/2));
198 float x0 = NSMinX(rect), y0 = NSMinY(rect),
199 x1 = NSMaxX(rect), y1 = NSMaxY(rect);
200 NSBezierPath *path = [NSBezierPath bezierPath];
202 [path moveToPoint: NSMakePoint(x0+radius,y0)];
204 [path appendBezierPathWithArcFromPoint: NSMakePoint(x1,y0)
205 toPoint: NSMakePoint(x1,y1) radius: radius];
206 [path appendBezierPathWithArcFromPoint: NSMakePoint(x1,y1)
207 toPoint: NSMakePoint(x0,y1) radius: radius];
208 [path appendBezierPathWithArcFromPoint: NSMakePoint(x0,y1)
209 toPoint: NSMakePoint(x0,y0) radius: radius];
210 [path appendBezierPathWithArcFromPoint: NSMakePoint(x0,y0)
211 toPoint: NSMakePoint(x1,y0) radius: radius];
220 NSArray* OpenWindowsWithDelegateClass( Class klass )
222 NSMutableArray *windows = $marray();
223 for( NSWindow *window in [NSApp windows] ) {
224 id delegate = window.delegate;
225 if( (window.isVisible || window.isMiniaturized) && (klass==nil || [delegate isKindOfClass: klass]) )
226 [windows addObject: window];
233 NSRect PinRect( NSRect r, NSRect container )
235 // Push r's origin inside container, and limit its size to the container's:
236 r = NSMakeRect(MAX(r.origin.x, container.origin.x),
237 MAX(r.origin.y, container.origin.y),
238 MIN(r.size.width, container.size.width),
239 MIN(r.size.height, container.size.height));
240 // Push r's outside edges into the container:
241 r.origin.x -= MAX(0, NSMaxX(r)-NSMaxX(container));
242 r.origin.y -= MAX(0, NSMaxY(r)-NSMaxY(container));
248 OSStatus LoadFontsFromBundle( NSBundle *bundle )
250 NSString *fontsPath = [[bundle resourcePath] stringByAppendingPathComponent:@"Fonts"];
252 return LoadFontsFromPath(fontsPath);
258 OSStatus LoadFontsFromPath( NSString* path )
260 // Tip of the hat to Buddy Kurz!
262 OSStatus err = PathToFSRef(path,&fsRef);
264 err = ATSFontActivateFromFileReference(&fsRef,
265 kATSFontContextLocal,
266 kATSFontFormatUnspecified,
268 kATSOptionFlagsDefault,
271 if( err ) Warn(@"LoadFontsFromPath: Error %i for %@",err,path);
278 Copyright (c) 2008, Jens Alfke <jens@mooseyard.com>. All rights reserved.
280 Redistribution and use in source and binary forms, with or without modification, are permitted
281 provided that the following conditions are met:
283 * Redistributions of source code must retain the above copyright notice, this list of conditions
284 and the following disclaimer.
285 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
286 and the following disclaimer in the documentation and/or other materials provided with the
289 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
290 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
291 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRI-
292 BUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
293 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
294 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
295 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
296 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.