Browse Source

Added more global composite operator support

v1.x
Tj Holowaychuk 14 years ago
parent
commit
dd9430ec4a
  1. 17
      Readme.md
  2. 42
      src/CanvasRenderingContext2d.cc
  3. 104
      test/public/tests.js

17
Readme.md

@ -39,7 +39,8 @@ If not previously installed, you will want to install the [cairo graphics librar
## Non-Standard API
Due to interfacing with existing node internals such as I/O node-canvas includes a non-standard API which is shown below.
node-canvas extends the canvas API to provide interfacing with node, for example streaming PNG data, converting to a `Buffer` instance, etc. Among the interfacing API, in some cases the drawing API has been extended for SSJS image manipulation / creation usage, however keep in mind these additions may fail to render properly within browsers.
### Canvas#createPNGStream()
@ -88,6 +89,20 @@ or specify the mime type:
});
### Global Composite Operations
In addition to those specified and commonly implemented by browsers, the following have been addded:
- multiply
- screen
- overlay
- hard-light
- soft-light
- hsl-hue
- hsl-saturation
- hsl-color
- hsl-luminosity
## Benchmarks
Although node-canvas is extremely new, and we have not even begun optimization yet it is already quite fast. For benchmarks vs other node canvas implementations view this [gist](https://gist.github.com/664922), or update the submodules and run `$ make benchmark` yourself.

42
src/CanvasRenderingContext2d.cc

@ -429,8 +429,29 @@ Context2d::GetGlobalCompositeOperation(Local<String> prop, const AccessorInfo &i
return String::NewSymbol("destination-out");
case CAIRO_OPERATOR_DEST_OVER:
return String::NewSymbol("destination-over");
case CAIRO_OPERATOR_ADD:
case CAIRO_OPERATOR_LIGHTEN:
return String::NewSymbol("lighter");
case CAIRO_OPERATOR_DARKEN:
return String::NewSymbol("darkler");
// Non-standard
case CAIRO_OPERATOR_MULTIPLY:
return String::NewSymbol("multiply");
case CAIRO_OPERATOR_SCREEN:
return String::NewSymbol("screen");
case CAIRO_OPERATOR_OVERLAY:
return String::NewSymbol("overlay");
case CAIRO_OPERATOR_HARD_LIGHT:
return String::NewSymbol("hard-light");
case CAIRO_OPERATOR_SOFT_LIGHT:
return String::NewSymbol("soft-light");
case CAIRO_OPERATOR_HSL_HUE:
return String::NewSymbol("hsl-hue");
case CAIRO_OPERATOR_HSL_SATURATION:
return String::NewSymbol("hsl-saturation");
case CAIRO_OPERATOR_HSL_COLOR:
return String::NewSymbol("hsl-color");
case CAIRO_OPERATOR_HSL_LUMINOSITY:
return String::NewSymbol("hsl-luminosity");
default:
return String::NewSymbol("source-over");
}
@ -465,6 +486,25 @@ Context2d::SetGlobalCompositeOperation(Local<String> prop, Local<Value> val, con
cairo_set_operator(ctx, CAIRO_OPERATOR_DEST_OUT);
} else if (0 == strcmp("destination-over", *type)) {
cairo_set_operator(ctx, CAIRO_OPERATOR_DEST_OVER);
// Non-standard
} else if (0 == strcmp("multiply", *type)) {
cairo_set_operator(ctx, CAIRO_OPERATOR_MULTIPLY);
} else if (0 == strcmp("screen", *type)) {
cairo_set_operator(ctx, CAIRO_OPERATOR_SCREEN);
} else if (0 == strcmp("overlay", *type)) {
cairo_set_operator(ctx, CAIRO_OPERATOR_OVERLAY);
} else if (0 == strcmp("hard-light", *type)) {
cairo_set_operator(ctx, CAIRO_OPERATOR_HARD_LIGHT);
} else if (0 == strcmp("soft-light", *type)) {
cairo_set_operator(ctx, CAIRO_OPERATOR_SOFT_LIGHT);
} else if (0 == strcmp("hsl-hue", *type)) {
cairo_set_operator(ctx, CAIRO_OPERATOR_HSL_HUE);
} else if (0 == strcmp("hsl-saturation", *type)) {
cairo_set_operator(ctx, CAIRO_OPERATOR_HSL_SATURATION);
} else if (0 == strcmp("hsl-color", *type)) {
cairo_set_operator(ctx, CAIRO_OPERATOR_HSL_COLOR);
} else if (0 == strcmp("hsl-luminosity", *type)) {
cairo_set_operator(ctx, CAIRO_OPERATOR_HSL_LUMINOSITY);
} else {
cairo_set_operator(ctx, CAIRO_OPERATOR_OVER);
}

104
test/public/tests.js

@ -928,6 +928,110 @@ tests['globalCompositeOperation darker'] = function(ctx){
ctx.fill();
};
tests['globalCompositeOperation multiply'] = function(ctx){
ctx.fillStyle = 'rgba(0,0,255,0.6)';
ctx.fillRect(0,0,100,100);
ctx.globalCompositeOperation = 'multiply';
var grad = ctx.createRadialGradient(80,80,5,60,60,60);
grad.addColorStop(0, 'yellow');
grad.addColorStop(0.2, 'red');
grad.addColorStop(1, 'black');
ctx.fillStyle = grad;
ctx.arc(80,80,50,0,Math.PI * 2);
ctx.fill();
};
tests['globalCompositeOperation screen'] = function(ctx){
ctx.fillStyle = 'rgba(0,0,255,0.6)';
ctx.fillRect(0,0,100,100);
ctx.globalCompositeOperation = 'screen';
var grad = ctx.createRadialGradient(80,80,5,60,60,60);
grad.addColorStop(0, 'yellow');
grad.addColorStop(0.2, 'red');
grad.addColorStop(1, 'black');
ctx.fillStyle = grad;
ctx.arc(80,80,50,0,Math.PI * 2);
ctx.fill();
};
tests['globalCompositeOperation overlay'] = function(ctx){
ctx.fillStyle = 'rgba(0,0,255,0.6)';
ctx.fillRect(0,0,100,100);
ctx.globalCompositeOperation = 'overlay';
var grad = ctx.createRadialGradient(80,80,5,60,60,60);
grad.addColorStop(0, 'yellow');
grad.addColorStop(0.2, 'red');
grad.addColorStop(1, 'black');
ctx.fillStyle = grad;
ctx.arc(80,80,50,0,Math.PI * 2);
ctx.fill();
};
tests['globalCompositeOperation hard-light'] = function(ctx){
ctx.fillStyle = 'rgba(0,0,255,0.6)';
ctx.fillRect(0,0,100,100);
ctx.globalCompositeOperation = 'hard-light';
var grad = ctx.createRadialGradient(80,80,5,60,60,60);
grad.addColorStop(0, 'yellow');
grad.addColorStop(0.2, 'red');
grad.addColorStop(1, 'black');
ctx.fillStyle = grad;
ctx.arc(80,80,50,0,Math.PI * 2);
ctx.fill();
};
tests['globalCompositeOperation hsl-hue'] = function(ctx){
ctx.fillStyle = 'rgba(0,0,255,0.6)';
ctx.fillRect(0,0,100,100);
ctx.globalCompositeOperation = 'hsl-hue';
var grad = ctx.createRadialGradient(80,80,5,60,60,60);
grad.addColorStop(0, 'yellow');
grad.addColorStop(0.2, 'red');
grad.addColorStop(1, 'black');
ctx.fillStyle = grad;
ctx.arc(80,80,50,0,Math.PI * 2);
ctx.fill();
};
tests['globalCompositeOperation hsl-saturation'] = function(ctx){
ctx.fillStyle = 'rgba(0,0,255,0.6)';
ctx.fillRect(0,0,100,100);
ctx.globalCompositeOperation = 'hsl-saturation';
var grad = ctx.createRadialGradient(80,80,5,60,60,60);
grad.addColorStop(0, 'yellow');
grad.addColorStop(0.2, 'red');
grad.addColorStop(1, 'black');
ctx.fillStyle = grad;
ctx.arc(80,80,50,0,Math.PI * 2);
ctx.fill();
};
tests['globalCompositeOperation hsl-color'] = function(ctx){
ctx.fillStyle = 'rgba(0,0,255,0.6)';
ctx.fillRect(0,0,100,100);
ctx.globalCompositeOperation = 'hsl-color';
var grad = ctx.createRadialGradient(80,80,5,60,60,60);
grad.addColorStop(0, 'yellow');
grad.addColorStop(0.2, 'red');
grad.addColorStop(1, 'black');
ctx.fillStyle = grad;
ctx.arc(80,80,50,0,Math.PI * 2);
ctx.fill();
};
tests['globalCompositeOperation hsl-luminosity'] = function(ctx){
ctx.fillStyle = 'rgba(0,0,255,0.6)';
ctx.fillRect(0,0,100,100);
ctx.globalCompositeOperation = 'hsl-luminosity';
var grad = ctx.createRadialGradient(80,80,5,60,60,60);
grad.addColorStop(0, 'yellow');
grad.addColorStop(0.2, 'red');
grad.addColorStop(1, 'black');
ctx.fillStyle = grad;
ctx.arc(80,80,50,0,Math.PI * 2);
ctx.fill();
};
tests['shadowBlur'] = function(ctx){
ctx.fillRect(150,10,20,20);

Loading…
Cancel
Save