Implement GSReadRect in art/.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@19800 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
alexm 2004-07-30 13:57:27 +00:00
parent b9709b714f
commit e131192a2f
10 changed files with 252 additions and 32 deletions

View file

@ -1,3 +1,19 @@
2004-07-30 15:52 Alexander Malmberg <alexander@malmberg.org>
* Headers/gsc/GSCStateOps.h, Source/gsc/GSContext.m,
Source/gsc/GSGState.m (-GSReadRect:): New method.
* Source/art/GNUmakefile: Add ReadRect.m.
* Source/art/ReadRect.m: New file.
* Source/art/blit.m, Source/art/blit.h: Add read_pixels_a and
read_pixels_o. Fix spurious low bits in BLEAN_READ for 16bpp and
15bpp modes.
* Source/xlib/XGContext.m (-GSReadRect:): Remove.
* Source/xlib/XGGState.m (-GSReadRect:): Update key names and set all
keys even if the rectangle is degenerate. Return nil if the image
can't be read. Set the Matrix key.
2004-07-26 15:37 Matt Rice <ratmice@yahoo.com>
Alexander Malmberg <alexander@malmberg.org>

View file

@ -139,6 +139,8 @@
- (void) GSRectClipList: (const NSRect *)rects : (int) count;
- (void) GSRectFillList: (const NSRect *)rects : (int) count;
- (NSDictionary *) GSReadRect: (NSRect)rect;
- (void)DPSimage: (NSAffineTransform*) matrix
: (int) pixelsWide : (int) pixelsHigh
: (int) bitsPerSample : (int) samplesPerPixel

View file

@ -40,7 +40,8 @@ art_OBJC_FILES = \
image.m \
composite.m \
path.m \
shfill.m
shfill.m \
ReadRect.m
-include GNUmakefile.preamble

139
Source/art/ReadRect.m Normal file
View file

@ -0,0 +1,139 @@
/*
Copyright (C) 2004 Free Software Foundation, Inc.
Author: Alexander Malmberg <alexander@malmberg.org>
This file is part of GNUstep.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "ARTGState.h"
#ifndef RDS
#include "x11/XWindowBuffer.h"
#endif
#include "blit.h"
#include <math.h>
#include <Foundation/NSData.h>
#include <Foundation/NSValue.h>
#include <AppKit/NSAffineTransform.h>
#include <AppKit/NSGraphics.h>
@implementation ARTGState (ReadRect)
-(NSDictionary *) GSReadRect: (NSRect)r
{
NSMutableDictionary *md = [[NSMutableDictionary alloc] init];
NSAffineTransform *matrix;
int x0, y0, x1, y1, w, h;
NSPoint p;
/* Get the bounding rect in pixel coordinates. */
p = r.origin;
p = [ctm pointInMatrixSpace: p];
x0 = floor(p.x); x1 = ceil(p.x);
y0 = floor(p.y); y1 = ceil(p.y);
#define CHECK do { \
if (floor(p.x)<x0) x0=floor(p.x); \
if (floor(p.y)<y0) y0=floor(p.y); \
if (ceil(p.x)>x1) x1=ceil(p.x); \
if (ceil(p.y)>y1) y1=ceil(p.y); } while (0)
p = r.origin; p.x += r.size.width;
p = [ctm pointInMatrixSpace: p];
CHECK;
p = r.origin; p.x += r.size.width; p.y += r.size.height;
p = [ctm pointInMatrixSpace: p];
CHECK;
p = r.origin; p.y += r.size.height;
p = [ctm pointInMatrixSpace: p];
CHECK;
#undef CHECK
/* Clip to the window. */
if (x0 < 0) x0 = 0;
if (x1 < 0) x1 = 0;
if (x0 > wi->sx) x0 = wi->sx;
if (x1 > wi->sx) x1 = wi->sx;
if (y0 < 0) y0 = 0;
if (y1 < 0) y1 = 0;
if (y0 > wi->sy) y0 = wi->sy;
if (y1 > wi->sy) y1 = wi->sy;
w = x1 - x0;
h = y1 - y0;
if (w <= 0 || h <= 0)
w = h = 0;
/* The matrix is the transform from user space to image space, and image
space has its origin in the lower left corner if the image. Thus, we need
to translate the ctm according to the position of the lower left corner
in the window. */
matrix=[ctm copy];
[matrix translateXBy: -x0 yBy: -y0];
[md setObject: NSDeviceRGBColorSpace forKey: @"ColorSpace"];
[md setObject: [NSNumber numberWithUnsignedInt: 1] forKey: @"HasAlpha"];
[md setObject: [NSNumber numberWithUnsignedInt: 8] forKey: @"BitsPerSample"];
[md setObject: [NSNumber numberWithUnsignedInt: 4] forKey: @"SamplesPerPixel"];
[md setObject: [NSValue valueWithSize: NSMakeSize(w, h)] forKey: @"Size"];
[md setObject: matrix forKey: @"Matrix"];
[matrix release];
if (!w || !h)
return [[md autorelease] makeImmutableCopyOnFail: YES];
/* The rectangle isn't degenerate, so we need to actually copy some data. */
{
NSMutableData *d;
int y;
composite_run_t c;
d = [[NSMutableData alloc] initWithLength: w * h * 4];
c.dst = [d mutableBytes];
c.src = wi->data + (wi->sy - y1) * wi->bytes_per_line + x0 * DI.bytes_per_pixel;
c.srca = wi->alpha + (wi->sy - y1) * wi->sx + x0;
for (y = 0; y < h; y++)
{
if (wi->has_alpha)
DI.read_pixels_a(&c, w);
else
DI.read_pixels_o(&c, w);
c.src += wi->bytes_per_line;
c.srca += wi->sx;
c.dst += w * 4;
}
[md setObject: [[d autorelease] makeImmutableCopyOnFail: YES] forKey: @"Data"];
}
return [[md autorelease] makeImmutableCopyOnFail: YES];
}
@end

