All files text.js

82.19% Statements 60/73
72.5% Branches 29/40
90% Functions 9/10
86.44% Lines 51/59

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 1496x           6x           6x                         6x 4x                 9x 5x 5x   4x 4x 4x 4x 4x 4x                               4x     6x                       11x 11x 11x                           6x 5x 5x     5x 5x 5x 5x   5x 5x 5x 5x 5x 5x 5x 5x 5x 385x 18x 255x 98x     14x 14x 14x 14x                             6x 6x 6x 6x 6x 6x 24x   6x            
const opentype = require('opentype.js');
 
 
/**
 * @type {object} Map containing all the fonts available for use
 */
var _fonts = { };
 
/**
 * The default font family to use for text
 * @type {string}
 */
const DEFAULT_FONT_FAMILY = 'source';
 
/**
 * Register Font
 *
 * @param {string} binaryPath Path to the font binary file(.eot, .ttf etc.)
 * @param {string} family     The name to give the font
 * @param {number} weight     The font weight to use
 * @param {string} style      Font style
 * @param {string} variant    Font variant
 *
 * @returns {font} Font instance
 */
exports.registerFont = function(binaryPath, family, weight, style, variant) {
    _fonts[family] = {
        binary: binaryPath,
        family: family,
        weight: weight,
        style: style,
        variant: variant,
        loaded: false,
        font: null,
        load: function(cb) {
            if(this.loaded) {
                Eif(cb)cb();
                return;
            }
            var self = this;
            opentype.load(binaryPath, function (err, font) {
                Iif (err) throw new Error('Could not load font: ' + err);
                self.loaded = true;
                self.font = font;
                Eif(cb)cb();
            });
        },
        loadSync: function() {
            if(this.loaded) {
                return;
            }
            try {
                this.font = opentype.loadSync(binaryPath);
                this.loaded = true;
                return this;
            } catch (err) {
                throw new Error('Could not load font: ' + err);
            }
        }
    };
    return _fonts[family];
};
/**@ignore */
exports.debug_list_of_fonts = _fonts;
 
/**
 * Find Font
 *
 * Search the `fonts` array for a given font family name
 *
 * @param {string} family The name of the font family to search for
 *
 * @returns {object}
 */
function findFont(family) {
    Iif(_fonts[family]) return _fonts[family];
    family =  Object.keys(_fonts)[0];
    return _fonts[family];
}
 
/**
 * Process Text Path
 *
 * @param {Context} ctx  The {@link Context} to paint on
 * @param {string}  text The text to write to the given Context
 * @param {number}  x    X position
 * @param {number}  y    Y position
 * @param {boolean} fill Indicates wether or not the font should be filled
 *
 * @returns {void}
 */
exports.processTextPath = function(ctx,text,x,y, fill, hAlign, vAlign) {
    let font = findFont(ctx._font.family);
    Iif(!font) {
        console.warn("Font missing",ctx._font)
    }
    const metrics = exports.measureText(ctx,text)
    if(hAlign === 'start' || hAlign === 'left') /* x = x*/ ;
    if(hAlign === 'end'   || hAlign === 'right')  x = x - metrics.width
    if(hAlign === 'center')  x = x - metrics.width/2
 
    if(vAlign === 'alphabetic') /* y = y */ ;
    Iif(vAlign === 'top') y = y + metrics.emHeightAscent
    Iif(vAlign === 'middle') y = y + metrics.emHeightAscent/2+metrics.emHeightDescent/2
    if(vAlign === 'bottom') y = y + metrics.emHeightDescent
    var size = ctx._font.size;
    font.load(function(){
        var path = font.font.getPath(text, x, y, size);
        ctx.beginPath();
        path.commands.forEach(function(cmd) {
            switch(cmd.type) {
                case 'M': ctx.moveTo(cmd.x,cmd.y); break;
                case 'Q': ctx.quadraticCurveTo(cmd.x1,cmd.y1,cmd.x,cmd.y); break;
                case 'L': ctx.lineTo(cmd.x,cmd.y); break;
                case 'Z':
                {
                    ctx.closePath();
                    fill ? ctx.fill() : ctx.stroke();
                    ctx.beginPath();
                    break;
                }
            }
        });
    });
};
 
/**
 * Process Text Path
 *
 * @param {Context} ctx The {@link Context} to paint on
 * @param {string} text The name to give the font
 *
 * @returns {object}
 */
exports.measureText = function(ctx,text) {
    let font = findFont(ctx._font.family);
    Iif(!font) console.warn("WARNING. Can't find font family ", ctx._font);
    var fsize   = ctx._font.size;
    var glyphs  = font.font.stringToGlyphs(text);
    var advance = 0;
    glyphs.forEach(function(g) { advance += g.advanceWidth; });
 
    return {
        width: advance/font.font.unitsPerEm*fsize,
        emHeightAscent: font.font.ascender/font.font.unitsPerEm*fsize,
        emHeightDescent: font.font.descender/font.font.unitsPerEm*fsize,
    };
};