_determineFontProperties(fontStyle)
    {
        if (CanvasTextWriter.fontPropertiesCache[fontStyle])
        {
            return CanvasTextWriter.fontPropertiesCache[fontStyle];
        }

        const properties = CanvasTextWriter.fontPropertiesCache[fontStyle];

        // initialize if necessary
        if (!CanvasTextWriter.fontPropertiesCanvas)
        {
            CanvasTextWriter.fontPropertiesCanvas = document.createElement('canvas');
            CanvasTextWriter.fontPropertiesContext = CanvasTextWriter.fontPropertiesCanvas.getContext('2d');
        }

        const canvas = CanvasTextWriter.fontPropertiesCanvas;
        const context = CanvasTextWriter.fontPropertiesContext;
        const testText = '|MÉqg';

        context.textBaseline = 'alphabetic';
        context.fillStyle = '#000';
        context.font = fontStyle;

        const width = Math.ceil(context.measureText(testText).width);
        const mwidth = Math.ceil(context.measureText('M').width);
        const baseline = Math.ceil(mwidth * 1.5);
        const height = 2 * mwidth;

        canvas.width = width;
        canvas.height = height;

        context.fillStyle = '#f00';
        context.fillRect(0, 0, width, height);
        context.fillText(testText, 0, baseline);

        const imagedata = context.getImageData(0, 0, width, height).data;
        const maxX = width * 4;

        let y = 0;
        let x = 0;

        // ascent. scan from top to bottom until we find a non red pixel
        ascent:
        for (y = 0; y < baseline; ++y)
        {
            for (x = 0; x < maxX; x += 4)
            {
                if (imagedata[(y * maxX) + x] !== 255)
                {
                    break ascent;
                }
            }
        }

        properties.ascent = baseline - y;

        // descent. scan from bottom to top until we find a non red pixel
        descent:
        for (y = height; y > baseline; --y)
        {
            for (x = 0; x < maxX; x += 4)
            {
                if (imagedata[(y * maxX) + x] !== 255)
                {
                    break descent;
                }
            }
        }

        properties.descent = y - baseline;
        properties.fontSize = properties.ascent + properties.descent;

        return properties;
    }
/**
     * Calculates the ascent, descent and fontSize of a given fontStyle
     *
     * @private
     * @param {string} fontStyle - String representing the style of the font
     * @return {Object} Font properties object
     */
Calculates the ascent, descent and fontSize of a given fontStyle
@private
@param {string} fontStyle - String representing the style of the font
@return {Object} Font properties object
Calculates the ascent descent and fontSize of a given fontStyle @private @param { string } fontStyle - String representing the style of the font @return { Object } Font properties object
_determineFontProperties(fontStyle)
    {
        if (CanvasTextWriter.fontPropertiesCache[fontStyle])
        {
            return CanvasTextWriter.fontPropertiesCache[fontStyle];
        }
        const properties = CanvasTextWriter.fontPropertiesCache[fontStyle];
        if (!CanvasTextWriter.fontPropertiesCanvas)
        {
            CanvasTextWriter.fontPropertiesCanvas = document.createElement('canvas');
            CanvasTextWriter.fontPropertiesContext = CanvasTextWriter.fontPropertiesCanvas.getContext('2d');
        }
        const canvas = CanvasTextWriter.fontPropertiesCanvas;
        const context = CanvasTextWriter.fontPropertiesContext;
        const testText = '|MÉqg';
        context.textBaseline = 'alphabetic';
        context.fillStyle = '#000';
        context.font = fontStyle;
        const width = Math.ceil(context.measureText(testText).width);
        const mwidth = Math.ceil(context.measureText('M').width);
        const baseline = Math.ceil(mwidth * 1.5);
        const height = 2 * mwidth;
        canvas.width = width;
        canvas.height = height;
        context.fillStyle = '#f00';
        context.fillRect(0, 0, width, height);
        context.fillText(testText, 0, baseline);
        const imagedata = context.getImageData(0, 0, width, height).data;
        const maxX = width * 4;
        let y = 0;
        let x = 0;
        ascent:
        for (y = 0; y < baseline; ++y)
        {
            for (x = 0; x < maxX; x += 4)
            {
                if (imagedata[(y * maxX) + x] !== 255)
                {
                    break ascent;
                }
            }
        }
        properties.ascent = baseline - y;
        descent:
        for (y = height; y > baseline; --y)
        {
            for (x = 0; x < maxX; x += 4)
            {
                if (imagedata[(y * maxX) + x] !== 255)
                {
                    break descent;
                }
            }
        }
        properties.descent = y - baseline;
        properties.fontSize = properties.ascent + properties.descent;
        return properties;
    }
_determineFontProperties ( fontStyle ) { if ( CanvasTextWriter . fontPropertiesCache [ fontStyle ] ) { return CanvasTextWriter . fontPropertiesCache [ fontStyle ] ; } const properties = CanvasTextWriter . fontPropertiesCache [ fontStyle ] ; if ( ! CanvasTextWriter . fontPropertiesCanvas ) { CanvasTextWriter . fontPropertiesCanvas = document . createElement ( 'canvas' ) ; CanvasTextWriter . fontPropertiesContext = CanvasTextWriter . fontPropertiesCanvas . getContext ( '2d' ) ; } const canvas = CanvasTextWriter . fontPropertiesCanvas ; const context = CanvasTextWriter . fontPropertiesContext ; const testText = '|MÉqg'; context . textBaseline = 'alphabetic' ; context . fillStyle = '#000' ; context . font = fontStyle ; const width = Math . ceil ( context . measureText ( testText ) . width ) ; const mwidth = Math . ceil ( context . measureText ( 'M' ) . width ) ; const baseline = Math . ceil ( mwidth * 1.5 ) ; const height = 2 * mwidth ; canvas . width = width ; canvas . height = height ; context . fillStyle = '#f00' ; context . fillRect ( 0 , 0 , width , height ) ; context . fillText ( testText , 0 , baseline ) ; const imagedata = context . getImageData ( 0 , 0 , width , height ) . data ; const maxX = width * 4 ; let y = 0 ; let x = 0 ; ascent : for ( y = 0 ; y < baseline ; ++ y ) { for ( x = 0 ; x < maxX ; x += 4 ) { if ( imagedata [ ( y * maxX ) + x ] !== 255 ) { break ascent ; } } } properties . ascent = baseline - y ; descent : for ( y = height ; y > baseline ; -- y ) { for ( x = 0 ; x < maxX ; x += 4 ) { if ( imagedata [ ( y * maxX ) + x ] !== 255 ) { break descent ; } } } properties . descent = y - baseline ; properties . fontSize = properties . ascent + properties . descent ; return properties ; }
Calculates the ascent, descent and fontSize of a given fontStyle
 @private
 @param {string} fontStyle - String representing the style of the font
 @return {Object} Font properties object
Calculates the ascent descent and fontSize of a given fontStyle @private @param { string } fontStyle - String representing the style of the font @return { Object } Font properties object
// initialize if necessary // ascent. scan from top to bottom until we find a non red pixel // descent. scan from bottom to top until we find a non red pixel