You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
5.0 KiB
JavaScript
136 lines
5.0 KiB
JavaScript
import measureText from "../ThirdParty/measureText.js";
|
|
import Color from "./Color.js";
|
|
import defaultValue from "./defaultValue.js";
|
|
import defined from "./defined.js";
|
|
import DeveloperError from "./DeveloperError.js";
|
|
|
|
var imageSmoothingEnabledName;
|
|
|
|
/**
|
|
* Writes the given text into a new canvas. The canvas will be sized to fit the text.
|
|
* If text is blank, returns undefined.
|
|
*
|
|
* @param {String} text The text to write.
|
|
* @param {Object} [options] Object with the following properties:
|
|
* @param {String} [options.font='10px sans-serif'] The CSS font to use.
|
|
* @param {String} [options.textBaseline='bottom'] The baseline of the text.
|
|
* @param {Boolean} [options.fill=true] Whether to fill the text.
|
|
* @param {Boolean} [options.stroke=false] Whether to stroke the text.
|
|
* @param {Color} [options.fillColor=Color.WHITE] The fill color.
|
|
* @param {Color} [options.strokeColor=Color.BLACK] The stroke color.
|
|
* @param {Number} [options.strokeWidth=1] The stroke width.
|
|
* @param {Color} [options.backgroundColor=Color.TRANSPARENT] The background color of the canvas.
|
|
* @param {Number} [options.padding=0] The pixel size of the padding to add around the text.
|
|
* @returns {HTMLCanvasElement|undefined} A new canvas with the given text drawn into it. The dimensions object
|
|
* from measureText will also be added to the returned canvas. If text is
|
|
* blank, returns undefined.
|
|
* @function writeTextToCanvas
|
|
*/
|
|
function writeTextToCanvas(text, options) {
|
|
//>>includeStart('debug', pragmas.debug);
|
|
if (!defined(text)) {
|
|
throw new DeveloperError("text is required.");
|
|
}
|
|
//>>includeEnd('debug');
|
|
if (text === "") {
|
|
return undefined;
|
|
}
|
|
|
|
options = defaultValue(options, defaultValue.EMPTY_OBJECT);
|
|
var font = defaultValue(options.font, "10px sans-serif");
|
|
var stroke = defaultValue(options.stroke, false);
|
|
var fill = defaultValue(options.fill, true);
|
|
var strokeWidth = defaultValue(options.strokeWidth, 1);
|
|
var backgroundColor = defaultValue(
|
|
options.backgroundColor,
|
|
Color.TRANSPARENT
|
|
);
|
|
var padding = defaultValue(options.padding, 0);
|
|
var doublePadding = padding * 2.0;
|
|
|
|
var canvas = document.createElement("canvas");
|
|
canvas.width = 1;
|
|
canvas.height = 1;
|
|
canvas.style.font = font;
|
|
|
|
var context2D = canvas.getContext("2d");
|
|
|
|
if (!defined(imageSmoothingEnabledName)) {
|
|
if (defined(context2D.imageSmoothingEnabled)) {
|
|
imageSmoothingEnabledName = "imageSmoothingEnabled";
|
|
} else if (defined(context2D.mozImageSmoothingEnabled)) {
|
|
imageSmoothingEnabledName = "mozImageSmoothingEnabled";
|
|
} else if (defined(context2D.webkitImageSmoothingEnabled)) {
|
|
imageSmoothingEnabledName = "webkitImageSmoothingEnabled";
|
|
} else if (defined(context2D.msImageSmoothingEnabled)) {
|
|
imageSmoothingEnabledName = "msImageSmoothingEnabled";
|
|
}
|
|
}
|
|
|
|
context2D.font = font;
|
|
context2D.lineJoin = "round";
|
|
context2D.lineWidth = strokeWidth;
|
|
context2D[imageSmoothingEnabledName] = false;
|
|
|
|
// textBaseline needs to be set before the measureText call. It won't work otherwise.
|
|
// It's magic.
|
|
context2D.textBaseline = defaultValue(options.textBaseline, "bottom");
|
|
|
|
// in order for measureText to calculate style, the canvas has to be
|
|
// (temporarily) added to the DOM.
|
|
canvas.style.visibility = "hidden";
|
|
document.body.appendChild(canvas);
|
|
|
|
var dimensions = measureText(context2D, text, stroke, fill);
|
|
canvas.dimensions = dimensions;
|
|
|
|
document.body.removeChild(canvas);
|
|
canvas.style.visibility = "";
|
|
|
|
//Some characters, such as the letter j, have a non-zero starting position.
|
|
//This value is used for kerning later, but we need to take it into account
|
|
//now in order to draw the text completely on the canvas
|
|
var x = -dimensions.bounds.minx;
|
|
|
|
//Expand the width to include the starting position.
|
|
var width = Math.ceil(dimensions.width) + x + doublePadding;
|
|
|
|
//While the height of the letter is correct, we need to adjust
|
|
//where we start drawing it so that letters like j and y properly dip
|
|
//below the line.
|
|
|
|
var height = dimensions.height + doublePadding;
|
|
var baseline = height - dimensions.ascent + padding;
|
|
var y = height - baseline + doublePadding;
|
|
|
|
canvas.width = width;
|
|
canvas.height = height;
|
|
|
|
// Properties must be explicitly set again after changing width and height
|
|
context2D.font = font;
|
|
context2D.lineJoin = "round";
|
|
context2D.lineWidth = strokeWidth;
|
|
context2D[imageSmoothingEnabledName] = false;
|
|
|
|
// Draw background
|
|
if (backgroundColor !== Color.TRANSPARENT) {
|
|
context2D.fillStyle = backgroundColor.toCssColorString();
|
|
context2D.fillRect(0, 0, canvas.width, canvas.height);
|
|
}
|
|
|
|
if (stroke) {
|
|
var strokeColor = defaultValue(options.strokeColor, Color.BLACK);
|
|
context2D.strokeStyle = strokeColor.toCssColorString();
|
|
context2D.strokeText(text, x + padding, y);
|
|
}
|
|
|
|
if (fill) {
|
|
var fillColor = defaultValue(options.fillColor, Color.WHITE);
|
|
context2D.fillStyle = fillColor.toCssColorString();
|
|
context2D.fillText(text, x + padding, y);
|
|
}
|
|
|
|
return canvas;
|
|
}
|
|
export default writeTextToCanvas;
|