Skip to content

Commit

Permalink
avoid expensive resizing in image/glyph atlases
Browse files Browse the repository at this point in the history
  • Loading branch information
mourner committed Aug 8, 2018
1 parent 9a53717 commit c35b5b2
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 56 deletions.
54 changes: 25 additions & 29 deletions src/render/glyph_atlas.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,47 +26,43 @@ export default class GlyphAtlas {
positions: { [string]: { [number]: GlyphPosition } };

constructor(stacks: { [string]: { [number]: ?StyleGlyph } }) {
const image = new AlphaImage({width: 0, height: 0});
const positions = {};

const pack = new ShelfPack(0, 0, {autoResize: true});
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) {
const bin = pack.packOne(
src.bitmap.width + 2 * padding,
src.bitmap.height + 2 * padding);

image.resize({
width: pack.w,
height: pack.h
});

AlphaImage.copy(
src.bitmap,
image,
{x: 0, y: 0},
{
x: bin.x + padding,
y: bin.y + padding
},
src.bitmap);

stackPositions[id] = {rect: bin, metrics: src.metrics};
}
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};
}
}

pack.shrink();
image.resize({
width: pack.w,
height: pack.h
});
pack.pack(bins, {inPlace: true});

const image = new AlphaImage({width: pack.w, height: pack.h});

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;
Expand Down
44 changes: 17 additions & 27 deletions src/render/image_atlas.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,41 +52,31 @@ export default class ImageAtlas {
positions: {[string]: ImagePosition};

constructor(images: {[string]: StyleImage}) {
const image = new RGBAImage({width: 0, height: 0});
const positions = {};

const pack = new ShelfPack(0, 0, {autoResize: true});
const bins = [];

for (const id in images) {
const src = images[id];

const bin = pack.packOne(
src.data.width + 2 * padding,
src.data.height + 2 * padding);

image.resize({
width: pack.w,
height: pack.h
});

RGBAImage.copy(
src.data,
image,
{ x: 0, y: 0 },
{
x: bin.x + padding,
y: bin.y + padding
},
src.data);

const bin = {
x: 0,
y: 0,
w: src.data.width + 2 * padding,
h: src.data.height + 2 * padding,
};
bins.push(bin);
positions[id] = new ImagePosition(bin, src);
}

pack.shrink();
image.resize({
width: pack.w,
height: pack.h
});
pack.pack(bins, {inPlace: true});

const image = new RGBAImage({width: pack.w, height: pack.h});

for (const id in images) {
const src = images[id];
const bin = positions[id].paddedRect;
RGBAImage.copy(src.data, image, {x: 0, y: 0}, {x: bin.x + padding, y: bin.y + padding}, src.data);
}

this.image = image;
this.positions = positions;
Expand Down

0 comments on commit c35b5b2

Please sign in to comment.