import BoundingRect from '../core/BoundingRect.js'; import LRU from '../core/LRU.js'; import { DEFAULT_FONT, platformApi } from '../core/platform.js'; var textWidthCache = {}; export function getWidth(text, font) { font = font || DEFAULT_FONT; var cacheOfFont = textWidthCache[font]; if (!cacheOfFont) { cacheOfFont = textWidthCache[font] = new LRU(500); } var width = cacheOfFont.get(text); if (width == null) { width = platformApi.measureText(text, font).width; cacheOfFont.put(text, width); } return width; } export function innerGetBoundingRect(text, font, textAlign, textBaseline) { var width = getWidth(text, font); var height = getLineHeight(font); var x = adjustTextX(0, width, textAlign); var y = adjustTextY(0, height, textBaseline); var rect = new BoundingRect(x, y, width, height); return rect; } export function getBoundingRect(text, font, textAlign, textBaseline) { var textLines = ((text || '') + '').split('\n'); var len = textLines.length; if (len === 1) { return innerGetBoundingRect(textLines[0], font, textAlign, textBaseline); } else { var uniondRect = new BoundingRect(0, 0, 0, 0); for (var i = 0; i < textLines.length; i++) { var rect = innerGetBoundingRect(textLines[i], font, textAlign, textBaseline); i === 0 ? uniondRect.copy(rect) : uniondRect.union(rect); } return uniondRect; } } export function adjustTextX(x, width, textAlign) { if (textAlign === 'right') { x -= width; } else if (textAlign === 'center') { x -= width / 2; } return x; } export function adjustTextY(y, height, verticalAlign) { if (verticalAlign === 'middle') { y -= height / 2; } else if (verticalAlign === 'bottom') { y -= height; } return y; } export function getLineHeight(font) { return getWidth('国', font); } export function measureText(text, font) { return platformApi.measureText(text, font); } export function parsePercent(value, maxValue) { if (typeof value === 'string') { if (value.lastIndexOf('%') >= 0) { return parseFloat(value) / 100 * maxValue; } return parseFloat(value); } return value; } export function calculateTextPosition(out, opts, rect) { var textPosition = opts.position || 'inside'; var distance = opts.distance != null ? opts.distance : 5; var height = rect.height; var width = rect.width; var halfHeight = height / 2; var x = rect.x; var y = rect.y; var textAlign = 'left'; var textVerticalAlign = 'top'; if (textPosition instanceof Array) { x += parsePercent(textPosition[0], rect.width); y += parsePercent(textPosition[1], rect.height); textAlign = null; textVerticalAlign = null; } else { switch (textPosition) { case 'left': x -= distance; y += halfHeight; textAlign = 'right'; textVerticalAlign = 'middle'; break; case 'right': x += distance + width; y += halfHeight; textVerticalAlign = 'middle'; break; case 'top': x += width / 2; y -= distance; textAlign = 'center'; textVerticalAlign = 'bottom'; break; case 'bottom': x += width / 2; y += height + distance; textAlign = 'center'; break; case 'inside': x += width / 2; y += halfHeight; textAlign = 'center'; textVerticalAlign = 'middle'; break; case 'insideLeft': x += distance; y += halfHeight; textVerticalAlign = 'middle'; break; case 'insideRight': x += width - distance; y += halfHeight; textAlign = 'right'; textVerticalAlign = 'middle'; break; case 'insideTop': x += width / 2; y += distance; textAlign = 'center'; break; case 'insideBottom': x += width / 2; y += height - distance; textAlign = 'center'; textVerticalAlign = 'bottom'; break; case 'insideTopLeft': x += distance; y += distance; break; case 'insideTopRight': x += width - distance; y += distance; textAlign = 'right'; break; case 'insideBottomLeft': x += distance; y += height - distance; textVerticalAlign = 'bottom'; break; case 'insideBottomRight': x += width - distance; y += height - distance; textAlign = 'right'; textVerticalAlign = 'bottom'; break; } } out = out || {}; out.x = x; out.y = y; out.align = textAlign; out.verticalAlign = textVerticalAlign; return out; }