UNPKG

phaser

Version:

A fast, free and fun HTML5 Game Framework for Desktop and Mobile web browsers from the team at Phaser Studio Inc.

145 lines (115 loc) 3.43 kB
/** * @author Richard Davey <rich@phaser.io> * @copyright 2013-2025 Phaser Studio Inc. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ var CanvasPool = require('../../display/canvas/CanvasPool'); /** * Calculates the ascent, descent and fontSize of a given font style. * * @function Phaser.GameObjects.MeasureText * @since 3.0.0 * * @param {Phaser.GameObjects.TextStyle} textStyle - The TextStyle object to measure. * * @return {Phaser.Types.GameObjects.Text.TextMetrics} An object containing the ascent, descent and fontSize of the TextStyle. */ var MeasureText = function (textStyle) { var canvas = CanvasPool.create(this); var context = canvas.getContext('2d', { willReadFrequently: true }); textStyle.syncFont(canvas, context); var metrics = context.measureText(textStyle.testString); if ('actualBoundingBoxAscent' in metrics) { var ascent = metrics.actualBoundingBoxAscent; var descent = metrics.actualBoundingBoxDescent; CanvasPool.remove(canvas); return { ascent: ascent, descent: descent, fontSize: ascent + descent }; } var width = Math.ceil(metrics.width * textStyle.baselineX); var baseline = width; var height = 2 * baseline; baseline = baseline * textStyle.baselineY | 0; canvas.width = width; canvas.height = height; context.fillStyle = '#f00'; context.fillRect(0, 0, width, height); context.font = textStyle._font; context.textBaseline = 'alphabetic'; context.fillStyle = '#000'; context.fillText(textStyle.testString, 0, baseline); var output = { ascent: 0, descent: 0, fontSize: 0 }; var imagedata = context.getImageData(0, 0, width, height); if (!imagedata) { output.ascent = baseline; output.descent = baseline + 6; output.fontSize = output.ascent + output.descent; CanvasPool.remove(canvas); return output; } var pixels = imagedata.data; var numPixels = pixels.length; var line = width * 4; var i; var j; var idx = 0; var stop = false; // ascent. scan from top to bottom until we find a non red pixel for (i = 0; i < baseline; i++) { for (j = 0; j < line; j += 4) { if (pixels[idx + j] !== 255) { stop = true; break; } } if (!stop) { idx += line; } else { break; } } output.ascent = baseline - i; idx = numPixels - line; stop = false; // descent. scan from bottom to top until we find a non red pixel for (i = height; i > baseline; i--) { for (j = 0; j < line; j += 4) { if (pixels[idx + j] !== 255) { stop = true; break; } } if (!stop) { idx -= line; } else { break; } } output.descent = (i - baseline); output.fontSize = output.ascent + output.descent; CanvasPool.remove(canvas); return output; }; module.exports = MeasureText;