Add GSReadRect support to xlib backend

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@17692 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
fedor 2003-09-21 03:19:17 +00:00
parent ea1bf2768e
commit 69fb0dcf76
6 changed files with 240 additions and 6 deletions

View file

@ -1,3 +1,10 @@
2003-09-20 Adam Fedor <fedor@gnu.org>
* 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.
2003-09-15 Adam Fedor <fedor@gnu.org>
* Source/gsc/GSGState.m ([GSGState -deepen]): Typo fix - copy

View file

@ -72,5 +72,9 @@
@end
@interface XGGState (Ops)
- (NSDictionary *) GSReadRect: (NSRect)rect;
@end
#endif /* _XGGState_h_INCLUDE */

View file

@ -102,6 +102,10 @@ extern int _bitmap_combine_alpha(RContext *context,
NSCompositingOperation op,
XGDrawMechanism drawMechanism);
extern NSData *_pixmap_read_alpha(RContext *context,
RXImage *source_im, RXImage *source_alpha,
XRectangle srect,
XGDrawMechanism drawMechanism);
#endif

View file

@ -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;
}

View file

@ -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

View file

@ -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