mirror of
https://github.com/gnustep/libs-back.git
synced 2025-05-30 17:00:52 +00:00
Add a generic basic implementation for the DPSshfill: operator. This
needs to be optimized for each individual backend and the original art implemenation should be moved to this. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@25519 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
69745597e4
commit
f2ac847ff4
8 changed files with 580 additions and 16 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
||||||
|
2007-10-05 Fred Kiefer <FredKiefer@gmx.de>
|
||||||
|
|
||||||
|
* Source/art/shfill.m (-DPSshfill:): Correct typing error. Remove
|
||||||
|
now obsolete method declaration.
|
||||||
|
* Headers/gsc/GSFunction.h,
|
||||||
|
* Source/gsc/GSFunction.m: New files. Implementation of Postscript
|
||||||
|
function taken from art/shfill.m.
|
||||||
|
* Source/gsc/GNUmakefile: Compile new file.
|
||||||
|
* Source/gsc/GSContext.m (-DPSshfill:),
|
||||||
|
* Source/gsc/GSGState.m (-DPSshfill:): Implement new method.
|
||||||
|
|
||||||
2007-10-05 Fred Kiefer <FredKiefer@gmx.de>
|
2007-10-05 Fred Kiefer <FredKiefer@gmx.de>
|
||||||
|
|
||||||
* Source/cairo/CairoGState.m (-copyWithZone:): Only use cairo 1.4
|
* Source/cairo/CairoGState.m (-copyWithZone:): Only use cairo 1.4
|
||||||
|
|
65
Headers/gsc/GSFunction.h
Normal file
65
Headers/gsc/GSFunction.h
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
/* -*-objc-*-
|
||||||
|
GSFunction - PS Function for GSGState
|
||||||
|
|
||||||
|
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
Author: Alexander Malmberg <alexander@malmberg.org>
|
||||||
|
Author: Fred Kiefer <fredkiefer@gmx.de>
|
||||||
|
Extracted into separate class.
|
||||||
|
|
||||||
|
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., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02111 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _GSFunction_h_INCLUDE
|
||||||
|
#define _GSFunction_h_INCLUDE
|
||||||
|
|
||||||
|
#include <Foundation/NSObject.h>
|
||||||
|
|
||||||
|
@interface GSFunction : NSObject
|
||||||
|
{
|
||||||
|
/* General information about the function. */
|
||||||
|
int num_in, num_out;
|
||||||
|
|
||||||
|
double *domain; /* num_in * 2 */
|
||||||
|
double *range; /* num_out * 2 */
|
||||||
|
|
||||||
|
/* Type specific information */
|
||||||
|
const unsigned char *data_source;
|
||||||
|
int *size; /* num_in */
|
||||||
|
int bits_per_sample;
|
||||||
|
double *encode; /* num_in * 2 */
|
||||||
|
double *decode; /* num_out * 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id) initWith: (NSDictionary *)d;
|
||||||
|
- (void) eval: (double *)inValues : (double *)outValues;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface GSFunction2in3out : GSFunction
|
||||||
|
{
|
||||||
|
/* sample cache for in == 2, out == 3 */
|
||||||
|
int sample_index[2];
|
||||||
|
double sample_cache[4][3];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSRect) affectedRect;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#endif // _GSFunction_h_INCLUDE
|
|
@ -19,7 +19,8 @@
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public
|
You should have received a copy of the GNU Library General Public
|
||||||
License along with this library; if not, write to the Free
|
License along with this library; if not, write to the Free
|
||||||
Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA.
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02111 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _GSGStateOps_h_INCLUDE
|
#ifndef _GSGStateOps_h_INCLUDE
|
||||||
|
@ -148,6 +149,8 @@
|
||||||
: (BOOL) hasAlpha : (NSString *) colorSpaceName
|
: (BOOL) hasAlpha : (NSString *) colorSpaceName
|
||||||
: (const unsigned char *const [5]) data;
|
: (const unsigned char *const [5]) data;
|
||||||
|
|
||||||
|
- (void) DPSshfill: (NSDictionary *)shader;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -215,11 +215,6 @@ static BOOL _rect_advance(rect_trace_t * t, int *x0, int *x1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@interface ARTGState (shfill)
|
|
||||||
- (void) DPSshfill: (NSDictionary *)shader;
|
|
||||||
@end
|
|
||||||
|
|
||||||
|
|
||||||
@implementation ARTGState (shfill)
|
@implementation ARTGState (shfill)
|
||||||
|
|
||||||
|
|
||||||
|
@ -738,7 +733,7 @@ static void function_free(function_t * f)
|
||||||
if (state)
|
if (state)
|
||||||
{
|
{
|
||||||
p = [inverse transformPoint:
|
p = [inverse transformPoint:
|
||||||
NSMakePoint(clip_x0 + x0 - offset.y, offset.y - y)];
|
NSMakePoint(clip_x0 + x0 - offset.x, offset.y - y)];
|
||||||
|
|
||||||
in[0] = p.x;
|
in[0] = p.x;
|
||||||
in[1] = p.y;
|
in[1] = p.y;
|
||||||
|
@ -782,12 +777,3 @@ done:
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
@implementation ARTContext (shfill)
|
|
||||||
/* TODO: move to gsc? */
|
|
||||||
- (void) DPSshfill: (NSDictionary *)shader
|
|
||||||
{
|
|
||||||
[(ARTGState *)gstate DPSshfill: shader];
|
|
||||||
}
|
|
||||||
@end
|
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ GSContext.m \
|
||||||
GSGState.m \
|
GSGState.m \
|
||||||
GSStreamContext.m \
|
GSStreamContext.m \
|
||||||
GSStreamGState.m \
|
GSStreamGState.m \
|
||||||
|
GSFunction.m \
|
||||||
externs.m
|
externs.m
|
||||||
|
|
||||||
gsc_C_FILES = gscolors.c
|
gsc_C_FILES = gscolors.c
|
||||||
|
|
|
@ -865,6 +865,11 @@ static NSMapTable *gtable;
|
||||||
: data];
|
: data];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) DPSshfill: (NSDictionary *)shader
|
||||||
|
{
|
||||||
|
[gstate DPSshfill: shader];
|
||||||
|
}
|
||||||
|
|
||||||
- (void) GSWSetViewIsFlipped: (BOOL) flipped
|
- (void) GSWSetViewIsFlipped: (BOOL) flipped
|
||||||
{
|
{
|
||||||
if (gstate)
|
if (gstate)
|
||||||
|
|
385
Source/gsc/GSFunction.m
Normal file
385
Source/gsc/GSFunction.m
Normal file
|
@ -0,0 +1,385 @@
|
||||||
|
/*
|
||||||
|
GSFunction - Function for GSGState
|
||||||
|
|
||||||
|
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
Author: Alexander Malmberg <alexander@malmberg.org>
|
||||||
|
Author: Fred Kiefer <fredkiefer@gmx.de>
|
||||||
|
Extracted into separate class.
|
||||||
|
|
||||||
|
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., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02111 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// for floor
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include <Foundation/NSArray.h>
|
||||||
|
#include <Foundation/NSData.h>
|
||||||
|
#include <Foundation/NSDebug.h>
|
||||||
|
#include <Foundation/NSDictionary.h>
|
||||||
|
#include <Foundation/NSValue.h>
|
||||||
|
#include "gsc/GSFunction.h"
|
||||||
|
|
||||||
|
|
||||||
|
@implementation GSFunction
|
||||||
|
|
||||||
|
- (id) initWith: (NSDictionary *)d
|
||||||
|
{
|
||||||
|
NSNumber * v = [d objectForKey: @"FunctionType"];
|
||||||
|
NSArray *a;
|
||||||
|
NSData *data;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
if ([v intValue] != 0)
|
||||||
|
{
|
||||||
|
NSDebugLLog(@"GSFunction", @"FunctionType != 0 not supported.");
|
||||||
|
RELEASE(self);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
bits_per_sample = [[d objectForKey: @"BitsPerSample"] intValue];
|
||||||
|
if (!(bits_per_sample == 8 || bits_per_sample == 16))
|
||||||
|
{
|
||||||
|
NSDebugLLog(@"GSFunction", @"BitsPerSample other than 8 or 16 aren't supported.");
|
||||||
|
RELEASE(self);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = [d objectForKey: @"DataSource"];
|
||||||
|
if (!data || ![data isKindOfClass: [NSData class]])
|
||||||
|
{
|
||||||
|
NSDebugLLog(@"GSFunction", @"No valid DataSource given.");
|
||||||
|
RELEASE(self);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
data_source =[data bytes];
|
||||||
|
|
||||||
|
a = [d objectForKey: @"Size"];
|
||||||
|
num_in = [a count];
|
||||||
|
if (!num_in)
|
||||||
|
{
|
||||||
|
NSDebugLLog(@"GSFunction", @"Size has no entries.");
|
||||||
|
RELEASE(self);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
num_out = [[d objectForKey: @"Range"] count] / 2;
|
||||||
|
if (!num_out)
|
||||||
|
{
|
||||||
|
NSDebugLLog(@"GSFunction", @"Range has no entries.");
|
||||||
|
RELEASE(self);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
size = malloc(sizeof(int) * num_in);
|
||||||
|
domain = malloc(sizeof(double) * num_in * 2);
|
||||||
|
range = malloc(sizeof(double) * num_out * 2);
|
||||||
|
encode = malloc(sizeof(double) * num_in * 2);
|
||||||
|
decode = malloc(sizeof(double) * num_out * 2);
|
||||||
|
|
||||||
|
if (!size || !domain || !range || !encode || !decode)
|
||||||
|
{
|
||||||
|
NSDebugLLog(@"GSFunction", @"Memory allocation failed.");
|
||||||
|
RELEASE(self);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
j = 1;
|
||||||
|
for (i = 0; i < num_in; i++)
|
||||||
|
{
|
||||||
|
size[i] = [[a objectAtIndex: i] intValue];
|
||||||
|
j *= size[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
j *= bits_per_sample * num_out;
|
||||||
|
j = (j +7)/8;
|
||||||
|
if ([data length] < j)
|
||||||
|
{
|
||||||
|
NSDebugLLog(@"GSFunction", @"Need %i bytes of data, DataSource only has %i bytes.",
|
||||||
|
j, [data length]);
|
||||||
|
RELEASE(self);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
a = [d objectForKey: @"Domain"];
|
||||||
|
for (i = 0; i < num_in * 2; i++)
|
||||||
|
{
|
||||||
|
domain[i] = [[a objectAtIndex: i] doubleValue];
|
||||||
|
}
|
||||||
|
|
||||||
|
a = [d objectForKey: @"Range"];
|
||||||
|
for (i = 0; i < num_out * 2; i++)
|
||||||
|
{
|
||||||
|
range[i] = [[a objectAtIndex: i] doubleValue];
|
||||||
|
}
|
||||||
|
|
||||||
|
a = [d objectForKey: @"Decode"];
|
||||||
|
if (a)
|
||||||
|
{
|
||||||
|
for (i = 0; i < num_out * 2; i++)
|
||||||
|
{
|
||||||
|
decode[i] = [[a objectAtIndex: i] doubleValue];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < num_out * 2; i++)
|
||||||
|
{
|
||||||
|
decode[i] = range[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a = [d objectForKey: @"Encode"];
|
||||||
|
if (a)
|
||||||
|
{
|
||||||
|
for (i = 0; i < num_in * 2; i++)
|
||||||
|
{
|
||||||
|
encode[i] = [[a objectAtIndex: i] doubleValue];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < num_in; i++)
|
||||||
|
{
|
||||||
|
encode[i * 2 + 0] = 0;
|
||||||
|
encode[i * 2 + 1] = size[i] - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)dealloc
|
||||||
|
{
|
||||||
|
if (size)
|
||||||
|
free(size);
|
||||||
|
if (domain)
|
||||||
|
free(domain);
|
||||||
|
if (range)
|
||||||
|
free(range);
|
||||||
|
if (encode)
|
||||||
|
free(encode);
|
||||||
|
if (decode)
|
||||||
|
free(decode);
|
||||||
|
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (double)getsample: (int)sample : (int) i
|
||||||
|
{
|
||||||
|
double v;
|
||||||
|
|
||||||
|
if (bits_per_sample == 8)
|
||||||
|
{
|
||||||
|
v = data_source[sample * num_out + i] / 255.0;
|
||||||
|
}
|
||||||
|
else if (bits_per_sample == 16)
|
||||||
|
{
|
||||||
|
int c0, c1;
|
||||||
|
|
||||||
|
c0 = data_source[(sample * num_out + i) * 2 + 0];
|
||||||
|
c1 = data_source[(sample * num_out + i) * 2 + 1];
|
||||||
|
v = (c0 * 256 + c1) / 65535.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NSLog(@"unhandled bits per sample %i", bits_per_sample);
|
||||||
|
v = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
v = decode[i * 2] + v * (decode[i * 2 + 1] - decode[i * 2]);
|
||||||
|
if (v < range[i * 2])
|
||||||
|
v = range[i * 2];
|
||||||
|
if (v > range[i * 2 + 1])
|
||||||
|
v = range[i * 2 + 1];
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) eval: (double *)inValues : (double *)outValues;
|
||||||
|
{
|
||||||
|
double in[num_in];
|
||||||
|
int sample[num_in];
|
||||||
|
int i, j, sample_index, sample_factor;
|
||||||
|
unsigned int u, v;
|
||||||
|
double c;
|
||||||
|
|
||||||
|
for (i = 0; i < num_in; i++)
|
||||||
|
{
|
||||||
|
in[i] =(inValues[i] - domain[i * 2]) / (domain[i * 2 + 1] - domain[i * 2]);
|
||||||
|
if (in[i] < 0.0) in[i] = 0.0;
|
||||||
|
if (in[i] > 1.0) in[i] = 1.0;
|
||||||
|
|
||||||
|
in[i] = encode[i * 2] + in[i] * (encode[i * 2 + 1] - encode[i * 2]);
|
||||||
|
sample[i] = floor(in[i]);
|
||||||
|
/* we only want sample[i] == size[i] -1 when size[i] == 1 */
|
||||||
|
if (sample[i] >= size[i]-1) sample[i] = size[i]-2;
|
||||||
|
if (sample[i] < 0) sample[i] = 0;
|
||||||
|
|
||||||
|
in[i] = in[i] - sample[i];
|
||||||
|
if (in[i] < 0.0) in[i] = 0.0;
|
||||||
|
if (in[i] > 1.0) in[i] = 1.0;
|
||||||
|
|
||||||
|
// printf(" coord %i, sample %i, frac %g \n", i, sample[i], in[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < num_out; i++)
|
||||||
|
{
|
||||||
|
double out_value;
|
||||||
|
/*
|
||||||
|
iterate over all corners in the num_in-dimensional
|
||||||
|
hypercube we're in
|
||||||
|
*/
|
||||||
|
out_value = 0.0;
|
||||||
|
for (u = 0; u < (1 << num_in); u++)
|
||||||
|
{
|
||||||
|
sample_index = 0;
|
||||||
|
sample_factor = 1;
|
||||||
|
c = 1;
|
||||||
|
for (v = 1, j = 0; j < num_in; j ++, v <<= 1)
|
||||||
|
{
|
||||||
|
sample_index += sample[j] * sample_factor;
|
||||||
|
if (u & v)
|
||||||
|
{
|
||||||
|
c *= in[j];
|
||||||
|
sample_index += sample_factor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c *= (1.0 - in[j]);
|
||||||
|
}
|
||||||
|
sample_factor *= size[j];
|
||||||
|
if (c == 0.0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// printf(" %08x index %i, factor %i, c =%g \n", u, sample_index, sample_factor, c);
|
||||||
|
if (c > 0.0)
|
||||||
|
out_value += c * [self getsample: sample_index : i];
|
||||||
|
}
|
||||||
|
// printf(" final =%g \n", out_value);
|
||||||
|
outValues[i] = out_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
@implementation GSFunction2in3out
|
||||||
|
|
||||||
|
- (id) initWith: (NSDictionary *)d
|
||||||
|
{
|
||||||
|
if (!(self = [super initWith: d]))
|
||||||
|
return nil;
|
||||||
|
|
||||||
|
if (num_in != 2 || num_out != 3)
|
||||||
|
{
|
||||||
|
NSDebugLLog(@"GSFunction", @"Function doesn't have 2 inputs and 3 outputs.");
|
||||||
|
RELEASE(self);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
sample_index[0] = sample_index[1] = -1;
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
special case: f->num_in == 2, f->num_out == 3
|
||||||
|
*/
|
||||||
|
- (void) eval: (double *)inValues : (double *)outValues;
|
||||||
|
{
|
||||||
|
double in[2];
|
||||||
|
int sample[2];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 2; i ++)
|
||||||
|
{
|
||||||
|
in[i] = (inValues[i] - domain[i * 2]) / (domain[i * 2 + 1] - domain[i * 2]);
|
||||||
|
if (in[i] < 0.0) in[i] = 0.0;
|
||||||
|
if (in[i] > 1.0) in[i] = 1.0;
|
||||||
|
|
||||||
|
in[i] = encode[i * 2]+in[i]* (encode[i * 2 + 1] - encode[i * 2]);
|
||||||
|
sample[i] = floor(in[i]);
|
||||||
|
/* we only want sample[i] == size[i]-1 when size[i] == 1 */
|
||||||
|
if (sample[i] >= size[i]-1) sample[i] = size[i]-2;
|
||||||
|
if (sample[i] < 0) sample[i] = 0;
|
||||||
|
|
||||||
|
in[i] = in[i] - sample[i];
|
||||||
|
if (in[i] < 0.0) in[i] = 0.0;
|
||||||
|
if (in[i] > 1.0) in[i] = 1.0;
|
||||||
|
|
||||||
|
// printf(" coord %i, sample %i, frac %g \n", i, sample[i], in[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sample[0] != sample_index[0] || sample[1] != sample_index[1])
|
||||||
|
{
|
||||||
|
sample_index[0] = sample[0];
|
||||||
|
sample_index[1] = sample[1];
|
||||||
|
|
||||||
|
for (i = 0; i < 3; i ++)
|
||||||
|
{
|
||||||
|
sample_cache[0][i] =
|
||||||
|
[self getsample: sample[0] + sample[1] * size[0] : i];
|
||||||
|
if (sample[0] + 1 < size[0])
|
||||||
|
sample_cache[1][i] =
|
||||||
|
[self getsample: sample[0] + 1 + sample[1] * size[0] : i];
|
||||||
|
if (sample[1] + 1 < size[1])
|
||||||
|
sample_cache[2][i] =
|
||||||
|
[self getsample: sample[0] + (sample[1] + 1) * size[0] : i];
|
||||||
|
if (sample[0] + 1 < size[0] && sample[1] + 1 < size[1])
|
||||||
|
sample_cache[3][i] =
|
||||||
|
[self getsample: sample[0] + 1 +(sample[1] + 1) * size[0] : i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
double out_value;
|
||||||
|
double A, B, C, D;
|
||||||
|
double p, q, pq;
|
||||||
|
|
||||||
|
A = sample_cache[0][i];
|
||||||
|
B = sample_cache[1][i];
|
||||||
|
C = sample_cache[2][i];
|
||||||
|
D = sample_cache[3][i];
|
||||||
|
|
||||||
|
out_value = 0.0;
|
||||||
|
p = in[0];
|
||||||
|
q = in[1];
|
||||||
|
pq = p * q;
|
||||||
|
if (p != 1.0 && q != 1.0) out_value += A * (1 - p -q + pq);
|
||||||
|
if (p != 0.0 && q != 1.0) out_value += B * (p - pq);
|
||||||
|
if (p != 1.0 && q != 0.0) out_value += C * (q - pq);
|
||||||
|
if (p != 0.0 && q != 0.0) out_value += D * pq;
|
||||||
|
|
||||||
|
outValues[i] = out_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSRect) affectedRect
|
||||||
|
{
|
||||||
|
NSRect rect;
|
||||||
|
|
||||||
|
rect.origin.x = domain[0];
|
||||||
|
rect.size.width = domain[1] - domain[0];
|
||||||
|
rect.origin.y = domain[2];
|
||||||
|
rect.size.height = domain[3] - domain[2];
|
||||||
|
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -33,6 +33,7 @@
|
||||||
#include <AppKit/NSGraphics.h>
|
#include <AppKit/NSGraphics.h>
|
||||||
#include "gsc/GSContext.h"
|
#include "gsc/GSContext.h"
|
||||||
#include "gsc/GSGState.h"
|
#include "gsc/GSGState.h"
|
||||||
|
#include "gsc/GSFunction.h"
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
#include <GNUstepBase/Unicode.h>
|
#include <GNUstepBase/Unicode.h>
|
||||||
|
|
||||||
|
@ -1068,6 +1069,113 @@ typedef enum {
|
||||||
{
|
{
|
||||||
[self subclassResponsibility: _cmd];
|
[self subclassResponsibility: _cmd];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) DPSshfill: (NSDictionary *)shader
|
||||||
|
{
|
||||||
|
NSNumber *v;
|
||||||
|
NSDictionary *function_dict;
|
||||||
|
GSFunction2in3out *function;
|
||||||
|
NSAffineTransform *matrix, *inverse;
|
||||||
|
NSAffineTransformStruct ts;
|
||||||
|
NSRect rect;
|
||||||
|
int iwidth, iheight;
|
||||||
|
double x, y;
|
||||||
|
int i;
|
||||||
|
unsigned char *data;
|
||||||
|
|
||||||
|
v = [shader objectForKey: @"ShadingType"];
|
||||||
|
|
||||||
|
/* only type 1 shaders */
|
||||||
|
if ([v intValue] != 1)
|
||||||
|
{
|
||||||
|
NSLog(@"ShadingType != 1 not supported.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* in device rgb space */
|
||||||
|
if ([shader objectForKey: @"ColorSpace"])
|
||||||
|
if (![[shader objectForKey: @"ColorSpace"] isEqual: NSDeviceRGBColorSpace])
|
||||||
|
{
|
||||||
|
NSLog(@"Only device RGB ColorSpace supported for shading.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
function_dict = [shader objectForKey: @"Function"];
|
||||||
|
if (!function_dict)
|
||||||
|
{
|
||||||
|
NSLog(@"Shading function not set.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
function = [[GSFunction2in3out alloc] initWith: function_dict];
|
||||||
|
if (!function)
|
||||||
|
return;
|
||||||
|
|
||||||
|
matrix = [ctm copy];
|
||||||
|
if ([shader objectForKey: @"Matrix"])
|
||||||
|
{
|
||||||
|
[matrix prependTransform: [shader objectForKey: @"Matrix"]];
|
||||||
|
}
|
||||||
|
|
||||||
|
inverse = [matrix copy];
|
||||||
|
[inverse invert];
|
||||||
|
|
||||||
|
rect = [function affectedRect];
|
||||||
|
iwidth = rect.size.width;
|
||||||
|
iheight = rect.size.height;
|
||||||
|
data = objc_malloc(sizeof(char) * iwidth * iheight * 4);
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
for (y = NSMinY(rect); y < NSMaxY(rect); y++)
|
||||||
|
{
|
||||||
|
double in[2], out[3];
|
||||||
|
NSPoint p;
|
||||||
|
|
||||||
|
p = [inverse transformPoint: NSMakePoint(NSMinX(rect), y)];
|
||||||
|
in[0] = p.x;
|
||||||
|
in[1] = p.y;
|
||||||
|
|
||||||
|
out[0] = out[1] = out[2] = 0.0;
|
||||||
|
for (x = NSMinX(rect); x < NSMaxX(rect); x++)
|
||||||
|
{
|
||||||
|
char r, g, b, a;
|
||||||
|
|
||||||
|
[function eval: in : out];
|
||||||
|
|
||||||
|
// Set data at x - NSMinX(rect), y - NSMinY(rect) to out
|
||||||
|
r = out[0] * 255;
|
||||||
|
g = out[1] * 255;
|
||||||
|
b = out[2] * 255;
|
||||||
|
a = 255;
|
||||||
|
data[i++] = r;
|
||||||
|
data[i++] = g;
|
||||||
|
data[i++] = b;
|
||||||
|
data[i++] = a;
|
||||||
|
|
||||||
|
// This gives the same result as:
|
||||||
|
// p = [inverse transformPoint: NSMakePoint(x, y)];
|
||||||
|
in[0] += ts.m11;
|
||||||
|
in[1] += ts.m12;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy data to device
|
||||||
|
DESTROY(matrix);
|
||||||
|
matrix = [NSAffineTransform new];
|
||||||
|
[matrix translateXBy: NSMinX(rect) yBy: NSMinY(rect)];
|
||||||
|
[self DPSimage: matrix
|
||||||
|
: iwidth : iheight
|
||||||
|
: 8 : 4
|
||||||
|
: 32 : 4 * iwidth : NO
|
||||||
|
: YES : NSDeviceRGBColorSpace
|
||||||
|
: (const unsigned char **)&data];
|
||||||
|
objc_free(data);
|
||||||
|
|
||||||
|
DESTROY(matrix);
|
||||||
|
DESTROY(inverse);
|
||||||
|
DESTROY(function);
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue