colorspace support

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@6515 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2000-04-25 20:26:51 +00:00
parent 1106e48a99
commit 44945db528
7 changed files with 470 additions and 141 deletions

View file

@ -1,3 +1,11 @@
2000-04-25 Richard Frith-Macdonald <rfm@gnu.org>
Patch by Gregory John Casamento <borgheron@yahoo.com> edited to
conform to standards. Adds improved colorspace support.
Files modified - Headers/gnustep/gui/NSGraphics.h,
Headers/gnustep/gui/NSScreen.h, Source/Functions.m, Source/NSScreen.m,
Source/externs.m, Tools/Functions.m
2000-04-25 Adam Fedor <fedor@gnu.org>
* Source/NSView.m (-_updateBoundsMatrix): New method from

View file

@ -31,9 +31,9 @@
@class NSString;
@class NSColor;
//
// Colorspace Names
//
/*
* Colorspace Names
*/
extern NSString *NSCalibratedWhiteColorSpace;
extern NSString *NSCalibratedBlackColorSpace;
extern NSString *NSCalibratedRGBColorSpace;
@ -46,6 +46,23 @@ extern NSString *NSCustomColorSpace;
typedef int NSWindowDepth;
/*
* Color function externs
*/
extern const NSWindowDepth _GSGrayBitValue;
extern const NSWindowDepth _GSRGBBitValue;
extern const NSWindowDepth _GSCMYKBitValue;
extern const NSWindowDepth _GSCustomBitValue;
extern const NSWindowDepth _GSNamedBitValue;
extern const NSWindowDepth *_GSWindowDepths[7];
extern const NSWindowDepth NSDefaultDepth;
extern const NSWindowDepth NSTwoBitGrayDepth;
extern const NSWindowDepth NSEightBitGrayDepth;
extern const NSWindowDepth NSEightBitRGBDepth;
extern const NSWindowDepth NSTwelveBitRGBDepth;
extern const NSWindowDepth GSSixteenBitRGBDepth;
extern const NSWindowDepth NSTwentyFourBitRGBDepth;
/*
* Gray Values
*/
@ -102,6 +119,8 @@ int NSBitsPerSampleFromDepth(NSWindowDepth depth);
NSString *NSColorSpaceFromDepth(NSWindowDepth depth);
int NSNumberOfColorComponents(NSString *colorSpaceName);
BOOL NSPlanarFromDepth(NSWindowDepth depth);
NSWindowDepth GSWindowDepthForScreen(int screen);
const NSWindowDepth *GSAvailableDepthsForScreen(int screen);
/*
* Read the Color at a Screen Position
@ -146,6 +165,7 @@ void NSWindowList(int size, int list[]);
NSArray* GSAllWindows();
NSWindow* GSWindowWithNumber(int num);
#endif
#endif /* __NSGraphics_h__ */

View file

@ -3,10 +3,14 @@
Class representing monitors
Copyright (C) 1996 Free Software Foundation, Inc.
Copyright (C) 1996, 2000 Free Software Foundation, Inc.
Author: Scott Christley <scottc@net-community.com>
Author: Scott Christley <scottc@net-community.com>
Date: 1996
Fixes and updates made by
Author: Gregory John Casamento <borgheron@yahoo.com>
Date: 2000
This file is part of the GNUstep GUI Library.
@ -38,28 +42,27 @@
@interface NSScreen : NSObject
{
// Attributes
NSWindowDepth depth;
NSRect frame;
NSMutableDictionary *device_desc;
@private
NSWindowDepth _depth;
NSRect _frame;
int _screenNumber;
// Reserved for backend use
void *be_screen_reserved;
void *_reserved;
}
//
// Creating NSScreen Instances
//
+ (NSScreen *)mainScreen;
+ (NSScreen *)deepestScreen;
+ (NSArray *)screens;
/*
* Creating NSScreen Instances
*/
+ (NSScreen*) mainScreen;
+ (NSScreen*) deepestScreen;
+ (NSArray*) screens;
//
// Reading Screen Information
//
- (NSWindowDepth)depth;
- (NSRect)frame;
- (NSDictionary *)deviceDescription;
/*
* Reading Screen Information
*/
- (NSWindowDepth) depth;
- (NSRect) frame;
- (NSDictionary*) deviceDescription;
#ifndef STRICT_OPENSTEP
- (const NSWindowDepth*) supportedWindowDepths;
@ -67,12 +70,4 @@
#endif
@end
#ifndef NO_GNUSTEP
// Need this definition for backend classes
@interface NSScreen (GNUstep)
- initWithDeviceDescription: (NSDictionary *)dict;
@end
#endif
#endif // _GNUstep_H_NSScreen

