mirror of
https://github.com/gnustep/libs-back.git
synced 2025-02-23 11:51:27 +00:00
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:
parent
d7dc549a3e
commit
3c8eab0c49
8 changed files with 361 additions and 9 deletions
10
ChangeLog
10
ChangeLog
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue