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

Reply via email to