Merge pull request #10527 from ahocevar/no-label-cache
Remove label cache, render text directly to target canvas
This commit is contained in:
@@ -5,7 +5,9 @@ import {getFontParameters} from '../css.js';
|
||||
import {createCanvasContext2D} from '../dom.js';
|
||||
import {clear} from '../obj.js';
|
||||
import {create as createTransform} from '../transform.js';
|
||||
import LabelCache from './canvas/LabelCache.js';
|
||||
import {executeLabelInstructions} from './canvas/Executor.js';
|
||||
import BaseObject from '../Object.js';
|
||||
import EventTarget from '../events/Target.js';
|
||||
|
||||
|
||||
/**
|
||||
@@ -164,21 +166,23 @@ export const defaultPadding = [0, 0, 0, 0];
|
||||
*/
|
||||
export const defaultLineWidth = 1;
|
||||
|
||||
/**
|
||||
* @type {BaseObject}
|
||||
*/
|
||||
export const checkedFonts = new BaseObject();
|
||||
|
||||
/**
|
||||
* The label cache for text rendering. To change the default cache size of 2048
|
||||
* entries, use {@link module:ol/structs/LRUCache#setSize}.
|
||||
* @type {LabelCache}
|
||||
* Deprecated - there is no label cache any more.
|
||||
* @type {?}
|
||||
* @api
|
||||
* @deprecated
|
||||
*/
|
||||
export const labelCache = new LabelCache();
|
||||
|
||||
|
||||
/**
|
||||
* @type {!Object<string, number>}
|
||||
*/
|
||||
export const checkedFonts = {};
|
||||
|
||||
export const labelCache = new EventTarget();
|
||||
labelCache.setSize = function() {
|
||||
console.warn('labelCache is deprecated.'); //eslint-disable-line
|
||||
};
|
||||
|
||||
/**
|
||||
* @type {CanvasRenderingContext2D}
|
||||
@@ -200,9 +204,8 @@ export const textHeights = {};
|
||||
* Clears the label cache when a font becomes available.
|
||||
* @param {string} fontSpec CSS font spec.
|
||||
*/
|
||||
export const checkFont = (function() {
|
||||
export const registerFont = (function() {
|
||||
const retries = 100;
|
||||
const checked = checkedFonts;
|
||||
const size = '32px ';
|
||||
const referenceFonts = ['monospace', 'serif'];
|
||||
const len = referenceFonts.length;
|
||||
@@ -235,19 +238,18 @@ export const checkFont = (function() {
|
||||
|
||||
function check() {
|
||||
let done = true;
|
||||
for (const font in checked) {
|
||||
if (checked[font] < retries) {
|
||||
const fonts = checkedFonts.getKeys();
|
||||
for (let i = 0, ii = fonts.length; i < ii; ++i) {
|
||||
const font = fonts[i];
|
||||
if (checkedFonts.get(font) < retries) {
|
||||
if (isAvailable.apply(this, font.split('\n'))) {
|
||||
checked[font] = retries;
|
||||
clear(textHeights);
|
||||
// Make sure that loaded fonts are picked up by Safari
|
||||
measureContext = null;
|
||||
measureFont = undefined;
|
||||
if (labelCache.getCount()) {
|
||||
labelCache.clear();
|
||||
}
|
||||
checkedFonts.set(font, retries);
|
||||
} else {
|
||||
++checked[font];
|
||||
checkedFonts.set(font, checkedFonts.get(font) + 1, true);
|
||||
done = false;
|
||||
}
|
||||
}
|
||||
@@ -267,10 +269,10 @@ export const checkFont = (function() {
|
||||
for (let i = 0, ii = families.length; i < ii; ++i) {
|
||||
const family = families[i];
|
||||
const key = font.style + '\n' + font.weight + '\n' + family;
|
||||
if (!(key in checked)) {
|
||||
checked[key] = retries;
|
||||
if (checkedFonts.get(key) === undefined) {
|
||||
checkedFonts.set(key, retries, true);
|
||||
if (!isAvailable(font.style, font.weight, family)) {
|
||||
checked[key] = 0;
|
||||
checkedFonts.set(key, 0, true);
|
||||
if (interval === undefined) {
|
||||
interval = setInterval(check, 32);
|
||||
}
|
||||
@@ -388,7 +390,7 @@ export const resetTransform = createTransform();
|
||||
* @param {CanvasRenderingContext2D} context Context.
|
||||
* @param {import("../transform.js").Transform|null} transform Transform.
|
||||
* @param {number} opacity Opacity.
|
||||
* @param {HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} image Image.
|
||||
* @param {import("./canvas/Executor.js").Label|HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} labelOrImage Label.
|
||||
* @param {number} originX Origin X.
|
||||
* @param {number} originY Origin Y.
|
||||
* @param {number} w Width.
|
||||
@@ -397,8 +399,8 @@ export const resetTransform = createTransform();
|
||||
* @param {number} y Y.
|
||||
* @param {number} scale Scale.
|
||||
*/
|
||||
export function drawImage(context,
|
||||
transform, opacity, image, originX, originY, w, h, x, y, scale) {
|
||||
export function drawImageOrLabel(context,
|
||||
transform, opacity, labelOrImage, originX, originY, w, h, x, y, scale) {
|
||||
let alpha;
|
||||
if (opacity != 1) {
|
||||
alpha = context.globalAlpha;
|
||||
@@ -408,12 +410,21 @@ export function drawImage(context,
|
||||
context.setTransform.apply(context, transform);
|
||||
}
|
||||
|
||||
context.drawImage(image, originX, originY, w, h, x, y, w * scale, h * scale);
|
||||
const isLabel = !!(/** @type {*} */ (labelOrImage).contextInstructions);
|
||||
|
||||
if (isLabel) {
|
||||
context.translate(x, y);
|
||||
context.scale(scale, scale);
|
||||
executeLabelInstructions(/** @type {import("./canvas/Executor.js").Label} */ (labelOrImage), context);
|
||||
} else {
|
||||
context.drawImage(/** @type {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} */ (labelOrImage), originX, originY, w, h, x, y, w * scale, h * scale);
|
||||
}
|
||||
|
||||
if (opacity != 1) {
|
||||
context.globalAlpha = alpha;
|
||||
}
|
||||
if (transform) {
|
||||
|
||||
if (transform || isLabel) {
|
||||
context.setTransform.apply(context, resetTransform);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import {createEmpty, createOrUpdate,
|
||||
import {lineStringLength} from '../../geom/flat/length.js';
|
||||
import {drawTextOnPath} from '../../geom/flat/textpath.js';
|
||||
import {transform2D} from '../../geom/flat/transform.js';
|
||||
import {drawImage, defaultPadding, defaultTextBaseline} from '../canvas.js';
|
||||
import {drawImageOrLabel, defaultPadding, defaultTextBaseline} from '../canvas.js';
|
||||
import CanvasInstruction from './Instruction.js';
|
||||
import {TEXT_ALIGN} from './TextBuilder.js';
|
||||
import {
|
||||
@@ -16,8 +16,7 @@ import {
|
||||
apply as applyTransform,
|
||||
setFromArray as transformSetFromArray
|
||||
} from '../../transform.js';
|
||||
import {createCanvasContext2D} from '../../dom.js';
|
||||
import {labelCache, defaultTextAlign, measureTextHeight, measureAndCacheTextWidth, measureTextWidths} from '../canvas.js';
|
||||
import {defaultTextAlign, measureTextHeight, measureAndCacheTextWidth, measureTextWidths} from '../canvas.js';
|
||||
import RBush from 'rbush/rbush.js';
|
||||
|
||||
|
||||
@@ -31,6 +30,28 @@ import RBush from 'rbush/rbush.js';
|
||||
* @property {!Object<string, import("../canvas.js").StrokeState>} strokeStates The stroke states (decluttering).
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef Label
|
||||
* @property {number} width
|
||||
* @property {number} height
|
||||
* @property {Array<string|number>} contextInstructions
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {Label} label Label.
|
||||
* @param {CanvasRenderingContext2D} context Context.
|
||||
*/
|
||||
export function executeLabelInstructions(label, context) {
|
||||
const contextInstructions = label.contextInstructions;
|
||||
for (let i = 0, ii = contextInstructions.length; i < ii; i += 2) {
|
||||
if (Array.isArray(contextInstructions[i + 1])) {
|
||||
CanvasRenderingContext2D.prototype[contextInstructions[i]].apply(context, contextInstructions[i + 1]);
|
||||
} else {
|
||||
context[contextInstructions[i]] = contextInstructions[i + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {import("../../extent.js").Extent}
|
||||
*/
|
||||
@@ -159,69 +180,66 @@ class Executor {
|
||||
* @param {string} textKey Text style key.
|
||||
* @param {string} fillKey Fill style key.
|
||||
* @param {string} strokeKey Stroke style key.
|
||||
* @return {HTMLCanvasElement} Image.
|
||||
* @return {Label} Label.
|
||||
*/
|
||||
getTextImage(text, textKey, fillKey, strokeKey) {
|
||||
let label;
|
||||
const key = strokeKey + textKey + text + fillKey + this.pixelRatio;
|
||||
createLabel(text, textKey, fillKey, strokeKey) {
|
||||
const strokeState = strokeKey ? this.strokeStates[strokeKey] : null;
|
||||
const fillState = fillKey ? this.fillStates[fillKey] : null;
|
||||
const textState = this.textStates[textKey];
|
||||
const pixelRatio = this.pixelRatio;
|
||||
const scale = textState.scale * pixelRatio;
|
||||
const align = TEXT_ALIGN[textState.textAlign || defaultTextAlign];
|
||||
const strokeWidth = strokeKey && strokeState.lineWidth ? strokeState.lineWidth : 0;
|
||||
|
||||
if (!labelCache.containsKey(key)) {
|
||||
const strokeState = strokeKey ? this.strokeStates[strokeKey] : null;
|
||||
const fillState = fillKey ? this.fillStates[fillKey] : null;
|
||||
const textState = this.textStates[textKey];
|
||||
const pixelRatio = this.pixelRatio;
|
||||
const scale = textState.scale * pixelRatio;
|
||||
const align = TEXT_ALIGN[textState.textAlign || defaultTextAlign];
|
||||
const strokeWidth = strokeKey && strokeState.lineWidth ? strokeState.lineWidth : 0;
|
||||
|
||||
const lines = text.split('\n');
|
||||
const numLines = lines.length;
|
||||
const widths = [];
|
||||
const width = measureTextWidths(textState.font, lines, widths);
|
||||
const lineHeight = measureTextHeight(textState.font);
|
||||
const height = lineHeight * numLines;
|
||||
const renderWidth = width + strokeWidth;
|
||||
const context = createCanvasContext2D(
|
||||
// make canvas 2 pixels wider to account for italic text width measurement errors
|
||||
Math.ceil((renderWidth + 2) * scale),
|
||||
Math.ceil((height + strokeWidth) * scale));
|
||||
label = context.canvas;
|
||||
labelCache.set(key, label);
|
||||
if (scale != 1) {
|
||||
context.scale(scale, scale);
|
||||
}
|
||||
context.font = textState.font;
|
||||
if (strokeKey) {
|
||||
context.strokeStyle = strokeState.strokeStyle;
|
||||
context.lineWidth = strokeWidth;
|
||||
context.lineCap = strokeState.lineCap;
|
||||
context.lineJoin = strokeState.lineJoin;
|
||||
context.miterLimit = strokeState.miterLimit;
|
||||
if (context.setLineDash && strokeState.lineDash.length) {
|
||||
context.setLineDash(strokeState.lineDash);
|
||||
context.lineDashOffset = strokeState.lineDashOffset;
|
||||
}
|
||||
}
|
||||
if (fillKey) {
|
||||
context.fillStyle = fillState.fillStyle;
|
||||
}
|
||||
context.textBaseline = 'middle';
|
||||
context.textAlign = 'center';
|
||||
const leftRight = (0.5 - align);
|
||||
const x = align * renderWidth + leftRight * strokeWidth;
|
||||
let i;
|
||||
if (strokeKey) {
|
||||
for (i = 0; i < numLines; ++i) {
|
||||
context.strokeText(lines[i], x + leftRight * widths[i], 0.5 * (strokeWidth + lineHeight) + i * lineHeight);
|
||||
}
|
||||
}
|
||||
if (fillKey) {
|
||||
for (i = 0; i < numLines; ++i) {
|
||||
context.fillText(lines[i], x + leftRight * widths[i], 0.5 * (strokeWidth + lineHeight) + i * lineHeight);
|
||||
}
|
||||
const lines = text.split('\n');
|
||||
const numLines = lines.length;
|
||||
const widths = [];
|
||||
const width = measureTextWidths(textState.font, lines, widths);
|
||||
const lineHeight = measureTextHeight(textState.font);
|
||||
const height = lineHeight * numLines;
|
||||
const renderWidth = width + strokeWidth;
|
||||
const contextInstructions = [];
|
||||
/** @type {Label} */
|
||||
const label = {
|
||||
// make canvas 2 pixels wider to account for italic text width measurement errors
|
||||
width: Math.ceil((renderWidth + 2) * scale),
|
||||
height: Math.ceil((height + strokeWidth) * scale),
|
||||
contextInstructions: contextInstructions
|
||||
};
|
||||
if (scale != 1) {
|
||||
contextInstructions.push('scale', [scale, scale]);
|
||||
}
|
||||
contextInstructions.push('font', textState.font);
|
||||
if (strokeKey) {
|
||||
contextInstructions.push('strokeStyle', strokeState.strokeStyle);
|
||||
contextInstructions.push('lineWidth', strokeWidth);
|
||||
contextInstructions.push('lineCap', strokeState.lineCap);
|
||||
contextInstructions.push('lineJoin', strokeState.lineJoin);
|
||||
contextInstructions.push('miterLimit', strokeState.miterLimit);
|
||||
if (CanvasRenderingContext2D.prototype.setLineDash && strokeState.lineDash.length) {
|
||||
contextInstructions.push('setLineDash', [strokeState.lineDash]);
|
||||
contextInstructions.push('lineDashOffset', strokeState.lineDashOffset);
|
||||
}
|
||||
}
|
||||
return labelCache.get(key, this);
|
||||
if (fillKey) {
|
||||
contextInstructions.push('fillStyle', fillState.fillStyle);
|
||||
}
|
||||
contextInstructions.push('textBaseline', 'middle');
|
||||
contextInstructions.push('textAlign', 'center');
|
||||
const leftRight = (0.5 - align);
|
||||
const x = align * renderWidth + leftRight * strokeWidth;
|
||||
let i;
|
||||
if (strokeKey) {
|
||||
for (i = 0; i < numLines; ++i) {
|
||||
contextInstructions.push('strokeText', [lines[i], x + leftRight * widths[i], 0.5 * (strokeWidth + lineHeight) + i * lineHeight]);
|
||||
}
|
||||
}
|
||||
if (fillKey) {
|
||||
for (i = 0; i < numLines; ++i) {
|
||||
contextInstructions.push('fillText', [lines[i], x + leftRight * widths[i], 0.5 * (strokeWidth + lineHeight) + i * lineHeight]);
|
||||
}
|
||||
}
|
||||
return label;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -254,7 +272,7 @@ class Executor {
|
||||
* @param {CanvasRenderingContext2D} context Context.
|
||||
* @param {number} x X.
|
||||
* @param {number} y Y.
|
||||
* @param {HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} image Image.
|
||||
* @param {Label|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} imageOrLabel Image.
|
||||
* @param {number} anchorX Anchor X.
|
||||
* @param {number} anchorY Anchor Y.
|
||||
* @param {import("../canvas.js").DeclutterGroup} declutterGroup Declutter group.
|
||||
@@ -270,11 +288,11 @@ class Executor {
|
||||
* @param {Array<*>} fillInstruction Fill instruction.
|
||||
* @param {Array<*>} strokeInstruction Stroke instruction.
|
||||
*/
|
||||
replayImage_(
|
||||
replayImageOrLabel_(
|
||||
context,
|
||||
x,
|
||||
y,
|
||||
image,
|
||||
imageOrLabel,
|
||||
anchorX,
|
||||
anchorY,
|
||||
declutterGroup,
|
||||
@@ -296,8 +314,8 @@ class Executor {
|
||||
x -= anchorX;
|
||||
y -= anchorY;
|
||||
|
||||
const w = (width + originX > image.width) ? image.width - originX : width;
|
||||
const h = (height + originY > image.height) ? image.height - originY : height;
|
||||
const w = (width + originX > imageOrLabel.width) ? imageOrLabel.width - originX : width;
|
||||
const h = (height + originY > imageOrLabel.height) ? imageOrLabel.height - originY : height;
|
||||
const boxW = padding[3] + w * scale + padding[1];
|
||||
const boxH = padding[0] + h * scale + padding[2];
|
||||
const boxX = x - padding[3];
|
||||
@@ -351,7 +369,7 @@ class Executor {
|
||||
}
|
||||
extend(declutterGroup, tmpExtent);
|
||||
const declutterArgs = intersects ?
|
||||
[context, transform ? transform.slice(0) : null, opacity, image, originX, originY, w, h, x, y, scale] :
|
||||
[context, transform ? transform.slice(0) : null, opacity, imageOrLabel, originX, originY, w, h, x, y, scale] :
|
||||
null;
|
||||
if (declutterArgs) {
|
||||
if (fillStroke) {
|
||||
@@ -365,7 +383,7 @@ class Executor {
|
||||
/** @type {Array<*>} */ (fillInstruction),
|
||||
/** @type {Array<*>} */ (strokeInstruction));
|
||||
}
|
||||
drawImage(context, transform, opacity, image, originX, originY, w, h, x, y, scale);
|
||||
drawImageOrLabel(context, transform, opacity, imageOrLabel, originX, originY, w, h, x, y, scale);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -440,7 +458,7 @@ class Executor {
|
||||
declutterData[13], declutterData[14], declutterData[15], declutterData[16],
|
||||
declutterData[11], declutterData[12]);
|
||||
}
|
||||
drawImage.apply(undefined, declutterData);
|
||||
drawImageOrLabel.apply(undefined, declutterData);
|
||||
if (currentAlpha !== opacity) {
|
||||
context.globalAlpha = currentAlpha;
|
||||
}
|
||||
@@ -459,12 +477,12 @@ class Executor {
|
||||
* @param {string} textKey The key of the text state.
|
||||
* @param {string} strokeKey The key for the stroke state.
|
||||
* @param {string} fillKey The key for the fill state.
|
||||
* @return {{label: HTMLCanvasElement, anchorX: number, anchorY: number}} The text image and its anchor.
|
||||
* @return {{label: Label, anchorX: number, anchorY: number}} The text image and its anchor.
|
||||
*/
|
||||
drawTextImageWithPointPlacement_(text, textKey, strokeKey, fillKey) {
|
||||
drawLabelWithPointPlacement_(text, textKey, strokeKey, fillKey) {
|
||||
const textState = this.textStates[textKey];
|
||||
|
||||
const label = this.getTextImage(text, textKey, fillKey, strokeKey);
|
||||
const label = this.createLabel(text, textKey, fillKey, strokeKey);
|
||||
|
||||
const strokeState = this.strokeStates[strokeKey];
|
||||
const pixelRatio = this.pixelRatio;
|
||||
@@ -472,7 +490,7 @@ class Executor {
|
||||
const baseline = TEXT_ALIGN[textState.textBaseline || defaultTextBaseline];
|
||||
const strokeWidth = strokeState && strokeState.lineWidth ? strokeState.lineWidth : 0;
|
||||
|
||||
// Remove the 2 pixels we added in getTextImage() for the anchor
|
||||
// Remove the 2 pixels we added in createLabel() for the anchor
|
||||
const width = label.width / pixelRatio - 2 * textState.scale;
|
||||
const anchorX = align * width + 2 * (0.5 - align) * strokeWidth;
|
||||
const anchorY = baseline * label.height / pixelRatio + 2 * (0.5 - baseline) * strokeWidth;
|
||||
@@ -637,7 +655,7 @@ class Executor {
|
||||
textKey = /** @type {string} */ (instruction[19]);
|
||||
strokeKey = /** @type {string} */ (instruction[20]);
|
||||
fillKey = /** @type {string} */ (instruction[21]);
|
||||
const labelWithAnchor = this.drawTextImageWithPointPlacement_(text, textKey, strokeKey, fillKey);
|
||||
const labelWithAnchor = this.drawLabelWithPointPlacement_(text, textKey, strokeKey, fillKey);
|
||||
image = labelWithAnchor.label;
|
||||
instruction[3] = image;
|
||||
const textOffsetX = /** @type {number} */ (instruction[22]);
|
||||
@@ -690,7 +708,7 @@ class Executor {
|
||||
}
|
||||
declutterGroup = declutterGroups[index];
|
||||
}
|
||||
this.replayImage_(context,
|
||||
this.replayImageOrLabel_(context,
|
||||
pixelCoordinates[d], pixelCoordinates[d + 1], image, anchorX, anchorY,
|
||||
declutterGroup, height, opacity, originX, originY, rotation, scale,
|
||||
snapToPixel, width, padding,
|
||||
@@ -747,10 +765,10 @@ class Executor {
|
||||
for (c = 0, cc = parts.length; c < cc; ++c) {
|
||||
part = parts[c]; // x, y, anchorX, rotation, chunk
|
||||
chars = /** @type {string} */ (part[4]);
|
||||
label = this.getTextImage(chars, textKey, '', strokeKey);
|
||||
label = this.createLabel(chars, textKey, '', strokeKey);
|
||||
anchorX = /** @type {number} */ (part[2]) + strokeWidth;
|
||||
anchorY = baseline * label.height + (0.5 - baseline) * 2 * strokeWidth - offsetY;
|
||||
this.replayImage_(context,
|
||||
this.replayImageOrLabel_(context,
|
||||
/** @type {number} */ (part[0]), /** @type {number} */ (part[1]), label,
|
||||
anchorX, anchorY, declutterGroup, label.height, 1, 0, 0,
|
||||
/** @type {number} */ (part[3]), pixelRatioScale, false, label.width,
|
||||
@@ -761,10 +779,10 @@ class Executor {
|
||||
for (c = 0, cc = parts.length; c < cc; ++c) {
|
||||
part = parts[c]; // x, y, anchorX, rotation, chunk
|
||||
chars = /** @type {string} */ (part[4]);
|
||||
label = this.getTextImage(chars, textKey, fillKey, '');
|
||||
label = this.createLabel(chars, textKey, fillKey, '');
|
||||
anchorX = /** @type {number} */ (part[2]);
|
||||
anchorY = baseline * label.height - offsetY;
|
||||
this.replayImage_(context,
|
||||
this.replayImageOrLabel_(context,
|
||||
/** @type {number} */ (part[0]), /** @type {number} */ (part[1]), label,
|
||||
anchorX, anchorY, declutterGroup, label.height, 1, 0, 0,
|
||||
/** @type {number} */ (part[3]), pixelRatioScale, false, label.width,
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
import LRUCache from '../../structs/LRUCache.js';
|
||||
|
||||
/**
|
||||
* @module ol/render/canvas/LabelCache
|
||||
*/
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Cache of pre-rendered labels.
|
||||
*/
|
||||
class LabelCache extends LRUCache {
|
||||
|
||||
expireCache() {
|
||||
while (this.canExpireCache()) {
|
||||
this.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default LabelCache;
|
||||
@@ -6,7 +6,7 @@ import {asColorLike} from '../../colorlike.js';
|
||||
import {intersects} from '../../extent.js';
|
||||
import {matchingChunk} from '../../geom/flat/straightchunk.js';
|
||||
import GeometryType from '../../geom/GeometryType.js';
|
||||
import {labelCache, defaultTextAlign, defaultPadding, defaultLineCap, defaultLineDashOffset, defaultLineDash, defaultLineJoin, defaultFillStyle, checkFont, defaultFont, defaultLineWidth, defaultMiterLimit, defaultStrokeStyle, defaultTextBaseline} from '../canvas.js';
|
||||
import {defaultTextAlign, defaultPadding, defaultLineCap, defaultLineDashOffset, defaultLineDash, defaultLineJoin, defaultFillStyle, registerFont, defaultFont, defaultLineWidth, defaultMiterLimit, defaultStrokeStyle, defaultTextBaseline} from '../canvas.js';
|
||||
import CanvasInstruction from './Instruction.js';
|
||||
import CanvasBuilder from './Builder.js';
|
||||
import TextPlacement from '../../style/TextPlacement.js';
|
||||
@@ -138,7 +138,6 @@ class CanvasTextBuilder extends CanvasBuilder {
|
||||
*/
|
||||
finish() {
|
||||
const instructions = super.finish();
|
||||
labelCache.expireCache();
|
||||
instructions.textStates = this.textStates;
|
||||
instructions.fillStates = this.fillStates;
|
||||
instructions.strokeStates = this.strokeStates;
|
||||
@@ -432,7 +431,7 @@ class CanvasTextBuilder extends CanvasBuilder {
|
||||
|
||||
textState = this.textState_;
|
||||
const font = textStyle.getFont() || defaultFont;
|
||||
checkFont(font);
|
||||
registerFont(font);
|
||||
const textScale = textStyle.getScale();
|
||||
textState.overflow = textStyle.getOverflow();
|
||||
textState.font = font;
|
||||
|
||||
@@ -8,9 +8,9 @@ import RenderEventType from '../render/EventType.js';
|
||||
import MapRenderer from './Map.js';
|
||||
import SourceState from '../source/State.js';
|
||||
import {replaceChildren} from '../dom.js';
|
||||
import {labelCache} from '../render/canvas.js';
|
||||
import EventType from '../events/EventType.js';
|
||||
import {listen, unlistenByKey} from '../events.js';
|
||||
import {checkedFonts} from '../render/canvas.js';
|
||||
import ObjectEventType from '../ObjectEventType.js';
|
||||
|
||||
|
||||
/**
|
||||
@@ -29,7 +29,7 @@ class CompositeMapRenderer extends MapRenderer {
|
||||
/**
|
||||
* @type {import("../events.js").EventsKey}
|
||||
*/
|
||||
this.labelCacheKey_ = listen(labelCache, EventType.CLEAR, map.redrawText.bind(map));
|
||||
this.fontChangeListenerKey_ = listen(checkedFonts, ObjectEventType.PROPERTYCHANGE, map.redrawText.bind(map));
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -73,7 +73,7 @@ class CompositeMapRenderer extends MapRenderer {
|
||||
}
|
||||
|
||||
disposeInternal() {
|
||||
unlistenByKey(this.labelCacheKey_);
|
||||
unlistenByKey(this.fontChangeListenerKey_);
|
||||
this.element_.parentNode.removeChild(this.element_);
|
||||
super.disposeInternal();
|
||||
}
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
*/
|
||||
|
||||
import {assert} from '../asserts.js';
|
||||
import EventTarget from '../events/Target.js';
|
||||
import EventType from '../events/EventType.js';
|
||||
|
||||
|
||||
/**
|
||||
@@ -25,15 +23,13 @@ import EventType from '../events/EventType.js';
|
||||
* @fires import("../events/Event.js").default
|
||||
* @template T
|
||||
*/
|
||||
class LRUCache extends EventTarget {
|
||||
class LRUCache {
|
||||
|
||||
/**
|
||||
* @param {number=} opt_highWaterMark High water mark.
|
||||
*/
|
||||
constructor(opt_highWaterMark) {
|
||||
|
||||
super();
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
@@ -82,7 +78,6 @@ class LRUCache extends EventTarget {
|
||||
this.entries_ = {};
|
||||
this.oldest_ = null;
|
||||
this.newest_ = null;
|
||||
this.dispatchEvent(EventType.CLEAR);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user