mirror of
https://github.com/gnustep/libs-back.git
synced 2025-04-22 23:42:16 +00:00
Brought art backend closer to the GNUstep coding style.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@24923 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
3ab2c8bd91
commit
680ea7befd
8 changed files with 1250 additions and 1288 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
2007-03-22 Fred Kiefer <FredKiefer@gmx.de>
|
||||
|
||||
* Source/art/ARTGState.h: Declare internal methods.
|
||||
* Source/art/ARTGState.m: New file split out from ARTContext.m.
|
||||
* Source/art/ARTConext.m: Removed ARTContext bits.
|
||||
* Source/art/blit-main.m: New file split out from blit.m.
|
||||
* Source/art/blit.m: Removed self include stuff.
|
||||
* Source/GNUmakefile: Add new source files.
|
||||
* Source/art/composite.m: Adopt to GNUstep coding style.
|
||||
|
||||
2007-03-22 Fred Kiefer <FredKiefer@gmx.de>
|
||||
|
||||
* Source/cairo/CairoGState.m (-compositeGState:...fraction:):
|
||||
|
|
|
@ -20,717 +20,23 @@
|
|||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <AppKit/NSAffineTransform.h>
|
||||
#include <AppKit/NSBezierPath.h>
|
||||
#include <AppKit/NSColor.h>
|
||||
#include <Foundation/NSDebug.h>
|
||||
|
||||
#include "ARTGState.h"
|
||||
#include "blit.h"
|
||||
#include "ftfont.h"
|
||||
|
||||
#ifndef RDS
|
||||
#include "x11/XWindowBuffer.h"
|
||||
#endif
|
||||
#include "blit.h"
|
||||
#include "ftfont.h"
|
||||
|
||||
|
||||
#include <libart_lgpl/libart.h>
|
||||
|
||||
|
||||
#ifndef PI
|
||||
#define PI 3.14159265358979323846264338327950288
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
||||
** subclassResponsibility **
|
||||
Note that these aren't actually subclassResponsibility anymore; instead
|
||||
of crashing, they just print a warning.
|
||||
|
||||
- (void) dissolveGState: (GSGState *)source
|
||||
fromRect: (NSRect)aRect
|
||||
toPoint: (NSPoint)aPoint
|
||||
delta: (float)delta
|
||||
|
||||
** Other unimplemented stuff **
|
||||
|
||||
FontInfo:
|
||||
-(void) set
|
||||
|
||||
Context:
|
||||
- (NSColor *) NSReadPixel: (NSPoint) location
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/* Portions based on gnustep-back code, eg.: */
|
||||
/* GSGState - Generic graphic state
|
||||
|
||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Adam Fedor <fedor@gnu.org>
|
||||
Date: Mar 2002
|
||||
|
||||
This file is part of the GNU Objective C User Interface Library.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
|
||||
draw_info_t ART_DI;
|
||||
|
||||
|
||||
@implementation ARTGState
|
||||
|
||||
|
||||
/* TODO:
|
||||
optimize all this. passing device_color_t structures around by value is
|
||||
very expensive
|
||||
*/
|
||||
-(void) setColor: (device_color_t *)color state: (color_state_t)cState
|
||||
{
|
||||
device_color_t c;
|
||||
unsigned char r,g,b;
|
||||
|
||||
[super setColor: color state: cState];
|
||||
if (cState&(COLOR_FILL|COLOR_STROKE))
|
||||
{
|
||||
c=fillColor;
|
||||
gsColorToRGB(&c); /* TODO: check this */
|
||||
if (c.field[0]>1.0) c.field[0]=1.0;
|
||||
if (c.field[0]<0.0) c.field[0]=0.0;
|
||||
r=c.field[0]*255;
|
||||
if (c.field[1]>1.0) c.field[1]=1.0;
|
||||
if (c.field[1]<0.0) c.field[1]=0.0;
|
||||
g=c.field[1]*255;
|
||||
if (c.field[2]>1.0) c.field[2]=1.0;
|
||||
if (c.field[2]<0.0) c.field[2]=0.0;
|
||||
b=c.field[2]*255;
|
||||
|
||||
if (cState&COLOR_FILL)
|
||||
{
|
||||
fill_color[0]=r;
|
||||
fill_color[1]=g;
|
||||
fill_color[2]=b;
|
||||
fill_color[3]=fillColor.field[AINDEX]*255;
|
||||
}
|
||||
if (cState&COLOR_STROKE)
|
||||
{
|
||||
stroke_color[0]=r;
|
||||
stroke_color[1]=g;
|
||||
stroke_color[2]=b;
|
||||
stroke_color[3]=strokeColor.field[AINDEX]*255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* specially optimized versions (since these are common and simple) */
|
||||
-(void) DPSsetgray: (float)gray
|
||||
{
|
||||
if (gray < 0.0) gray = 0.0;
|
||||
if (gray > 1.0) gray = 1.0;
|
||||
|
||||
fillColor.space = strokeColor.space = gray_colorspace;
|
||||
fillColor.field[0] = strokeColor.field[0] = gray;
|
||||
cstate = COLOR_FILL | COLOR_STROKE;
|
||||
|
||||
stroke_color[0] = stroke_color[1] = stroke_color[2] =
|
||||
fill_color[0] = fill_color[1] = fill_color[2] = gray * 255;
|
||||
}
|
||||
|
||||
-(void) DPSsetalpha: (float)a
|
||||
{
|
||||
if (a < 0.0) a = 0.0;
|
||||
if (a > 1.0) a = 1.0;
|
||||
fillColor.field[AINDEX] = strokeColor.field[AINDEX] = a;
|
||||
stroke_color[3] = fill_color[3] = a * 255;
|
||||
}
|
||||
|
||||
- (void) DPSsetrgbcolor: (float)r : (float)g : (float)b
|
||||
{
|
||||
if (r < 0.0) r = 0.0; if (r > 1.0) r = 1.0;
|
||||
if (g < 0.0) g = 0.0; if (g > 1.0) g = 1.0;
|
||||
if (b < 0.0) b = 0.0; if (b > 1.0) b = 1.0;
|
||||
|
||||
fillColor.space = strokeColor.space = rgb_colorspace;
|
||||
fillColor.field[0] = strokeColor.field[0] = r;
|
||||
fillColor.field[1] = strokeColor.field[1] = g;
|
||||
fillColor.field[2] = strokeColor.field[2] = b;
|
||||
cstate = COLOR_FILL | COLOR_STROKE;
|
||||
|
||||
stroke_color[0] = fill_color[0] = r * 255;
|
||||
stroke_color[1] = fill_color[1] = g * 255;
|
||||
stroke_color[2] = fill_color[2] = b * 255;
|
||||
}
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/* Text operations */
|
||||
/* ----------------------------------------------------------------------- */
|
||||
- (void) DPSashow: (float)ax : (float)ay : (const char*)s
|
||||
{ /* adds (x,y) in user space to each glyph's x/y advancement */
|
||||
NSPoint p;
|
||||
int x, y;
|
||||
float numarray[2];
|
||||
|
||||
if (!wi || !wi->data) return;
|
||||
if (all_clipped)
|
||||
return;
|
||||
|
||||
if ([path isEmpty]) return;
|
||||
p = [path currentPoint];
|
||||
|
||||
numarray[0] = ax; numarray[1] = ay;
|
||||
|
||||
x = p.x - offset.x;
|
||||
y = offset.y - p.y;
|
||||
[(id<FTFontInfo>)font
|
||||
drawString: s
|
||||
at: x:y
|
||||
to: clip_x0:clip_y0:clip_x1:clip_y1 : CLIP_DATA : wi->bytes_per_line
|
||||
: (wi->has_alpha? wi->alpha + clip_x0 + clip_y0 * wi->sx : NULL) : wi->sx
|
||||
color: fill_color[0]:fill_color[1]:fill_color[2]:fill_color[3]
|
||||
transform: ctm
|
||||
deltas: numarray : 1 : 4
|
||||
widthChar: 0
|
||||
drawinfo: &DI];
|
||||
UPDATE_UNBUFFERED
|
||||
}
|
||||
|
||||
- (void) DPSawidthshow: (float)cx : (float)cy : (int)c : (float)ax : (float)ay
|
||||
: (const char*)s
|
||||
{ /* adds (ax,ay) in user space to every glyph's advancement and (cx,cy)
|
||||
to character c's x/y advancement */
|
||||
NSPoint p;
|
||||
int x, y;
|
||||
float numarray[4];
|
||||
|
||||
if (!wi || !wi->data) return;
|
||||
if (all_clipped)
|
||||
return;
|
||||
|
||||
if ([path isEmpty]) return;
|
||||
p = [path currentPoint];
|
||||
|
||||
numarray[0] = ax; numarray[1] = ay;
|
||||
numarray[2] = cx; numarray[3] = cy;
|
||||
|
||||
x = p.x - offset.x;
|
||||
y = offset.y - p.y;
|
||||
[(id<FTFontInfo>)font
|
||||
drawString: s
|
||||
at: x:y
|
||||
to: clip_x0:clip_y0:clip_x1:clip_y1 : CLIP_DATA : wi->bytes_per_line
|
||||
: (wi->has_alpha? wi->alpha + clip_x0 + clip_y0 * wi->sx : NULL) : wi->sx
|
||||
color: fill_color[0]:fill_color[1]:fill_color[2]:fill_color[3]
|
||||
transform: ctm
|
||||
deltas: numarray : 1 : 12
|
||||
widthChar: c
|
||||
drawinfo: &DI];
|
||||
UPDATE_UNBUFFERED
|
||||
}
|
||||
|
||||
- (void) DPScharpath: (const char*)s : (int)b
|
||||
{ /* TODO: handle b? will freetype ever give us a stroke-only font? */
|
||||
NSPoint p;
|
||||
|
||||
if ([path isEmpty]) return;
|
||||
p=[self currentPoint];
|
||||
|
||||
[(id<FTFontInfo>)font
|
||||
outlineString: s
|
||||
at: p.x:p.y
|
||||
gstate: self];
|
||||
[self DPSclosepath];
|
||||
}
|
||||
|
||||
- (void) DPSshow: (const char*)s
|
||||
{
|
||||
NSPoint p;
|
||||
int x, y;
|
||||
|
||||
if (!wi || !wi->data) return;
|
||||
if (all_clipped)
|
||||
return;
|
||||
|
||||
if ([path isEmpty]) return;
|
||||
p = [path currentPoint];
|
||||
|
||||
x = p.x - offset.x;
|
||||
y = offset.y - p.y;
|
||||
[(id<FTFontInfo>)font
|
||||
drawString: s
|
||||
at: x:y
|
||||
to: clip_x0:clip_y0:clip_x1:clip_y1 : CLIP_DATA : wi->bytes_per_line
|
||||
: (wi->has_alpha? wi->alpha + clip_x0 + clip_y0 * wi->sx : NULL) : wi->sx
|
||||
color: fill_color[0]:fill_color[1]:fill_color[2]:fill_color[3]
|
||||
transform: ctm
|
||||
deltas: NULL : 0 : 0
|
||||
widthChar: 0
|
||||
drawinfo: &DI];
|
||||
UPDATE_UNBUFFERED
|
||||
}
|
||||
|
||||
- (void) DPSwidthshow: (float)cx : (float)cy : (int)c : (const char*)s
|
||||
{ /* adds (x,y) in user space to character c's x/y advancement */
|
||||
NSPoint p;
|
||||
int x, y;
|
||||
float numarray[2];
|
||||
|
||||
if (!wi || !wi->data) return;
|
||||
if (all_clipped)
|
||||
return;
|
||||
|
||||
if ([path isEmpty]) return;
|
||||
p = [path currentPoint];
|
||||
|
||||
numarray[0] = cx; numarray[1] = cy;
|
||||
|
||||
x = p.x - offset.x;
|
||||
y = offset.y - p.y;
|
||||
[(id<FTFontInfo>)font
|
||||
drawString: s
|
||||
at: x:y
|
||||
to: clip_x0:clip_y0:clip_x1:clip_y1 : CLIP_DATA : wi->bytes_per_line
|
||||
: (wi->has_alpha? wi->alpha + clip_x0 + clip_y0 * wi->sx : NULL) : wi->sx
|
||||
color: fill_color[0]:fill_color[1]:fill_color[2]:fill_color[3]
|
||||
transform: ctm
|
||||
deltas: numarray : 1 : 8
|
||||
widthChar: c
|
||||
drawinfo: &DI];
|
||||
UPDATE_UNBUFFERED
|
||||
}
|
||||
|
||||
- (void) DPSxshow: (const char*)s : (const float*)numarray : (int)size
|
||||
{
|
||||
NSPoint p;
|
||||
int x, y;
|
||||
|
||||
if (!wi || !wi->data) return;
|
||||
if (all_clipped)
|
||||
return;
|
||||
|
||||
if ([path isEmpty]) return;
|
||||
p = [path currentPoint];
|
||||
|
||||
x = p.x - offset.x;
|
||||
y = offset.y - p.y;
|
||||
[(id<FTFontInfo>)font
|
||||
drawString: s
|
||||
at: x:y
|
||||
to: clip_x0:clip_y0:clip_x1:clip_y1 : CLIP_DATA : wi->bytes_per_line
|
||||
: (wi->has_alpha? wi->alpha + clip_x0 + clip_y0 * wi->sx : NULL) : wi->sx
|
||||
color: fill_color[0]:fill_color[1]:fill_color[2]:fill_color[3]
|
||||
transform: ctm
|
||||
deltas: numarray : size : 1
|
||||
widthChar: 0
|
||||
drawinfo: &DI];
|
||||
UPDATE_UNBUFFERED
|
||||
}
|
||||
|
||||
- (void) DPSxyshow: (const char*)s : (const float*)numarray : (int)size
|
||||
{
|
||||
NSPoint p;
|
||||
int x, y;
|
||||
|
||||
if (!wi || !wi->data) return;
|
||||
if (all_clipped)
|
||||
return;
|
||||
|
||||
if ([path isEmpty]) return;
|
||||
p = [path currentPoint];
|
||||
|
||||
x = p.x - offset.x;
|
||||
y = offset.y - p.y;
|
||||
[(id<FTFontInfo>)font
|
||||
drawString: s
|
||||
at: x:y
|
||||
to: clip_x0:clip_y0:clip_x1:clip_y1 : CLIP_DATA : wi->bytes_per_line
|
||||
: (wi->has_alpha? wi->alpha + clip_x0 + clip_y0 * wi->sx : NULL) : wi->sx
|
||||
color: fill_color[0]:fill_color[1]:fill_color[2]:fill_color[3]
|
||||
transform: ctm
|
||||
deltas: numarray : size : 3
|
||||
widthChar: 0
|
||||
drawinfo: &DI];
|
||||
UPDATE_UNBUFFERED
|
||||
}
|
||||
|
||||
- (void) DPSyshow: (const char*)s : (const float*)numarray : (int)size
|
||||
{
|
||||
NSPoint p;
|
||||
int x, y;
|
||||
|
||||
if (!wi || !wi->data) return;
|
||||
if (all_clipped)
|
||||
return;
|
||||
|
||||
if (!path || [path isEmpty]) return;
|
||||
p = [path currentPoint];
|
||||
|
||||
x = p.x - offset.x;
|
||||
y = offset.y - p.y;
|
||||
[(id<FTFontInfo>)font
|
||||
drawString: s
|
||||
at: x:y
|
||||
to: clip_x0:clip_y0:clip_x1:clip_y1 : CLIP_DATA : wi->bytes_per_line
|
||||
: (wi->has_alpha? wi->alpha + clip_x0 + clip_y0 * wi->sx : NULL) : wi->sx
|
||||
color: fill_color[0]:fill_color[1]:fill_color[2]:fill_color[3]
|
||||
transform: ctm
|
||||
deltas: numarray : size : 2
|
||||
widthChar: 0
|
||||
drawinfo: &DI];
|
||||
UPDATE_UNBUFFERED
|
||||
}
|
||||
|
||||
|
||||
- (void) GSShowGlyphs: (const NSGlyph *)glyphs : (size_t) length
|
||||
{
|
||||
NSPoint p;
|
||||
int x, y;
|
||||
|
||||
if (!wi || !wi->data) return;
|
||||
if (all_clipped)
|
||||
return;
|
||||
|
||||
if (!path || [path isEmpty]) return;
|
||||
p = [path currentPoint];
|
||||
|
||||
x = p.x - offset.x;
|
||||
y = offset.y - p.y;
|
||||
if (wi->has_alpha)
|
||||
{
|
||||
[(id<FTFontInfo>)font
|
||||
drawGlyphs: glyphs : length
|
||||
at: x:y
|
||||
to: clip_x0:clip_y0:clip_x1:clip_y1 : CLIP_DATA : wi->bytes_per_line
|
||||
alpha: wi->alpha + clip_x0 + clip_y0 * wi->sx : wi->sx
|
||||
color: fill_color[0]:fill_color[1]:fill_color[2]:fill_color[3]
|
||||
transform: ctm
|
||||
drawinfo: &DI];
|
||||
}
|
||||
else
|
||||
{
|
||||
[(id<FTFontInfo>)font
|
||||
drawGlyphs: glyphs : length
|
||||
at: x:y
|
||||
to: clip_x0:clip_y0:clip_x1:clip_y1 : CLIP_DATA : wi->bytes_per_line
|
||||
color: fill_color[0]:fill_color[1]:fill_color[2]:fill_color[3]
|
||||
transform: ctm
|
||||
drawinfo: &DI];
|
||||
}
|
||||
UPDATE_UNBUFFERED
|
||||
}
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/* Gstate operations */
|
||||
/* ----------------------------------------------------------------------- */
|
||||
- (void) DPSinitgraphics
|
||||
{
|
||||
[super DPSinitgraphics];
|
||||
|
||||
line_width=1.0;
|
||||
linecapstyle=ART_PATH_STROKE_CAP_BUTT;
|
||||
linejoinstyle=ART_PATH_STROKE_JOIN_MITER;
|
||||
miter_limit=10.0;
|
||||
if (dash.n_dash)
|
||||
{
|
||||
free(dash.dash);
|
||||
dash.dash=NULL;
|
||||
dash.n_dash=0;
|
||||
do_dash=0;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) DPScurrentlinecap: (int*)linecap
|
||||
{
|
||||
switch (linecapstyle)
|
||||
{
|
||||
default:
|
||||
case ART_PATH_STROKE_CAP_BUTT:
|
||||
*linecap=NSButtLineCapStyle;
|
||||
break;
|
||||
case ART_PATH_STROKE_CAP_ROUND:
|
||||
*linecap=NSRoundLineCapStyle;
|
||||
break;
|
||||
case ART_PATH_STROKE_CAP_SQUARE:
|
||||
*linecap=NSSquareLineCapStyle;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) DPScurrentlinejoin: (int*)linejoin
|
||||
{
|
||||
switch (linejoinstyle)
|
||||
{
|
||||
default:
|
||||
case ART_PATH_STROKE_JOIN_MITER:
|
||||
*linejoin=NSMiterLineJoinStyle;
|
||||
break;
|
||||
case ART_PATH_STROKE_JOIN_ROUND:
|
||||
*linejoin=NSRoundLineJoinStyle;
|
||||
break;
|
||||
case ART_PATH_STROKE_JOIN_BEVEL:
|
||||
*linejoin=NSBevelLineJoinStyle;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) DPScurrentlinewidth: (float*)width
|
||||
{
|
||||
*width=line_width;
|
||||
}
|
||||
|
||||
- (void) DPScurrentmiterlimit: (float*)limit
|
||||
{
|
||||
*limit=miter_limit;
|
||||
}
|
||||
|
||||
- (void) DPSsetdash: (const float*)pat : (int)size : (float)offs
|
||||
{
|
||||
int i;
|
||||
|
||||
if (dash.n_dash)
|
||||
{
|
||||
free(dash.dash);
|
||||
dash.dash=NULL;
|
||||
dash.n_dash=0;
|
||||
do_dash=0;
|
||||
}
|
||||
|
||||
if (size>0)
|
||||
{
|
||||
dash.offset=offs;
|
||||
dash.n_dash=size;
|
||||
dash.dash=malloc(sizeof(double)*size);
|
||||
if (!dash.dash)
|
||||
{
|
||||
/* Revert to no dash. Better than crashing. */
|
||||
dash.n_dash=0;
|
||||
dash.offset=0;
|
||||
do_dash=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0;i<size;i++)
|
||||
dash.dash[i]=pat[i];
|
||||
do_dash=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) DPSsetlinecap: (int)linecap
|
||||
{
|
||||
switch (linecap)
|
||||
{
|
||||
default:
|
||||
case NSButtLineCapStyle:
|
||||
linecapstyle=ART_PATH_STROKE_CAP_BUTT;
|
||||
break;
|
||||
case NSRoundLineCapStyle:
|
||||
linecapstyle=ART_PATH_STROKE_CAP_ROUND;
|
||||
break;
|
||||
case NSSquareLineCapStyle:
|
||||
linecapstyle=ART_PATH_STROKE_CAP_SQUARE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) DPSsetlinejoin: (int)linejoin
|
||||
{
|
||||
switch (linejoin)
|
||||
{
|
||||
default:
|
||||
case NSMiterLineJoinStyle:
|
||||
linejoinstyle=ART_PATH_STROKE_JOIN_MITER;
|
||||
break;
|
||||
case NSRoundLineJoinStyle:
|
||||
linejoinstyle=ART_PATH_STROKE_JOIN_ROUND;
|
||||
break;
|
||||
case NSBevelLineJoinStyle:
|
||||
linejoinstyle=ART_PATH_STROKE_JOIN_BEVEL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) DPSsetlinewidth: (float)width
|
||||
{
|
||||
line_width=width;
|
||||
/* TODO? handle line_width=0 properly */
|
||||
if (line_width<=0) line_width=1;
|
||||
}
|
||||
|
||||
- (void) DPSsetmiterlimit: (float)limit
|
||||
{
|
||||
miter_limit=limit;
|
||||
}
|
||||
|
||||
|
||||
- (void) DPScurrentstrokeadjust: (int*)b
|
||||
{
|
||||
*b = strokeadjust;
|
||||
}
|
||||
|
||||
- (void) DPSsetstrokeadjust: (int)b
|
||||
{
|
||||
strokeadjust = b;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface ARTGState (internal_stuff)
|
||||
-(void) _setup_stuff: (gswindow_device_t *)win : (int)x : (int)y;
|
||||
-(void) GSCurrentDevice: (void **)device : (int *)x : (int *)y;
|
||||
@end
|
||||
|
||||
@implementation ARTGState (internal_stuff)
|
||||
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
if (dash.dash)
|
||||
free(dash.dash);
|
||||
|
||||
if (clip_span)
|
||||
free(clip_span);
|
||||
if (clip_index)
|
||||
free(clip_index);
|
||||
|
||||
DESTROY(wi);
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
-(id) deepen
|
||||
{
|
||||
[super deepen];
|
||||
|
||||
if (dash.dash)
|
||||
{
|
||||
double *tmp=malloc(sizeof(double)*dash.n_dash);
|
||||
if (tmp)
|
||||
{
|
||||
memcpy(tmp,dash.dash,sizeof(double)*dash.n_dash);
|
||||
dash.dash=tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
dash.dash=NULL;
|
||||
dash.n_dash=0;
|
||||
do_dash=0;
|
||||
}
|
||||
}
|
||||
|
||||
if (clip_span)
|
||||
{
|
||||
unsigned int *n;
|
||||
n=malloc(sizeof(unsigned int)*clip_num_span);
|
||||
if (n)
|
||||
{
|
||||
memcpy(n,clip_span,sizeof(unsigned int)*clip_num_span);
|
||||
clip_span=n;
|
||||
n=malloc(sizeof(unsigned int *)*(clip_sy+1));
|
||||
if (n)
|
||||
{
|
||||
memcpy(n,clip_index,sizeof(unsigned int *)*(clip_sy+1));
|
||||
clip_index = n;
|
||||
}
|
||||
else
|
||||
{
|
||||
free(clip_span);
|
||||
clip_span=clip_index=NULL;
|
||||
clip_num_span=0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
clip_span=clip_index=NULL;
|
||||
clip_num_span=0;
|
||||
}
|
||||
}
|
||||
|
||||
wi=RETAIN(wi);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void) _setup_stuff: (gswindow_device_t *)window : (int)x : (int)y
|
||||
{
|
||||
struct XWindowBuffer_depth_info_s di;
|
||||
|
||||
XWindowBuffer *new_wi;
|
||||
[self setOffset: NSMakePoint(x, y)];
|
||||
|
||||
#ifndef RDS
|
||||
di.drawing_depth = DI.drawing_depth;
|
||||
#endif
|
||||
di.bytes_per_pixel = DI.bytes_per_pixel;
|
||||
di.inline_alpha = DI.inline_alpha;
|
||||
di.inline_alpha_ofs = DI.inline_alpha_ofs;
|
||||
new_wi=[XWindowBuffer windowBufferForWindow: window depthInfo: &di];
|
||||
if (new_wi != wi)
|
||||
{
|
||||
DESTROY(wi);
|
||||
wi=new_wi;
|
||||
}
|
||||
else
|
||||
{
|
||||
DESTROY(new_wi);
|
||||
}
|
||||
}
|
||||
|
||||
-(void) GSCurrentDevice: (void **)device : (int *)x : (int *)y
|
||||
{
|
||||
if (x)
|
||||
*x = 0;
|
||||
if (y)
|
||||
*y = 0;
|
||||
if (device)
|
||||
{
|
||||
if (wi)
|
||||
*device = wi->window;
|
||||
else
|
||||
*device = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation ARTContext
|
||||
|
||||
+ (void)initializeBackend
|
||||
{
|
||||
NSDebugLLog(@"back-art",@"Initializing libart/freetype backend");
|
||||
|
||||
[NSGraphicsContext setDefaultContextClass: [ARTContext class]];
|
||||
|
||||
[FTFontInfo initializeBackend];
|
||||
}
|
||||
|
||||
|
||||
// Could use NSSwapInt() instead
|
||||
static unsigned int flip_bytes(unsigned int i)
|
||||
{
|
||||
return ((i>>24)&0xff)
|
||||
|((i>> 8)&0xff00)
|
||||
|((i<< 8)&0xff0000)
|
||||
|((i<<24)&0xff000000);
|
||||
return ((i >> 24) & 0xff)
|
||||
|((i >> 8) & 0xff00)
|
||||
|((i << 8) & 0xff0000)
|
||||
|((i << 24) & 0xff000000);
|
||||
}
|
||||
|
||||
static int byte_order(void)
|
||||
|
@ -744,6 +50,15 @@ static int byte_order(void)
|
|||
return foo.c != 1;
|
||||
}
|
||||
|
||||
@implementation ARTContext
|
||||
|
||||
+ (void)initializeBackend
|
||||
{
|
||||
NSDebugLLog(@"back-art",@"Initializing libart/freetype backend");
|
||||
|
||||
[NSGraphicsContext setDefaultContextClass: [ARTContext class]];
|
||||
[FTFontInfo initializeBackend];
|
||||
}
|
||||
|
||||
- (id) initWithContextInfo: (NSDictionary *)info
|
||||
{
|
||||
|
@ -756,22 +71,19 @@ static int byte_order(void)
|
|||
{
|
||||
/* Most likely this is a PS or PDF context, so just return what
|
||||
super gave us
|
||||
TODO: figure out if this comment still applies
|
||||
*/
|
||||
return self;
|
||||
}
|
||||
|
||||
/* Create a default gstate */
|
||||
gstate = [[ARTGState allocWithZone: [self zone]] initWithDrawContext: self];
|
||||
[gstate DPSsetalpha: 1.0];
|
||||
[gstate DPSsetlinewidth: 1.0];
|
||||
[gstate DPSsetstrokeadjust: 1];
|
||||
|
||||
#ifdef RDS
|
||||
{
|
||||
RDSServer *s=(RDSServer *)server;
|
||||
RDSServer *s = (RDSServer *)server;
|
||||
int bpp;
|
||||
int red_mask, green_mask, blue_mask;
|
||||
|
||||
[s getPixelFormat: &bpp masks: &red_mask : &green_mask : &blue_mask];
|
||||
artcontext_setup_draw_info(&DI, red_mask, green_mask, blue_mask, bpp);
|
||||
}
|
||||
|
@ -790,12 +102,12 @@ static int byte_order(void)
|
|||
Thus, we try to find a DirectColor or TrueColor visual. If that fails,
|
||||
we use the default visual and hope that it's usable.
|
||||
*/
|
||||
template.class=DirectColor;
|
||||
visualInfo=XGetVisualInfo(d, VisualClassMask, &template, &numMatches);
|
||||
template.class = DirectColor;
|
||||
visualInfo = XGetVisualInfo(d, VisualClassMask, &template, &numMatches);
|
||||
if (!visualInfo)
|
||||
{
|
||||
template.class=TrueColor;
|
||||
visualInfo=XGetVisualInfo(d, VisualClassMask, &template, &numMatches);
|
||||
template.class = TrueColor;
|
||||
visualInfo = XGetVisualInfo(d, VisualClassMask, &template, &numMatches);
|
||||
}
|
||||
if (visualInfo)
|
||||
{
|
||||
|
@ -836,42 +148,28 @@ static int byte_order(void)
|
|||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (void) flushGraphics
|
||||
{ /* TODO: _really_ flush? (ie. force updates and wait for shm completion?) */
|
||||
{
|
||||
/* TODO: _really_ flush? (ie. force updates and wait for shm completion?) */
|
||||
#ifndef RDS
|
||||
XFlush([(XGServer *)server xDisplay]);
|
||||
XFlush([(XGServer *)server xDisplay]);
|
||||
#endif
|
||||
}
|
||||
|
||||
+(void) waitAllContexts
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
#ifndef RDS
|
||||
+(void) _gotShmCompletion: (Drawable)d
|
||||
+ (void) _gotShmCompletion: (Drawable)d
|
||||
{
|
||||
[XWindowBuffer _gotShmCompletion: d];
|
||||
[XWindowBuffer _gotShmCompletion: d];
|
||||
}
|
||||
|
||||
-(void) gotShmCompletion: (Drawable)d
|
||||
- (void) gotShmCompletion: (Drawable)d
|
||||
{
|
||||
[XWindowBuffer _gotShmCompletion: d];
|
||||
[XWindowBuffer _gotShmCompletion: d];
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// Read the Color at a Screen Position
|
||||
//
|
||||
- (NSColor *) NSReadPixel: (NSPoint) location
|
||||
{
|
||||
NSLog(@"ignoring NSReadPixel: (%g %g)",location.x,location.y);
|
||||
return nil;
|
||||
}
|
||||
|
||||
/* Private backend methods */
|
||||
+(void) handleExposeRect: (NSRect)rect forDriver: (void *)driver
|
||||
+ (void) handleExposeRect: (NSRect)rect forDriver: (void *)driver
|
||||
{
|
||||
[(XWindowBuffer *)driver _exposeRect: rect];
|
||||
}
|
||||
|
@ -881,12 +179,11 @@ static int byte_order(void)
|
|||
@implementation ARTContext (ops)
|
||||
- (void) GSSetDevice: (void*)device : (int)x : (int)y
|
||||
{
|
||||
[(ARTGState *)gstate _setup_stuff: device : x : y];
|
||||
[(ARTGState *)gstate GSSetDevice: device : x : y];
|
||||
}
|
||||
|
||||
-(void) GSCurrentDevice: (void **)device : (int *)x : (int *)y
|
||||
- (void) GSCurrentDevice: (void **)device : (int *)x : (int *)y
|
||||
{
|
||||
[(ARTGState *)gstate GSCurrentDevice: device : x : y];
|
||||
[(ARTGState *)gstate GSCurrentDevice: device : x : y];
|
||||
}
|
||||
@end
|
||||
|
||||
|
|
|
@ -91,14 +91,17 @@
|
|||
@end
|
||||
|
||||
|
||||
@interface ARTGState (internal_stuff)
|
||||
-(void) GSSetDevice: (gswindow_device_t *)win : (int)x : (int)y;
|
||||
-(void) GSCurrentDevice: (void **)device : (int *)x : (int *)y;
|
||||
@end
|
||||
|
||||
#define UPDATE_UNBUFFERED \
|
||||
if (wi->window->type==NSBackingStoreNonretained) \
|
||||
{ \
|
||||
[wi _exposeRect: NSMakeRect(clip_x0,clip_y0,clip_sx,clip_sy)]; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern struct draw_info_s ART_DI;
|
||||
#define DI ART_DI
|
||||
|
||||
|
|
659
Source/art/ARTGState.m
Normal file
659
Source/art/ARTGState.m
Normal file
|
@ -0,0 +1,659 @@
|
|||
/*
|
||||
Copyright (C) 2002, 2003, 2005 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 <math.h>
|
||||
|
||||
#include <AppKit/NSAffineTransform.h>
|
||||
#include <AppKit/NSBezierPath.h>
|
||||
#include <AppKit/NSColor.h>
|
||||
|
||||
#include "ARTGState.h"
|
||||
|
||||
#include "blit.h"
|
||||
#include "ftfont.h"
|
||||
|
||||
#ifndef RDS
|
||||
#include "x11/XWindowBuffer.h"
|
||||
#endif
|
||||
|
||||
#include <libart_lgpl/libart.h>
|
||||
|
||||
draw_info_t ART_DI;
|
||||
|
||||
@implementation ARTGState
|
||||
|
||||
/* TODO:
|
||||
optimize all this. passing device_color_t structures around by value is
|
||||
very expensive
|
||||
*/
|
||||
-(void) setColor: (device_color_t *)color state: (color_state_t)cState
|
||||
{
|
||||
device_color_t c;
|
||||
unsigned char r,g,b;
|
||||
|
||||
[super setColor: color state: cState];
|
||||
if (cState&(COLOR_FILL|COLOR_STROKE))
|
||||
{
|
||||
c = fillColor;
|
||||
gsColorToRGB(&c); /* TODO: check this */
|
||||
if (c.field[0] > 1.0) c.field[0] = 1.0;
|
||||
if (c.field[0] < 0.0) c.field[0] = 0.0;
|
||||
r = c.field[0] * 255;
|
||||
if (c.field[1] > 1.0) c.field[1] = 1.0;
|
||||
if (c.field[1] < 0.0) c.field[1] = 0.0;
|
||||
g = c.field[1] * 255;
|
||||
if (c.field[2] > 1.0) c.field[2] = 1.0;
|
||||
if (c.field[2] < 0.0) c.field[2] = 0.0;
|
||||
b = c.field[2] * 255;
|
||||
|
||||
if (cState & COLOR_FILL)
|
||||
{
|
||||
fill_color[0] = r;
|
||||
fill_color[1] = g;
|
||||
fill_color[2] = b;
|
||||
fill_color[3] = fillColor.field[AINDEX] * 255;
|
||||
}
|
||||
if (cState & COLOR_STROKE)
|
||||
{
|
||||
stroke_color[0] = r;
|
||||
stroke_color[1] = g;
|
||||
stroke_color[2] = b;
|
||||
stroke_color[3] = strokeColor.field[AINDEX] * 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* specially optimized versions (since these are common and simple) */
|
||||
-(void) DPSsetgray: (float)gray
|
||||
{
|
||||
if (gray < 0.0) gray = 0.0;
|
||||
if (gray > 1.0) gray = 1.0;
|
||||
|
||||
fillColor.space = strokeColor.space = gray_colorspace;
|
||||
fillColor.field[0] = strokeColor.field[0] = gray;
|
||||
cstate = COLOR_FILL | COLOR_STROKE;
|
||||
|
||||
stroke_color[0] = stroke_color[1] = stroke_color[2] =
|
||||
fill_color[0] = fill_color[1] = fill_color[2] = gray * 255;
|
||||
}
|
||||
|
||||
-(void) DPSsetalpha: (float)a
|
||||
{
|
||||
if (a < 0.0) a = 0.0;
|
||||
if (a > 1.0) a = 1.0;
|
||||
fillColor.field[AINDEX] = strokeColor.field[AINDEX] = a;
|
||||
stroke_color[3] = fill_color[3] = a * 255;
|
||||
}
|
||||
|
||||
- (void) DPSsetrgbcolor: (float)r : (float)g : (float)b
|
||||
{
|
||||
if (r < 0.0) r = 0.0; if (r > 1.0) r = 1.0;
|
||||
if (g < 0.0) g = 0.0; if (g > 1.0) g = 1.0;
|
||||
if (b < 0.0) b = 0.0; if (b > 1.0) b = 1.0;
|
||||
|
||||
fillColor.space = strokeColor.space = rgb_colorspace;
|
||||
fillColor.field[0] = strokeColor.field[0] = r;
|
||||
fillColor.field[1] = strokeColor.field[1] = g;
|
||||
fillColor.field[2] = strokeColor.field[2] = b;
|
||||
cstate = COLOR_FILL | COLOR_STROKE;
|
||||
|
||||
stroke_color[0] = fill_color[0] = r * 255;
|
||||
stroke_color[1] = fill_color[1] = g * 255;
|
||||
stroke_color[2] = fill_color[2] = b * 255;
|
||||
}
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/* Text operations */
|
||||
/* ----------------------------------------------------------------------- */
|
||||
- (void) DPSashow: (float)ax : (float)ay : (const char*)s
|
||||
{ /* adds (ax,ay) in user space to each glyph's x/y advancement */
|
||||
NSPoint p;
|
||||
int x, y;
|
||||
float numarray[2];
|
||||
|
||||
if (!wi || !wi->data) return;
|
||||
if (all_clipped)
|
||||
return;
|
||||
|
||||
if ([path isEmpty]) return;
|
||||
p = [path currentPoint];
|
||||
|
||||
numarray[0] = ax;
|
||||
numarray[1] = ay;
|
||||
|
||||
x = p.x - offset.x;
|
||||
y = offset.y - p.y;
|
||||
[(id<FTFontInfo>)font
|
||||
drawString: s
|
||||
at: x : y
|
||||
to: clip_x0 : clip_y0 : clip_x1 : clip_y1 : CLIP_DATA : wi->bytes_per_line
|
||||
: (wi->has_alpha? wi->alpha + clip_x0 + clip_y0 * wi->sx : NULL) : wi->sx
|
||||
color: fill_color[0] : fill_color[1] : fill_color[2] : fill_color[3]
|
||||
transform: ctm
|
||||
deltas: numarray : 1 : 4
|
||||
widthChar: 0
|
||||
drawinfo: &DI];
|
||||
UPDATE_UNBUFFERED
|
||||
}
|
||||
|
||||
- (void) DPSawidthshow: (float)cx : (float)cy : (int)c : (float)ax : (float)ay
|
||||
: (const char*)s
|
||||
{ /* adds (ax,ay) in user space to every glyph's advancement and (cx,cy)
|
||||
to character c's x/y advancement */
|
||||
NSPoint p;
|
||||
int x, y;
|
||||
float numarray[4];
|
||||
|
||||
if (!wi || !wi->data) return;
|
||||
if (all_clipped)
|
||||
return;
|
||||
|
||||
if ([path isEmpty]) return;
|
||||
p = [path currentPoint];
|
||||
|
||||
numarray[0] = ax;
|
||||
numarray[1] = ay;
|
||||
numarray[2] = cx;
|
||||
numarray[3] = cy;
|
||||
|
||||
x = p.x - offset.x;
|
||||
y = offset.y - p.y;
|
||||
[(id<FTFontInfo>)font
|
||||
drawString: s
|
||||
at: x : y
|
||||
to: clip_x0 : clip_y0 : clip_x1 : clip_y1 : CLIP_DATA : wi->bytes_per_line
|
||||
: (wi->has_alpha? wi->alpha + clip_x0 + clip_y0 * wi->sx : NULL) : wi->sx
|
||||
color: fill_color[0] : fill_color[1] : fill_color[2] : fill_color[3]
|
||||
transform: ctm
|
||||
deltas: numarray : 1 : 12
|
||||
widthChar: c
|
||||
drawinfo: &DI];
|
||||
UPDATE_UNBUFFERED
|
||||
}
|
||||
|
||||
- (void) DPScharpath: (const char*)s : (int)b
|
||||
{ /* TODO: handle b? will freetype ever give us a stroke-only font? */
|
||||
NSPoint p;
|
||||
|
||||
if ([path isEmpty]) return;
|
||||
p=[self currentPoint];
|
||||
|
||||
[(id<FTFontInfo>)font
|
||||
outlineString: s
|
||||
at: p.x : p.y
|
||||
gstate: self];
|
||||
[self DPSclosepath];
|
||||
}
|
||||
|
||||
- (void) DPSshow: (const char*)s
|
||||
{
|
||||
NSPoint p;
|
||||
int x, y;
|
||||
|
||||
if (!wi || !wi->data) return;
|
||||
if (all_clipped)
|
||||
return;
|
||||
|
||||
if ([path isEmpty]) return;
|
||||
p = [path currentPoint];
|
||||
|
||||
x = p.x - offset.x;
|
||||
y = offset.y - p.y;
|
||||
[(id<FTFontInfo>)font
|
||||
drawString: s
|
||||
at: x : y
|
||||
to: clip_x0 : clip_y0 : clip_x1 : clip_y1 : CLIP_DATA : wi->bytes_per_line
|
||||
: (wi->has_alpha? wi->alpha + clip_x0 + clip_y0 * wi->sx : NULL) : wi->sx
|
||||
color: fill_color[0] : fill_color[1] : fill_color[2] : fill_color[3]
|
||||
transform: ctm
|
||||
deltas: NULL : 0 : 0
|
||||
widthChar: 0
|
||||
drawinfo: &DI];
|
||||
UPDATE_UNBUFFERED
|
||||
}
|
||||
|
||||
- (void) DPSwidthshow: (float)cx : (float)cy : (int)c : (const char*)s
|
||||
{ /* adds (x,y) in user space to character c's x/y advancement */
|
||||
NSPoint p;
|
||||
int x, y;
|
||||
float numarray[2];
|
||||
|
||||
if (!wi || !wi->data) return;
|
||||
if (all_clipped)
|
||||
return;
|
||||
|
||||
if ([path isEmpty]) return;
|
||||
p = [path currentPoint];
|
||||
|
||||
numarray[0] = cx; numarray[1] = cy;
|
||||
|
||||
x = p.x - offset.x;
|
||||
y = offset.y - p.y;
|
||||
[(id<FTFontInfo>)font
|
||||
drawString: s
|
||||
at: x : y
|
||||
to: clip_x0:clip_y0:clip_x1:clip_y1 : CLIP_DATA : wi->bytes_per_line
|
||||
: (wi->has_alpha? wi->alpha + clip_x0 + clip_y0 * wi->sx : NULL) : wi->sx
|
||||
color: fill_color[0]:fill_color[1]:fill_color[2]:fill_color[3]
|
||||
transform: ctm
|
||||
deltas: numarray : 1 : 8
|
||||
widthChar: c
|
||||
drawinfo: &DI];
|
||||
UPDATE_UNBUFFERED
|
||||
}
|
||||
|
||||
- (void) DPSxshow: (const char*)s : (const float*)numarray : (int)size
|
||||
{
|
||||
NSPoint p;
|
||||
int x, y;
|
||||
|
||||
if (!wi || !wi->data) return;
|
||||
if (all_clipped)
|
||||
return;
|
||||
|
||||
if ([path isEmpty]) return;
|
||||
p = [path currentPoint];
|
||||
|
||||
x = p.x - offset.x;
|
||||
y = offset.y - p.y;
|
||||
[(id<FTFontInfo>)font
|
||||
drawString: s
|
||||
at: x : y
|
||||
to: clip_x0 : clip_y0 : clip_x1 : clip_y1 : CLIP_DATA : wi->bytes_per_line
|
||||
: (wi->has_alpha? wi->alpha + clip_x0 + clip_y0 * wi->sx : NULL) : wi->sx
|
||||
color: fill_color[0] : fill_color[1] : fill_color[2] : fill_color[3]
|
||||
transform: ctm
|
||||
deltas: numarray : size : 1
|
||||
widthChar: 0
|
||||
drawinfo: &DI];
|
||||
UPDATE_UNBUFFERED
|
||||
}
|
||||
|
||||
- (void) DPSxyshow: (const char*)s : (const float*)numarray : (int)size
|
||||
{
|
||||
NSPoint p;
|
||||
int x, y;
|
||||
|
||||
if (!wi || !wi->data) return;
|
||||
if (all_clipped)
|
||||
return;
|
||||
|
||||
if ([path isEmpty]) return;
|
||||
p = [path currentPoint];
|
||||
|
||||
x = p.x - offset.x;
|
||||
y = offset.y - p.y;
|
||||
[(id<FTFontInfo>)font
|
||||
drawString: s
|
||||
at: x : y
|
||||
to: clip_x0 : clip_y0 : clip_x1 : clip_y1 : CLIP_DATA : wi->bytes_per_line
|
||||
: (wi->has_alpha? wi->alpha + clip_x0 + clip_y0 * wi->sx : NULL) : wi->sx
|
||||
color: fill_color[0] : fill_color[1] : fill_color[2] : fill_color[3]
|
||||
transform: ctm
|
||||
deltas: numarray : size : 3
|
||||
widthChar: 0
|
||||
drawinfo: &DI];
|
||||
UPDATE_UNBUFFERED
|
||||
}
|
||||
|
||||
- (void) DPSyshow: (const char*)s : (const float*)numarray : (int)size
|
||||
{
|
||||
NSPoint p;
|
||||
int x, y;
|
||||
|
||||
if (!wi || !wi->data) return;
|
||||
if (all_clipped)
|
||||
return;
|
||||
|
||||
if (!path || [path isEmpty]) return;
|
||||
p = [path currentPoint];
|
||||
|
||||
x = p.x - offset.x;
|
||||
y = offset.y - p.y;
|
||||
[(id<FTFontInfo>)font
|
||||
drawString: s
|
||||
at: x : y
|
||||
to: clip_x0 : clip_y0 : clip_x1 : clip_y1 : CLIP_DATA : wi->bytes_per_line
|
||||
: (wi->has_alpha? wi->alpha + clip_x0 + clip_y0 * wi->sx : NULL) : wi->sx
|
||||
color: fill_color[0] : fill_color[1] : fill_color[2] : fill_color[3]
|
||||
transform: ctm
|
||||
deltas: numarray : size : 2
|
||||
widthChar: 0
|
||||
drawinfo: &DI];
|
||||
UPDATE_UNBUFFERED
|
||||
}
|
||||
|
||||
|
||||
- (void) GSShowGlyphs: (const NSGlyph *)glyphs : (size_t) length
|
||||
{
|
||||
NSPoint p;
|
||||
int x, y;
|
||||
|
||||
if (!wi || !wi->data) return;
|
||||
if (all_clipped)
|
||||
return;
|
||||
|
||||
if (!path || [path isEmpty]) return;
|
||||
p = [path currentPoint];
|
||||
|
||||
x = p.x - offset.x;
|
||||
y = offset.y - p.y;
|
||||
if (wi->has_alpha)
|
||||
{
|
||||
[(id<FTFontInfo>)font
|
||||
drawGlyphs: glyphs : length
|
||||
at: x : y
|
||||
to: clip_x0 : clip_y0 : clip_x1 : clip_y1 : CLIP_DATA : wi->bytes_per_line
|
||||
alpha: wi->alpha + clip_x0 + clip_y0 * wi->sx : wi->sx
|
||||
color: fill_color[0] : fill_color[1] : fill_color[2] : fill_color[3]
|
||||
transform: ctm
|
||||
drawinfo: &DI];
|
||||
}
|
||||
else
|
||||
{
|
||||
[(id<FTFontInfo>)font
|
||||
drawGlyphs: glyphs : length
|
||||
at: x : y
|
||||
to: clip_x0 : clip_y0 : clip_x1 : clip_y1 : CLIP_DATA : wi->bytes_per_line
|
||||
color: fill_color[0] : fill_color[1] : fill_color[2] : fill_color[3]
|
||||
transform: ctm
|
||||
drawinfo: &DI];
|
||||
}
|
||||
UPDATE_UNBUFFERED
|
||||
}
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/* Gstate operations */
|
||||
/* ----------------------------------------------------------------------- */
|
||||
- (void) DPSinitgraphics
|
||||
{
|
||||
[super DPSinitgraphics];
|
||||
|
||||
line_width = 1.0;
|
||||
linecapstyle = ART_PATH_STROKE_CAP_BUTT;
|
||||
linejoinstyle = ART_PATH_STROKE_JOIN_MITER;
|
||||
strokeadjust = 1;
|
||||
miter_limit = 10.0;
|
||||
[self DPSsetalpha: 1.0];
|
||||
|
||||
if (dash.n_dash)
|
||||
{
|
||||
free(dash.dash);
|
||||
dash.dash = NULL;
|
||||
dash.n_dash = 0;
|
||||
do_dash = 0;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) DPScurrentlinecap: (int*)linecap
|
||||
{
|
||||
switch (linecapstyle)
|
||||
{
|
||||
default:
|
||||
case ART_PATH_STROKE_CAP_BUTT:
|
||||
*linecap = NSButtLineCapStyle;
|
||||
break;
|
||||
case ART_PATH_STROKE_CAP_ROUND:
|
||||
*linecap = NSRoundLineCapStyle;
|
||||
break;
|
||||
case ART_PATH_STROKE_CAP_SQUARE:
|
||||
*linecap = NSSquareLineCapStyle;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) DPScurrentlinejoin: (int*)linejoin
|
||||
{
|
||||
switch (linejoinstyle)
|
||||
{
|
||||
default:
|
||||
case ART_PATH_STROKE_JOIN_MITER:
|
||||
*linejoin = NSMiterLineJoinStyle;
|
||||
break;
|
||||
case ART_PATH_STROKE_JOIN_ROUND:
|
||||
*linejoin = NSRoundLineJoinStyle;
|
||||
break;
|
||||
case ART_PATH_STROKE_JOIN_BEVEL:
|
||||
*linejoin = NSBevelLineJoinStyle;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) DPScurrentlinewidth: (float*)width
|
||||
{
|
||||
*width = line_width;
|
||||
}
|
||||
|
||||
- (void) DPScurrentmiterlimit: (float*)limit
|
||||
{
|
||||
*limit = miter_limit;
|
||||
}
|
||||
|
||||
- (void) DPSsetdash: (const float*)pat : (int)size : (float)offs
|
||||
{
|
||||
int i;
|
||||
|
||||
if (dash.n_dash)
|
||||
{
|
||||
free(dash.dash);
|
||||
dash.dash = NULL;
|
||||
dash.n_dash = 0;
|
||||
do_dash = 0;
|
||||
}
|
||||
|
||||
if (size>0)
|
||||
{
|
||||
dash.offset = offs;
|
||||
dash.n_dash = size;
|
||||
dash.dash = malloc(sizeof(double)*size);
|
||||
if (!dash.dash)
|
||||
{
|
||||
/* Revert to no dash. Better than crashing. */
|
||||
dash.n_dash = 0;
|
||||
dash.offset = 0;
|
||||
do_dash = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < size; i++)
|
||||
dash.dash[i] = pat[i];
|
||||
do_dash = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) DPSsetlinecap: (int)linecap
|
||||
{
|
||||
switch (linecap)
|
||||
{
|
||||
default:
|
||||
case NSButtLineCapStyle:
|
||||
linecapstyle = ART_PATH_STROKE_CAP_BUTT;
|
||||
break;
|
||||
case NSRoundLineCapStyle:
|
||||
linecapstyle = ART_PATH_STROKE_CAP_ROUND;
|
||||
break;
|
||||
case NSSquareLineCapStyle:
|
||||
linecapstyle = ART_PATH_STROKE_CAP_SQUARE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) DPSsetlinejoin: (int)linejoin
|
||||
{
|
||||
switch (linejoin)
|
||||
{
|
||||
default:
|
||||
case NSMiterLineJoinStyle:
|
||||
linejoinstyle = ART_PATH_STROKE_JOIN_MITER;
|
||||
break;
|
||||
case NSRoundLineJoinStyle:
|
||||
linejoinstyle = ART_PATH_STROKE_JOIN_ROUND;
|
||||
break;
|
||||
case NSBevelLineJoinStyle:
|
||||
linejoinstyle = ART_PATH_STROKE_JOIN_BEVEL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) DPSsetlinewidth: (float)width
|
||||
{
|
||||
line_width = width;
|
||||
/* TODO? handle line_width=0 properly */
|
||||
if (line_width <= 0) line_width = 1;
|
||||
}
|
||||
|
||||
- (void) DPSsetmiterlimit: (float)limit
|
||||
{
|
||||
miter_limit=limit;
|
||||
}
|
||||
|
||||
- (void) DPScurrentstrokeadjust: (int*)b
|
||||
{
|
||||
*b = strokeadjust;
|
||||
}
|
||||
|
||||
- (void) DPSsetstrokeadjust: (int)b
|
||||
{
|
||||
strokeadjust = b;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation ARTGState (internal_stuff)
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
if (dash.dash)
|
||||
free(dash.dash);
|
||||
|
||||
if (clip_span)
|
||||
free(clip_span);
|
||||
if (clip_index)
|
||||
free(clip_index);
|
||||
|
||||
DESTROY(wi);
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
-(id) deepen
|
||||
{
|
||||
[super deepen];
|
||||
|
||||
if (dash.dash)
|
||||
{
|
||||
double *tmp = malloc(sizeof(double) * dash.n_dash);
|
||||
|
||||
if (tmp)
|
||||
{
|
||||
memcpy(tmp, dash.dash, sizeof(double) * dash.n_dash);
|
||||
dash.dash = tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
dash.dash = NULL;
|
||||
dash.n_dash = 0;
|
||||
do_dash = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (clip_span)
|
||||
{
|
||||
unsigned int *n;
|
||||
|
||||
n = malloc(sizeof(unsigned int) * clip_num_span);
|
||||
if (n)
|
||||
{
|
||||
memcpy(n, clip_span, sizeof(unsigned int) * clip_num_span);
|
||||
clip_span = n;
|
||||
n = malloc(sizeof(unsigned int *) * (clip_sy+1));
|
||||
if (n)
|
||||
{
|
||||
memcpy(n, clip_index, sizeof(unsigned int *) * (clip_sy + 1));
|
||||
clip_index = n;
|
||||
}
|
||||
else
|
||||
{
|
||||
free(clip_span);
|
||||
clip_span=clip_index = NULL;
|
||||
clip_num_span = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
clip_span = clip_index = NULL;
|
||||
clip_num_span = 0;
|
||||
}
|
||||
}
|
||||
|
||||
wi = RETAIN(wi);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void) GSSetDevice: (gswindow_device_t *)window : (int)x : (int)y
|
||||
{
|
||||
struct XWindowBuffer_depth_info_s di;
|
||||
XWindowBuffer *new_wi;
|
||||
|
||||
[self setOffset: NSMakePoint(x, y)];
|
||||
|
||||
#ifndef RDS
|
||||
di.drawing_depth = DI.drawing_depth;
|
||||
#endif
|
||||
di.bytes_per_pixel = DI.bytes_per_pixel;
|
||||
di.inline_alpha = DI.inline_alpha;
|
||||
di.inline_alpha_ofs = DI.inline_alpha_ofs;
|
||||
new_wi = [XWindowBuffer windowBufferForWindow: window depthInfo: &di];
|
||||
if (new_wi != wi)
|
||||
{
|
||||
DESTROY(wi);
|
||||
wi = new_wi;
|
||||
}
|
||||
else
|
||||
{
|
||||
DESTROY(new_wi);
|
||||
}
|
||||
}
|
||||
|
||||
-(void) GSCurrentDevice: (void **)device : (int *)x : (int *)y
|
||||
{
|
||||
NSPoint theOffset = [self offset];
|
||||
|
||||
if (x)
|
||||
*x = theOffset.x;
|
||||
if (y)
|
||||
*y = theOffset.y;
|
||||
|
||||
if (device)
|
||||
{
|
||||
if (wi)
|
||||
*device = wi->window;
|
||||
else
|
||||
*device = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
|
@ -35,7 +35,8 @@ SUBPROJECT_NAME=art
|
|||
# The Objective-C source files to be compiled
|
||||
art_OBJC_FILES = \
|
||||
ARTContext.m \
|
||||
blit.m \
|
||||
ARTGState.m \
|
||||
blit-main.m \
|
||||
ftfont.m \
|
||||
image.m \
|
||||
composite.m \
|
||||
|
|
523
Source/art/blit-main.m
Normal file
523
Source/art/blit-main.m
Normal file
|
@ -0,0 +1,523 @@
|
|||
/*
|
||||
Copyright (C) 2002, 2003, 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 <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <Foundation/NSDebug.h>
|
||||
|
||||
#include "blit.h"
|
||||
|
||||
/*
|
||||
First attempt at gamma correction. Only used in text rendering (blit_*),
|
||||
but that's where it's needed the most. The gamma adjustment is a large
|
||||
hack, but the results are good.
|
||||
*/
|
||||
static unsigned char gamma_table[256],inv_gamma_table[256];
|
||||
|
||||
|
||||
#define NPRE(r, pre) pre##_##r
|
||||
#define M2PRE(a, b) NPRE(a, b)
|
||||
#define MPRE(r) M2PRE(r, FORMAT_INSTANCE)
|
||||
|
||||
|
||||
/*
|
||||
For each supported pixel format we define a bunch of macros and include
|
||||
ourself.
|
||||
*/
|
||||
|
||||
|
||||
/* 24-bit red green blue */
|
||||
#define FORMAT_INSTANCE rgb
|
||||
#define FORMAT_HOW DI_24_RGB
|
||||
|
||||
#define BLEND_TYPE unsigned char
|
||||
#define BLEND_READ(p,nr,ng,nb) nr=p[0]; ng=p[1]; nb=p[2];
|
||||
#define BLEND_READ_ALPHA(p,pa,nr,ng,nb,na) nr=p[0]; ng=p[1]; nb=p[2]; na=pa[0];
|
||||
#define BLEND_WRITE(p,nr,ng,nb) p[0]=nr; p[1]=ng; p[2]=nb;
|
||||
#define BLEND_WRITE_ALPHA(p,pa,nr,ng,nb,na) p[0]=nr; p[1]=ng; p[2]=nb; pa[0]=na;
|
||||
#define BLEND_INC(p) p+=3;
|
||||
|
||||
#define ALPHA_READ(s,sa,d) d=sa[0];
|
||||
#define ALPHA_INC(s,sa) s+=3; sa++;
|
||||
|
||||
#define COPY_TYPE unsigned char
|
||||
#define COPY_TYPE_PIXEL(a) unsigned char a[3];
|
||||
#define COPY_ASSEMBLE_PIXEL(v,r,g,b) v[0]=r; v[1]=g; v[2]=b;
|
||||
#define COPY_WRITE(dst,v) dst[0]=v[0]; dst[1]=v[1]; dst[2]=v[2];
|
||||
#define COPY_INC(dst) dst+=3;
|
||||
|
||||
#include "blit.m"
|
||||
|
||||
#undef FORMAT_INSTANCE
|
||||
|
||||
|
||||
/* 24-bit blue green red */
|
||||
#define FORMAT_INSTANCE bgr
|
||||
#define FORMAT_HOW DI_24_BGR
|
||||
|
||||
#define BLEND_TYPE unsigned char
|
||||
#define BLEND_READ(p,nr,ng,nb) nb=p[0]; ng=p[1]; nr=p[2];
|
||||
#define BLEND_READ_ALPHA(p,pa,nr,ng,nb,na) nb=p[0]; ng=p[1]; nr=p[2]; na=pa[0];
|
||||
#define BLEND_WRITE(p,nr,ng,nb) p[0]=nb; p[1]=ng; p[2]=nr;
|
||||
#define BLEND_WRITE_ALPHA(p,pa,nr,ng,nb,na) p[0]=nb; p[1]=ng; p[2]=nr; pa[0]=na;
|
||||
#define BLEND_INC(p) p+=3;
|
||||
|
||||
#define ALPHA_READ(s,sa,d) d=sa[0];
|
||||
#define ALPHA_INC(s,sa) s+=3; sa++;
|
||||
|
||||
#define COPY_TYPE unsigned char
|
||||
#define COPY_TYPE_PIXEL(a) unsigned char a[3];
|
||||
#define COPY_ASSEMBLE_PIXEL(v,r,g,b) v[0]=b; v[1]=g; v[2]=r;
|
||||
#define COPY_WRITE(dst,v) dst[0]=v[0]; dst[1]=v[1]; dst[2]=v[2];
|
||||
#define COPY_INC(dst) dst+=3;
|
||||
|
||||
#include "blit.m"
|
||||
|
||||
#undef FORMAT_INSTANCE
|
||||
|
||||
|
||||
/* 32-bit red green blue alpha */
|
||||
#define FORMAT_INSTANCE rgba
|
||||
#define FORMAT_HOW DI_32_RGBA
|
||||
|
||||
#define INLINE_ALPHA
|
||||
|
||||
#define BLEND_TYPE unsigned char
|
||||
#define BLEND_READ(p,nr,ng,nb) nr=p[0]; ng=p[1]; nb=p[2];
|
||||
#define BLEND_READ_ALPHA(p,pa,nr,ng,nb,na) nr=p[0]; ng=p[1]; nb=p[2]; na=p[3];
|
||||
#define BLEND_WRITE(p,nr,ng,nb) p[0]=nr; p[1]=ng; p[2]=nb;
|
||||
#define BLEND_WRITE_ALPHA(p,pa,nr,ng,nb,na) p[0]=nr; p[1]=ng; p[2]=nb; p[3]=na;
|
||||
#define BLEND_INC(p) p+=4;
|
||||
|
||||
#define ALPHA_READ(s,sa,d) d=s[3];
|
||||
#define ALPHA_INC(s,sa) s+=4;
|
||||
|
||||
#define COPY_TYPE unsigned int
|
||||
#define COPY_TYPE_PIXEL(a) unsigned int a;
|
||||
#if GS_WORDS_BIGENDIAN
|
||||
#define COPY_ASSEMBLE_PIXEL(v,r,g,b) v=(r<<24)|(g<<16)|(b<<8);
|
||||
#define COPY_ASSEMBLE_PIXEL_ALPHA(v,r,g,b,a) v=(r<<24)|(g<<16)|(b<<8)|(a);
|
||||
#else
|
||||
#define COPY_ASSEMBLE_PIXEL(v,r,g,b) v=(b<<16)|(g<<8)|(r<<0);
|
||||
#define COPY_ASSEMBLE_PIXEL_ALPHA(v,r,g,b,a) v=(b<<16)|(g<<8)|(r<<0)|(a<<24);
|
||||
#endif
|
||||
#define COPY_WRITE(dst,v) dst[0]=v;
|
||||
#define COPY_INC(dst) dst++;
|
||||
|
||||
#include "blit.m"
|
||||
|
||||
#undef FORMAT_INSTANCE
|
||||
|
||||
|
||||
/* 32-bit blue green red alpha */
|
||||
#define FORMAT_INSTANCE bgra
|
||||
#define FORMAT_HOW DI_32_BGRA
|
||||
|
||||
#define INLINE_ALPHA
|
||||
|
||||
#define BLEND_TYPE unsigned char
|
||||
#define BLEND_READ(p,nr,ng,nb) nb=p[0]; ng=p[1]; nr=p[2];
|
||||
#define BLEND_READ_ALPHA(p,pa,nr,ng,nb,na) nb=p[0]; ng=p[1]; nr=p[2]; na=p[3];
|
||||
#define BLEND_WRITE(p,nr,ng,nb) p[0]=nb; p[1]=ng; p[2]=nr;
|
||||
#define BLEND_WRITE_ALPHA(p,pa,nr,ng,nb,na) p[0]=nb; p[1]=ng; p[2]=nr; p[3]=na;
|
||||
#define BLEND_INC(p) p+=4;
|
||||
|
||||
#define ALPHA_READ(s,sa,d) d=s[3];
|
||||
#define ALPHA_INC(s,sa) s+=4;
|
||||
|
||||
#define COPY_TYPE unsigned int
|
||||
#define COPY_TYPE_PIXEL(a) unsigned int a;
|
||||
#if GS_WORDS_BIGENDIAN
|
||||
#define COPY_ASSEMBLE_PIXEL(v,r,g,b) v=(b<<24)|(g<<16)|(r<<8);
|
||||
#define COPY_ASSEMBLE_PIXEL_ALPHA(v,r,g,b,a) v=(b<<24)|(g<<16)|(r<<8)|(a);
|
||||
#else
|
||||
#define COPY_ASSEMBLE_PIXEL(v,r,g,b) v=(r<<16)|(g<<8)|(b<<0);
|
||||
#define COPY_ASSEMBLE_PIXEL_ALPHA(v,r,g,b,a) v=(r<<16)|(g<<8)|(b<<0)|(a<<24);
|
||||
#endif
|
||||
#define COPY_WRITE(dst,v) dst[0]=v;
|
||||
#define COPY_INC(dst) dst++;
|
||||
|
||||
#include "blit.m"
|
||||
|
||||
#undef FORMAT_INSTANCE
|
||||
|
||||
|
||||
/* 32-bit alpha red green blue */
|
||||
#define FORMAT_INSTANCE argb
|
||||
#define FORMAT_HOW DI_32_ARGB
|
||||
|
||||
#define INLINE_ALPHA
|
||||
|
||||
#define BLEND_TYPE unsigned char
|
||||
#define BLEND_READ(p,nr,ng,nb) nr=p[1]; ng=p[2]; nb=p[3];
|
||||
#define BLEND_READ_ALPHA(p,pa,nr,ng,nb,na) nr=p[1]; ng=p[2]; nb=p[3]; na=p[0];
|
||||
#define BLEND_WRITE(p,nr,ng,nb) p[1]=nr; p[2]=ng; p[3]=nb;
|
||||
#define BLEND_WRITE_ALPHA(p,pa,nr,ng,nb,na) p[1]=nr; p[2]=ng; p[3]=nb; p[0]=na;
|
||||
#define BLEND_INC(p) p+=4;
|
||||
|
||||
#define ALPHA_READ(s,sa,d) d=s[0];
|
||||
#define ALPHA_INC(s,sa) s+=4;
|
||||
|
||||
#define COPY_TYPE unsigned int
|
||||
#define COPY_TYPE_PIXEL(a) unsigned int a;
|
||||
#if GS_WORDS_BIGENDIAN
|
||||
#define COPY_ASSEMBLE_PIXEL(v,r,g,b) v=(r<<16)|(g<<8)|(b<<0);
|
||||
#define COPY_ASSEMBLE_PIXEL_ALPHA(v,r,g,b,a) v=(r<<16)|(g<<8)|(b<<0)|(a<<24);
|
||||
#else
|
||||
#define COPY_ASSEMBLE_PIXEL(v,r,g,b) v=(b<<24)|(g<<16)|(r<<8);
|
||||
#define COPY_ASSEMBLE_PIXEL_ALPHA(v,r,g,b,a) v=(b<<24)|(g<<16)|(r<<8)|(a);
|
||||
#endif
|
||||
#define COPY_WRITE(dst,v) dst[0]=v;
|
||||
#define COPY_INC(dst) dst++;
|
||||
|
||||
#include "blit.m"
|
||||
|
||||
#undef FORMAT_INSTANCE
|
||||
|
||||
|
||||
/* 32-bit alpha blue green red */
|
||||
#define FORMAT_INSTANCE abgr
|
||||
#define FORMAT_HOW DI_32_ABGR
|
||||
|
||||
#define INLINE_ALPHA
|
||||
|
||||
#define BLEND_TYPE unsigned char
|
||||
#define BLEND_READ(p,nr,ng,nb) nb=p[1]; ng=p[2]; nr=p[3];
|
||||
#define BLEND_READ_ALPHA(p,pa,nr,ng,nb,na) nb=p[1]; ng=p[2]; nr=p[3]; na=p[0];
|
||||
#define BLEND_WRITE(p,nr,ng,nb) p[1]=nb; p[2]=ng; p[3]=nr;
|
||||
#define BLEND_WRITE_ALPHA(p,pa,nr,ng,nb,na) p[1]=nb; p[2]=ng; p[3]=nr; p[0]=na;
|
||||
#define BLEND_INC(p) p+=4;
|
||||
|
||||
#define ALPHA_READ(s,sa,d) d=s[0];
|
||||
#define ALPHA_INC(s,sa) s+=4;
|
||||
|
||||
#define COPY_TYPE unsigned int
|
||||
#define COPY_TYPE_PIXEL(a) unsigned int a;
|
||||
#if GS_WORDS_BIGENDIAN
|
||||
#define COPY_ASSEMBLE_PIXEL(v,r,g,b) v=(b<<16)|(g<<8)|(r<<0);
|
||||
#define COPY_ASSEMBLE_PIXEL_ALPHA(v,r,g,b,a) v=(b<<16)|(g<<8)|(r<<0)|(a<<24);
|
||||
#else
|
||||
#define COPY_ASSEMBLE_PIXEL(v,r,g,b) v=(r<<24)|(g<<16)|(b<<8);
|
||||
#define COPY_ASSEMBLE_PIXEL_ALPHA(v,r,g,b,a) v=(r<<24)|(g<<16)|(b<<8)|(a);
|
||||
#endif
|
||||
#define COPY_WRITE(dst,v) dst[0]=v;
|
||||
#define COPY_INC(dst) dst++;
|
||||
|
||||
#include "blit.m"
|
||||
|
||||
#undef FORMAT_INSTANCE
|
||||
|
||||
|
||||
/* 16-bit 5 bits blue, 6 bits green, 5 bits red */
|
||||
#define FORMAT_INSTANCE b5g6r5
|
||||
#define FORMAT_HOW DI_16_B5_G6_R5
|
||||
|
||||
#define BLEND_TYPE unsigned short
|
||||
#define BLEND_READ(p,nr,ng,nb) \
|
||||
{ \
|
||||
unsigned short _s=p[0]; \
|
||||
nr=(_s>>11)<<3; \
|
||||
ng=((_s>>5)<<2)&0xff; \
|
||||
nb=(_s<<3)&0xff; \
|
||||
}
|
||||
#define BLEND_READ_ALPHA(p,pa,nr,ng,nb,na) \
|
||||
{ \
|
||||
unsigned short _s=p[0]; \
|
||||
nr=(_s>>11)<<3; \
|
||||
ng=((_s>>5)<<2)&0xff; \
|
||||
nb=(_s<<3)&0xff; \
|
||||
na=pa[0]; \
|
||||
}
|
||||
#define BLEND_WRITE(p,nr,ng,nb) p[0]=((nr>>3)<<11)|((ng>>2)<<5)|(nb>>3);
|
||||
#define BLEND_WRITE_ALPHA(p,pa,nr,ng,nb,na) p[0]=((nr>>3)<<11)|((ng>>2)<<5)|(nb>>3); pa[0]=na;
|
||||
#define BLEND_INC(p) p++;
|
||||
|
||||
#define ALPHA_READ(s,sa,d) d=sa[0];
|
||||
#define ALPHA_INC(s,sa) s++; sa++;
|
||||
|
||||
#define COPY_TYPE unsigned short
|
||||
#define COPY_TYPE_PIXEL(a) unsigned short a;
|
||||
#define COPY_ASSEMBLE_PIXEL(v,r,g,b) v=((r>>3)<<11)|((g>>2)<<5)|(b>>3);
|
||||
#define COPY_WRITE(dst,v) dst[0]=v;
|
||||
#define COPY_INC(dst) dst++;
|
||||
|
||||
#include "blit.m"
|
||||
#undef FORMAT_INSTANCE
|
||||
|
||||
|
||||
/* 16-bit 5 bits blue, 5 bits green, 5 bits red */
|
||||
#define FORMAT_INSTANCE b5g5r5a1
|
||||
#define FORMAT_HOW DI_16_B5_G5_R5_A1
|
||||
|
||||
#define BLEND_TYPE unsigned short
|
||||
#define BLEND_READ(p,nr,ng,nb) \
|
||||
{ \
|
||||
unsigned short _s=p[0]; \
|
||||
nr=(_s>>10)<<3; \
|
||||
ng=((_s>>5)<<3)&0xff; \
|
||||
nb=(_s<<3)&0xff; \
|
||||
}
|
||||
#define BLEND_READ_ALPHA(p,pa,nr,ng,nb,na) \
|
||||
{ \
|
||||
unsigned short _s=p[0]; \
|
||||
nr=(_s>>10)<<3; \
|
||||
ng=((_s>>5)<<3)&0xff; \
|
||||
nb=(_s<<3)&0xff; \
|
||||
na=pa[0]; \
|
||||
}
|
||||
#define BLEND_WRITE(p,nr,ng,nb) p[0]=((nr>>3)<<10)+((ng>>3)<<5)+(nb>>3);
|
||||
#define BLEND_WRITE_ALPHA(p,pa,nr,ng,nb,na) p[0]=((nr>>3)<<10)+((ng>>3)<<5)+(nb>>3); pa[0]=na;
|
||||
#define BLEND_INC(p) p++;
|
||||
|
||||
#define ALPHA_READ(s,sa,d) d=sa[0];
|
||||
#define ALPHA_INC(s,sa) s++; sa++;
|
||||
|
||||
#define COPY_TYPE unsigned short
|
||||
#define COPY_TYPE_PIXEL(a) unsigned short a;
|
||||
#define COPY_ASSEMBLE_PIXEL(v,r,g,b) v=((r>>3)<<10)|((g>>3)<<5)|(b>>3);
|
||||
#define COPY_WRITE(dst,v) dst[0]=v;
|
||||
#define COPY_INC(dst) dst++;
|
||||
|
||||
#include "blit.m"
|
||||
#undef FORMAT_INSTANCE
|
||||
|
||||
/* end of pixel formats */
|
||||
|
||||
|
||||
static draw_info_t draw_infos[DI_NUM] = {
|
||||
|
||||
#define C(x) \
|
||||
NPRE(run_alpha,x), \
|
||||
NPRE(run_opaque,x), \
|
||||
NPRE(run_alpha_a,x), \
|
||||
NPRE(run_opaque_a,x), \
|
||||
NPRE(blit_alpha_opaque,x), \
|
||||
NPRE(blit_mono_opaque,x), \
|
||||
NPRE(blit_alpha,x), \
|
||||
NPRE(blit_mono,x), \
|
||||
NPRE(blit_alpha_a,x), \
|
||||
NPRE(blit_mono_a,x), \
|
||||
\
|
||||
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), \
|
||||
NPRE(sin_oa,x), \
|
||||
NPRE(sout_aa,x), \
|
||||
NPRE(sout_oa,x), \
|
||||
NPRE(satop_aa,x), \
|
||||
NPRE(dover_aa,x), \
|
||||
NPRE(dover_oa,x), \
|
||||
NPRE(din_aa,x), \
|
||||
NPRE(dout_aa,x), \
|
||||
NPRE(datop_aa,x), \
|
||||
NPRE(xor_aa,x), \
|
||||
NPRE(plusl_aa,x), \
|
||||
NPRE(plusl_oa,x), \
|
||||
NPRE(plusl_ao_oo,x), \
|
||||
NPRE(plusl_ao_oo,x), \
|
||||
NPRE(plusd_aa,x), \
|
||||
NPRE(plusd_oa,x), \
|
||||
NPRE(plusd_ao_oo,x), \
|
||||
NPRE(plusd_ao_oo,x), \
|
||||
NPRE(dissolve_aa,x), \
|
||||
NPRE(dissolve_oa,x), \
|
||||
NPRE(dissolve_ao,x), \
|
||||
NPRE(dissolve_oo,x),
|
||||
|
||||
/* TODO: try to implement fallback versions? possible? */
|
||||
{DI_FALLBACK ,0, 0,0,-1,/*C(fallback)*/},
|
||||
|
||||
{DI_16_B5_G5_R5_A1 ,2,15,0,-1,C(b5g5r5a1)},
|
||||
{DI_16_B5_G6_R5 ,2,16,0,-1,C(b5g6r5)},
|
||||
{DI_24_RGB ,3,24,0,-1,C(rgb)},
|
||||
{DI_24_BGR ,3,24,0,-1,C(bgr)},
|
||||
/* ARTContext.m assumes that only 32-bit modes have inline alpha. this
|
||||
might eventually need to be fixed */
|
||||
{DI_32_RGBA ,4,24,1, 3,C(rgba)},
|
||||
{DI_32_BGRA ,4,24,1, 3,C(bgra)},
|
||||
{DI_32_ARGB ,4,24,1, 0,C(argb)},
|
||||
{DI_32_ABGR ,4,24,1, 0,C(abgr)},
|
||||
};
|
||||
|
||||
|
||||
|
||||
static int byte_ofs_of_mask(unsigned int m)
|
||||
{
|
||||
union
|
||||
{
|
||||
unsigned char b[4];
|
||||
unsigned int m;
|
||||
} tmp;
|
||||
|
||||
tmp.m = m;
|
||||
if (tmp.b[0] == 0xff && !tmp.b[1] && !tmp.b[2] && !tmp.b[3])
|
||||
return 0;
|
||||
else if (tmp.b[1] == 0xff && !tmp.b[0] && !tmp.b[2] && !tmp.b[3])
|
||||
return 1;
|
||||
else if (tmp.b[2] == 0xff && !tmp.b[0] && !tmp.b[1] && !tmp.b[3])
|
||||
return 2;
|
||||
else if (tmp.b[3] == 0xff && !tmp.b[0] && !tmp.b[1] && !tmp.b[2])
|
||||
return 3;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
#include <Foundation/NSUserDefaults.h>
|
||||
|
||||
void artcontext_setup_draw_info(draw_info_t *di,
|
||||
unsigned int red_mask, unsigned int green_mask, unsigned int blue_mask,
|
||||
int bpp)
|
||||
{
|
||||
int t = DI_FALLBACK;
|
||||
|
||||
NSDebugLLog(@"back-art", @"%s masks=(%08x %08x %08x) bpp=%i",
|
||||
__PRETTY_FUNCTION__, red_mask, green_mask, blue_mask, bpp);
|
||||
|
||||
if (bpp == 16 && red_mask == 0xf800 && green_mask == 0x7e0 &&
|
||||
blue_mask == 0x1f)
|
||||
{
|
||||
t = DI_16_B5_G6_R5;
|
||||
}
|
||||
else if (bpp == 16 && red_mask == 0x7c00 && green_mask == 0x3e0 &&
|
||||
blue_mask == 0x1f)
|
||||
{
|
||||
t = DI_16_B5_G5_R5_A1;
|
||||
}
|
||||
else if (bpp == 24 || bpp == 32)
|
||||
{
|
||||
int r, g, b;
|
||||
|
||||
r = byte_ofs_of_mask(red_mask);
|
||||
g = byte_ofs_of_mask(green_mask);
|
||||
b = byte_ofs_of_mask(blue_mask);
|
||||
|
||||
if (bpp == 24)
|
||||
{
|
||||
if (r == 0 && g == 1 && b == 2)
|
||||
t = DI_24_RGB;
|
||||
else if (r == 2 && g == 1 && b == 0)
|
||||
t = DI_24_BGR;
|
||||
}
|
||||
else if (bpp == 32)
|
||||
{
|
||||
if (r == 0 && g == 1 && b == 2)
|
||||
t = DI_32_RGBA;
|
||||
else if (r == 2 && g == 1 && b == 0)
|
||||
t = DI_32_BGRA;
|
||||
else if (r == 1 && g == 2 && b == 3)
|
||||
t = DI_32_ARGB;
|
||||
else if (r == 3 && g == 2 && b == 1)
|
||||
t = DI_32_ABGR;
|
||||
}
|
||||
}
|
||||
|
||||
NSDebugLLog(@"back-art", @"got t=%i", t);
|
||||
|
||||
*di = draw_infos[t];
|
||||
if (!di->render_run_alpha)
|
||||
*di = draw_infos[DI_FALLBACK];
|
||||
if (di->how == DI_FALLBACK)
|
||||
{
|
||||
NSLog(@"gnustep-back(art): Unrecognized color masks: %08x:%08x:%08x %i",
|
||||
red_mask, green_mask, blue_mask, bpp);
|
||||
NSLog(@"Please report this along with details on your pixel format "
|
||||
@"(ie. the four numbers above) to bug-gnustep@gnu.org."
|
||||
@"Better: implement it and send a patch.)");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
{
|
||||
float gamma = [[NSUserDefaults standardUserDefaults]
|
||||
floatForKey: @"back-art-text-gamma"];
|
||||
int i;
|
||||
if (!gamma)
|
||||
gamma = 1.4;
|
||||
|
||||
NSDebugLLog(@"back-art",@"gamma=%g",gamma);
|
||||
|
||||
gamma = 1.0 / gamma;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
gamma_table[i] = pow(i / 255.0, gamma) * 255 + .5;
|
||||
inv_gamma_table[i] = pow(i / 255.0, 1.0 / gamma) * 255 + .5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
compositing: source opaque/dest. opaque
|
||||
00 01 10 11
|
||||
Clear 0 0 +ab, clear
|
||||
Copy 1 0 copy all +ab, copy copy copy
|
||||
|
||||
Sover 1 1 - srcA impl impl copy copy
|
||||
Sin dstA 0 impl +ab, copy impl copy
|
||||
Sout 1 - dstA 0 impl clear impl clear
|
||||
Satop dstA 1 - srcA impl Sover 01 Sin 10 copy
|
||||
|
||||
Dover 1 - dstA 1 impl noop impl noop
|
||||
Din 0 srcA impl +ab, 00 noop noop
|
||||
Dout 0 1 - srcA impl +ab, 00 clear clear
|
||||
Datop 1 - dstA srcA impl +ab, 00 Dover 10 noop
|
||||
|
||||
Xor 1 - dstA 1 - srcA impl +ab, 00 Sout 10 clear
|
||||
|
||||
PlusL impl impl impl impl
|
||||
dst=dst+src, dsta=dsta+srca
|
||||
|
||||
PlusD impl impl impl impl
|
||||
dst=dst+src-1, dsta=dsta+srca
|
||||
|
||||
|
||||
compositing (source transparent) dest. opaque
|
||||
0 1
|
||||
Clear 0 0 clear clear
|
||||
Copy 1 0 clear clear
|
||||
|
||||
Sover 1 1 - srcA noop noop
|
||||
Sin dstA 0 clear clear
|
||||
Sout 1 - dstA 0 clear clear
|
||||
Satop dstA 1 - srcA noop noop
|
||||
|
||||
Dover 1 - dstA 1 noop noop
|
||||
Din 0 srcA clear clear
|
||||
Dout 0 1 - srcA noop noop
|
||||
Datop 1 - dstA srcA clear clear
|
||||
|
||||
Xor 1 - dstA 1 - srcA noop noop
|
||||
|
||||
|
||||
|
||||
PlusL dst=src+dst , clamp to 1.0; dsta=srca+dsta, clamp to 1.0
|
||||
PlusD dst=src+dst-1, clamp to 0.0; dsta=srca+dsta, clamp to 1.0
|
||||
|
||||
*/
|
|
@ -20,22 +20,6 @@
|
|||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file includes itself. Many times. You have been warned.
|
||||
*/
|
||||
|
||||
#ifndef FORMAT_INSTANCE
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <Foundation/NSDebug.h>
|
||||
|
||||
#include "blit.h"
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
TODO: rounding of alpha is wrong in many places, ie. an alpha of 255 is
|
||||
treated as an alpha of 255/256 instead of 255/255. The
|
||||
|
@ -62,29 +46,12 @@ TODO: more cpp magic to reduce the amount of code?
|
|||
|
||||
|
||||
/*
|
||||
First attempt at gamma correction. Only used in text rendering (blit_*),
|
||||
but that's where it's needed the most. The gamma adjustment is a large
|
||||
hack, but the results are good.
|
||||
*/
|
||||
static unsigned char gamma_table[256],inv_gamma_table[256];
|
||||
|
||||
|
||||
#define NPRE(r, pre) pre##_##r
|
||||
|
||||
|
||||
|
||||
#ifdef FORMAT_INSTANCE
|
||||
|
||||
/*
|
||||
Define the different blitting functions. This is the important part when
|
||||
the file includes itself. Each blitter is defined once for each format
|
||||
Define the different blitting functions.
|
||||
Each blitter is defined once for each format
|
||||
using the different helper macros (or specially optimized functions in
|
||||
some cases).
|
||||
*/
|
||||
|
||||
#define M2PRE(a, b) NPRE(a, b)
|
||||
#define MPRE(r) M2PRE(r, FORMAT_INSTANCE)
|
||||
|
||||
|
||||
static void MPRE(blit_alpha_opaque) (unsigned char *adst,
|
||||
const unsigned char *asrc,
|
||||
|
@ -1517,502 +1484,4 @@ static void MPRE(dissolve_oo) (composite_run_t *c, int num)
|
|||
#undef FORMAT_HOW
|
||||
#undef INLINE_ALPHA
|
||||
|
||||
#else
|
||||
|
||||
|
||||
/*
|
||||
For each supported pixel format we define a bunch of macros and include
|
||||
ourself.
|
||||
*/
|
||||
|
||||
|
||||
/* 24-bit red green blue */
|
||||
#define FORMAT_INSTANCE rgb
|
||||
#define FORMAT_HOW DI_24_RGB
|
||||
|
||||
#define BLEND_TYPE unsigned char
|
||||
#define BLEND_READ(p,nr,ng,nb) nr=p[0]; ng=p[1]; nb=p[2];
|
||||
#define BLEND_READ_ALPHA(p,pa,nr,ng,nb,na) nr=p[0]; ng=p[1]; nb=p[2]; na=pa[0];
|
||||
#define BLEND_WRITE(p,nr,ng,nb) p[0]=nr; p[1]=ng; p[2]=nb;
|
||||
#define BLEND_WRITE_ALPHA(p,pa,nr,ng,nb,na) p[0]=nr; p[1]=ng; p[2]=nb; pa[0]=na;
|
||||
#define BLEND_INC(p) p+=3;
|
||||
|
||||
#define ALPHA_READ(s,sa,d) d=sa[0];
|
||||
#define ALPHA_INC(s,sa) s+=3; sa++;
|
||||
|
||||
#define COPY_TYPE unsigned char
|
||||
#define COPY_TYPE_PIXEL(a) unsigned char a[3];
|
||||
#define COPY_ASSEMBLE_PIXEL(v,r,g,b) v[0]=r; v[1]=g; v[2]=b;
|
||||
#define COPY_WRITE(dst,v) dst[0]=v[0]; dst[1]=v[1]; dst[2]=v[2];
|
||||
#define COPY_INC(dst) dst+=3;
|
||||
|
||||
#include "blit.m"
|
||||
|
||||
#undef FORMAT_INSTANCE
|
||||
|
||||
|
||||
/* 24-bit blue green red */
|
||||
#define FORMAT_INSTANCE bgr
|
||||
#define FORMAT_HOW DI_24_BGR
|
||||
|
||||
#define BLEND_TYPE unsigned char
|
||||
#define BLEND_READ(p,nr,ng,nb) nb=p[0]; ng=p[1]; nr=p[2];
|
||||
#define BLEND_READ_ALPHA(p,pa,nr,ng,nb,na) nb=p[0]; ng=p[1]; nr=p[2]; na=pa[0];
|
||||
#define BLEND_WRITE(p,nr,ng,nb) p[0]=nb; p[1]=ng; p[2]=nr;
|
||||
#define BLEND_WRITE_ALPHA(p,pa,nr,ng,nb,na) p[0]=nb; p[1]=ng; p[2]=nr; pa[0]=na;
|
||||
#define BLEND_INC(p) p+=3;
|
||||
|
||||
#define ALPHA_READ(s,sa,d) d=sa[0];
|
||||
#define ALPHA_INC(s,sa) s+=3; sa++;
|
||||
|
||||
#define COPY_TYPE unsigned char
|
||||
#define COPY_TYPE_PIXEL(a) unsigned char a[3];
|
||||
#define COPY_ASSEMBLE_PIXEL(v,r,g,b) v[0]=b; v[1]=g; v[2]=r;
|
||||
#define COPY_WRITE(dst,v) dst[0]=v[0]; dst[1]=v[1]; dst[2]=v[2];
|
||||
#define COPY_INC(dst) dst+=3;
|
||||
|
||||
#include "blit.m"
|
||||
|
||||
#undef FORMAT_INSTANCE
|
||||
|
||||
|
||||
/* 32-bit red green blue alpha */
|
||||
#define FORMAT_INSTANCE rgba
|
||||
#define FORMAT_HOW DI_32_RGBA
|
||||
|
||||
#define INLINE_ALPHA
|
||||
|
||||
#define BLEND_TYPE unsigned char
|
||||
#define BLEND_READ(p,nr,ng,nb) nr=p[0]; ng=p[1]; nb=p[2];
|
||||
#define BLEND_READ_ALPHA(p,pa,nr,ng,nb,na) nr=p[0]; ng=p[1]; nb=p[2]; na=p[3];
|
||||
#define BLEND_WRITE(p,nr,ng,nb) p[0]=nr; p[1]=ng; p[2]=nb;
|
||||
#define BLEND_WRITE_ALPHA(p,pa,nr,ng,nb,na) p[0]=nr; p[1]=ng; p[2]=nb; p[3]=na;
|
||||
#define BLEND_INC(p) p+=4;
|
||||
|
||||
#define ALPHA_READ(s,sa,d) d=s[3];
|
||||
#define ALPHA_INC(s,sa) s+=4;
|
||||
|
||||
#define COPY_TYPE unsigned int
|
||||
#define COPY_TYPE_PIXEL(a) unsigned int a;
|
||||
#if GS_WORDS_BIGENDIAN
|
||||
#define COPY_ASSEMBLE_PIXEL(v,r,g,b) v=(r<<24)|(g<<16)|(b<<8);
|
||||
#define COPY_ASSEMBLE_PIXEL_ALPHA(v,r,g,b,a) v=(r<<24)|(g<<16)|(b<<8)|(a);
|
||||
#else
|
||||
#define COPY_ASSEMBLE_PIXEL(v,r,g,b) v=(b<<16)|(g<<8)|(r<<0);
|
||||
#define COPY_ASSEMBLE_PIXEL_ALPHA(v,r,g,b,a) v=(b<<16)|(g<<8)|(r<<0)|(a<<24);
|
||||
#endif
|
||||
#define COPY_WRITE(dst,v) dst[0]=v;
|
||||
#define COPY_INC(dst) dst++;
|
||||
|
||||
#include "blit.m"
|
||||
|
||||
#undef FORMAT_INSTANCE
|
||||
|
||||
|
||||
/* 32-bit blue green red alpha */
|
||||
#define FORMAT_INSTANCE bgra
|
||||
#define FORMAT_HOW DI_32_BGRA
|
||||
|
||||
#define INLINE_ALPHA
|
||||
|
||||
#define BLEND_TYPE unsigned char
|
||||
#define BLEND_READ(p,nr,ng,nb) nb=p[0]; ng=p[1]; nr=p[2];
|
||||
#define BLEND_READ_ALPHA(p,pa,nr,ng,nb,na) nb=p[0]; ng=p[1]; nr=p[2]; na=p[3];
|
||||
#define BLEND_WRITE(p,nr,ng,nb) p[0]=nb; p[1]=ng; p[2]=nr;
|
||||
#define BLEND_WRITE_ALPHA(p,pa,nr,ng,nb,na) p[0]=nb; p[1]=ng; p[2]=nr; p[3]=na;
|
||||
#define BLEND_INC(p) p+=4;
|
||||
|
||||
#define ALPHA_READ(s,sa,d) d=s[3];
|
||||
#define ALPHA_INC(s,sa) s+=4;
|
||||
|
||||
#define COPY_TYPE unsigned int
|
||||
#define COPY_TYPE_PIXEL(a) unsigned int a;
|
||||
#if GS_WORDS_BIGENDIAN
|
||||
#define COPY_ASSEMBLE_PIXEL(v,r,g,b) v=(b<<24)|(g<<16)|(r<<8);
|
||||
#define COPY_ASSEMBLE_PIXEL_ALPHA(v,r,g,b,a) v=(b<<24)|(g<<16)|(r<<8)|(a);
|
||||
#else
|
||||
#define COPY_ASSEMBLE_PIXEL(v,r,g,b) v=(r<<16)|(g<<8)|(b<<0);
|
||||
#define COPY_ASSEMBLE_PIXEL_ALPHA(v,r,g,b,a) v=(r<<16)|(g<<8)|(b<<0)|(a<<24);
|
||||
#endif
|
||||
#define COPY_WRITE(dst,v) dst[0]=v;
|
||||
#define COPY_INC(dst) dst++;
|
||||
|
||||
#include "blit.m"
|
||||
|
||||
#undef FORMAT_INSTANCE
|
||||
|
||||
|
||||
/* 32-bit alpha red green blue */
|
||||
#define FORMAT_INSTANCE argb
|
||||
#define FORMAT_HOW DI_32_ARGB
|
||||
|
||||
#define INLINE_ALPHA
|
||||
|
||||
#define BLEND_TYPE unsigned char
|
||||
#define BLEND_READ(p,nr,ng,nb) nr=p[1]; ng=p[2]; nb=p[3];
|
||||
#define BLEND_READ_ALPHA(p,pa,nr,ng,nb,na) nr=p[1]; ng=p[2]; nb=p[3]; na=p[0];
|
||||
#define BLEND_WRITE(p,nr,ng,nb) p[1]=nr; p[2]=ng; p[3]=nb;
|
||||
#define BLEND_WRITE_ALPHA(p,pa,nr,ng,nb,na) p[1]=nr; p[2]=ng; p[3]=nb; p[0]=na;
|
||||
#define BLEND_INC(p) p+=4;
|
||||
|
||||
#define ALPHA_READ(s,sa,d) d=s[0];
|
||||
#define ALPHA_INC(s,sa) s+=4;
|
||||
|
||||
#define COPY_TYPE unsigned int
|
||||
#define COPY_TYPE_PIXEL(a) unsigned int a;
|
||||
#if GS_WORDS_BIGENDIAN
|
||||
#define COPY_ASSEMBLE_PIXEL(v,r,g,b) v=(r<<16)|(g<<8)|(b<<0);
|
||||
#define COPY_ASSEMBLE_PIXEL_ALPHA(v,r,g,b,a) v=(r<<16)|(g<<8)|(b<<0)|(a<<24);
|
||||
#else
|
||||
#define COPY_ASSEMBLE_PIXEL(v,r,g,b) v=(b<<24)|(g<<16)|(r<<8);
|
||||
#define COPY_ASSEMBLE_PIXEL_ALPHA(v,r,g,b,a) v=(b<<24)|(g<<16)|(r<<8)|(a);
|
||||
#endif
|
||||
#define COPY_WRITE(dst,v) dst[0]=v;
|
||||
#define COPY_INC(dst) dst++;
|
||||
|
||||
#include "blit.m"
|
||||
|
||||
#undef FORMAT_INSTANCE
|
||||
|
||||
|
||||
/* 32-bit alpha blue green red */
|
||||
#define FORMAT_INSTANCE abgr
|
||||
#define FORMAT_HOW DI_32_ABGR
|
||||
|
||||
#define INLINE_ALPHA
|
||||
|
||||
#define BLEND_TYPE unsigned char
|
||||
#define BLEND_READ(p,nr,ng,nb) nb=p[1]; ng=p[2]; nr=p[3];
|
||||
#define BLEND_READ_ALPHA(p,pa,nr,ng,nb,na) nb=p[1]; ng=p[2]; nr=p[3]; na=p[0];
|
||||
#define BLEND_WRITE(p,nr,ng,nb) p[1]=nb; p[2]=ng; p[3]=nr;
|
||||
#define BLEND_WRITE_ALPHA(p,pa,nr,ng,nb,na) p[1]=nb; p[2]=ng; p[3]=nr; p[0]=na;
|
||||
#define BLEND_INC(p) p+=4;
|
||||
|
||||
#define ALPHA_READ(s,sa,d) d=s[0];
|
||||
#define ALPHA_INC(s,sa) s+=4;
|
||||
|
||||
#define COPY_TYPE unsigned int
|
||||
#define COPY_TYPE_PIXEL(a) unsigned int a;
|
||||
#if GS_WORDS_BIGENDIAN
|
||||
#define COPY_ASSEMBLE_PIXEL(v,r,g,b) v=(b<<16)|(g<<8)|(r<<0);
|
||||
#define COPY_ASSEMBLE_PIXEL_ALPHA(v,r,g,b,a) v=(b<<16)|(g<<8)|(r<<0)|(a<<24);
|
||||
#else
|
||||
#define COPY_ASSEMBLE_PIXEL(v,r,g,b) v=(r<<24)|(g<<16)|(b<<8);
|
||||
#define COPY_ASSEMBLE_PIXEL_ALPHA(v,r,g,b,a) v=(r<<24)|(g<<16)|(b<<8)|(a);
|
||||
#endif
|
||||
#define COPY_WRITE(dst,v) dst[0]=v;
|
||||
#define COPY_INC(dst) dst++;
|
||||
|
||||
#include "blit.m"
|
||||
|
||||
#undef FORMAT_INSTANCE
|
||||
|
||||
|
||||
/* 16-bit 5 bits blue, 6 bits green, 5 bits red */
|
||||
#define FORMAT_INSTANCE b5g6r5
|
||||
#define FORMAT_HOW DI_16_B5_G6_R5
|
||||
|
||||
#define BLEND_TYPE unsigned short
|
||||
#define BLEND_READ(p,nr,ng,nb) \
|
||||
{ \
|
||||
unsigned short _s=p[0]; \
|
||||
nr=(_s>>11)<<3; \
|
||||
ng=((_s>>5)<<2)&0xff; \
|
||||
nb=(_s<<3)&0xff; \
|
||||
}
|
||||
#define BLEND_READ_ALPHA(p,pa,nr,ng,nb,na) \
|
||||
{ \
|
||||
unsigned short _s=p[0]; \
|
||||
nr=(_s>>11)<<3; \
|
||||
ng=((_s>>5)<<2)&0xff; \
|
||||
nb=(_s<<3)&0xff; \
|
||||
na=pa[0]; \
|
||||
}
|
||||
#define BLEND_WRITE(p,nr,ng,nb) p[0]=((nr>>3)<<11)|((ng>>2)<<5)|(nb>>3);
|
||||
#define BLEND_WRITE_ALPHA(p,pa,nr,ng,nb,na) p[0]=((nr>>3)<<11)|((ng>>2)<<5)|(nb>>3); pa[0]=na;
|
||||
#define BLEND_INC(p) p++;
|
||||
|
||||
#define ALPHA_READ(s,sa,d) d=sa[0];
|
||||
#define ALPHA_INC(s,sa) s++; sa++;
|
||||
|
||||
#define COPY_TYPE unsigned short
|
||||
#define COPY_TYPE_PIXEL(a) unsigned short a;
|
||||
#define COPY_ASSEMBLE_PIXEL(v,r,g,b) v=((r>>3)<<11)|((g>>2)<<5)|(b>>3);
|
||||
#define COPY_WRITE(dst,v) dst[0]=v;
|
||||
#define COPY_INC(dst) dst++;
|
||||
|
||||
#include "blit.m"
|
||||
#undef FORMAT_INSTANCE
|
||||
|
||||
|
||||
/* 16-bit 5 bits blue, 5 bits green, 5 bits red */
|
||||
#define FORMAT_INSTANCE b5g5r5a1
|
||||
#define FORMAT_HOW DI_16_B5_G5_R5_A1
|
||||
|
||||
#define BLEND_TYPE unsigned short
|
||||
#define BLEND_READ(p,nr,ng,nb) \
|
||||
{ \
|
||||
unsigned short _s=p[0]; \
|
||||
nr=(_s>>10)<<3; \
|
||||
ng=((_s>>5)<<3)&0xff; \
|
||||
nb=(_s<<3)&0xff; \
|
||||
}
|
||||
#define BLEND_READ_ALPHA(p,pa,nr,ng,nb,na) \
|
||||
{ \
|
||||
unsigned short _s=p[0]; \
|
||||
nr=(_s>>10)<<3; \
|
||||
ng=((_s>>5)<<3)&0xff; \
|
||||
nb=(_s<<3)&0xff; \
|
||||
na=pa[0]; \
|
||||
}
|
||||
#define BLEND_WRITE(p,nr,ng,nb) p[0]=((nr>>3)<<10)+((ng>>3)<<5)+(nb>>3);
|
||||
#define BLEND_WRITE_ALPHA(p,pa,nr,ng,nb,na) p[0]=((nr>>3)<<10)+((ng>>3)<<5)+(nb>>3); pa[0]=na;
|
||||
#define BLEND_INC(p) p++;
|
||||
|
||||
#define ALPHA_READ(s,sa,d) d=sa[0];
|
||||
#define ALPHA_INC(s,sa) s++; sa++;
|
||||
|
||||
#define COPY_TYPE unsigned short
|
||||
#define COPY_TYPE_PIXEL(a) unsigned short a;
|
||||
#define COPY_ASSEMBLE_PIXEL(v,r,g,b) v=((r>>3)<<10)|((g>>3)<<5)|(b>>3);
|
||||
#define COPY_WRITE(dst,v) dst[0]=v;
|
||||
#define COPY_INC(dst) dst++;
|
||||
|
||||
#include "blit.m"
|
||||
#undef FORMAT_INSTANCE
|
||||
|
||||
/* end of pixel formats */
|
||||
|
||||
|
||||
static draw_info_t draw_infos[DI_NUM] = {
|
||||
|
||||
#define C(x) \
|
||||
NPRE(run_alpha,x), \
|
||||
NPRE(run_opaque,x), \
|
||||
NPRE(run_alpha_a,x), \
|
||||
NPRE(run_opaque_a,x), \
|
||||
NPRE(blit_alpha_opaque,x), \
|
||||
NPRE(blit_mono_opaque,x), \
|
||||
NPRE(blit_alpha,x), \
|
||||
NPRE(blit_mono,x), \
|
||||
NPRE(blit_alpha_a,x), \
|
||||
NPRE(blit_mono_a,x), \
|
||||
\
|
||||
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), \
|
||||
NPRE(sin_oa,x), \
|
||||
NPRE(sout_aa,x), \
|
||||
NPRE(sout_oa,x), \
|
||||
NPRE(satop_aa,x), \
|
||||
NPRE(dover_aa,x), \
|
||||
NPRE(dover_oa,x), \
|
||||
NPRE(din_aa,x), \
|
||||
NPRE(dout_aa,x), \
|
||||
NPRE(datop_aa,x), \
|
||||
NPRE(xor_aa,x), \
|
||||
NPRE(plusl_aa,x), \
|
||||
NPRE(plusl_oa,x), \
|
||||
NPRE(plusl_ao_oo,x), \
|
||||
NPRE(plusl_ao_oo,x), \
|
||||
NPRE(plusd_aa,x), \
|
||||
NPRE(plusd_oa,x), \
|
||||
NPRE(plusd_ao_oo,x), \
|
||||
NPRE(plusd_ao_oo,x), \
|
||||
NPRE(dissolve_aa,x), \
|
||||
NPRE(dissolve_oa,x), \
|
||||
NPRE(dissolve_ao,x), \
|
||||
NPRE(dissolve_oo,x),
|
||||
|
||||
/* TODO: try to implement fallback versions? possible? */
|
||||
{DI_FALLBACK ,0, 0,0,-1,/*C(fallback)*/},
|
||||
|
||||
{DI_16_B5_G5_R5_A1 ,2,15,0,-1,C(b5g5r5a1)},
|
||||
{DI_16_B5_G6_R5 ,2,16,0,-1,C(b5g6r5)},
|
||||
{DI_24_RGB ,3,24,0,-1,C(rgb)},
|
||||
{DI_24_BGR ,3,24,0,-1,C(bgr)},
|
||||
/* ARTContext.m assumes that only 32-bit modes have inline alpha. this
|
||||
might eventually need to be fixed */
|
||||
{DI_32_RGBA ,4,24,1, 3,C(rgba)},
|
||||
{DI_32_BGRA ,4,24,1, 3,C(bgra)},
|
||||
{DI_32_ARGB ,4,24,1, 0,C(argb)},
|
||||
{DI_32_ABGR ,4,24,1, 0,C(abgr)},
|
||||
};
|
||||
|
||||
|
||||
|
||||
static int byte_ofs_of_mask(unsigned int m)
|
||||
{
|
||||
union
|
||||
{
|
||||
unsigned char b[4];
|
||||
unsigned int m;
|
||||
} tmp;
|
||||
|
||||
tmp.m = m;
|
||||
if (tmp.b[0] == 0xff && !tmp.b[1] && !tmp.b[2] && !tmp.b[3])
|
||||
return 0;
|
||||
else if (tmp.b[1] == 0xff && !tmp.b[0] && !tmp.b[2] && !tmp.b[3])
|
||||
return 1;
|
||||
else if (tmp.b[2] == 0xff && !tmp.b[0] && !tmp.b[1] && !tmp.b[3])
|
||||
return 2;
|
||||
else if (tmp.b[3] == 0xff && !tmp.b[0] && !tmp.b[1] && !tmp.b[2])
|
||||
return 3;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
#include <Foundation/NSUserDefaults.h>
|
||||
|
||||
void artcontext_setup_draw_info(draw_info_t *di,
|
||||
unsigned int red_mask, unsigned int green_mask, unsigned int blue_mask,
|
||||
int bpp)
|
||||
{
|
||||
int t = DI_FALLBACK;
|
||||
|
||||
NSDebugLLog(@"back-art", @"%s masks=(%08x %08x %08x) bpp=%i",
|
||||
__PRETTY_FUNCTION__, red_mask, green_mask, blue_mask, bpp);
|
||||
|
||||
if (bpp == 16 && red_mask == 0xf800 && green_mask == 0x7e0 &&
|
||||
blue_mask == 0x1f)
|
||||
{
|
||||
t = DI_16_B5_G6_R5;
|
||||
}
|
||||
else if (bpp == 16 && red_mask == 0x7c00 && green_mask == 0x3e0 &&
|
||||
blue_mask == 0x1f)
|
||||
{
|
||||
t = DI_16_B5_G5_R5_A1;
|
||||
}
|
||||
else if (bpp == 24 || bpp == 32)
|
||||
{
|
||||
int r, g, b;
|
||||
|
||||
r = byte_ofs_of_mask(red_mask);
|
||||
g = byte_ofs_of_mask(green_mask);
|
||||
b = byte_ofs_of_mask(blue_mask);
|
||||
|
||||
if (bpp == 24)
|
||||
{
|
||||
if (r == 0 && g == 1 && b == 2)
|
||||
t = DI_24_RGB;
|
||||
else if (r == 2 && g == 1 && b == 0)
|
||||
t = DI_24_BGR;
|
||||
}
|
||||
else if (bpp == 32)
|
||||
{
|
||||
if (r == 0 && g == 1 && b == 2)
|
||||
t = DI_32_RGBA;
|
||||
else if (r == 2 && g == 1 && b == 0)
|
||||
t = DI_32_BGRA;
|
||||
else if (r == 1 && g == 2 && b == 3)
|
||||
t = DI_32_ARGB;
|
||||
else if (r == 3 && g == 2 && b == 1)
|
||||
t = DI_32_ABGR;
|
||||
}
|
||||
}
|
||||
|
||||
NSDebugLLog(@"back-art", @"got t=%i", t);
|
||||
|
||||
*di = draw_infos[t];
|
||||
if (!di->render_run_alpha)
|
||||
*di = draw_infos[DI_FALLBACK];
|
||||
if (di->how == DI_FALLBACK)
|
||||
{
|
||||
NSLog(@"gnustep-back(art): Unrecognized color masks: %08x:%08x:%08x %i",
|
||||
red_mask, green_mask, blue_mask, bpp);
|
||||
NSLog(@"Please report this along with details on your pixel format "
|
||||
@"(ie. the four numbers above) to bug-gnustep@gnu.org."
|
||||
@"Better: implement it and send a patch.)");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
{
|
||||
float gamma = [[NSUserDefaults standardUserDefaults]
|
||||
floatForKey: @"back-art-text-gamma"];
|
||||
int i;
|
||||
if (!gamma)
|
||||
gamma = 1.4;
|
||||
|
||||
NSDebugLLog(@"back-art",@"gamma=%g",gamma);
|
||||
|
||||
gamma = 1.0 / gamma;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
gamma_table[i] = pow(i / 255.0, gamma) * 255 + .5;
|
||||
inv_gamma_table[i] = pow(i / 255.0, 1.0 / gamma) * 255 + .5;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
/* potentially interesting old implementations of stuff */
|
||||
|
||||
static void r5g6b5_blit_mono_opaque(
|
||||
/* ... */
|
||||
/* TODO: could optimize with a two-bit check and a four-way branch
|
||||
that writes two pixels in one go */
|
||||
/* ... */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
||||
compositing: source opaque/dest. opaque
|
||||
00 01 10 11
|
||||
Clear 0 0 +ab, clear
|
||||
Copy 1 0 copy all +ab, copy copy copy
|
||||
|
||||
Sover 1 1 - srcA impl impl copy copy
|
||||
Sin dstA 0 impl +ab, copy impl copy
|
||||
Sout 1 - dstA 0 impl clear impl clear
|
||||
Satop dstA 1 - srcA impl Sover 01 Sin 10 copy
|
||||
|
||||
Dover 1 - dstA 1 impl noop impl noop
|
||||
Din 0 srcA impl +ab, 00 noop noop
|
||||
Dout 0 1 - srcA impl +ab, 00 clear clear
|
||||
Datop 1 - dstA srcA impl +ab, 00 Dover 10 noop
|
||||
|
||||
Xor 1 - dstA 1 - srcA impl +ab, 00 Sout 10 clear
|
||||
|
||||
PlusL impl impl impl impl
|
||||
dst=dst+src, dsta=dsta+srca
|
||||
|
||||
PlusD impl impl impl impl
|
||||
dst=dst+src-1, dsta=dsta+srca
|
||||
|
||||
|
||||
compositing (source transparent) dest. opaque
|
||||
0 1
|
||||
Clear 0 0 clear clear
|
||||
Copy 1 0 clear clear
|
||||
|
||||
Sover 1 1 - srcA noop noop
|
||||
Sin dstA 0 clear clear
|
||||
Sout 1 - dstA 0 clear clear
|
||||
Satop dstA 1 - srcA noop noop
|
||||
|
||||
Dover 1 - dstA 1 noop noop
|
||||
Din 0 srcA clear clear
|
||||
Dout 0 1 - srcA noop noop
|
||||
Datop 1 - dstA srcA clear clear
|
||||
|
||||
Xor 1 - dstA 1 - srcA noop noop
|
||||
|
||||
|
||||
|
||||
PlusL dst=src+dst , clamp to 1.0; dsta=srca+dsta, clamp to 1.0
|
||||
PlusD dst=src+dst-1, clamp to 0.0; dsta=srca+dsta, clamp to 1.0
|
||||
|
||||
*/
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
windows are known to be totally opaque, we can optimize in many ways
|
||||
(see big table at the end of blit.m). Will set dst_need_alpha and blit_func
|
||||
if necessary. Returns new operation, or -1 it it's a noop. */
|
||||
-(int) _composite_func: (BOOL)src_opaque : (BOOL)src_transparent
|
||||
- (int) _composite_func: (BOOL)src_opaque : (BOOL)src_transparent
|
||||
: (BOOL)dst_opaque : (BOOL *)dst_needs_alpha
|
||||
: (int)op : (void (**)(composite_run_t *c, int num))blit_func_r
|
||||
{
|
||||
|
@ -217,27 +217,28 @@ if necessary. Returns new operation, or -1 it it's a noop. */
|
|||
|
||||
static void copy_oo(composite_run_t *c, int num)
|
||||
{
|
||||
memcpy(c->dst,c->src,num*DI.bytes_per_pixel);
|
||||
memcpy(c->dst, c->src, num * DI.bytes_per_pixel);
|
||||
}
|
||||
|
||||
static void copy_oa(composite_run_t *c, int num)
|
||||
{
|
||||
memcpy(c->dst,c->src,num*DI.bytes_per_pixel);
|
||||
if (DI.inline_alpha)
|
||||
{
|
||||
unsigned char *dsta=c->dst+DI.inline_alpha_ofs;
|
||||
for (;num;num--,dsta+=4)
|
||||
*dsta=0xff;
|
||||
}
|
||||
else
|
||||
memset(c->dsta,0xff,num);
|
||||
memcpy(c->dst, c->src, num * DI.bytes_per_pixel);
|
||||
if (DI.inline_alpha)
|
||||
{
|
||||
unsigned char *dsta = c->dst + DI.inline_alpha_ofs;
|
||||
|
||||
for (; num; num--, dsta += 4)
|
||||
*dsta = 0xff;
|
||||
}
|
||||
else
|
||||
memset(c->dsta, 0xff, num);
|
||||
}
|
||||
|
||||
static void copy_aa(composite_run_t *c, int num)
|
||||
{
|
||||
memcpy(c->dst,c->src,num*DI.bytes_per_pixel);
|
||||
if (!DI.inline_alpha)
|
||||
memcpy(c->dsta,c->srca,num);
|
||||
memcpy(c->dst,c->src,num*DI.bytes_per_pixel);
|
||||
if (!DI.inline_alpha)
|
||||
memcpy(c->dsta, c->srca, num);
|
||||
}
|
||||
|
||||
|
||||
|
@ -453,7 +454,6 @@ static BOOL _rect_advance(rect_trace_t *t, int *x0, int *x1)
|
|||
if (!wi || !wi->data || !ags->wi || !ags->wi->data) return;
|
||||
if (all_clipped) return;
|
||||
|
||||
|
||||
{
|
||||
BOOL dst_needs_alpha;
|
||||
op = [self _composite_func: !ags->wi->has_alpha : NO
|
||||
|
|
Loading…
Reference in a new issue