Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Headers/gsc/GSGState.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
@class NSBezierPath;
@class NSFont;
@class NSColorSpace;
@class NSShadow;
@class GSContext;

typedef enum {
Expand Down Expand Up @@ -72,6 +73,7 @@ typedef enum {
BOOL _antialias;
NSPoint _patternPhase;
NSCompositingOperation _compositingOperation;
NSShadow *_shadow; /* Current shadow, or nil */
}

- initWithDrawContext: (GSContext *)context;
Expand All @@ -89,6 +91,8 @@ typedef enum {
- (void) setPatternPhase: (NSPoint)phase;
- (NSCompositingOperation) compositingOperation;
- (void) setCompositingOperation:(NSCompositingOperation) operation;
- (void) setShadow: (NSShadow *)shadow;
- (NSShadow *) shadow;

- (void) compositeGState: (GSGState *)source
fromRect: (NSRect)aRect
Expand Down
63 changes: 63 additions & 0 deletions Source/art/path.m
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@

#include <AppKit/NSAffineTransform.h>
#include <AppKit/NSBezierPath.h>
#include <AppKit/NSColor.h>
#include <AppKit/NSGraphics.h>
#include <AppKit/NSShadow.h>

#include "ARTGState.h"

Expand All @@ -42,6 +45,9 @@
#include <libart_lgpl/libart.h>
#include <libart_lgpl/art_svp_intersect.h>

@interface ARTGState (ShadowRendering)
- (void) _stroke: (ArtVpath *)vp;
@end

#if 0
/* useful when debugging */
Expand Down Expand Up @@ -950,6 +956,59 @@ - (void) _fill: (int)rule
UPDATE_UNBUFFERED
}

/* Renders the current path offset by the active shadow, in the shadow colour,
as a plain (unblurred) shadow, before the path itself is drawn. The shadow
parameters live on the shared GSGState. */
- (void) _drawShadowForOperation: (ctxt_object_t)drawType
{
NSColor *shadowColor;
NSBezierPath *savedPath, *shadowPath;
NSAffineTransform *xform;
device_color_t savedColor, dc;
NSSize soffset;
CGFloat r, g, b, a;
BOOL isStroke = (drawType == path_stroke);
color_state_t cs = isStroke ? COLOR_STROKE : COLOR_FILL;

if (_shadow == nil || path == nil || [path isEmpty])
return;

shadowColor = [[_shadow shadowColor]
colorUsingColorSpaceName: NSDeviceRGBColorSpace];
if (shadowColor == nil)
return;
[shadowColor getRed: &r green: &g blue: &b alpha: &a];

soffset = [_shadow shadowOffset];
savedPath = path;
shadowPath = [path copy];
xform = [NSAffineTransform transform];
[xform translateXBy: soffset.width yBy: soffset.height];
[shadowPath transformUsingAffineTransform: xform];

savedColor = isStroke ? strokeColor : fillColor;
gsMakeColor(&dc, rgb_colorspace, r, g, b, 0);
dc.field[AINDEX] = a;

path = shadowPath;
[self setColor: &dc state: cs];
if (isStroke)
{
ArtVpath *vp = [self _vpath_from_current_path: NO];

if (vp)
[self _stroke: vp];
}
else
{
[self _fill: (drawType == path_eofill)
? ART_WIND_RULE_ODDEVEN : ART_WIND_RULE_NONZERO];
}
[self setColor: &savedColor state: cs];
path = savedPath;
RELEASE(shadowPath);
}

- (void) DPSeofill
{
if (pattern != nil)
Expand All @@ -958,6 +1017,7 @@ - (void) DPSeofill
return;
}

[self _drawShadowForOperation: path_eofill];
[self _fill: ART_WIND_RULE_ODDEVEN];
}

Expand All @@ -969,6 +1029,7 @@ - (void) DPSfill
return;
}

[self _drawShadowForOperation: path_fill];
[self _fill: ART_WIND_RULE_NONZERO];
}

Expand Down Expand Up @@ -1381,6 +1442,8 @@ - (void) DPSstroke
if (all_clipped) return;
if (!stroke_color[3]) return;

[self _drawShadowForOperation: path_stroke];

/* TODO: this is wrong. we should transform _after_ we dash and
stroke */
vp = [self _vpath_from_current_path: NO];
Expand Down
51 changes: 51 additions & 0 deletions Source/cairo/CairoGState.m
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <AppKit/NSColor.h>
#include <AppKit/NSGradient.h>
#include <AppKit/NSGraphics.h>
#include <AppKit/NSShadow.h>
#include "cairo/CairoGState.h"
#include "cairo/CairoFontInfo.h"
#include "cairo/CairoSurface.h"
Expand Down Expand Up @@ -760,6 +761,8 @@ - (void) DPSeofill
return;
}

[self _drawShadowForOperation: path_eofill];

c = fillColor;
gsColorToRGB(&c);
// The underlying concept does not allow to determine if alpha is set or not.
Expand All @@ -772,6 +775,50 @@ - (void) DPSeofill
[self DPSnewpath];
}

