123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349 |
- 'use strict';
-
- /*!
- * Canvas - Context2d
- * Copyright (c) 2010 LearnBoost <tj@learnboost.com>
- * MIT Licensed
- */
-
- /**
- * Module dependencies.
- */
-
- var canvas = require('./bindings')
- , Context2d = canvas.CanvasRenderingContext2d
- , CanvasGradient = canvas.CanvasGradient
- , CanvasPattern = canvas.CanvasPattern
- , ImageData = canvas.ImageData;
-
- /**
- * Export `Context2d` as the module.
- */
-
- var Context2d = exports = module.exports = Context2d;
-
- /**
- * Cache color string RGBA values.
- */
-
- var cache = {};
-
- /**
- * Text baselines.
- */
-
- var baselines = ['alphabetic', 'top', 'bottom', 'middle', 'ideographic', 'hanging'];
-
- /**
- * Font RegExp helpers.
- */
-
- var weights = 'normal|bold|bolder|lighter|[1-9]00'
- , styles = 'normal|italic|oblique'
- , units = 'px|pt|pc|in|cm|mm|%'
- , string = '\'([^\']+)\'|"([^"]+)"|[\\w-]+';
-
- /**
- * Font parser RegExp;
- */
-
- var fontre = new RegExp('^ *'
- + '(?:(' + weights + ') *)?'
- + '(?:(' + styles + ') *)?'
- + '([\\d\\.]+)(' + units + ') *'
- + '((?:' + string + ')( *, *(?:' + string + '))*)'
- );
-
- /**
- * Parse font `str`.
- *
- * @param {String} str
- * @return {Object}
- * @api private
- */
-
- var parseFont = exports.parseFont = function(str){
- var font = {}
- , captures = fontre.exec(str);
-
- // Invalid
- if (!captures) return;
-
- // Cached
- if (cache[str]) return cache[str];
-
- // Populate font object
- font.weight = captures[1] || 'normal';
- font.style = captures[2] || 'normal';
- font.size = parseFloat(captures[3]);
- font.unit = captures[4];
- font.family = captures[5].replace(/["']/g, '').split(',')[0].trim();
-
- // TODO: dpi
- // TODO: remaining unit conversion
- switch (font.unit) {
- case 'pt':
- font.size /= .75;
- break;
- case 'in':
- font.size *= 96;
- break;
- case 'mm':
- font.size *= 96.0 / 25.4;
- break;
- case 'cm':
- font.size *= 96.0 / 2.54;
- break;
- }
-
- return cache[str] = font;
- };
-
- /**
- * Enable or disable image smoothing.
- *
- * @api public
- */
-
- Context2d.prototype.__defineSetter__('imageSmoothingEnabled', function(val){
- this._imageSmoothing = !! val;
- this.patternQuality = val ? 'best' : 'fast';
- });
-
- /**
- * Get image smoothing value.
- *
- * @api public
- */
-
- Context2d.prototype.__defineGetter__('imageSmoothingEnabled', function(val){
- return !! this._imageSmoothing;
- });
-
- /**
- * Create a pattern from `Image` or `Canvas`.
- *
- * @param {Image|Canvas} image
- * @param {String} repetition
- * @return {CanvasPattern}
- * @api public
- */
-
- Context2d.prototype.createPattern = function(image, repetition){
- // TODO Use repetition (currently always 'repeat')
- return new CanvasPattern(image);
- };
-
- /**
- * Create a linear gradient at the given point `(x0, y0)` and `(x1, y1)`.
- *
- * @param {Number} x0
- * @param {Number} y0
- * @param {Number} x1
- * @param {Number} y1
- * @return {CanvasGradient}
- * @api public
- */
-
- Context2d.prototype.createLinearGradient = function(x0, y0, x1, y1){
- return new CanvasGradient(x0, y0, x1, y1);
- };
-
- /**
- * Create a radial gradient at the given point `(x0, y0)` and `(x1, y1)`
- * and radius `r0` and `r1`.
- *
- * @param {Number} x0
- * @param {Number} y0
- * @param {Number} r0
- * @param {Number} x1
- * @param {Number} y1
- * @param {Number} r1
- * @return {CanvasGradient}
- * @api public
- */
-
- Context2d.prototype.createRadialGradient = function(x0, y0, r0, x1, y1, r1){
- return new CanvasGradient(x0, y0, r0, x1, y1, r1);
- };
-
- /**
- * Reset transform matrix to identity, then apply the given args.
- *
- * @param {...}
- * @api public
- */
-
- Context2d.prototype.setTransform = function(){
- this.resetTransform();
- this.transform.apply(this, arguments);
- };
-
- /**
- * Set the fill style with the given css color string.
- *
- * @api public
- */
-
- Context2d.prototype.__defineSetter__('fillStyle', function(val){
- if (!val) return;
- if ('CanvasGradient' == val.constructor.name
- || 'CanvasPattern' == val.constructor.name) {
- this.lastFillStyle = val;
- this._setFillPattern(val);
- } else if ('string' == typeof val) {
- this._setFillColor(val);
- }
- });
-
- /**
- * Get previous fill style.
- *
- * @return {CanvasGradient|String}
- * @api public
- */
-
- Context2d.prototype.__defineGetter__('fillStyle', function(){
- return this.lastFillStyle || this.fillColor;
- });
-
- /**
- * Set the stroke style with the given css color string.
- *
- * @api public
- */
-
- Context2d.prototype.__defineSetter__('strokeStyle', function(val){
- if (!val) return;
- if ('CanvasGradient' == val.constructor.name
- || 'CanvasPattern' == val.constructor.name) {
- this.lastStrokeStyle = val;
- this._setStrokePattern(val);
- } else if ('string' == typeof val) {
- this._setStrokeColor(val);
- }
- });
-
- /**
- * Get previous stroke style.
- *
- * @return {CanvasGradient|String}
- * @api public
- */
-
- Context2d.prototype.__defineGetter__('strokeStyle', function(){
- return this.lastStrokeStyle || this.strokeColor;
- });
-
- /**
- * Set font.
- *
- * @see exports.parseFont()
- * @api public
- */
-
- Context2d.prototype.__defineSetter__('font', function(val){
- if (!val) return;
- if ('string' == typeof val) {
- var font;
- if (font = parseFont(val)) {
- this.lastFontString = val;
- this._setFont(
- font.weight
- , font.style
- , font.size
- , font.unit
- , font.family);
- }
- }
- });
-
- /**
- * Get the current font.
- *
- * @api public
- */
-
- Context2d.prototype.__defineGetter__('font', function(){
- return this.lastFontString || '10px sans-serif';
- });
-
- /**
- * Set text baseline.
- *
- * @api public
- */
-
- Context2d.prototype.__defineSetter__('textBaseline', function(val){
- if (!val) return;
- var n = baselines.indexOf(val);
- if (~n) {
- this.lastBaseline = val;
- this._setTextBaseline(n);
- }
- });
-
- /**
- * Get the current baseline setting.
- *
- * @api public
- */
-
- Context2d.prototype.__defineGetter__('textBaseline', function(){
- return this.lastBaseline || 'alphabetic';
- });
-
- /**
- * Set text alignment.
- *
- * @api public
- */
-
- Context2d.prototype.__defineSetter__('textAlign', function(val){
- switch (val) {
- case 'center':
- this._setTextAlignment(0);
- this.lastTextAlignment = val;
- break;
- case 'left':
- case 'start':
- this._setTextAlignment(-1);
- this.lastTextAlignment = val;
- break;
- case 'right':
- case 'end':
- this._setTextAlignment(1);
- this.lastTextAlignment = val;
- break;
- }
- });
-
- /**
- * Get the current font.
- *
- * @see exports.parseFont()
- * @api public
- */
-
- Context2d.prototype.__defineGetter__('textAlign', function(){
- return this.lastTextAlignment || 'start';
- });
-
- /**
- * Create `ImageData` with the given dimensions or
- * `ImageData` instance for dimensions.
- *
- * @param {Number|ImageData} width
- * @param {Number} height
- * @return {ImageData}
- * @api public
- */
-
- Context2d.prototype.createImageData = function(width, height){
- if ('ImageData' == width.constructor.name) {
- height = width.height;
- width = width.width;
- }
- return new ImageData(new Uint8ClampedArray(width * height * 4), width, height);
- };
|