* Fix #1446 by modifying gulp/atlas2json.js

* Clean up gulp/atlas2json.js and add more comments
pull/1280/merge
Jasper Meggitt 2 years ago committed by GitHub
parent 6a8e519c0a
commit 2d45fa8cd1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -4,124 +4,155 @@ const { readFileSync, readdirSync, writeFileSync } = require("fs");
const suffixToScale = { const suffixToScale = {
lq: "0.25", lq: "0.25",
mq: "0.5", mq: "0.5",
hq: "0.75" hq: "0.75",
}; };
function convert(srcDir) { function convert(srcDir) {
const full = resolve(srcDir); const fullPath = resolve(srcDir);
const srcFiles = readdirSync(full) const srcFiles = readdirSync(fullPath)
.filter(n => n.endsWith(".atlas")) .filter(n => n.endsWith(".atlas"))
.map(n => join(full, n)); .map(n => join(fullPath, n));
for (const atlas of srcFiles) { for (const atlas of srcFiles) {
console.log(`Processing: ${atlas}`); console.log(`Processing: ${atlas}`);
// Read all text, split it into line array // Sections for different atlas images are broken up via an extra line break
// and filter all empty lines const atlasSections = readFileSync(atlas, "utf-8")
const lines = readFileSync(atlas, "utf-8") .trim()
.split("\n") .split("\n\n");
.filter(n => n.trim());
// Get source image name
const image = lines.shift();
const srcMeta = {};
// Read all metadata (supports only one page)
while (true) {
const kv = lines.shift().split(":");
if (kv.length != 2) {
lines.unshift(kv[0]);
break;
}
srcMeta[kv[0]] = kv[1].trim(); console.log("Found " + atlasSections.length + " sections!");
// Perform the conversion for each section
for (const section of atlasSections) {
preformConversion(fullPath, section);
} }
}
}
const frames = {}; function formatImageData(keywordArgs) {
let current = null; let { name, rotate, xy, size, orig, offset, index } = keywordArgs;
lines.push("Dummy line to make it convert last frame"); // Convert to arrays because Node.js doesn't
// support latest JS features
for (const line of lines) { xy = xy.split(",").map(v => Number(v));
if (!line.startsWith(" ")) { size = size.split(",").map(v => Number(v));
// New frame, convert previous if it exists orig = orig.split(",").map(v => Number(v));
if (current != null) { offset = offset.split(",").map(v => Number(v));
let { name, rotate, xy, size, orig, offset, index } = current;
// GDX TexturePacker removes index suffixes
// Convert to arrays because Node.js doesn't let imageName = index === -1 ? `${name}.png` : `${name}_${index}.png`;
// support latest JS features
xy = xy.split(",").map(v => Number(v));
size = size.split(",").map(v => Number(v)); const frameInfo = {
orig = orig.split(",").map(v => Number(v)); // Bounds on atlas
offset = offset.split(",").map(v => Number(v)); frame: {
x: xy[0],
// GDX TexturePacker removes index suffixes y: xy[1],
const indexSuff = index != -1 ? `_${index}` : ""; w: size[0],
const isTrimmed = size != orig; h: size[1],
},
frames[`${name}${indexSuff}.png`] = {
// Bounds on atlas // Whether image was rotated
frame: { rotated: rotate === "true",
x: xy[0],
y: xy[1], // If blank space was trimmed from the image
w: size[0], trimmed: size !== orig,
h: size[1]
}, // How is the image trimmed
spriteSourceSize: {
// Whether image was rotated x: offset[0],
rotated: rotate == "true", y: (orig[1] - size[1]) - offset[1],
trimmed: isTrimmed, w: size[0],
h: size[1],
// How is the image trimmed },
spriteSourceSize: {
x: offset[0], // Original image size
y: (orig[1] - size[1]) - offset[1], sourceSize: {
w: size[0], w: orig[0],
h: size[1] h: orig[1],
}, },
};
sourceSize: {
w: orig[0], return [imageName, frameInfo];
h: orig[1] }
}
} function preformConversion(pathPrefix, atlasData) {
} // Read all text, split it into line array
// and filter all empty lines
// Simple object that will hold other metadata const lines = atlasData
current = { .split("\n")
name: line .filter(n => n.trim());
};
} else { // Get source image name
// Read and set current image metadata const image = lines.shift();
const kv = line.split(":").map(v => v.trim()); const srcMeta = {};
current[kv[0]] = isNaN(Number(kv[1])) ? kv[1] : Number(kv[1]);
} // Read all metadata
while (true) {
const nextLine = lines.shift();
// If a line does not contain a colon, we have gone too far
if (!nextLine.includes(":")) {
lines.unshift(nextLine);
break;
} }
const atlasSize = srcMeta.size.split(",").map(v => Number(v)); // Append the parsed key value pair to our metadata map
const atlasScale = suffixToScale[atlas.match(/_(\w+)\.atlas$/)[1]]; const [key, value] = nextLine.split(":");
srcMeta[key] = value.trim();
const result = JSON.stringify({ }
frames,
meta: { const frames = {};
image, let current = null;
format: srcMeta.format,
size: { for (const line of lines) {
w: atlasSize[0], if (!line.startsWith(" ")) {
h: atlasSize[1] // New frame, convert previous if it exists
}, if (current !== null) {
scale: atlasScale.toString() // Add the previous image's frame info to the frame map
const [imageName, frameInfo] = formatImageData(current);
frames[imageName] = frameInfo;
} }
});
writeFileSync(atlas.replace(".atlas", ".json"), result, { // Reset the frame info with the new frame name.
encoding: "utf-8" current = { name: line };
}); } else {
// Read and set current image metadata
const [key, value] = line.split(":").map(v => v.trim());
// Check if the value should be a number
const valueAsNum = Number(value);
current[key] = isNaN(valueAsNum) ? value : valueAsNum;
}
}
// Assuming the image was not empty, there should be one last remaining entry that needs to be added.
if (current !== null) {
// Add the previous image's frame info to the frame map
const [imageName, frameInfo] = formatImageData(current);
frames[imageName] = frameInfo;
} }
}
if (require.main == module) { const atlasSize = srcMeta.size.split(",").map(v => Number(v));
convert(process.argv[2]); const atlasScale = suffixToScale[image.match(/_([a-z]+)\d*\.png$/)[1]];
const result = JSON.stringify({
frames,
meta: {
image,
format: srcMeta.format,
size: {
w: atlasSize[0],
h: atlasSize[1],
},
scale: atlasScale.toString(),
},
});
const dstFile = join(pathPrefix, image.replace(".png", ".json"));
writeFileSync(dstFile, result, {
encoding: "utf-8",
});
} }
module.exports = { convert }; module.exports = { convert };

Loading…
Cancel
Save