mirror of
https://github.com/gnustep/libs-back.git
synced 2025-04-22 15:31:14 +00:00
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:
parent
ea1bf2768e
commit
69fb0dcf76
6 changed files with 240 additions and 6 deletions
|
@ -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
|
||||
|
|
|
@ -72,5 +72,9 @@
|
|||
|
||||
@end
|
||||
|
||||
@interface XGGState (Ops)
|
||||
- (NSDictionary *) GSReadRect: (NSRect)rect;
|
||||
@end
|
||||
|
||||
#endif /* _XGGState_h_INCLUDE */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue