phaser/v3/src/gameobjects/text/MeasureText.js
photonstorm a87f1ca88b TextStyle is now responsible for MeasureText and caches the results.
Lots of new TextStyle methods.
TextStyle methods return the Text object itself, so you can chain easily.
Fixed Width and Height options added.
2017-03-20 16:09:01 +00:00

126 lines
2.7 KiB
JavaScript

var CanvasPool = require('../../dom/CanvasPool');
/**
* Calculates the ascent, descent and fontSize of a given font style.
*
* @method Phaser.GameObject.Text#determineFontProperties
* @private
* @param {object} textStyle
*/
var MeasureText = function (textStyle, testString)
{
if (testString === undefined) { testString = '|MÉq'; }
/**
* @property {HTMLCanvasElement} canvas - The canvas element that the text is rendered.
*/
var canvas = CanvasPool.create(this);
/**
* @property {HTMLCanvasElement} context - The context of the canvas element that the text is rendered to.
*/
var context = canvas.getContext('2d');
textStyle.syncFont(canvas, context);
var width = Math.ceil(context.measureText(testString).width);
var baseline = width;
var height = 2 * baseline;
baseline = baseline * 1.4 | 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(testString, 0, baseline);
var output = {
ascent: 0,
descent: 0,
fontSize: 0
};
if (!context.getImageData(0, 0, width, height))
{
output.ascent = baseline;
output.descent = baseline + 6;
output.fontSize = output.ascent + output.descent;
CanvasPool.remove(canvas);
return output;
}
var imagedata = context.getImageData(0, 0, width, height).data;
var pixels = imagedata.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 (imagedata[idx + j] !== 255)
{
stop = true;
break;
}
}
if (!stop)
{
idx += line;
}
else
{
break;
}
}
output.ascent = baseline - i;
idx = pixels - 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 (imagedata[idx + j] !== 255)
{
stop = true;
break;
}
}
if (!stop)
{
idx -= line;
}
else
{
break;
}
}
output.descent = (i - baseline) + 6;
output.fontSize = output.ascent + output.descent;
CanvasPool.remove(canvas);
return output;
};
module.exports = MeasureText;