View file

@ -32,6 +32,7 @@
#include <AppKit/NSApplication.h>
#include <AppKit/NSEvent.h>
#include <AppKit/NSGraphicsContext.h>
#include <AppKit/NSGraphics.h>
char **NSArgv = NULL;
@ -104,3 +105,192 @@ NSEventMaskFromType(NSEventType type)
}
return 0;
}
/*
* Color Functions
*/
/*
* Get Information About Color Space and Window Depth
*/
const NSWindowDepth*
NSAvailableWindowDepths(void)
{
/*
* Perhaps this is the only function which
* belongs in the backend. It should be possible
* to detect which depths the window server is capable
* of.
*/
return (const NSWindowDepth *)_GSWindowDepths;
}
NSWindowDepth
NSBestDepth(NSString *colorSpace, int bitsPerSample, int bitsPerPixel,
BOOL planar, BOOL *exactMatch)
{
int components = NSNumberOfColorComponents(colorSpace);
int index = 0;
const NSWindowDepth *depths = NSAvailableWindowDepths();
NSWindowDepth bestDepth = NSDefaultDepth;
*exactMatch = NO;
if (components == 1)
{
for (index = 0; depths[index] != 0; index++)
{
NSWindowDepth depth = depths[index];
if (NSPlanarFromDepth(depth))
{
bestDepth = depth;
if (NSBitsPerSampleFromDepth(depth) == bitsPerSample)
{
*exactMatch = YES;
}
}
}
}
else
{
for (index = 0; depths[index] != 0; index++)
{
NSWindowDepth depth = depths[index];
if (!NSPlanarFromDepth(depth))
{
bestDepth = depth;
if (NSBitsPerSampleFromDepth(depth) == bitsPerSample)
{
*exactMatch = YES;
}
}
}
}
return bestDepth;
}
int
NSBitsPerPixelFromDepth(NSWindowDepth depth)
{
int bps = NSBitsPerSampleFromDepth(depth);
int spp = 0;
if (depth & _GSRGBBitValue)
{
spp = 3;
}
else if (depth & _GSCMYKBitValue)
{
spp = 4;
}
else if (depth & _GSGrayBitValue)
{
spp = 1;
}
return (spp * bps);
}
int
NSBitsPerSampleFromDepth(NSWindowDepth depth)
{
NSWindowDepth bitValue = 0;
/*
* Test against colorspace bit.
* and out the bit to get the bps value.
*/
if (depth & _GSRGBBitValue)
{
bitValue = _GSRGBBitValue;
}
else if (depth & _GSCMYKBitValue)
{
bitValue = _GSCMYKBitValue;
}
else if (depth & _GSGrayBitValue)
{
bitValue = _GSGrayBitValue;
}
/*
* AND against the complement
* to extract the bps value.
*/
return (depth & ~(bitValue));
}
NSString*
NSColorSpaceFromDepth(NSWindowDepth depth)
{
NSString *colorSpace = NSCalibratedWhiteColorSpace;
/*
* Test against each of the possible colorspace bits
* and return the corresponding colorspace.
*/
if (depth == 0)
{
colorSpace = NSCalibratedBlackColorSpace;
}
else if (depth & _GSRGBBitValue)
{
colorSpace = NSCalibratedRGBColorSpace;
}
else if (depth & _GSCMYKBitValue)
{
colorSpace = NSDeviceCMYKColorSpace;
}
else if (depth & _GSGrayBitValue)
{
colorSpace = NSCalibratedWhiteColorSpace;
}
else if (depth & _GSNamedBitValue)
{
colorSpace = NSNamedColorSpace;
}
else if (depth & _GSCustomBitValue)
{
colorSpace = NSCustomColorSpace;
}
return colorSpace;
}
int
NSNumberOfColorComponents(NSString *colorSpaceName)
{
int components = 1;
/*
* These are the only exceptions to the above.
* All other colorspaces have as many bps as bpp.
*/
if ([colorSpaceName isEqualToString: NSCalibratedRGBColorSpace]
|| [colorSpaceName isEqualToString: NSDeviceRGBColorSpace])
{
components = 3;
}
else if ([colorSpaceName isEqualToString: NSDeviceCMYKColorSpace])
{
components = 4;
}
return components;
}
BOOL
NSPlanarFromDepth(NSWindowDepth depth)
{
BOOL planar = NO;
/*
* Only the grayscale depths are planar.
* All others are interleaved.
*/
if (depth & _GSGrayBitValue)
{
planar = YES;
}
return planar;
}

