Implement pattern colours for all backends.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@28850 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Fred Kiefer 2009-10-19 14:17:45 +00:00
parent d7dc549a3e
commit 3c8eab0c49
8 changed files with 361 additions and 9 deletions

View file

@ -1,3 +1,13 @@
2009-10-19 Fred Kiefer <FredKiefer@gmx.de>
* Headers/gsc/GSGStateOps.h,
* Source/gsc/GSGState.m,
* Source/art/path.m,
* Source/art/ARTGState.m,
* Source/cairo/CairoGState.m,
* Source/xlib/XGGState.m,
* Source/winlib/WIN32GState.m: Implement pattern colours for all backends.
2009-10-18 Richard Frith-Macdonald <rfm@gnu.org>
* Source/x11/XGServerWindow.m:

View file

@ -156,4 +156,14 @@
@end
@interface GSGState (PatternColor)
- (void *) saveClip;
- (void) restoreClip: (void *)savedClip;
- (void) fillRect: (NSRect)rect withPattern: (NSImage*)pattern;
- (void) fillPath: (NSBezierPath*)fillPath withPattern: (NSImage*)pattern;
- (void) eofillPath: (NSBezierPath*)fillPath withPattern: (NSImage*)pattern;
@end
#endif

View file

@ -650,3 +650,72 @@ draw_info_t ART_DI;
}
@end
@implementation ARTGState (PatternColor)
typedef struct _SavedClip {
int clip_x0,clip_y0,clip_x1,clip_y1;
BOOL all_clipped;
int clip_sx,clip_sy;
unsigned int *clip_span;
unsigned int *clip_index;
int clip_num_span;
} SavedClip;
- (void *) saveClip
{
SavedClip *savedClip = malloc(sizeof(SavedClip));
int i;
savedClip->clip_x0 = clip_x0;
savedClip->clip_y0 = clip_y0;
savedClip->clip_x1 = clip_x1;
savedClip->clip_y1 = clip_y1;
savedClip->all_clipped = all_clipped;
savedClip->clip_sx = clip_sx;
savedClip->clip_sy = clip_sy;
if (clip_num_span == 0)
{
savedClip->clip_span = NULL;
savedClip->clip_index = NULL;
}
else
{
savedClip->clip_span = malloc(sizeof(int) * clip_num_span);
savedClip->clip_index = malloc(sizeof(int) * clip_num_span);
for (i = 0; i < clip_num_span; i++)
{
savedClip->clip_span[i] = clip_span[i];
}
for (i = 0; i < clip_num_span; i++)
{
savedClip->clip_index[i] = clip_index[i];
}
}
savedClip->clip_num_span = clip_num_span;
return savedClip;
}
- (void) restoreClip: (void *)saved
{
SavedClip *savedClip = (SavedClip *)saved;
clip_x0 = savedClip->clip_x0;
clip_y0 = savedClip->clip_y0;
clip_x1 = savedClip->clip_x1;
clip_y1 = savedClip->clip_y1;
all_clipped = savedClip->all_clipped;
clip_sx = savedClip->clip_sx;
clip_sy = savedClip->clip_sy;
if (clip_span)
{
free(clip_span);
free(clip_index);
}
clip_span = savedClip->clip_span;
clip_index = savedClip->clip_index;
clip_num_span = savedClip->clip_num_span;
free(savedClip);
}
@end

View file

