84 lines
2.1 KiB
TypeScript
84 lines
2.1 KiB
TypeScript
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);
|