I've implemented support for NSBitmapImageRep's initWithFocusedViewRect:
by changing the backend method NSReadPixel: to GSReadRect: (the
NSReadPixel function could be implemented in terms of GSReadRect
anyway).
I implemented it in the xlib backend. Perhaps Alex could give me a hint
of how to do it in the art backend (or maybe do a quick hack himself :-)
Seem ok?
2003-09-15 Adam Fedor <[EMAIL PROTECTED]>
* Headers/Additions/GNUstepGUI/GSMethodTable.h: Change NSReadPixel
to GSReadRect
* Headers/AppKit/NSGraphicsContext.h, Source/NSGraphicsContext.m: Idem.
* Headers/AppKit/NSGraphics.h (NSReadPixel): Move to...
* Source/Functions.m (NSReadPixel): here.
* Source/NSBitmapImageRep.m (-initWithFocusedViewRect:): Implement.
Index: Headers/Additions/GNUstepGUI/GSMethodTable.h
===================================================================
RCS file:
/cvsroot/gnustep/gnustep/core/gui/Headers/Additions/GNUstepGUI/GSMethodTable.h,v
retrieving revision 1.1
diff -u -p -r1.1 GSMethodTable.h
--- Headers/Additions/GNUstepGUI/GSMethodTable.h 31 Jul 2003 23:52:08 -0000
1.1
+++ Headers/Additions/GNUstepGUI/GSMethodTable.h 16 Sep 2003 02:57:56 -0000
@@ -279,8 +279,8 @@ typedef struct {
/* ----------------------------------------------------------------------- */
/* NSGraphics Ops */
/* ----------------------------------------------------------------------- */
- NSColor * (*NSReadPixel_)
- (NSGraphicsContext*, SEL, NSPoint);
+ NSDictionary * (*GSReadRect_)
+ (NSGraphicsContext*, SEL, NSRect);
void (*NSBeep)
(NSGraphicsContext*, SEL);
Index: Headers/AppKit/NSGraphics.h
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/gui/Headers/AppKit/NSGraphics.h,v
retrieving revision 1.1
diff -u -p -r1.1 NSGraphics.h
--- Headers/AppKit/NSGraphics.h 31 Jul 2003 23:52:08 -0000 1.1
+++ Headers/AppKit/NSGraphics.h 16 Sep 2003 02:57:56 -0000
@@ -138,13 +138,7 @@ APPKIT_EXPORT void NSDottedFrameRect(NSR
APPKIT_EXPORT void NSFrameRect(const NSRect aRect);
APPKIT_EXPORT void NSFrameRectWithWidth(const NSRect aRect, float frameWidth);
-static inline NSColor*
-NSReadPixel(NSPoint location)
-{
- NSGraphicsContext *ctxt = GSCurrentContext();
- return (ctxt->methods->NSReadPixel_)
- (ctxt, @selector(NSReadPixel:), location);
-}
+APPKIT_EXPORT NSColor* NSReadPixel(NSPoint location);
APPKIT_EXPORT void NSCopyBitmapFromGState(int srcGstate, NSRect srcRect,
NSRect destRect);
Index: Headers/AppKit/NSGraphicsContext.h
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/gui/Headers/AppKit/NSGraphicsContext.h,v
retrieving revision 1.1
diff -u -p -r1.1 NSGraphicsContext.h
--- Headers/AppKit/NSGraphicsContext.h 31 Jul 2003 23:52:08 -0000 1.1
+++ Headers/AppKit/NSGraphicsContext.h 16 Sep 2003 02:57:57 -0000
@@ -373,7 +373,7 @@ APPKIT_EXPORT NSGraphicsContext *GSCurre
/* NSGraphics Ops */
/* ----------------------------------------------------------------------- */
@interface NSGraphicsContext (NSGraphics)
-- (NSColor *) NSReadPixel: (NSPoint) location;
+- (NSDictionary *) GSReadRect: (NSRect)rect;
/* Soon to be obsolete */
- (void) NSDrawBitmap: (NSRect) rect : (int) pixelsWide : (int) pixelsHigh
Index: Source/Functions.m
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/gui/Source/Functions.m,v
retrieving revision 1.28
diff -u -p -r1.28 Functions.m
--- Source/Functions.m 13 Jun 2003 15:01:10 -0000 1.28
+++ Source/Functions.m 16 Sep 2003 02:57:57 -0000
@@ -301,8 +301,15 @@ NSPlanarFromDepth(NSWindowDepth depth)
}
/* Graphic Ops */
+NSColor* NSReadPixel(NSPoint location)
+{
+ NSLog(@"NSReadPixel not implemented");
+ return nil;
+}
+
void NSCopyBitmapFromGState(int srcGstate, NSRect srcRect, NSRect destRect)
{
+ NSLog(@"NSCopyBitmapFromGState not implemented");
}
void NSCopyBits(int srcGstate, NSRect srcRect, NSPoint destPoint)
Index: Source/NSBitmapImageRep.m
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/gui/Source/NSBitmapImageRep.m,v
retrieving revision 1.40
diff -u -p -r1.40 NSBitmapImageRep.m
--- Source/NSBitmapImageRep.m 8 Sep 2003 02:07:53 -0000 1.40
+++ Source/NSBitmapImageRep.m 16 Sep 2003 02:57:58 -0000
@@ -35,9 +35,11 @@
#include <Foundation/NSDebug.h>
#include <Foundation/NSException.h>
#include <Foundation/NSFileManager.h>
+#include <Foundation/NSValue.h>
#include "AppKit/AppKitExceptions.h"
#include "AppKit/NSBitmapImageRep.h"
#include "AppKit/NSGraphics.h"
+#include "AppKit/NSGraphicsContext.h"
#include "AppKit/NSPasteboard.h"
#include "AppKit/NSView.h"
#include "GSGuiPrivate.h"
@@ -224,11 +226,45 @@ static BOOL supports_lzw_compression = N
- (id) initWithFocusedViewRect: (NSRect)rect
{
- // TODO
- [self notImplemented: _cmd];
+ int bps, spp, alpha;
+ NSSize size;
+ NSString *space;
+ unsigned char *planes[4];
+ NSDictionary *dict;
- RELEASE(self);
- return nil;
+ dict = [GSCurrentContext() GSReadRect: rect];
+ if (dict == nil)
+ {
+ NSLog(@"NSBitmapImageRep initWithFocusedViewRect: failed");
+ RELEASE(self);
+ return nil;
+ }
+ _imageData = RETAIN([dict objectForKey: @"ImageData"]);
+ if (_imageData == nil)
+ {
+ NSLog(@"NSBitmapImageRep initWithFocusedViewRect: failed");
+ RELEASE(self);
+ return nil;
+ }
+ bps = [[dict objectForKey: @"ImageBPS"] intValue];
+ if (bps == 0)
+ bps = 8;
+ spp = [[dict objectForKey: @"ImageSPP"] intValue];
+ alpha = [[dict objectForKey: @"ImageAlpha"] intValue];
+ size = [[dict objectForKey: @"ImageSize"] sizeValue];
+ space = [dict objectForKey: @"ImageColorSpace"];
+ planes[0] = (unsigned char *)[_imageData mutableBytes];
+ self = [self initWithBitmapDataPlanes: planes
+ pixelsWide: size.width
+ pixelsHigh: size.height
+ bitsPerSample: bps
+ samplesPerPixel: spp
+ hasAlpha: (alpha) ? YES : NO
+ isPlanar: NO
+ colorSpaceName: space
+ bytesPerRow: 0
+ bitsPerPixel: 0];
+ return self;
}
/**
Index: Source/NSGraphicsContext.m
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/gui/Source/NSGraphicsContext.m,v
retrieving revision 1.73
diff -u -p -r1.73 NSGraphicsContext.m
--- Source/NSGraphicsContext.m 31 Jul 2003 23:52:09 -0000 1.73
+++ Source/NSGraphicsContext.m 16 Sep 2003 02:57:58 -0000
@@ -652,8 +652,8 @@ NSGraphicsContext *GSCurrentContext(void
/* ----------------------------------------------------------------------- */
/* NSGraphics Ops */
/* ----------------------------------------------------------------------- */
- methodTable.NSReadPixel_ =
- GET_IMP(@selector(NSReadPixel:));
+ methodTable.GSReadRect_ =
+ GET_IMP(@selector(GSReadRect:));
methodTable.NSBeep =
GET_IMP(@selector(NSBeep));
@@ -1454,9 +1454,13 @@ NSGraphicsContext *GSCurrentContext(void
/* NSGraphics Ops */
/* ----------------------------------------------------------------------- */
@implementation NSGraphicsContext (NSGraphics)
-/** Read the Color at a Screen Position
+/** Read the data inside rect (defined in the current graphics state)
+ and return the information as a bitmap. The dictionary contains
+ the bitmap data plus various information about the size and format
+ of the data. The dictionary keys include ImageSize, ImageBPS,
+ ImageSPP, and ImageData.
*/
-- (NSColor *) NSReadPixel: (NSPoint) location
+- (NSDictionary *) GSReadRect: (NSRect) rect
{
[self subclassResponsibility: _cmd];
return nil;
2003-09-15 Adam Fedor <[EMAIL PROTECTED]>
* Headers/xlib/XGGState.h: Add GSReadRect def.
* Headers/xlib/XGPrivate.h: Add _pixmap_read_alpha def.
* Source/xlib/XGBitmap.m (_pixmap_read_alpha): Implement.
* Source/xlib/XGGstate.m (-GSReadRect:): Idem.
Index: Headers/xlib/XGGState.h
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/back/Headers/xlib/XGGState.h,v
retrieving revision 1.5
diff -u -p -r1.5 XGGState.h
--- Headers/xlib/XGGState.h 10 May 2002 15:06:17 -0000 1.5
+++ Headers/xlib/XGGState.h 16 Sep 2003 03:26:01 -0000
@@ -72,5 +72,9 @@
@end
[EMAIL PROTECTED] XGGState (Ops)
+- (NSDictionary *) GSReadRect: (NSRect)rect;
[EMAIL PROTECTED]
+
#endif /* _XGGState_h_INCLUDE */
Index: Headers/xlib/XGPrivate.h
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/back/Headers/xlib/XGPrivate.h,v
retrieving revision 1.6
diff -u -p -r1.6 XGPrivate.h
--- Headers/xlib/XGPrivate.h 31 Jul 2003 23:57:10 -0000 1.6
+++ Headers/xlib/XGPrivate.h 16 Sep 2003 03:26:01 -0000
@@ -102,6 +102,10 @@ extern int _bitmap_combine_alpha(RContex
NSCompositingOperation op,
XGDrawMechanism drawMechanism);
+extern NSData *_pixmap_read_alpha(RContext *context,
+ RXImage *source_im, RXImage *source_alpha,
+ XRectangle srect,
+ XGDrawMechanism drawMechanism);
#endif
Index: Source/xlib/XGBitmap.m
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/back/Source/xlib/XGBitmap.m,v
retrieving revision 1.4
diff -u -p -r1.4 XGBitmap.m
--- Source/xlib/XGBitmap.m 3 Aug 2002 03:32:19 -0000 1.4
+++ Source/xlib/XGBitmap.m 16 Sep 2003 03:26:05 -0000
@@ -37,6 +37,7 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
+#include <Foundation/NSData.h>
#include <Foundation/NSDebug.h>
#include "gsc/gscolors.h"
#include "xlib/XGPrivate.h"
@@ -1137,3 +1138,128 @@ _bitmap_combine_alpha(RContext *context,
}
return 0;
}
+
+NSData *
+_pixmap_read_alpha(RContext *context,
+ RXImage *source_im, RXImage *source_alpha,
+ XRectangle srect,
+ XGDrawMechanism drawMechanism)
+{
+ unsigned long pixel;
+ NSMutableData *data;
+ unsigned char *bytes;
+ int spp;
+
+ spp = (source_alpha) ? 4 : 3;
+ data = [NSMutableData dataWithLength: srect.width*srect.height*spp];
+ if (data == nil)
+ return nil;
+ bytes = [data mutableBytes];
+
+ if (drawMechanism == XGDM_FAST15
+ || drawMechanism == XGDM_FAST16
+ || drawMechanism == XGDM_FAST32
+ || drawMechanism == XGDM_FAST32_BGR)
+ {
+ VARIABLES_DECLARATION;
+ unsigned row;
+
+ switch (drawMechanism)
+ {
+ case XGDM_FAST15:
+ InitRGBShiftsAndMasks(10,5,5,5,0,5,0,8);
+ break;
+ case XGDM_FAST16:
+ InitRGBShiftsAndMasks(11,5,5,6,0,5,0,8);
+ break;
+ case XGDM_FAST32:
+ InitRGBShiftsAndMasks(16,8,8,8,0,8,0,8);
+ break;
+ case XGDM_FAST32_BGR:
+ InitRGBShiftsAndMasks(0,8,8,8,16,8,0,8);
+ break;
+ default:
+ NSLog(@"Huh? Backend confused about XGDrawMechanism");
+ //Try something. With a bit of luck we see
+ //which picture goes wrong.
+ InitRGBShiftsAndMasks(11,5,5,6,0,5,0,8);
+ }
+
+ for (row = 0; row < srect.height; row++)
+ {
+ unsigned col;
+
+ for (col = 0; col < srect.width; col++)
+ {
+ unsigned sr, sg, sb, sa;
+
+ // Get the source pixel information
+ pixel = XGetPixel(source_im->image, col, row);
+ PixelToRGB(pixel, sr, sg, sb);
+ // Expand to 8 bit value
+ sr = (sr << (8-_rwidth));
+ sg = (sg << (8-_gwidth));
+ sb = (sb << (8-_bwidth));
+
+ if (source_alpha)
+ {
+ pixel = XGetPixel(source_alpha->image, col, row);
+ sa = (pixel >> _ashift) & _amask;
+ }
+ else
+ sa = _amask;
+
+ bytes[(row * srect.width + col)*spp] = sr;
+ bytes[(row * srect.width + col)*spp+1] = sg;
+ bytes[(row * srect.width + col)*spp+2] = sb;
+ if (source_alpha)
+ bytes[(row * srect.width + col)*spp+3] = sa;
+ }
+ }
+ }
+ else
+ {
+ XColor c2;
+ unsigned row;
+
+ /*
+ * This block of code should be totally portable as it uses the
+ * 'official' X mechanism for converting from pixel values to
+ * RGB color values - on the downside, it's very slow.
+ */
+ pixel = (unsigned long)-1; // Never valid?
+ c2.pixel = pixel;
+
+ for (row = 0; row < srect.height; row++)
+ {
+ unsigned col;
+
+ for (col = 0; col < srect.width; col++)
+ {
+ int r, g, b, alpha;
+ XColor pcolor, acolor;
+ pcolor.pixel = XGetPixel(source_im->image, col, row);
+ XQueryColor(context->dpy, context->cmap, &pcolor);
+ r = pcolor.red >> 8;
+ g = pcolor.green >> 8;
+ b = pcolor.blue >> 8;
+ alpha = 255;
+ if (source_alpha)
+ {
+ acolor.pixel = XGetPixel(source_alpha->image, col, row);
+ XQueryColor(context->dpy, context->cmap, &acolor);
+ alpha = acolor.red >> 8;
+ }
+
+ bytes[(row * srect.width + col)*spp] = r;
+ bytes[(row * srect.width + col)*spp+1] = g;
+ bytes[(row * srect.width + col)*spp+2] = b;
+ if (source_alpha)
+ bytes[(row * srect.width + col)*spp+3] = alpha;
+ }
+ }
+ }
+
+ return (NSData *)data;
+}
+
Index: Source/xlib/XGContext.m
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/back/Source/xlib/XGContext.m,v
retrieving revision 1.10
diff -u -p -r1.10 XGContext.m
--- Source/xlib/XGContext.m 24 Jul 2003 03:24:13 -0000 1.10
+++ Source/xlib/XGContext.m 16 Sep 2003 03:26:05 -0000
@@ -153,13 +153,9 @@
XFlush([(XGServer *)server xDisplay]);
}
-//
-// Read the Color at a Screen Position
-//
-- (NSColor *) NSReadPixel: (NSPoint) location
+- (NSDictionary *) GSReadRect: (NSRect)rect
{
- [self notImplemented: _cmd];
- return nil;
+ return [(XGGState *)gstate GSReadRect: rect];
}
@end
Index: Source/xlib/XGGState.m
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/back/Source/xlib/XGGState.m,v
retrieving revision 1.17
diff -u -p -r1.17 XGGState.m
--- Source/xlib/XGGState.m 17 Jun 2003 13:34:38 -0000 1.17
+++ Source/xlib/XGGState.m 16 Sep 2003 03:26:10 -0000
@@ -1857,6 +1857,103 @@ typedef enum {
}
}
+- (NSDictionary *) GSReadRect: (NSRect)rect
+{
+ NSSize ssize;
+ XRectangle srect;
+ RXImage *source_im;
+ RXImage *source_alpha;
+ gswindow_device_t *source_win;
+ NSMutableDictionary *dict;
+ NSData *data;
+
+ source_win = (gswindow_device_t *)windevice;
+ if (!source_win)
+ {
+ DPS_ERROR(DPSinvalidid, @"Invalid read gstate");
+ return nil;
+ }
+
+ if (source_win->buffer == 0 && source_win->map_state != IsViewable)
+ {
+ /* Can't read anything */
+ DPS_ERROR(DPSinvalidid, @"Invalid window not readable");
+ return nil;
+ }
+
+ dict = [NSMutableDictionary dictionary];
+
+ // --- determine region to read --------------------------------------
+
+ rect.origin = [ctm pointInMatrixSpace: rect.origin];
+ srect = XGWindowRectToX(self, rect);
+ srect = XGIntersectionRect (srect, accessibleRectForWindow (source_win));
+ ssize.width = srect.width;
+ ssize.height = srect.height;
+ [dict setObject: [NSValue valueWithSize: ssize] forKey: @"ImageSize"];
+
+ if (XGIsEmptyRect(srect))
+ return dict;
+
+ [dict setObject: [NSNumber numberWithUnsignedInt: source_win->depth]
+ forKey: @"ImageDepth"];
+
+ // --- get source XImage ----------------------------------------
+
+ if (draw == source_win->ident && source_win->visibility < 0)
+ {
+ /* Non-backingstore window isn't visible, so just make up the image */
+ NSLog(@"Focused view window not readable");
+ source_im = RCreateXImage(context, source_win->depth,
+ XGWidth(srect), XGHeight(srect));
+ }
+ else
+ {
+ source_im = RGetXImage(context, draw, XGMinX(srect), XGMinY (srect),
+ XGWidth (srect), XGHeight (srect));
+ }
+
+ if (source_im->image == 0)
+ {
+ // Should not happen,
+ DPS_ERROR (DPSinvalidaccess, @"unable to fetch source image");
+ return dict;
+ }
+
+ [self _alphaBuffer: source_win];
+ if (alpha_buffer)
+ {
+ source_alpha = RGetXImage((RContext *)context, alpha_buffer,
+ XGMinX(srect), XGMinY(srect),
+ XGWidth(srect), XGHeight(srect));
+ [dict setObject: [NSNumber numberWithUnsignedInt: 4]
+ forKey: @"ImageSPP"];
+ [dict setObject: [NSNumber numberWithUnsignedInt: 1]
+ forKey: @"ImageAlpha"];
+ }
+ else
+ {
+ source_alpha = NULL;
+ [dict setObject: [NSNumber numberWithUnsignedInt: 3]
+ forKey: @"ImageSPP"];
+ [dict setObject: [NSNumber numberWithUnsignedInt: 0]
+ forKey: @"ImageAlpha"];
+ }
+
+ data = _pixmap_read_alpha(context, source_im, source_alpha, srect,
+ drawMechanism);
+ [dict setObject: data forKey: @"ImageData"];
+ /* Pixmap routine always returns image in same format (FIXME?). */
+ [dict setObject: NSDeviceRGBColorSpace forKey: @"ImageColorSpace"];
+ [dict setObject: [NSNumber numberWithUnsignedInt: 8] forKey: @"ImageBPS"];
+
+ // --- clean up ------------------------------------------------------
+
+ RDestroyXImage((RContext *)context, source_im);
+ RDestroyXImage((RContext *)context, source_alpha);
+ return dict;
+}
+
@end
_______________________________________________
Bug-gnustep mailing list
[EMAIL PROTECTED]
http://mail.gnu.org/mailman/listinfo/bug-gnustep