View file

@ -100,6 +100,11 @@ typedef struct draw_info_s
int num);
/* dst should be a 32bpp RGBA buffer. */
void (*read_pixels_o)(composite_run_t *c, int num);
void (*read_pixels_a)(composite_run_t *c, int num);
void (*composite_sover_aa)(composite_run_t *c, int num);
void (*composite_sover_ao)(composite_run_t *c, int num);

View file

@ -456,6 +456,46 @@ static void MPRE(run_opaque_a) (render_run_t *ri, int num)
}
static void MPRE(read_pixels_o) (composite_run_t *c, int num)
{
BLEND_TYPE *s = (BLEND_TYPE *)c->src;
unsigned char *dst = c->dst;
int r, g, b;
for (; num; num--)
{
BLEND_READ(s, r, g, b)
BLEND_INC(s)
dst[0] = r;
dst[1] = g;
dst[2] = b;
dst[3] = 0xff;
dst += 4;
}
}
static void MPRE(read_pixels_a) (composite_run_t *c, int num)
{
BLEND_TYPE *s = (BLEND_TYPE *)c->src;
#ifndef INLINE_ALPHA
unsigned char *src_alpha = c->srca;
#endif
unsigned char *dst = c->dst;
int r, g, b, a;
for (; num; num--)
{
BLEND_READ_ALPHA(s, src_alpha, r, g, b, a)
ALPHA_INC(s, src_alpha)
dst[0] = r;
dst[1] = g;
dst[2] = b;
dst[3] = a;
dst += 4;
}
}
/* 1 : 1 - srca */
static void MPRE(sover_aa) (composite_run_t *c, int num)
{
@ -1683,8 +1723,8 @@ ourself.
#define BLEND_READ(p,nr,ng,nb) \
{ \
unsigned short _s=p[0]; \
nr=(_s>>8); \
ng=(_s>>3)&0xff; \
nr=(_s>>11)<<3; \
ng=((_s>>5)<<2)&0xff; \
nb=(_s<<3)&0xff; \
}
#define BLEND_READ_ALPHA(p,pa,nr,ng,nb,na) \
@ -1721,8 +1761,8 @@ ourself.
#define BLEND_READ(p,nr,ng,nb) \
{ \
unsigned short _s=p[0]; \
nr=(_s>>7); \
ng=(_s>>2)&0xff; \
nr=(_s>>10)<<3; \
ng=((_s>>5)<<3)&0xff; \
nb=(_s<<3)&0xff; \
}
#define BLEND_READ_ALPHA(p,pa,nr,ng,nb,na) \
@ -1768,6 +1808,9 @@ static draw_info_t draw_infos[DI_NUM] = {
\
NPRE(blit_subpixel,x), \
\
NPRE(read_pixels_o,x), \
NPRE(read_pixels_a,x), \
\
NPRE(sover_aa,x), \
NPRE(sover_ao,x), \
NPRE(sin_aa,x), \

View file

@ -781,6 +781,12 @@ static unsigned int unique_index = 0;
/* NSGraphics Ops */
/* ----------------------------------------------------------------------- */
@implementation GSContext (NSGraphics)
- (NSDictionary *) GSReadRect: (NSRect)rect
{
return [gstate GSReadRect: rect];
}
/*
* Render Bitmap Images
*/

View file

@ -1007,6 +1007,11 @@ typedef enum {
: NSWidth(rects[i]) : NSHeight(rects[i])];
}
- (NSDictionary *) GSReadRect: (NSRect)r
{
return nil;
}
- (void)DPSimage: (NSAffineTransform*) matrix
: (int) pixelsWide : (int) pixelsHigh
: (int) bitsPerSample : (int) samplesPerPixel

View file

@ -153,11 +153,6 @@
XFlush([(XGServer *)server xDisplay]);
}
- (NSDictionary *) GSReadRect: (NSRect)rect
{
return [(XGGState *)gstate GSReadRect: rect];
}
@end
@implementation XGContext (Ops)

