-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
/
cache.ts
90 lines (84 loc) · 2.97 KB
/
cache.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import { config } from './config';
import type { TRectBounds } from './typedefs';
export class Cache {
/**
* Cache of widths of chars in text rendering.
*/
charWidthsCache: Record<
/** fontFamily */ string,
Record<
/** fontStyleCacheKey */ string,
Record</** char */ string, /** width */ number>
>
> = {};
/**
* @return {Object} reference to cache
*/
getFontCache({
fontFamily,
fontStyle,
fontWeight,
}: {
fontFamily: string;
fontStyle: string;
fontWeight: string | number;
}) {
fontFamily = fontFamily.toLowerCase();
if (!this.charWidthsCache[fontFamily]) {
this.charWidthsCache[fontFamily] = {};
}
const fontCache = this.charWidthsCache[fontFamily];
const cacheKey = `${fontStyle.toLowerCase()}_${(
fontWeight + ''
).toLowerCase()}`;
if (!fontCache[cacheKey]) {
fontCache[cacheKey] = {};
}
return fontCache[cacheKey];
}
/**
* Clear char widths cache for the given font family or all the cache if no
* fontFamily is specified.
* Use it if you know you are loading fonts in a lazy way and you are not waiting
* for custom fonts to load properly when adding text objects to the canvas.
* If a text object is added when its own font is not loaded yet, you will get wrong
* measurement and so wrong bounding boxes.
* After the font cache is cleared, either change the textObject text content or call
* initDimensions() to trigger a recalculation
* @param {String} [fontFamily] font family to clear
*/
clearFontCache(fontFamily?: string) {
fontFamily = (fontFamily || '').toLowerCase();
if (!fontFamily) {
this.charWidthsCache = {};
} else if (this.charWidthsCache[fontFamily]) {
delete this.charWidthsCache[fontFamily];
}
}
/**
* Given current aspect ratio, determines the max width and height that can
* respect the total allowed area for the cache.
* @param {number} ar aspect ratio
* @return {number[]} Limited dimensions X and Y
*/
limitDimsByArea(ar: number) {
const { perfLimitSizeTotal } = config;
const roughWidth = Math.sqrt(perfLimitSizeTotal * ar);
// we are not returning a point on purpose, to avoid circular dependencies
// this is an internal utility
return [
Math.floor(roughWidth),
Math.floor(perfLimitSizeTotal / roughWidth),
];
}
/**
* This object keeps the results of the boundsOfCurve calculation mapped by the joined arguments necessary to calculate it.
* It does speed up calculation, if you parse and add always the same paths, but in case of heavy usage of freedrawing
* you do not get any speed benefit and you get a big object in memory.
* The object was a private variable before, while now is appended to the lib so that you have access to it and you
* can eventually clear it.
* It was an internal variable, is accessible since version 2.3.4
*/
boundsOfCurveCache: Record<string, TRectBounds> = {};
}
export const cache = new Cache();