Browse Source

Added Context2d::shadow()

v1.x
Tj Holowaychuk 14 years ago
parent
commit
a8202da8d8
  1. 83
      src/CanvasRenderingContext2d.cc
  2. 7
      src/CanvasRenderingContext2d.h
  3. 58
      test/public/tests.js

83
src/CanvasRenderingContext2d.cc

@ -792,7 +792,18 @@ Context2d::Stroke(const Arguments &args) {
Context2d *context = ObjectWrap::Unwrap<Context2d>(args.This());
cairo_t *ctx = context->getContext();
SET_SOURCE(context->state->stroke);
if (!context->hasShadow()) {
cairo_stroke_preserve(ctx);
return Undefined();
}
context->shadowStart();
cairo_stroke_preserve(ctx);
context->shadowApply();
cairo_stroke_preserve(ctx);
return Undefined();
}
@ -1049,22 +1060,8 @@ Context2d::FillRect(const Arguments &args) {
Context2d *context = ObjectWrap::Unwrap<Context2d>(args.This());
cairo_t *ctx = context->getContext();
cairo_new_path(ctx);
if (!context->hasShadow()) {
cairo_rectangle(ctx, x, y, width, height);
SET_SOURCE(context->state->fill);
cairo_fill(ctx);
return Undefined();
}
context->shadowStart();
cairo_rectangle(ctx, x, y, width, height);
cairo_fill(ctx);
context->shadowApply();
cairo_rectangle(ctx, x, y, width, height);
cairo_fill(ctx);
context->fill();
return Undefined();
}
@ -1169,6 +1166,58 @@ Context2d::Arc(const Arguments &args) {
return Undefined();
}
/*
* Fill and apply shadow.
*/
void
Context2d::fill() {
setSourceRGBA(state->fill);
hasShadow()
? shadow(cairo_fill)
: cairo_fill(_context);
}
/*
* Apply shadow with the given draw fn.
*/
void
Context2d::shadow(void (fn)(cairo_t *cr)) {
cairo_path_t *path = cairo_copy_path_flat(_context);
cairo_save(_context);
// Offset
cairo_translate(
_context
, state->shadowOffsetX
, state->shadowOffsetY);
// Apply shadow
cairo_push_group(_context);
cairo_new_path(_context);
cairo_append_path(_context, path);
setSourceRGBA(state->shadow);
fn(_context);
// No need to invoke blur if shadowBlur is 0
if (state->shadowBlur) {
Canvas::blur(cairo_get_group_target(_context), state->shadowBlur);
}
// Paint the shadow
cairo_pop_group_to_source(_context);
cairo_paint(_context);
// Restore state
cairo_restore(_context);
cairo_new_path(_context);
cairo_append_path(_context, path);
fn(_context);
cairo_path_destroy(path);
}
/*
* Set source RGBA.
*/
@ -1189,6 +1238,7 @@ Context2d::setSourceRGBA(rgba_t color) {
void
Context2d::shadowStart() {
savePath();
cairo_save(_context);
cairo_translate(
_context
@ -1196,6 +1246,7 @@ Context2d::shadowStart() {
, state->shadowOffsetY);
cairo_push_group(_context);
setSourceRGBA(state->shadow);
restorePath();
}
/*
@ -1204,12 +1255,14 @@ Context2d::shadowStart() {
void
Context2d::shadowApply() {
savePath();
if (state->shadowBlur) {
Canvas::blur(cairo_get_group_target(_context), state->shadowBlur);
}
cairo_pop_group_to_source(_context);
cairo_paint(_context);
cairo_restore(_context);
restorePath();
}
/*

7
src/CanvasRenderingContext2d.h

@ -103,14 +103,17 @@ class Context2d: public node::ObjectWrap {
inline bool hasShadow();
void inline setSourceRGBA(rgba_t color);
void setTextPath(const char *str, double x, double y);
void shadow(void (fn)(cairo_t *cr));
void shadowStart();
void shadowApply();
void savePath();
void restorePath();
void save();
void restore();
void saveState();
void restoreState();
void fill();
void stroke();
void save();
void restore();
protected:
Context2d(Canvas *canvas);

58
test/public/tests.js

@ -952,5 +952,63 @@ tests['shadowBlur strokeRect()'] = function(ctx){
ctx.lineTo(100,180);
ctx.stroke();
ctx.strokeRect(150,150,20,20);
};
tests['shadowBlur fill()'] = function(ctx){
ctx.strokeRect(150,10,20,20);
ctx.lineTo(20,5);
ctx.lineTo(100,5);
ctx.stroke();
ctx.shadowColor = '#000';
ctx.shadowBlur = 5;
ctx.shadowOffsetX = 2;
ctx.shadowOffsetY = 2;
ctx.rect(20,20,100,100);
ctx.fill();
ctx.beginPath();
ctx.lineTo(20,150);
ctx.lineTo(100,150);
ctx.stroke();
ctx.shadowColor = 'rgba(0,0,0,0)';
ctx.beginPath();
ctx.lineTo(20,180);
ctx.lineTo(100,180);
ctx.stroke();
ctx.strokeRect(150,150,20,20);
};
tests['shadowBlur stroke()'] = function(ctx){
ctx.strokeRect(150,10,20,20);
ctx.lineTo(20,5);
ctx.lineTo(100,5);
ctx.stroke();
ctx.shadowColor = '#000';
ctx.shadowBlur = 5;
ctx.shadowOffsetX = 2;
ctx.shadowOffsetY = 2;
ctx.rect(20,20,100,100);
ctx.stroke();
ctx.beginPath();
ctx.lineTo(20,150);
ctx.lineTo(100,150);
ctx.stroke();
ctx.shadowColor = 'rgba(0,0,0,0)';
ctx.beginPath();
ctx.lineTo(20,180);
ctx.lineTo(100,180);
ctx.stroke();
ctx.strokeRect(150,150,20,20);
};
Loading…
Cancel
Save