View file

@ -1,12 +1,16 @@
/*
/*
NSScreen.m
Description...
Copyright (C) 1996 Free Software Foundation, Inc.
Copyright (C) 1996, 2000 Free Software Foundation, Inc.
Author: Scott Christley <scottc@net-community.com>
Date: 1996
Major modifications and updates
Author: Gregory John Casamento <borgheron@yahoo.com>
Date: 2000
This file is part of the GNUstep GUI Library.
@ -27,129 +31,90 @@
*/
#include <gnustep/gui/config.h>
#include <Foundation/NSDictionary.h>
#include <Foundation/NSArray.h>
#include <Foundation/Foundation.h>
#include <AppKit/NSApplication.h>
#include <AppKit/NSScreen.h>
#include <AppKit/NSInterfaceStyle.h>
#include <AppKit/NSGraphicsContext.h>
#include <AppKit/DPSOperators.h>
#include <AppKit/NSGraphics.h>
static int *
_screen_numbers(void)
static int*
_screenNumbers(int *count)
{
int count, *list;
NSGraphicsContext *ctxt = GSCurrentContext();
int *list;
NSGraphicsContext *ctxt = GSCurrentContext();
DPScountscreenlist(ctxt, 0, &count);
if (count == 0)
return NULL;
list = NSZoneMalloc(NSDefaultMallocZone(), (count+1)*sizeof(int));
DPSscreenlist(ctxt, 0, count, list);
DPScountscreenlist(ctxt, 0, count);
// If the list is empty quit...
if (*count == 0)
{
NSLog(@"Internal error: No screens detected.");
return NULL; // something is wrong. This shouldn't happen.
}
list = NSZoneMalloc(NSDefaultMallocZone(), (*count+1)*sizeof(int));
DPSscreenlist(ctxt, 0, *count, list);
return list;
}
@implementation NSScreen
/*
* Class variables
*/
static NSScreen *mainScreen = nil;
/*
* Class methods
*/
+ (void) initialize
{
if (self == [NSScreen class])
{
[self setVersion:1];
}
}
/*
* Creating NSScreen Instances
*/
+ (NSScreen*) mainScreen
{
NSMutableDictionary *dict;
if (mainScreen)
return mainScreen;
dict = [NSMutableDictionary dictionary];
[dict setObject: @"Main" forKey: @"NSScreenKeyName"];
mainScreen = [[NSScreen alloc] initWithDeviceDescription: dict];
return mainScreen;
}
+ (NSScreen*) deepestScreen
{
return [self mainScreen];
}
+ (NSArray*) screens
{
return [NSArray arrayWithObject: [self mainScreen]];
}
/*
* Instance methods
*/
- (id) initWithDeviceDescription: (NSDictionary*)dict
{
int screen;
float x, y, w, h;
NSGraphicsContext *ctxt = GSCurrentContext();
[super init];
depth = 0;
frame = NSZeroRect;
if (dict)
device_desc = [dict mutableCopy];
else
device_desc = [[NSMutableDictionary dictionary] retain];
// NSScreen does not respond to the init method.
- (id) init
{
[self doesNotRecognizeSelector: _cmd];
return nil;
}
// Get all of the infomation for a given screen.
- (id) _initWithScreenNumber: (int)screen
{
float x, y, w, h;
NSGraphicsContext *ctxt = GSCurrentContext();
int bitsPerPixel = 0;
self = [super init];
// Initialize i-vars
_depth = 0;
_frame = NSZeroRect;
_screenNumber = 0;
// Check for problems
if (screen < 0)
{
NSLog(@"Internal error: Invalid screen number %d\n",screen);
RELEASE(self);
return nil;
}
if (ctxt == nil)
{
NSLog(@"Internal error: No current context\n");
[self release];
RELEASE(self);
return nil;
}
if ([ctxt isDrawingToScreen] == NO)
{
NSLog(@"Internal error: trying to find screen with wrong context\n");
[self release];
RELEASE(self);
return nil;
}
if (!dict || [dict objectForKey: @"NSScreenKeyName"] == nil
|| [[dict objectForKey: @"NSScreenKeyName"] isEqual: @"Main"])
{
/* Assume the main screen is the one we started with */
int *windows = _screen_numbers();
screen = 0;
if (windows)
screen = windows[0];
NSZoneFree(NSDefaultMallocZone(), windows);
}
else if ([dict objectForKey: @"NSScreenNumber"])
{
screen = [[dict objectForKey: @"NSScreenNumber"] intValue];
}
/* Special hack to get screen frame since window number of root window
is same as screen number */
// Fill in all of the i-vars with appropriate values.
_screenNumber = screen;
DPScurrentwindowbounds(ctxt, screen, &x, &y, &w, &h);
frame = NSMakeRect(x, y, w, h);
DPScurrentwindowdepth(ctxt, screen, &depth);
return self;
}
_frame = NSMakeRect(x, y, w, h);
_depth = GSWindowDepthForScreen(screen);
- (id) init
{
return [self initWithDeviceDescription: NULL];
return self;
}
/*
@ -157,34 +122,73 @@ static NSScreen *mainScreen = nil;
*/
- (NSWindowDepth) depth
{
return depth;
return _depth;
}
- (NSRect) frame
{
return frame;
return _frame;
}
- (NSDictionary*) deviceDescription
{
NSDictionary *d = [[NSDictionary alloc] initWithDictionary: device_desc];
NSMutableDictionary *devDesc = [[NSDictionary alloc] init];
int bps = 0;
NSSize screenResolution;
NSString *colorSpaceName = nil;
return d;
/*
* Testing of this method on OS4.2 indicates that the
* dictionary is re-created every time this method is called.
*/
// Set the screen number in the current object.
devDesc = [NSMutableDictionary new];
[devDesc setObject: [NSNumber numberWithInt: _screenNumber]
forKey: @"NSScreenNumber"];
// This is assumed since we are in NSScreen.
[devDesc setObject: @"YES" forKey: NSDeviceIsScreen];
// Add the NSDeviceSize dictionary item
[devDesc setObject: [NSValue valueWithSize: _frame.size]
forKey: NSDeviceSize];
// Add the NSDeviceResolution dictionary item
screenResolution.width = 72; // This is a fixed value for screens.
screenResolution.height = 72; // All screens I checked under OS4.2 report 72.
[devDesc setObject: [NSValue valueWithSize: screenResolution]
forKey: NSDeviceResolution];
// Add the bits per sample entry
bps = NSBitsPerSampleFromDepth(_depth);
[devDesc setObject: [NSNumber numberWithInt: bps]
forKey: NSDeviceBitsPerSample];
// Add the color space entry.
colorSpaceName = NSColorSpaceFromDepth(_depth);
[devDesc setObject: colorSpaceName
forKey: NSDeviceColorSpaceName];
return [NSDictionary dictionaryWithDictionary: devDesc];
}
// Mac OS X methods
- (const NSWindowDepth*) supportedWindowDepths
{
// Skeletal implementation
NSWindowDepth* retval = NSZoneMalloc([self zone], sizeof(NSWindowDepth)*2);
retval[1] = depth;
retval[2] = 0;
return retval;
/*
* Skeletal implementation
* NSWindowDepth* retval = NSZoneMalloc([self zone], sizeof(NSWindowDepth)*2);
* retval[1] = _depth;
* retval[2] = 0;
* return retval;
*/
return GSAvailableDepthsForScreen(_screenNumber);
}
- (NSRect) visibleFrame
{
NSRect visFrame = frame;
NSRect visFrame = _frame;
switch ([NSApp interfaceStyle])
{
@ -196,8 +200,94 @@ static NSScreen *mainScreen = nil;
case NSNextStepInterfaceStyle:
case NSNoInterfaceStyle:
default:
return frame;
return _frame;
}
}
/*
* Class methods
*/
+ (void) initialize
{
if (self == [NSScreen class])
{
[self setVersion:1];
}
}
// Creating NSScreen Instances
+ (NSScreen*) mainScreen
{
int *windows = 0, count;
NSScreen *mainScreen = nil;
// Initialize the window list.
windows = _screenNumbers(&count);
// If the list is empty quit...
if (windows == NULL)
return nil; // something is wrong. This shouldn't happen.
// main screen is always first in the array.
mainScreen = [[NSScreen alloc] _initWithScreenNumber: windows[0]];
NSZoneFree(NSDefaultMallocZone(), windows); // free the list
return mainScreen;
}
+ (NSScreen*) deepestScreen
{
NSArray *screenArray = [NSScreen screens];
NSEnumerator *screenEnumerator = nil;
NSScreen *deepestScreen = nil, *screen = nil;
int maxBits = 0;
// Iterate over the list of screens and find the
// one with the most depth.
screenEnumerator = [screenArray objectEnumerator];
while ((screen = [screenEnumerator nextObject]) != nil)
{
int bits = 0;
bits = [screen depth];
if (bits > maxBits)
{
maxBits = bits;
deepestScreen = screen;
}
}
return deepestScreen;
}
+ (NSArray*) screens
{
int count = 0, index = 0, *windows = 0;
NSGraphicsContext *ctxt = GSCurrentContext();
NSMutableArray *screenArray = [NSMutableArray array];
// Get the number of screens.
windows = _screenNumbers(&count);
// If the list is empty quit...
if (windows == NULL)
return nil; // something is wrong. This shouldn't happen.
// Iterate over the list
for (index = 0; index < count; index++)
{
NSScreen *screen = nil;
screen = [[NSScreen alloc] _initWithScreenNumber: windows[index]];
[screenArray addObject: screen];
}
NSZoneFree(NSDefaultMallocZone(), windows); // free the list
return [NSArray arrayWithArray: screenArray];
}
@end

View file

@ -160,12 +160,12 @@ NSString *NSAFMWeight = @"Weight";
NSString *NSAFMXHeight = @"XHeight";
// NSScreen Global device dictionary key strings
NSString *NSDeviceResolution = @"Resolution";
NSString *NSDeviceColorSpaceName = @"ColorSpaceName";
NSString *NSDeviceBitsPerSample = @"BitsPerSample";
NSString *NSDeviceIsScreen = @"IsScreen";
NSString *NSDeviceIsPrinter = @"IsPrinter";
NSString *NSDeviceSize = @"Size";
NSString *NSDeviceResolution = @"NSDeviceResolution";
NSString *NSDeviceColorSpaceName = @"NSDeviceColorSpaceName";
NSString *NSDeviceBitsPerSample = @"NSDeviceBitsPerSample";
NSString *NSDeviceIsScreen = @"NSDeviceIsScreen";
NSString *NSDeviceIsPrinter = @"NSDeviceIsPrinter";
NSString *NSDeviceSize = @"NSDeviceSize";
// NSImageRep notifications
NSString *NSImageRepRegistryChangedNotification =
@ -378,3 +378,25 @@ const float NSFontIdentityMatrix[] = {1, 0, 0, 1, 0, 0};
/* Drawing engine externs */
NSString *NSBackendContext = @"NSBackendContext";
typedef int NSWindowDepth;
/**** Color function externs ****/
/* Since these are constants it was not possible
to do the OR directly. If you change the
_GS*BitValue numbers, please remember to
change the corresponding depth values */
const NSWindowDepth _GSGrayBitValue = 256;
const NSWindowDepth _GSRGBBitValue = 512;
const NSWindowDepth _GSCMYKBitValue = 1024;
const NSWindowDepth _GSNamedBitValue = 2048;
const NSWindowDepth _GSCustomBitValue = 4096;
const NSWindowDepth NSDefaultDepth = 0; // GRAY = 256, RGB = 512
const NSWindowDepth NSTwoBitGrayDepth = 258; // 0100000010 GRAY | 2bps
const NSWindowDepth NSEightBitGrayDepth = 264; // 0100001000 GRAY | 8bps
const NSWindowDepth NSEightBitRGBDepth = 514; // 1000000010 RGB | 2bps
const NSWindowDepth NSTwelveBitRGBDepth = 516; // 1000000100 RGB | 4bps
const NSWindowDepth GSSixteenBitRGBDepth = 517; // 1000000101 RGB | 5bps GNUstep specific
const NSWindowDepth NSTwentyFourBitRGBDepth = 520; // 1000001000 RGB | 8bps
const NSWindowDepth _GSWindowDepths[7] = { 258, 264, 514, 516, 517, 520, 0 };
/* End of color functions externs */

View file

@ -281,3 +281,7 @@ float NSLinkFrameThickness(void)
return 0;
}
// Color Functions
NSWindowDepth GSWindowDepthForScreen(int screen) {}
const NSWindowDepth *GSAvailableDepthsForScreen(int screen) {}