View file

@ -1715,6 +1715,7 @@ static Region emptyRegion;
gswindow_device_t *source_win;
NSMutableDictionary *dict;
NSData *data;
NSAffineTransform *matrix;
source_win = (gswindow_device_t *)windevice;
if (!source_win)
@ -1739,22 +1740,41 @@ static Region emptyRegion;
srect = XGIntersectionRect (srect, accessibleRectForWindow (source_win));
ssize.width = srect.width;
ssize.height = srect.height;
[dict setObject: [NSValue valueWithSize: ssize] forKey: @"ImageSize"];
[dict setObject: [NSValue valueWithSize: ssize] forKey: @"Size"];
[dict setObject: NSDeviceRGBColorSpace forKey: @"ColorSpace"];
[dict setObject: [NSNumber numberWithUnsignedInt: 8] forKey: @"BitsPerSample"];
[dict setObject: [NSNumber numberWithUnsignedInt: source_win->depth]
forKey: @"Depth"];
[self _alphaBuffer: source_win];
if (alpha_buffer)
{
[dict setObject: [NSNumber numberWithUnsignedInt: 4]
forKey: @"SamplesPerPixel"];
[dict setObject: [NSNumber numberWithUnsignedInt: 1]
forKey: @"HasAlpha"];
}
else
{
[dict setObject: [NSNumber numberWithUnsignedInt: 3]
forKey: @"SamplesPerPixel"];
[dict setObject: [NSNumber numberWithUnsignedInt: 0]
forKey: @"HasAlpha"];
}
matrix = [ctm copy];
[matrix translateXBy: -srect.x - offset.x yBy: srect.y + srect.height - offset.y];
[dict setObject: matrix forKey: @"Matrix"];
DESTROY(matrix);
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));
/* Non-backingstore window isn't visible, so we can't read it. */
return nil;
}
else
{
@ -1765,36 +1785,24 @@ static Region emptyRegion;
if (source_im->image == 0)
{
// Should not happen,
DPS_ERROR (DPSinvalidaccess, @"unable to fetch source image");
return dict;
return nil;
}
[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"];
[dict setObject: data forKey: @"Data"];
/* Pixmap routine always returns image in same format (FIXME?). */
[dict setObject: NSDeviceRGBColorSpace forKey: @"ImageColorSpace"];
[dict setObject: [NSNumber numberWithUnsignedInt: 8] forKey: @"ImageBPS"];
// --- clean up ------------------------------------------------------