mirror of
https://github.com/gnustep/libs-back.git
synced 2025-04-22 15:31:14 +00:00
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:
parent
b9709b714f
commit
e131192a2f
10 changed files with 252 additions and 32 deletions
16
ChangeLog
16
ChangeLog
|
@ -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>
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
139
Source/art/ReadRect.m
Normal 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
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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), \
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -153,11 +153,6 @@
|
|||
XFlush([(XGServer *)server xDisplay]);
|
||||
}
|
||||
|
||||
- (NSDictionary *) GSReadRect: (NSRect)rect
|
||||
{
|
||||
return [(XGGState *)gstate GSReadRect: rect];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation XGContext (Ops)
|
||||
|
|
|
@ -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 ------------------------------------------------------
|
||||
|
||||
|
|
Loading…
Reference in a new issue