modules/UBCanvas/UBCanvas.js

/**
 * Canvas (draw text/pictures on PNG)
 *
 *        var
 *           UBCanvas = require('UBCanvas'),
 *           canvasWidth = 1200,
 *           canvasHeight = 300,
 *           canvas = new UBCanvas(canvasWidth, canvasHeight),
 *            base64Content;
 *        canvas.setFont('Times New Roman', {r: 0, g: 0, b: 0}, 22, [UBCanvas.FontStyles.Bold]);
 *        canvas.drawText(0, 0, 'Text on the center', canvasWidth - 950, canvasHeight,
 *           [UBCanvas.TextFormats.Center, UBCanvas.TextFormats.WordBreak]
 *        );
 *        canvas.setFont('Times New Roman', {r: 255, g: 0, b: 0}, 18);
 *        canvas.drawText(300, 0, 'Text on the left, canvasWidth, canvasHeight,
 *           [UBCanvas.TextFormats.Left, UBCanvas.TextFormats.WordBreak]
 *        );
 *        base64Content = canvas.getContent('bin2base64'); // PNG image encoded as base64
 *
 * @module UBCanvas
 */
var binding = require('./UBCanvas.dll');
/**
 * Create new Canvas and fill it by provided color.
 * @param {Number} width
 * @param {Number} height
 * @param {Number|Object} [fillColor=0] Either a result of UBCanvas#createColor or object {r: Number, g: number, b: Number}
 * @constructor
 */
function UBCanvas(width, height, fillColor){
    this._nativeCanvas = new binding.TubCanvas();
    this.createNew(width, height, fillColor);
}

function createByteMask(byteArray){
    var result = 0;
    if (byteArray && byteArray.length){
        byteArray.forEach(function(byteVal){
            result = result | 1 << byteVal;
        });
    }
    return result;
}

/**
 * Possible font style for setFont
 * @type {{Bold: number, Italic: number, Underline: number, StrikeOut: number}}
 */
UBCanvas.FontStyles = binding.TFontStyle;
/**
 * Possible text drawing options for drawText
 * @type {{Bottom: number, CalcRect: number, Center: number, EditControl: number, EndEllipsis: number, PathEllipsis: number, ExpandTabs: number, ExternalLeading: number, Left: number, ModifyString: number, NoClip: number, NoPrefix: number, Right: number, RtlReading: number, SingleLine: number, Top: number, VerticalCenter: number, WordBreak: number, HidePrefix: number, NoFullWidthCharBreak: number, PrefixOnly: number, TabStop: number, WordEllipsis: number, Composited: number}}
 */
UBCanvas.TextFormats = binding.TTextFormats;
/**
 * Class method. Create an RGB color to use in setFont
 * @memberOf UBCanvas
 * @param {Number} r
 * @param {Number} g
 * @param {Number} b
 */
UBCanvas.createColor = function (r, g, b){
    return 0 | (+r) | (+g<<8) | (+b<<16);
};

UBCanvas.imageTypes = {
    BMP: 0,
    PNG: 1,
    JPEG: 2,
    GIF: 3
};

UBCanvas.prototype = {
    /**
     * Set Canvas width and height in pixels & fill it by provided color.
     * In case color is 0 or omitted, fill with white.
     *
     * It is mandatory to call createNew before any other Canvas operation.
     *
     * @param {Number} width
     * @param {Number} height
     * @param {Number|Object} [fillColor=0] Either a result of UBCanvas#createColor or object {r: Number, g: number, b: Number}
     */
    createNew: function(width, height, fillColor){
        var color;
        if (_.isObject(fillColor)){
            color = UBCanvas.createColor(fillColor.r, fillColor.g, fillColor.b)
        } else {
            color = fillColor || 0;
        }
        return this._nativeCanvas.createNew(width, height, color);
    },
    /**
     * Set a font for future UBCanvas#drawText operations
     * @param {String} fontName Name of font as it displayed in the OS
     * @param {Number|Object} fontColor Either a result of UBCanvas#createColor or object {r: Number, g: number, b: Number}
     * @param {Number} fontSize Font size in punkts
     * @param {Array<UBCanvas.FontStyle>} [fontStyles] Default is []
     */
    setFont: function(fontName, fontColor, fontSize, fontStyles){
        var color, style;
        if (_.isObject(fontColor)){
            color = UBCanvas.createColor(fontColor.r, fontColor.g, fontColor.b);
        } else {
            color = fontColor || 0;
        }
        style = createByteMask(fontStyles);
        return this._nativeCanvas.setFont(fontName, color, fontSize, style);
    },


    /**
     * Draw a text on the Canvas using previously defined Font
     * @param {Number} x
     * @param {Number} y
     * @param {String} text
     * @param {Number} clipWidth
     * @param {Number} clipHeight
     * @param {Array<UBCanvas.TextFormat>} [drawOptions]
     * return {{width: Number, height: Number}} text rectangle
     */
    drawText: function(x, y, text, clipWidth, clipHeight, drawOptions){
        var opt = createByteMask(drawOptions);
        return this._nativeCanvas.drawText(x, y, text, clipWidth, clipHeight, opt);
    },

    /**
     *
     * @param {String} text
     * @return {{width: Number, height: Number}}
     */
    measureText: function(text){
        return this._nativeCanvas.measureText(text);
    },

    /**
     *
     * @param {Number} x
     * @param {Number} y
     * @param {ArrayBuffer} image
     * @param {Number} [width=0] 0 - image width or calculated proportionally
     * @param {Number} [height=0] 0 - image height or calculated proportionally
     * @param {Number} [imageType=UBCanvas.imageTypes.PNG]  UBCanvas.imageTypes (0 - BMP, 1 - PNG, 2 - JPEG, 3 - GIF)
     */
    drawImage: function(x, y, image, width, height,  imageType){
        return this._nativeCanvas.drawImage(x, y, width || 0, height || 0, image, imageType || 1);
    },

    /**
     * Save Canvas content to file in PNG format
     * @param {String} fileName
     */
    saveToFile: function(fileName){
        return this._nativeCanvas.saveToFile(fileName);
    },
    /**
     * Get Canvas content. See {@link UBReader#read}
     */
    getContent: function(encoding){
        return this._nativeCanvas.getContent(encoding);
    },
    /**
     * Release all internal resources.
     * Do not use this object after call to freeNative!
     */
    freeNative: function(){
        this._nativeCanvas.freeNative();
        this._nativeCanvas = null;
    }
};

module.exports = UBCanvas;