Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1001)

Unified Diff: third_party/WebKit/Source/devtools/scripts/spritesheet_assembler/Packer.js

Issue 2671413004: DevTools: introduce spritesheet assembler. (Closed)
Patch Set: rebaseline tests Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/devtools/scripts/spritesheet_assembler/Packer.js
diff --git a/third_party/WebKit/Source/devtools/scripts/spritesheet_assembler/Packer.js b/third_party/WebKit/Source/devtools/scripts/spritesheet_assembler/Packer.js
new file mode 100644
index 0000000000000000000000000000000000000000..b35d251b0eabcdb27678a258845f1ce501394892
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/scripts/spritesheet_assembler/Packer.js
@@ -0,0 +1,94 @@
+var SVGSpriteSheet = require('./SVGSpriteSheet');
+
+var Packer = {
+ SpriteSortOrder: {
+ // Sort by decreasing of sprite width
+ Width: (a, b) => b.width - a.width || Packer._compareNames(a, b),
+ // Sort by decreasing of sprite height
+ Height: (a, b) => b.height - a.height || Packer._compareNames(a, b),
+ // Sort by decreasing of sprite maxside
+ MaxSide: (a, b) => Math.max(b.width, b.height) - Math.max(a.width, a.height) || Packer._compareNames(a, b),
+ // Sort by decreasing of sprite area
+ Area: (a, b) => b.width * b.height - a.width * a.height || Packer._compareNames(a, b),
+ },
+
+ /**
+ * @param {!SVGSprite} spriteA
+ * @param {!SVGSprite} spriteB
+ * @return {number}
+ */
+ _compareNames: function(spriteA, spriteB) {
+ if (spriteA.filePath < spriteB.filePath)
+ return -1;
+ if (spriteA.filePath > spriteB.filePath)
+ return 1;
+ return 0;
+ },
+
+ /**
+ * @param {!Array<!SVGSprite>} sprites
+ * @param {!Packer.SpriteSortOrder} spriteComparator
+ * @param {number} rightPadding
+ * @param {number} bottomPadding
+ * @return {!SVGSpriteSheet}
+ */
+ packSprites: function(sprites, spriteComparator, rightPadding, bottomPadding) {
+ console.assert(sprites.length, 'cannot create spritesheet with 0 sprites!');
+ sprites.sort(spriteComparator);
+
+ var totalWidth = sprites[0].width + rightPadding;
+ var totalHeight = sprites[0].height + bottomPadding;
+ /** @type {!Map<!SVGSprite, !{x: number, y: number}>} */
+ var positions = new Map();
+
+ var freeSpaces = new Set();
+ freeSpaces.add({x: 0, y: 0, width: totalWidth, height: totalHeight});
+ for (var sprite of sprites) {
+ var spriteWidth = sprite.width + rightPadding;
+ var spriteHeight = sprite.height + bottomPadding;
+ var freeSpace = null;
+ for (var space of freeSpaces) {
+ if (space.width >= spriteWidth && space.height >= spriteHeight) {
+ freeSpace = space;
+ break;
+ }
+ }
+
+ if (!freeSpace) {
+ var canGrowRight = spriteHeight <= totalHeight;
+ var canGrowDown = spriteWidth <= totalWidth;
+ console.assert(canGrowDown || canGrowRight, 'cannot grow spritesheet in either direction!');
+ // Lean towards square sprite sheet.
+ var growRightAspectRatio = Math.abs(totalHeight / (totalWidth + spriteWidth) - 1);
+ var growDownAspectRatio = Math.abs((totalHeight + spriteHeight) / totalWidth - 1);
+ if (!canGrowDown || (canGrowRight && growRightAspectRatio < growDownAspectRatio)) {
+ freeSpace = {x: totalWidth, y: 0, width: spriteWidth, height: totalHeight};
+ totalWidth += spriteWidth;
+ } else {
+ freeSpace = {x: 0, y: totalHeight, width: totalWidth, height: spriteHeight};
+ totalHeight += spriteHeight;
+ }
+ } else {
+ freeSpaces.delete(freeSpace);
+ }
+
+ positions.set(sprite, {x: freeSpace.x, y: freeSpace.y});
+
+ var rightSpace =
+ {x: freeSpace.x + spriteWidth, y: freeSpace.y, width: freeSpace.width - spriteWidth, height: spriteHeight};
+ var downSpace = {
+ x: freeSpace.x,
+ y: freeSpace.y + spriteHeight,
+ width: freeSpace.width,
+ height: freeSpace.height - spriteHeight
+ };
+ if (rightSpace.width && rightSpace.height)
+ freeSpaces.add(rightSpace);
+ if (downSpace.width && downSpace.height)
+ freeSpaces.add(downSpace);
+ }
+ return new SVGSpriteSheet(totalWidth, totalHeight, positions);
+ }
+};
+
+module.exports = Packer;

Powered by Google App Engine
This is Rietveld 408576698