UNPKG

maplibre-gl

Version:

BSD licensed community fork of mapbox-gl, a WebGL interactive maps library

78 lines (62 loc) 2.04 kB
import {AlphaImage} from '../util/image'; import {register} from '../util/web_worker_transfer'; import potpack from 'potpack'; import type {GlyphMetrics, StyleGlyph} from '../style/style_glyph'; const padding = 1; export type Rect = { x: number; y: number; w: number; h: number; }; export type GlyphPosition = { rect: Rect; metrics: GlyphMetrics; }; export type GlyphPositions = { [_: string]: { [_: number]: GlyphPosition; }; }; export default class GlyphAtlas { image: AlphaImage; positions: GlyphPositions; constructor(stacks: { [_: string]: { [_: number]: StyleGlyph; }; }) { 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);