Get ascent and descent from context.measureText method

Get ascent and descent from context.measureText method instead of scanning image data.
This commit is contained in:
Rex 2020-08-21 10:42:24 +08:00
parent f2bd22d581
commit 29e317db39

View file

@ -26,101 +26,16 @@ var MeasureText = function (textStyle)
textStyle.syncFont(canvas, context);
var width = Math.ceil(context.measureText(textStyle.testString).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 metrics = context.measureText(textStyle.testString);
var ascent = metrics.actualBoundingBoxAscent;
var descent = metrics.actualBoundingBoxDescent;
var output = {
ascent: 0,
descent: 0,
fontSize: 0
ascent: ascent,
descent: descent,
fontSize: (ascent + descent)
};
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);
output.fontSize = output.ascent + output.descent;
CanvasPool.remove(canvas);
return output;