Skip to content

Commit

Permalink
Merge branch 'vdumont-layout_unique'
Browse files Browse the repository at this point in the history
  • Loading branch information
bhousel committed Jun 6, 2016
2 parents 70755ad + 8ae840b commit 00dd132
Show file tree
Hide file tree
Showing 17 changed files with 14,038 additions and 6,113 deletions.
74 changes: 65 additions & 9 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,55 @@ function heightAscThanNameComparator(a, b) {
* @param {Function} callback
*/
function generateLayout(imgs, pixelRatio, format, callback) {
assert(typeof pixelRatio === 'number' && Array.isArray(imgs));
var q = new queue();
return generateLayoutInternal(imgs, pixelRatio, format, false, callback);
}

/**
* Same as generateLayout but can be used to dedupe identical SVGs
* and still preserve the reference.
* For example if A.svg and B.svg are identical, a single icon
* will be in the sprite image and both A and B will reference the same image
*/
function generateLayoutUnique(imgs, pixelRatio, format, callback) {
return generateLayoutInternal(imgs, pixelRatio, format, true, callback);
}

function generateLayoutInternal(imgs, pixelRatio, format, unique, callback) {
assert(typeof pixelRatio === 'number' && Array.isArray(imgs));

if (unique) {
/* If 2 items are pointing to identical buffers (svg icons)
* create a single image in the sprite but have all ids point to it
* Remove duplicates from imgs, but if format == true then when creating the
* resulting layout, make sure all item that had the same signature
* of an item are also updated with the same layout information.
*/

/* The svg signature of each item */
var svgPerItemId = {}

/* The items for each SVG signature */
var itemIdsPerSvg = {};

imgs.forEach(function(item) {
var svg = item.svg.toString('base64');

svgPerItemId[item.id] = svg;

if (svg in itemIdsPerSvg) {
itemIdsPerSvg[svg].push(item.id);
} else {
itemIdsPerSvg[svg] = [item.id];
}
});

/* Only keep 1 item per svg signature for packing */
imgs = imgs.filter(function(item) {
var svg = svgPerItemId[item.id];
return item.id === itemIdsPerSvg[svg][0]
});
}

function createImagesWithSize(img, callback) {
mapnik.Image.fromSVGBytes(img.svg, { scale: pixelRatio }, function(err, image) {
if (err) return callback(err);
Expand All @@ -36,6 +82,8 @@ function generateLayout(imgs, pixelRatio, format, callback) {
});
}

var q = new queue();

imgs.forEach(function(img) {
q.defer(createImagesWithSize, img);
});
Expand All @@ -51,13 +99,20 @@ function generateLayout(imgs, pixelRatio, format, callback) {
if (format) {
var obj = {};
imagesWithSizes.forEach(function(item) {
obj[item.id] = {
width: item.width,
height: item.height,
x: item.x,
y: item.y,
pixelRatio: pixelRatio
};
var itemIdsToUpdate = [item.id];
if (unique) {
var svg = svgPerItemId[item.id];
itemIdsToUpdate = itemIdsPerSvg[svg];
}
itemIdsToUpdate.forEach(function(itemIdToUpdate) {
obj[itemIdToUpdate] = {
width: item.width,
height: item.height,
x: item.x,
y: item.y,
pixelRatio: pixelRatio
};
});
});
return callback(null, obj);

Expand All @@ -72,6 +127,7 @@ function generateLayout(imgs, pixelRatio, format, callback) {
});
}
module.exports.generateLayout = generateLayout;
module.exports.generateLayoutUnique = generateLayoutUnique;

/**
* Generate a PNG image with positioned icons on a sprite.
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
"mapnik": "~3.5.0",
"queue-async": "^1.0.7",
"shelf-pack": "1.0.0",
"xtend": "^4.0.1"
"xtend": "^4.0.1",
"json-stable-stringify": "^1.0.1"
},
"devDependencies": {
"dox": "^0.8.0",
Expand Down
Loading

0 comments on commit 00dd132

Please sign in to comment.