+TypeScript 예제
글꼴·크기는 여러 글자가 공유하고, 글자와 위치는 배치마다 보관한다. 둘을 분리해야 공통 스타일을 재사용하면서도 한 글자의 위치 변경이 다른 글자에 섞이지 않는다.
// 공유해도 되는 불변 값만 스타일 객체에 넣는다.
class GlyphStyle {
constructor(readonly font: string, readonly size: number) { Object.freeze(this); }
}
type PlacedGlyph = Readonly<{ letter: string; x: number; style: GlyphStyle }>;
// 배치별로 스타일을 새로 만들지 않고 같은 키의 객체를 재사용한다.
class StylePool {
private readonly fonts = new Map<string, Map<number, GlyphStyle>>();
get(font: string, size: number): GlyphStyle {
let sizes = this.fonts.get(font);
if (!sizes) { sizes = new Map(); this.fonts.set(font, sizes); }
let style = sizes.get(size);
if (!style) { style = new GlyphStyle(font, size); sizes.set(size, style); }
return style;
}
get count(): number { return [...this.fonts.values()].reduce((n, sizes) => n + sizes.size, 0); }
}
const pool = new StylePool();
const letters: PlacedGlyph[] = [
{ letter: "A", x: 0, style: pool.get("Serif", 16) },
{ letter: "B", x: 20, style: pool.get("Serif", 16) },
];
for (const glyph of letters) console.log(glyph.letter + "@" + glyph.x);
console.log("styles: " + pool.count);
A@0
B@20
styles: 1
Object.freeze로 공유 스타일을 변경하지 못하게 했고, 풀은 글꼴과 크기 두 키로 찾는다. 이 풀의 보관 수명이나 크기 제한은 별도 정책이므로 예제에는 넣지 않았다.