Spaces:
Sleeping
Sleeping
File size: 1,997 Bytes
fcf3b03 | 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 | // @flow
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);
|