/* Renders the current path offset by the active shadow, in the shadow colour,
as a plain (unblurred) shadow. The shadow parameters live on the shared
GSGState so that any backend can render a shadow the same way; blur is not
yet applied. */
- (void) _drawShadowForOperation: (ctxt_object_t)drawType
{
NSColor *shadowColor;
NSSize soffset;
CGFloat r, g, b, a;

if (_shadow == nil || _ct == NULL)
return;

shadowColor = [[_shadow shadowColor]
colorUsingColorSpaceName: NSDeviceRGBColorSpace];
if (shadowColor == nil)
return;
[shadowColor getRed: &r green: &g blue: &b alpha: &a];

soffset = [_shadow shadowOffset];

cairo_save(_ct);
/* The offset is expressed in the current user space, which is what the path
is built in, so translate by it directly. */
cairo_translate(_ct, soffset.width, soffset.height);
cairo_set_source_rgba(_ct, r, g, b, a);
[self _setPath];
switch (drawType)
{
case path_eofill:
cairo_set_fill_rule(_ct, CAIRO_FILL_RULE_EVEN_ODD);
/* fall through */
case path_fill:
cairo_fill(_ct);
break;
case path_stroke:
cairo_stroke(_ct);
break;
default:
break;
}
cairo_restore(_ct);
}

- (void) DPSfill
{
if (_ct)
Expand All @@ -784,6 +831,8 @@ - (void) DPSfill
return;
}

[self _drawShadowForOperation: path_fill];

c = fillColor;
gsColorToRGB(&c);
// The underlying concept does not allow to determine if alpha is set or not.
Expand All @@ -809,6 +858,8 @@ - (void) DPSstroke
BOOL zeroLineWidth = NO;
device_color_t c;

[self _drawShadowForOperation: path_stroke];

c = strokeColor;
gsColorToRGB(&c);
// The underlying concept does not allow to determine if alpha is set or not.
Expand Down
10 changes: 10 additions & 0 deletions Source/gsc/GSContext.m
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,16 @@ - (void) setCompositingOperation: (NSCompositingOperation)operation
[gstate setCompositingOperation: operation];
}

- (void) setShadow: (NSShadow *)shadow
{
[gstate setShadow: shadow];
}

- (NSShadow *) shadow
{
return [gstate shadow];
}

@end

@implementation GSContext (Ops)
Expand Down
13 changes: 13 additions & 0 deletions Source/gsc/GSGState.m
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ - (void) dealloc
RELEASE(fillColorS);
RELEASE(strokeColorS);
TEST_RELEASE(pattern);
TEST_RELEASE(_shadow);
[super dealloc];
}

Expand All @@ -97,6 +98,8 @@ - (id) deepen
RETAIN(strokeColorS);
if (pattern != nil)
RETAIN(pattern);
if (_shadow != nil)
RETAIN(_shadow);

return self;
}
Expand Down Expand Up @@ -177,6 +180,16 @@ - (void) setCompositingOperation: (NSCompositingOperation)operation
_compositingOperation = operation;
}

- (void) setShadow: (NSShadow *)shadow
{
ASSIGN(_shadow, shadow);
}

- (NSShadow *) shadow
{
return _shadow;
}

// This is only a fall back, the method should not be called any more.
- (void) compositeGState: (GSGState *)source
fromRect: (NSRect)aRect
Expand Down
52 changes: 49 additions & 3 deletions Source/winlib/WIN32GState.m
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#import <AppKit/NSAffineTransform.h>
#import <AppKit/NSBezierPath.h>
#import <AppKit/NSColor.h>
#import <AppKit/NSShadow.h>
#import <AppKit/NSFont.h>
#import <AppKit/NSGraphics.h>

Expand Down Expand Up @@ -1165,29 +1166,74 @@ - (void)DPSeoclip
[self _paintPath: path_eoclip];
}

- (void)DPSeofill
/* Renders the current path offset by the active shadow, in the shadow colour,
as a plain (unblurred) shadow, before the path itself is drawn. The shadow
parameters live on the shared GSGState. */
- (void) _drawShadowForOperation: (ctxt_object_t)drawType
{
NSColor *shadowColor;
NSBezierPath *savedPath, *shadowPath;
NSAffineTransform *xform;
device_color_t savedColor, dc;
NSSize soffset;
CGFloat r, g, b, a;
color_state_t cs = (drawType == path_stroke) ? COLOR_STROKE : COLOR_FILL;

if (_shadow == nil || path == nil || [path isEmpty])
return;

shadowColor = [[_shadow shadowColor]
colorUsingColorSpaceName: NSDeviceRGBColorSpace];
if (shadowColor == nil)
return;
[shadowColor getRed: &r green: &g blue: &b alpha: &a];

soffset = [_shadow shadowOffset];
savedPath = path;
shadowPath = [path copy];
xform = [NSAffineTransform transform];
[xform translateXBy: soffset.width yBy: soffset.height];
[shadowPath transformUsingAffineTransform: xform];

savedColor = (cs == COLOR_STROKE) ? strokeColor : fillColor;
gsMakeColor(&dc, rgb_colorspace, r, g, b, 0);
dc.field[AINDEX] = a;

path = shadowPath;
[self setColor: &dc state: cs];
[self _paintPath: drawType];
[self setColor: &savedColor state: cs];
path = savedPath;
RELEASE(shadowPath);
}

- (void)DPSeofill
{
if (pattern != nil)
{
[self eofillPath: path withPattern: pattern];
return;
}

[self _drawShadowForOperation: path_eofill];
[self _paintPath: path_eofill];
}

- (void)DPSfill
- (void)DPSfill
{
if (pattern != nil)
{
[self fillPath: path withPattern: pattern];
return;
}

[self _drawShadowForOperation: path_fill];
[self _paintPath: path_fill];
}

- (void)DPSstroke
- (void)DPSstroke
{
[self _drawShadowForOperation: path_stroke];
[self _paintPath: path_stroke];
}

Expand Down
Loading
Loading