@ -952,11 +952,23 @@ static void clip_svp_callback(void *data, int y, int start,
- (void) DPSeofill
{
if (pattern != nil)
{
[self eofillPath: path withPattern: pattern];
return;
}
[self _fill: ART_WIND_RULE_ODDEVEN];
}
- (void) DPSfill
{
if (pattern != nil)
{
[self fillPath: path withPattern: pattern];
return;
}
[self _fill: ART_WIND_RULE_NONZERO];
}
@ -969,6 +981,13 @@ static void clip_svp_callback(void *data, int y, int start,
if (!wi || !wi->data) return;
if (all_clipped) return;
if (pattern != nil)
{
[self fillRect: NSMakeRect(x, y, w, h) withPattern: pattern];
return;
}
if (!fill_color[3]) return;
axis_aligned = [self _axis_rectangle: x : y : w : h vpath: vp

View file

@ -747,7 +747,7 @@ static float floatToUserSpace(NSAffineTransform *ctm, float f)
{
float offs;
if ((remainderf(cairo_get_line_width(_ct), 2.0) == 0.0)
if ((remainderf((float)cairo_get_line_width(_ct), 2.0) == 0.0)
|| fillOrClip == YES)
offs = 0.0;
else
@ -810,6 +810,12 @@ static float floatToUserSpace(NSAffineTransform *ctm, float f)
{
if (_ct)
{
if (pattern != nil)
{
[self eofillPath: path withPattern: pattern];
return;
}
[self _setPath:YES];
cairo_set_fill_rule(_ct, CAIRO_FILL_RULE_EVEN_ODD);
cairo_fill(_ct);
@ -822,6 +828,12 @@ static float floatToUserSpace(NSAffineTransform *ctm, float f)
{
if (_ct)
{
if (pattern != nil)
{
[self fillPath: path withPattern: pattern];
return;
}
[self _setPath:YES];
cairo_fill(_ct);
}
@ -1340,3 +1352,64 @@ _set_op(cairo_t *ct, NSCompositingOperation op)
}
@end
@implementation CairoGState (PatternColor)
- (void *) saveClip
{
#if CAIRO_VERSION > CAIRO_VERSION_ENCODE(1, 4, 0)
cairo_status_t status;
cairo_rectangle_list_t *clip_rects = cairo_copy_clip_rectangle_list(_ct);
status = cairo_status(_ct);
if (status == CAIRO_STATUS_SUCCESS)
{
return clip_rects;
}
#endif
return NULL;
}
- (void) restoreClip: (void *)savedClip
{
#if CAIRO_VERSION > CAIRO_VERSION_ENCODE(1, 4, 0)
if (savedClip)
{
int i;
cairo_rectangle_list_t *clip_rects = (cairo_rectangle_list_t *)savedClip;
cairo_reset_clip(_ct);
if (cairo_version() >= CAIRO_VERSION_ENCODE(1, 6, 0))
{
for (i = 0; i < clip_rects->num_rectangles; i++)
{
cairo_rectangle_t rect = clip_rects->rectangles[i];
cairo_rectangle(_ct, rect.x, rect.y,
rect.width, rect.height);
cairo_clip(_ct);
}
}
else
{
for (i = 0; i < clip_rects->num_rectangles; i++)
{
cairo_rectangle_t rect = clip_rects->rectangles[i];
NSSize size = [_surface size];
cairo_rectangle(_ct, rect.x,
/* This strange computation is due
to the device offset missing for
clip rects in cairo < 1.6.0. */
rect.y + 2*(offset.y - size.height),
rect.width, rect.height);
cairo_clip(_ct);
}
}
cairo_rectangle_list_destroy(clip_rects);
}
#endif
}
@end

View file

@ -1157,6 +1157,7 @@ typedef enum {
inverse = [matrix copy];
[inverse invert];
ts = [inverse transformStruct];
rect = [function affectedRect];
iwidth = rect.size.width;
@ -1217,3 +1218,89 @@ typedef enum {
@end
@implementation GSGState (PatternColor)
- (void *) saveClip
{
[self subclassResponsibility: _cmd];
return NULL;
}
- (void) restoreClip: (void *)savedClip
{
[self subclassResponsibility: _cmd];
}
- (void) _fillRect: (NSRect)rect withPattern: (NSImage*)color_pattern
{
NSSize size;
float x;
float y;
size = [pattern size];
y = floor(NSMinY(rect) / size.height) * size.height;
while (y < NSMaxY(rect))
{
x = floor(NSMinX(rect) / size.width) * size.width;
while (x < NSMaxX(rect))
{
[color_pattern compositeToPoint: NSMakePoint(x, y)
operation: NSCompositeSourceOver];
x += size.width;
}
y += size.height;
}
}
- (void) fillRect: (NSRect)rect withPattern: (NSImage*)color_pattern
{
NSBezierPath *oldPath = path;
void *oldClip;
oldClip = [self saveClip];
path = [NSBezierPath bezierPathWithRect: rect];
[self DPSclip];
[self _fillRect: rect withPattern: color_pattern];
[self restoreClip: oldClip];
path = oldPath;
}
- (void) fillPath: (NSBezierPath*)fillPath withPattern: (NSImage*)color_pattern
{
NSBezierPath *oldPath = path;
NSRect rect;
void *oldClip;
oldClip = [self saveClip];
rect = [fillPath bounds];
path = fillPath;
[self DPSclip];
[self _fillRect: rect withPattern: color_pattern];
[self restoreClip: oldClip];
path = oldPath;
[self DPSnewpath];
}
- (void) eofillPath: (NSBezierPath*)fillPath withPattern: (NSImage*)color_pattern
{
NSBezierPath *oldPath = path;
NSRect rect;
void *oldClip;
oldClip = [self saveClip];
rect = [fillPath bounds];
path = fillPath;
[self DPSeoclip];
[self _fillRect: rect withPattern: color_pattern];
[self restoreClip: oldClip];
path = oldPath;
[self DPSnewpath];
}
@end

View file

@ -749,10 +749,10 @@ HBITMAP GSCreateBitmap(HDC hDC, int pixelsWide, int pixelsHigh,
SetPolyFillMode(hDC, ALTERNATE);
region = PathToRegion(hDC);
if (clipRegion)
{
CombineRgn(clipRegion, clipRegion, region, RGN_AND);
DeleteObject(region);
}
{
CombineRgn(clipRegion, clipRegion, region, RGN_AND);
DeleteObject(region);
}
else
{
clipRegion = region;
@ -766,10 +766,10 @@ HBITMAP GSCreateBitmap(HDC hDC, int pixelsWide, int pixelsHigh,
SetPolyFillMode(hDC, WINDING);
region = PathToRegion(hDC);
if (clipRegion)
{
CombineRgn(clipRegion, clipRegion, region, RGN_AND);
DeleteObject(region);
}
{
CombineRgn(clipRegion, clipRegion, region, RGN_AND);
DeleteObject(region);
}
else
{
clipRegion = region;
@ -804,11 +804,22 @@ HBITMAP GSCreateBitmap(HDC hDC, int pixelsWide, int pixelsHigh,
- (void)DPSeofill
{
if (pattern != nil)
{
[self eofillPath: path withPattern: pattern];
return;
}
[self _paintPath: path_eofill];
}
- (void)DPSfill
{
if (pattern != nil)
{
[self fillPath: path withPattern: pattern];
return;
}
[self _paintPath: path_fill];
}
@ -1112,3 +1123,32 @@ HBITMAP GSCreateBitmap(HDC hDC, int pixelsWide, int pixelsHigh,
}
@end
@implementation WIN32GState (PatternColor)
- (void *) saveClip
{
if (clipregion)
{
HRGN newClipRegion;
newClipRegion = CreateRectRgn(0, 0, 1, 1);
CombineRgn(newClipRegion, clipRegion, NULL, RGN_COPY);
return newClipRegion;
}
return clipregion;
}
- (void) restoreClip: (void *)savedClip
{
if (clipregion)
{
DeleteObject(clipRegion);
}
clipregion = savedClip;
[self setClipMask];
}
@end

View file

@ -1462,6 +1462,12 @@ static Region emptyRegion;
- (void)DPSeofill
{
if (pattern != nil)
{
[self eofillPath: path withPattern: pattern];
return;
}
if ((cstate & COLOR_FILL) == 0)
[self setColor: &fillColor state: COLOR_FILL];
@ -1470,6 +1476,12 @@ static Region emptyRegion;
- (void)DPSfill
{
if (pattern != nil)
{
[self fillPath: path withPattern: pattern];
return;
}
if ((cstate & COLOR_FILL) == 0)
[self setColor: &fillColor state: COLOR_FILL];
@ -1522,6 +1534,12 @@ static Region emptyRegion;
return;
}
if (pattern != nil)
{
[self fillRect: NSMakeRect(x, y, w, h) withPattern: pattern];
return;
}
if ((cstate & COLOR_FILL) == 0)
[self setColor: &fillColor state: COLOR_FILL];
@ -1879,3 +1897,29 @@ NSDebugLLog(@"XGGraphics", @"Fill %@ X rect %d,%d,%d,%d",
}
@end
@implementation XGGState (PatternColor)
- (void *) saveClip
{
if (clipregion)
{
Region region = XCreateRegion();
XIntersectRegion(clipregion, clipregion, region);
return region;
}
return clipregion;
}
- (void) restoreClip: (void *)savedClip
{
if (clipregion)
{
XDestroyRegion(clipregion);
}
clipregion = savedClip;
[self setClipMask];
}
@end