forked from maplibre/maplibre-gl-js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathglyph_atlas.ts
83 lines (68 loc) · 2.1 KB
/
glyph_atlas.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
import {AlphaImage} from '../util/image';
import {register} from '../util/web_worker_transfer';
import potpack from 'potpack';
import type {GlyphMetrics} from '../style/style_glyph';
import type {GetGlyphsResponse} from '../util/actor_messages';
const padding = 1;
/**
* A rectangle type with postion, width and height.
*/
export type Rect = {
x: number;
y: number;
w: number;
h: number;
};
/**
* The glyph's position
*/
export type GlyphPosition = {
rect: Rect;
metrics: GlyphMetrics;
};
/**
* The glyphs' positions
*/
export type GlyphPositions = {
[_: string]: {
[_: number]: GlyphPosition;
};
};
export class GlyphAtlas {
image: AlphaImage;
positions: GlyphPositions;
constructor(stacks: GetGlyphsResponse) {
const positions = {};
const bins = [];
for (const stack in stacks) {
const glyphs = stacks[stack];
const stackPositions = positions[stack] = {};
for (const id in glyphs) {
const src = glyphs[+id];
if (!src || src.bitmap.width === 0 || src.bitmap.height === 0) continue;
const bin = {
x: 0,
y: 0,
w: src.bitmap.width + 2 * padding,
h: src.bitmap.height + 2 * padding
};
bins.push(bin);
stackPositions[id] = {rect: bin, metrics: src.metrics};
}
}
const {w, h} = potpack(bins);
const image = new AlphaImage({width: w || 1, height: h || 1});
for (const stack in stacks) {
const glyphs = stacks[stack];
for (const id in glyphs) {
const src = glyphs[+id];
if (!src || src.bitmap.width === 0 || src.bitmap.height === 0) continue;
const bin = positions[stack][id].rect;
AlphaImage.copy(src.bitmap, image, {x: 0, y: 0}, {x: bin.x + padding, y: bin.y + padding}, src.bitmap);
}
}
this.image = image;
this.positions = positions;
}
}
register('GlyphAtlas', GlyphAtlas);