1996-08-22 18:51:08 +00:00
|
|
|
/*
|
1996-05-30 20:03:15 +00:00
|
|
|
NSImage.m
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
Load, manipulate and display images
|
1996-05-30 20:03:15 +00:00
|
|
|
|
|
|
|
Copyright (C) 1996 Free Software Foundation, Inc.
|
|
|
|
|
1996-10-18 17:14:13 +00:00
|
|
|
Author: Adam Fedor <fedor@colorado.edu>
|
1996-08-22 18:51:08 +00:00
|
|
|
Date: Feb 1996
|
|
|
|
|
1996-05-30 20:03:15 +00:00
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Library General Public License for more details.
|
1996-08-22 18:51:08 +00:00
|
|
|
|
1996-05-30 20:03:15 +00:00
|
|
|
You should have received a copy of the GNU Library General Public
|
1996-10-18 17:14:13 +00:00
|
|
|
License along with this library; see the file COPYING.LIB.
|
|
|
|
If not, write to the Free Software Foundation,
|
|
|
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
1996-08-22 18:51:08 +00:00
|
|
|
*/
|
|
|
|
/*
|
|
|
|
FIXME:
|
|
|
|
[1] Filter services not implemented.
|
|
|
|
[2] Should there be a place to look for system bitmaps?
|
|
|
|
(findImageNamed:).
|
|
|
|
[3] bestRepresentation is not complete.
|
|
|
|
*/
|
1997-09-23 22:43:24 +00:00
|
|
|
#include <gnustep/gui/config.h>
|
1997-02-18 00:29:25 +00:00
|
|
|
#include <string.h>
|
|
|
|
|
1997-08-18 17:10:23 +00:00
|
|
|
#include <Foundation/NSString.h>
|
1997-02-18 00:29:25 +00:00
|
|
|
#include <Foundation/NSException.h>
|
|
|
|
#include <Foundation/NSArray.h>
|
|
|
|
#include <Foundation/NSValue.h>
|
|
|
|
#include <Foundation/NSDictionary.h>
|
|
|
|
#include <Foundation/NSBundle.h>
|
1997-08-27 21:20:19 +00:00
|
|
|
#include <Foundation/NSString.h>
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
#include <AppKit/NSImage.h>
|
|
|
|
#include <AppKit/NSBitmapImageRep.h>
|
|
|
|
#include <AppKit/NSCachedImageRep.h>
|
|
|
|
#include <AppKit/NSView.h>
|
|
|
|
#include <AppKit/NSWindow.h>
|
|
|
|
#include <AppKit/NSScreen.h>
|
1997-02-18 00:29:25 +00:00
|
|
|
#include <AppKit/NSColor.h>
|
1996-08-22 18:51:08 +00:00
|
|
|
|
1997-03-04 19:21:04 +00:00
|
|
|
// Resource directories
|
|
|
|
static NSString* gnustep_libdir = @GNUSTEP_INSTALL_LIBDIR;
|
|
|
|
static NSString* NSImage_PATH = @"Images";
|
1997-01-31 13:40:15 +00:00
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
/* Backend protocol - methods that must be implemented by the backend to
|
|
|
|
complete the class */
|
|
|
|
@protocol NSImageBackend
|
|
|
|
- (void) compositeToPoint: (NSPoint)point fromRect: (NSRect)rect
|
|
|
|
operation: (NSCompositingOperation)op;
|
|
|
|
- (void) dissolveToPoint: (NSPoint)point fromRect: (NSRect)rect
|
|
|
|
fraction: (float)aFloat;
|
|
|
|
@end
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
typedef struct _rep_data_t
|
|
|
|
{
|
|
|
|
NSString* fileName;
|
|
|
|
id rep;
|
|
|
|
id cache;
|
|
|
|
id original;
|
|
|
|
BOOL validCache;
|
|
|
|
} rep_data_t;
|
|
|
|
|
|
|
|
NSArray *iterate_reps_for_types(NSArray *imageReps, SEL method);
|
|
|
|
|
|
|
|
/* Find the rep_data_t holding a representation */
|
|
|
|
rep_data_t
|
|
|
|
repd_for_rep(NSArray *_reps, NSImageRep *rep)
|
|
|
|
{
|
|
|
|
int i, count;
|
|
|
|
rep_data_t repd;
|
|
|
|
|
|
|
|
count = [_reps count];
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
[[_reps objectAtIndex: i] getValue: &repd];
|
|
|
|
if (repd.rep == rep)
|
|
|
|
return repd;
|
|
|
|
}
|
|
|
|
[NSException raise: NSInternalInconsistencyException
|
|
|
|
format: @"Cannot find stored representation"];
|
|
|
|
/* NOT REACHED */
|
|
|
|
return repd;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
set_repd_for_rep(NSMutableArray *_reps, NSImageRep *rep, rep_data_t *new_repd)
|
|
|
|
{
|
|
|
|
int i, count;
|
|
|
|
rep_data_t repd;
|
|
|
|
BOOL found = NO;
|
|
|
|
|
|
|
|
count = [_reps count];
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
[[_reps objectAtIndex: i] getValue: &repd];
|
|
|
|
if (repd.rep == rep && !found)
|
|
|
|
{
|
|
|
|
[_reps replaceObjectAtIndex: i withObject:
|
|
|
|
[NSValue value: new_repd withObjCType: @encode(rep_data_t)]];
|
|
|
|
found = YES;
|
1997-07-07 16:56:52 +00:00
|
|
|
break;
|
1996-08-22 18:51:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!found)
|
|
|
|
[_reps addObject:
|
|
|
|
[NSValue value: new_repd withObjCType: @encode(rep_data_t)]];
|
|
|
|
}
|
|
|
|
|
|
|
|
@interface NSImage (Backend) <NSImageBackend>
|
|
|
|
@end
|
|
|
|
|
|
|
|
@interface NSImage (Private)
|
|
|
|
- (BOOL) useFromFile: (NSString *)fileName;
|
|
|
|
- (BOOL) loadFromData: (NSData *)data;
|
|
|
|
- (BOOL) loadFromFile: (NSString *)fileName;
|
|
|
|
- (NSImageRep *) lastRepresentation;
|
|
|
|
@end
|
1996-05-30 20:03:15 +00:00
|
|
|
|
|
|
|
@implementation NSImage
|
|
|
|
|
1997-12-04 01:58:57 +00:00
|
|
|
/* Class variables and functions for class methods */
|
|
|
|
static NSMutableDictionary* nameDict = nil;
|
|
|
|
static NSDictionary* nsmapping = nil;
|
|
|
|
|
1997-03-05 01:11:17 +00:00
|
|
|
+ (void)initialize
|
|
|
|
{
|
|
|
|
if (self == [NSImage class])
|
|
|
|
{
|
1997-12-04 01:58:57 +00:00
|
|
|
NSBundle *system = [NSBundle bundleWithPath:gnustep_libdir];
|
|
|
|
NSString* path = [system pathForResource:@"nsmapping"
|
|
|
|
ofType:@"strings"
|
|
|
|
inDirectory:NSImage_PATH];
|
1997-03-05 01:11:17 +00:00
|
|
|
// Initial version
|
|
|
|
[self setVersion:1];
|
|
|
|
|
|
|
|
// initialize the class variables
|
|
|
|
nameDict = [[NSMutableDictionary alloc] initWithCapacity: 10];
|
1997-12-04 01:58:57 +00:00
|
|
|
if (path)
|
|
|
|
nsmapping = [[[NSString stringWithContentsOfFile:path]
|
|
|
|
propertyListFromStringsFileFormat]
|
|
|
|
retain];
|
1997-03-05 01:11:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
+ imageNamed: (NSString *)aName
|
|
|
|
{
|
1997-12-04 01:58:57 +00:00
|
|
|
NSString* realName = [nsmapping objectForKey:aName];
|
|
|
|
|
|
|
|
if (realName)
|
|
|
|
aName = realName;
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
/* If there is no image with that name, search in the main bundle */
|
|
|
|
if (!nameDict || ![nameDict objectForKey:aName])
|
|
|
|
{
|
|
|
|
NSString* ext;
|
1997-01-31 13:40:15 +00:00
|
|
|
NSString* path = nil;
|
1996-08-22 18:51:08 +00:00
|
|
|
NSBundle* main;
|
1997-03-20 19:23:21 +00:00
|
|
|
NSArray *array;
|
|
|
|
NSString *the_name = aName;
|
1996-08-22 18:51:08 +00:00
|
|
|
main = [NSBundle mainBundle];
|
1997-03-20 19:23:21 +00:00
|
|
|
ext = [aName pathExtension];
|
|
|
|
|
|
|
|
/* Check if extension is one of the image types */
|
|
|
|
array = [self imageFileTypes];
|
|
|
|
if ([array indexOfObject: ext] != NSNotFound)
|
|
|
|
{
|
|
|
|
/* Extension is one of the image types
|
|
|
|
So remove from the name */
|
|
|
|
the_name = [aName stringByDeletingPathExtension];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Otherwise extension is not an image type
|
|
|
|
So leave it alone */
|
|
|
|
the_name = aName;
|
|
|
|
ext = nil;
|
|
|
|
}
|
1997-01-31 13:40:15 +00:00
|
|
|
|
|
|
|
/* First search locally */
|
1996-08-22 18:51:08 +00:00
|
|
|
if (ext)
|
1997-03-20 19:23:21 +00:00
|
|
|
path = [main pathForResource: the_name ofType: ext];
|
1996-08-22 18:51:08 +00:00
|
|
|
else
|
|
|
|
{
|
1997-01-31 13:40:15 +00:00
|
|
|
id o, e;
|
1996-08-22 18:51:08 +00:00
|
|
|
|
1997-01-31 13:40:15 +00:00
|
|
|
e = [array objectEnumerator];
|
|
|
|
while ((o = [e nextObject]))
|
1996-08-22 18:51:08 +00:00
|
|
|
{
|
1997-02-18 18:45:16 +00:00
|
|
|
NSDebugLog(@"extension %s\n", [o cString]);
|
1997-03-20 19:23:21 +00:00
|
|
|
path = [main pathForResource:the_name
|
1997-01-31 13:40:15 +00:00
|
|
|
ofType: o];
|
1996-08-22 18:51:08 +00:00
|
|
|
if ([path length] != 0)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
1997-01-31 13:40:15 +00:00
|
|
|
|
|
|
|
/* If not found then search in system */
|
|
|
|
if (!path)
|
|
|
|
{
|
1997-03-04 19:21:04 +00:00
|
|
|
NSBundle *system = [NSBundle bundleWithPath: gnustep_libdir];
|
1997-02-18 00:29:25 +00:00
|
|
|
|
1997-01-31 13:40:15 +00:00
|
|
|
if (ext)
|
1997-03-20 19:23:21 +00:00
|
|
|
path = [system pathForResource: the_name
|
1997-03-04 19:21:04 +00:00
|
|
|
ofType: ext
|
|
|
|
inDirectory: NSImage_PATH];
|
1997-01-31 13:40:15 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
id o, e;
|
|
|
|
NSArray* array;
|
|
|
|
|
|
|
|
array = [self imageFileTypes];
|
|
|
|
if (!array)
|
1997-02-18 18:45:16 +00:00
|
|
|
NSDebugLog(@"array is nil\n");
|
1997-01-31 13:40:15 +00:00
|
|
|
e = [array objectEnumerator];
|
|
|
|
while ((o = [e nextObject]))
|
|
|
|
{
|
1997-03-20 19:23:21 +00:00
|
|
|
path = [system pathForResource: the_name
|
1997-03-04 19:21:04 +00:00
|
|
|
ofType: o
|
|
|
|
inDirectory: NSImage_PATH];
|
1997-01-31 13:40:15 +00:00
|
|
|
if ([path length] != 0)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
if ([path length] != 0)
|
|
|
|
{
|
1997-07-07 16:56:52 +00:00
|
|
|
NSImage* image = [[[NSImage alloc] initByReferencingFile:path]
|
|
|
|
autorelease];
|
1996-08-22 18:51:08 +00:00
|
|
|
if (image)
|
1997-03-20 19:23:21 +00:00
|
|
|
[image setName: [[path lastPathComponent]
|
|
|
|
stringByDeletingPathExtension]];
|
1998-10-19 06:10:49 +00:00
|
|
|
|
|
|
|
return image;
|
1996-08-22 18:51:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return [nameDict objectForKey:aName];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Designated initializer for nearly everything.
|
|
|
|
- initWithSize: (NSSize)aSize
|
|
|
|
{
|
|
|
|
[super init];
|
|
|
|
_reps = [[NSMutableArray arrayWithCapacity: 2] retain];
|
|
|
|
if (aSize.width && aSize.height)
|
|
|
|
{
|
|
|
|
_size = aSize;
|
|
|
|
_flags.sizeWasExplicitlySet = YES;
|
|
|
|
}
|
|
|
|
_flags.colorMatchPreferred = YES;
|
|
|
|
_flags.multipleResolutionMatching = YES;
|
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- init
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
[self initWithSize: NSMakeSize(0, 0)];
|
|
|
|
return self;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- initByReferencingFile: (NSString *)fileName
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
[self init];
|
|
|
|
_flags.dataRetained = NO;
|
|
|
|
// FIXME: Should this be an exception? What else should happen?
|
|
|
|
if (![self useFromFile:fileName])
|
|
|
|
[NSException raise: NSGenericException
|
|
|
|
format: @"Cannot find image representation for image %s",
|
|
|
|
[fileName cString]];
|
|
|
|
return self;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- initWithContentsOfFile: (NSString *)fileName
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
[self init];
|
|
|
|
_flags.dataRetained = YES;
|
|
|
|
// FIXME: Should this be an exception? What else should happen ?
|
|
|
|
if (![self useFromFile:fileName])
|
|
|
|
[NSException raise: NSGenericException
|
|
|
|
format: @"Cannot find image representation for image %s",
|
|
|
|
[fileName cString]];
|
|
|
|
return self;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- initWithData: (NSData *)data;
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
[self init];
|
|
|
|
// FIXME: Should this be an exception? What else should happen ?
|
|
|
|
if (![self loadFromData: data])
|
|
|
|
[NSException raise: NSGenericException
|
|
|
|
format: @"Cannot find image representation for data"];
|
|
|
|
return self;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- initWithPasteboard: (NSPasteboard *)pasteboard
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
[self notImplemented:_cmd];
|
1996-05-30 20:03:15 +00:00
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (void) setSize: (NSSize)aSize
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
_size = aSize;
|
|
|
|
_flags.sizeWasExplicitlySet = YES;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (NSSize) size
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
if (_size.width == 0)
|
|
|
|
{
|
|
|
|
NSImageRep* rep = [self bestRepresentationForDevice: nil];
|
|
|
|
_size = [rep size];
|
|
|
|
}
|
|
|
|
return _size;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (void) dealloc
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
[self representations];
|
|
|
|
[_repList release];
|
|
|
|
[_reps release];
|
|
|
|
/* Make sure we don't remove name from the nameDict if we are just a copy
|
|
|
|
of the named image, not the original image */
|
|
|
|
if (name && self == [nameDict objectForKey: name])
|
|
|
|
[nameDict removeObjectForKey:name];
|
|
|
|
[name release];
|
|
|
|
[super dealloc];
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- copyWithZone: (NSZone *)zone
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
NSImage* copy;
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
// FIXME: maybe we should retain if _flags.dataRetained = NO
|
1997-07-07 16:56:52 +00:00
|
|
|
copy = (NSImage*)NSCopyObject (self, 0, zone);
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
[name retain];
|
1997-07-07 16:56:52 +00:00
|
|
|
copy->_reps = [NSMutableArray new];
|
|
|
|
copy->_repList = [NSMutableArray new];
|
1996-08-22 18:51:08 +00:00
|
|
|
[_color retain];
|
|
|
|
_lockedView = nil;
|
1997-07-07 16:56:52 +00:00
|
|
|
[copy addRepresentations: [[[self representations] copyWithZone: zone]
|
|
|
|
autorelease]];
|
1996-08-22 18:51:08 +00:00
|
|
|
|
|
|
|
return copy;
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (BOOL)setName: (NSString *)string
|
|
|
|
{
|
|
|
|
if (!nameDict)
|
|
|
|
nameDict = [[NSMutableDictionary dictionaryWithCapacity: 2] retain];
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
if (!string || [nameDict objectForKey: string])
|
|
|
|
return NO;
|
1997-02-18 00:29:25 +00:00
|
|
|
|
|
|
|
[string retain];
|
|
|
|
[name release];
|
|
|
|
name = string;
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
[nameDict setObject: self forKey: name];
|
|
|
|
return YES;
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (NSString *)name
|
|
|
|
{
|
|
|
|
return name;
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
|
|
|
// Choosing Which Image Representation to Use
|
1996-08-22 18:51:08 +00:00
|
|
|
- (void) setUsesEPSOnResolutionMismatch: (BOOL)flag
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
_flags.useEPSOnResolutionMismatch = flag;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)usesEPSOnResolutionMismatch
|
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
return _flags.useEPSOnResolutionMismatch;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (void) setPrefersColorMatch: (BOOL)flag
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
_flags.colorMatchPreferred = flag;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (BOOL)prefersColorMatch
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
return _flags.colorMatchPreferred;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (void) setMatchesOnMultipleResolution: (BOOL)flag
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
_flags.multipleResolutionMatching = flag;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (BOOL)matchesOnMultipleResolution
|
|
|
|
{
|
|
|
|
return _flags.multipleResolutionMatching;
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
|
|
|
// Determining How the Image is Stored
|
1996-08-22 18:51:08 +00:00
|
|
|
- (void) setCachedSeparately: (BOOL)flag
|
|
|
|
{
|
|
|
|
_flags.cacheSeparately = flag;
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (BOOL) isCachedSeparately
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
return _flags.cacheSeparately;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (void) setDataRetained: (BOOL)flag
|
|
|
|
{
|
|
|
|
_flags.dataRetained = flag;
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (BOOL) isDataRetained
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
return _flags.dataRetained;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (void) setCacheDepthMatchesImageDepth: (BOOL)flag
|
|
|
|
{
|
|
|
|
_flags.unboundedCacheDepth = flag;
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (BOOL) cacheDepthMatchesImageDepth
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
return _flags.unboundedCacheDepth;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Determining How the Image is Drawn
|
1996-08-22 18:51:08 +00:00
|
|
|
- (BOOL) isValid
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1997-02-18 00:29:25 +00:00
|
|
|
BOOL valid = NO;
|
1996-08-22 18:51:08 +00:00
|
|
|
int i, count;
|
|
|
|
|
|
|
|
/* Go through all our representations and determine if at least one
|
|
|
|
is a valid cache */
|
|
|
|
// FIXME: Not sure if this is correct
|
|
|
|
count = [_reps count];
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
rep_data_t repd;
|
|
|
|
[[_reps objectAtIndex: i] getValue: &repd];
|
|
|
|
valid |= repd.validCache;
|
|
|
|
}
|
|
|
|
return valid;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) recache
|
|
|
|
{
|
|
|
|
int i, count;
|
|
|
|
|
|
|
|
count = [_reps count];
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
rep_data_t repd;
|
|
|
|
[[_reps objectAtIndex: i] getValue: &repd];
|
|
|
|
repd.validCache = NO;
|
|
|
|
[_reps replaceObjectAtIndex: i withObject:
|
|
|
|
[NSValue value: &repd withObjCType: @encode(rep_data_t)]];
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (void) setScalesWhenResized: (BOOL)flag
|
|
|
|
{
|
|
|
|
_flags.scalable = flag;
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
|
|
|
- (BOOL)scalesWhenResized
|
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
return _flags.scalable;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (void) setBackgroundColor: (NSColor *)aColor
|
|
|
|
{
|
|
|
|
[_color autorelease];
|
|
|
|
_color = [aColor retain];
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
|
|
|
- (NSColor *)backgroundColor
|
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
return _color;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Make sure any images that were added with useFromFile: are loaded
|
|
|
|
in and added to the representation list. */
|
|
|
|
- _loadImageFilenames
|
|
|
|
{
|
|
|
|
unsigned i, count;
|
|
|
|
rep_data_t repd;
|
|
|
|
|
|
|
|
_syncLoad = NO;
|
|
|
|
count = [_reps count];
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
[[_reps objectAtIndex: i] getValue: &repd];
|
|
|
|
if (repd.fileName)
|
|
|
|
[self loadFromFile: repd.fileName];
|
|
|
|
}
|
|
|
|
// Now get rid of them since they are already loaded
|
|
|
|
count = [_reps count];
|
|
|
|
while (count--)
|
|
|
|
{
|
|
|
|
[[_reps objectAtIndex: count] getValue: &repd];
|
|
|
|
if (repd.fileName)
|
|
|
|
{
|
|
|
|
[repd.fileName release];
|
|
|
|
[_reps removeObjectAtIndex: count];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Cache the bestRepresentation. If the bestRepresentation is not itself
|
|
|
|
// a cache and no cache exists, create one and draw the representation in it
|
|
|
|
// If a cache exists, but is not valid, redraw the cache from the original
|
|
|
|
// image (if there is one).
|
1997-01-31 20:14:40 +00:00
|
|
|
- (NSImageRep *)_doImageCache
|
1996-08-22 18:51:08 +00:00
|
|
|
{
|
1997-01-31 20:14:40 +00:00
|
|
|
NSImageRep *rep = nil;
|
1996-08-22 18:51:08 +00:00
|
|
|
rep_data_t repd;
|
1997-01-31 20:14:40 +00:00
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
repd = repd_for_rep(_reps, [self bestRepresentationForDevice: nil]);
|
|
|
|
rep = repd.rep;
|
|
|
|
if (repd.cache)
|
|
|
|
rep = repd.cache;
|
1997-01-31 20:14:40 +00:00
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
if (![rep isKindOfClass: [NSCachedImageRep class]])
|
|
|
|
{
|
1997-01-31 20:14:40 +00:00
|
|
|
#if 0
|
1996-08-22 18:51:08 +00:00
|
|
|
[self lockFocus];
|
|
|
|
{
|
|
|
|
rep_data_t cached;
|
|
|
|
NSRect bounds;
|
|
|
|
_lockedView = [NSView focusView];
|
|
|
|
bounds = [_lockedView bounds];
|
|
|
|
[self _displayEraseRect: bounds view: _lockedView color: _color];
|
|
|
|
[self unlockFocus];
|
|
|
|
[[_reps lastObject] getValue: &cached];
|
|
|
|
cached.original = rep;
|
|
|
|
cached.validCache = YES;
|
|
|
|
[_reps removeLastObject];
|
|
|
|
[_reps addObject:
|
|
|
|
[NSValue value: &cached withObjCType: @encode(rep_data_t)]];
|
|
|
|
}
|
1997-01-31 20:14:40 +00:00
|
|
|
#endif
|
1996-08-22 18:51:08 +00:00
|
|
|
}
|
|
|
|
else if (!repd.validCache)
|
|
|
|
{
|
1997-01-31 20:14:40 +00:00
|
|
|
#if 0
|
1996-08-22 18:51:08 +00:00
|
|
|
[self lockFocusOnRepresentation: rep];
|
|
|
|
{
|
|
|
|
NSRect bounds;
|
|
|
|
bounds = [_lockedView bounds];
|
|
|
|
[self _displayEraseRect: bounds view: _lockedView color: _color];
|
|
|
|
repd = repd_for_rep(_reps, rep);
|
|
|
|
[self drawRepresentation: repd.original
|
|
|
|
inRect: NSMakeRect(0, 0, _size.width, _size.height)];
|
|
|
|
[self unlockFocus];
|
|
|
|
repd.validCache = YES;
|
|
|
|
set_repd_for_rep(_reps, repd.rep, &repd);
|
|
|
|
}
|
1997-01-31 20:14:40 +00:00
|
|
|
#endif
|
1996-08-22 18:51:08 +00:00
|
|
|
}
|
|
|
|
|
1997-01-31 20:14:40 +00:00
|
|
|
return rep;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
// Using the Image
|
|
|
|
- (void) compositeToPoint: (NSPoint)aPoint
|
|
|
|
operation: (NSCompositingOperation)op;
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
NSRect rect;
|
|
|
|
[self size];
|
|
|
|
rect = NSMakeRect(0, 0, _size.width, _size.height);
|
|
|
|
[self compositeToPoint: aPoint fromRect:rect operation: op];
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (void) compositeToPoint: (NSPoint)aPoint fromRect: (NSRect)aRect
|
|
|
|
operation: (NSCompositingOperation)op;
|
|
|
|
{
|
1997-01-31 20:14:40 +00:00
|
|
|
NSImageRep *rep;
|
|
|
|
NSRect rect = NSMakeRect(aPoint.x, aPoint.y, _size.width, _size.height);
|
|
|
|
|
|
|
|
// xxx If fromRect specifies something other than full image
|
|
|
|
// then we need to construct a subimage to draw
|
|
|
|
|
|
|
|
rep = [self _doImageCache];
|
|
|
|
[self lockFocusOnRepresentation: rep];
|
|
|
|
[self drawRepresentation: rep inRect: rect];
|
|
|
|
[self unlockFocus];
|
1996-08-22 18:51:08 +00:00
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (void) dissolveToPoint: (NSPoint)aPoint fraction: (float)aFloat;
|
|
|
|
{
|
|
|
|
NSRect rect;
|
|
|
|
[self size];
|
|
|
|
rect = NSMakeRect(0, 0, _size.width, _size.height);
|
|
|
|
[self dissolveToPoint: aPoint fromRect: rect fraction: aFloat];
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (void) dissolveToPoint: (NSPoint)aPoint fromRect: (NSRect)aRect
|
|
|
|
fraction: (float)aFloat;
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1997-01-31 20:14:40 +00:00
|
|
|
NSImageRep *rep;
|
|
|
|
NSRect rect = NSMakeRect(aPoint.x, aPoint.y, _size.width, _size.height);
|
|
|
|
|
|
|
|
// xxx If fromRect specifies something other than full image
|
|
|
|
// then we need to construct a subimage to draw
|
|
|
|
|
|
|
|
rep = [self _doImageCache];
|
|
|
|
[self lockFocusOnRepresentation: rep];
|
|
|
|
[self drawRepresentation: rep inRect: rect];
|
|
|
|
[self unlockFocus];
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (BOOL)drawRepresentation: (NSImageRep *)imageRep inRect: (NSRect)rect
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
if (!_flags.scalable)
|
|
|
|
return [imageRep drawAtPoint: rect.origin];
|
|
|
|
return [imageRep drawInRect: rect];
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (BOOL)loadFromData: (NSData *)data
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
BOOL ok;
|
|
|
|
Class rep;
|
|
|
|
|
|
|
|
ok = NO;
|
|
|
|
rep = [NSImageRep imageRepClassForData: data];
|
1997-02-18 00:29:25 +00:00
|
|
|
if (rep && [rep respondsToSelector: @selector(imageRepsWithData:)])
|
1996-08-22 18:51:08 +00:00
|
|
|
{
|
|
|
|
NSArray* array;
|
|
|
|
array = [rep imageRepsWithData: data];
|
|
|
|
if (array)
|
|
|
|
ok = YES;
|
|
|
|
[self addRepresentations: array];
|
|
|
|
}
|
|
|
|
else if (rep)
|
|
|
|
{
|
|
|
|
NSImageRep* image;
|
|
|
|
image = [rep imageRepWithData: data];
|
|
|
|
if (image)
|
|
|
|
ok = YES;
|
|
|
|
[self addRepresentation: image];
|
|
|
|
}
|
|
|
|
return ok;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (BOOL)loadFromFile: (NSString *)fileName
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
NSArray* array;
|
|
|
|
|
|
|
|
array = [NSImageRep imageRepsWithContentsOfFile: fileName];
|
|
|
|
if (array)
|
|
|
|
[self addRepresentations: array];
|
|
|
|
|
|
|
|
return (array) ? YES : NO;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (BOOL)useFromFile: (NSString *)fileName
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
NSArray* array;
|
|
|
|
NSString* ext;
|
|
|
|
rep_data_t repd;
|
|
|
|
|
1997-03-20 19:23:21 +00:00
|
|
|
ext = [fileName pathExtension];
|
1996-08-22 18:51:08 +00:00
|
|
|
if (!ext)
|
|
|
|
return NO;
|
|
|
|
array = [[self class] imageFileTypes];
|
1997-01-31 13:40:15 +00:00
|
|
|
if ([array indexOfObject: ext] == NSNotFound)
|
1996-08-22 18:51:08 +00:00
|
|
|
return NO;
|
|
|
|
repd.fileName = [fileName retain];
|
|
|
|
[_reps addObject: [NSValue value: &repd withObjCType: @encode(rep_data_t)]];
|
|
|
|
_syncLoad = YES;
|
|
|
|
return YES;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (void) addRepresentation: (NSImageRep *)imageRep
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
[self addRepresentations: [NSArray arrayWithObject: imageRep]];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) addRepresentations: (NSArray *)imageRepArray
|
|
|
|
{
|
|
|
|
int i, count;
|
|
|
|
rep_data_t repd;
|
|
|
|
|
|
|
|
if (!imageRepArray)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (_syncLoad)
|
|
|
|
[self _loadImageFilenames];
|
|
|
|
count = [imageRepArray count];
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
repd.fileName = NULL;
|
1997-07-07 16:56:52 +00:00
|
|
|
repd.rep = [[imageRepArray objectAtIndex: i] retain];
|
1996-08-22 18:51:08 +00:00
|
|
|
repd.cache = NULL;
|
|
|
|
repd.original = NULL;
|
|
|
|
repd.validCache = NO;
|
|
|
|
[_reps addObject:
|
|
|
|
[NSValue value: &repd withObjCType: @encode(rep_data_t)]];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL) useCacheWithDepth: (int)depth
|
|
|
|
{
|
|
|
|
NSSize imageSize;
|
|
|
|
NSCachedImageRep* rep;
|
|
|
|
|
|
|
|
imageSize = [self size];
|
|
|
|
if (!imageSize.width || !imageSize.height)
|
|
|
|
return NO;
|
|
|
|
|
|
|
|
// FIMXE: determine alpha? separate?
|
|
|
|
rep = [[NSCachedImageRep alloc] initWithSize: _size
|
|
|
|
depth: depth
|
|
|
|
separate: NO
|
|
|
|
alpha: NO];
|
|
|
|
[self addRepresentation:rep];
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) removeRepresentation: (NSImageRep *)imageRep
|
|
|
|
{
|
|
|
|
int i, count;
|
|
|
|
rep_data_t repd;
|
|
|
|
count = [_reps count];
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
[[_reps objectAtIndex: i] getValue: &repd];
|
|
|
|
if (repd.rep == imageRep)
|
|
|
|
[_reps removeObjectAtIndex: i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) lockFocus
|
|
|
|
{
|
|
|
|
NSScreen *cur = [NSScreen mainScreen];
|
|
|
|
NSImageRep *rep;
|
|
|
|
|
|
|
|
if (!(rep = [self bestRepresentationForDevice: nil]))
|
|
|
|
{
|
|
|
|
[self useCacheWithDepth: [cur depth]];
|
|
|
|
rep = [self lastRepresentation];
|
|
|
|
}
|
|
|
|
[self lockFocusOnRepresentation: rep];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) lockFocusOnRepresentation: (NSImageRep *)imageRep
|
|
|
|
{
|
1997-02-18 00:29:25 +00:00
|
|
|
#if 0
|
1996-08-22 18:51:08 +00:00
|
|
|
NSScreen *cur = [NSScreen mainScreen];
|
|
|
|
NSWindow *window;
|
1997-02-18 00:29:25 +00:00
|
|
|
#endif
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
if (!imageRep)
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
format: @"Cannot lock focus on nil rep"];
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
if (![imageRep isKindOfClass: [NSCachedImageRep class]])
|
|
|
|
{
|
|
|
|
rep_data_t repd, cached;
|
|
|
|
int depth;
|
|
|
|
if (_flags.unboundedCacheDepth)
|
|
|
|
depth = [cur depth]; // FIXME: get depth correctly
|
|
|
|
else
|
|
|
|
depth = [cur depth];
|
|
|
|
if (![self useCacheWithDepth: depth])
|
|
|
|
{
|
|
|
|
[NSException raise: NSImageCacheException
|
|
|
|
format: @"Unable to create cache"];
|
|
|
|
}
|
|
|
|
repd = repd_for_rep(_reps, imageRep);
|
|
|
|
cached = repd_for_rep(_reps, [self lastRepresentation]);
|
|
|
|
repd.cache = cached.rep;
|
|
|
|
cached.original = repd.rep;
|
|
|
|
set_repd_for_rep(_reps, imageRep, &repd);
|
|
|
|
set_repd_for_rep(_reps, cached.rep, &cached);
|
|
|
|
imageRep = cached.rep;
|
|
|
|
}
|
|
|
|
window = [(NSCachedImageRep *)imageRep window];
|
|
|
|
_lockedView = [window contentView];
|
|
|
|
[_lockedView lockFocus];
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) unlockFocus
|
|
|
|
{
|
1996-10-18 17:14:13 +00:00
|
|
|
#if 0
|
1996-08-22 18:51:08 +00:00
|
|
|
if (_lockedView)
|
|
|
|
[_lockedView unlockFocus];
|
|
|
|
_lockedView = nil;
|
1996-10-18 17:14:13 +00:00
|
|
|
#endif
|
1996-08-22 18:51:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSImageRep *) lastRepresentation
|
|
|
|
{
|
|
|
|
// Reconstruct the repList if it has changed
|
|
|
|
[self representations];
|
|
|
|
return [_repList lastObject];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSImageRep *) bestRepresentationForDevice:
|
|
|
|
(NSDictionary *)deviceDescription;
|
|
|
|
{
|
|
|
|
id o, e;
|
1996-10-18 17:14:13 +00:00
|
|
|
NSImageRep *rep = nil;
|
1996-08-22 18:51:08 +00:00
|
|
|
rep_data_t repd;
|
|
|
|
|
|
|
|
// Make sure we have the images loaded in
|
|
|
|
if (_syncLoad)
|
|
|
|
[self _loadImageFilenames];
|
|
|
|
|
|
|
|
if ([_reps count] == 0)
|
|
|
|
return nil;
|
|
|
|
|
|
|
|
// What's the best representation? FIXME
|
|
|
|
e = [_reps objectEnumerator];
|
|
|
|
o = [e nextObject];
|
|
|
|
while (o)
|
|
|
|
{
|
|
|
|
[o getValue: &repd];
|
1996-10-18 17:14:13 +00:00
|
|
|
if ([repd.rep isKindOfClass: [NSBitmapImageRep class]])
|
1996-08-22 18:51:08 +00:00
|
|
|
rep = repd.rep;
|
|
|
|
o = [e nextObject];
|
|
|
|
}
|
|
|
|
#if 0
|
|
|
|
[[_reps lastObject] getValue: &repd];
|
|
|
|
if (repd.cache)
|
|
|
|
rep = repd.cache;
|
|
|
|
else
|
|
|
|
rep = repd.rep;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return rep;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSArray *) representations
|
|
|
|
{
|
|
|
|
int i, count;
|
|
|
|
if (!_repList)
|
|
|
|
_repList = [[NSMutableArray alloc] init];
|
|
|
|
if (_syncLoad)
|
|
|
|
[self _loadImageFilenames];
|
|
|
|
count = [_reps count];
|
|
|
|
[_repList removeAllObjects];
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
rep_data_t repd;
|
|
|
|
[[_reps objectAtIndex: i] getValue: &repd];
|
|
|
|
[_repList addObject:repd.rep];
|
|
|
|
}
|
|
|
|
return _repList;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setDelegate: anObject
|
|
|
|
{
|
|
|
|
delegate = anObject;
|
|
|
|
}
|
|
|
|
|
|
|
|
- delegate
|
|
|
|
{
|
|
|
|
return delegate;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
// Producing TIFF Data for the Image
|
|
|
|
- (NSData *) TIFFRepresentation;
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
[self notImplemented: _cmd];
|
1996-05-30 20:03:15 +00:00
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (NSData *) TIFFRepresentationUsingCompression: (NSTIFFCompression)comp
|
|
|
|
factor: (float)aFloat
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
[self notImplemented: _cmd];
|
1996-05-30 20:03:15 +00:00
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Methods Implemented by the Delegate
|
|
|
|
- (NSImage *)imageDidNotDraw:(id)sender
|
|
|
|
inRect:(NSRect)aRect
|
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
if ([delegate respondsToSelector:@selector(imageDidNotDraw:inRect:)])
|
|
|
|
return [delegate imageDidNotDraw: sender inRect: aRect];
|
|
|
|
else
|
|
|
|
return self;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
// NSCoding
|
|
|
|
- (void)encodeWithCoder:(NSCoder *)coder
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (id)initWithCoder:(NSCoder *)coder
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
return self;
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (id) awakeAfterUsingCoder: (NSCoder*)aDecoder
|
|
|
|
{
|
|
|
|
if (name && [nameDict objectForKey:name])
|
|
|
|
{
|
|
|
|
return [nameDict objectForKey:name];
|
|
|
|
}
|
|
|
|
|
1996-05-30 20:03:15 +00:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
// FIXME: Implement
|
|
|
|
+ (BOOL) canInitWithPasteboard: (NSPasteboard *)pasteboard
|
|
|
|
{
|
|
|
|
int i, count;
|
|
|
|
NSArray* array = [NSImageRep registeredImageRepClasses];
|
|
|
|
|
|
|
|
count = [array count];
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
if ([[array objectAtIndex: i] canInitWithPasteboard: pasteboard])
|
|
|
|
return YES;
|
|
|
|
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (NSArray *) imageUnfilteredFileTypes
|
|
|
|
{
|
|
|
|
return iterate_reps_for_types([NSImageRep registeredImageRepClasses],
|
|
|
|
@selector(imageUnfilteredFileTypes));
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (NSArray *) imageFileTypes
|
|
|
|
{
|
|
|
|
return iterate_reps_for_types([NSImageRep registeredImageRepClasses],
|
|
|
|
@selector(imageFileTypes));
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (NSArray *) imageUnfilteredPasteboardTypes
|
|
|
|
{
|
|
|
|
return iterate_reps_for_types([NSImageRep registeredImageRepClasses],
|
|
|
|
@selector(imageUnfilteredPasteboardTypes));
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (NSArray *) imagePasteboardTypes
|
|
|
|
{
|
|
|
|
return iterate_reps_for_types([NSImageRep registeredImageRepClasses],
|
|
|
|
@selector(imagePasteboardTypes));
|
|
|
|
}
|
|
|
|
|
1996-05-30 20:03:15 +00:00
|
|
|
@end
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
/* For every image rep, call the specified method to obtain an
|
|
|
|
array of objects. Add these together, with duplicates
|
|
|
|
weeded out. Used by imageUnfilteredPasteboardTypes,
|
|
|
|
imageUnfilteredFileTypes, etc. */
|
|
|
|
NSArray *
|
|
|
|
iterate_reps_for_types(NSArray* imageReps, SEL method)
|
|
|
|
{
|
|
|
|
NSImageRep *rep;
|
|
|
|
id e;
|
1997-02-18 00:29:25 +00:00
|
|
|
// int i, count;
|
1996-08-22 18:51:08 +00:00
|
|
|
NSMutableArray* types;
|
|
|
|
|
|
|
|
types = [NSMutableArray arrayWithCapacity: 2];
|
|
|
|
|
|
|
|
// Iterate through all the image reps
|
|
|
|
e = [imageReps objectEnumerator];
|
|
|
|
rep = [e nextObject];
|
|
|
|
while (rep)
|
|
|
|
{
|
|
|
|
id e1;
|
|
|
|
id obj;
|
|
|
|
NSArray* pb_list;
|
|
|
|
|
|
|
|
// Have the image rep perform the operation
|
1997-08-27 21:20:19 +00:00
|
|
|
pb_list = [rep performSelector: method];
|
1996-08-22 18:51:08 +00:00
|
|
|
|
|
|
|
// Iterate through the returned array
|
|
|
|
// and add elements to types list, duplicates weeded.
|
|
|
|
e1 = [pb_list objectEnumerator];
|
|
|
|
obj = [e1 nextObject];
|
|
|
|
while (obj)
|
|
|
|
{
|
1997-01-31 13:40:15 +00:00
|
|
|
if ([types indexOfObject: obj] == NSNotFound)
|
1996-08-22 18:51:08 +00:00
|
|
|
[types addObject: obj];
|
|
|
|
obj = [e1 nextObject];
|
|
|
|
}
|
|
|
|
|
|
|
|
rep = [e nextObject];
|
|
|
|
}
|
|
|
|
|
|
|
|
return (NSArray *)types;
|
|
|
|
}
|