修正识别问题
This commit is contained in:
1 parent
d02370d6bd
commit
e7f800aa8d
8 files changed
+128
-2
No files matched your search
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
// 每次改动递增。Eagle 里的 service 插件是启动时加载并常驻的,改完代码必须重新加载插件
|
// 每次改动递增。Eagle 里的 service 插件是启动时加载并常驻的,改完代码必须重新加载插件
|
||||||
// 才会生效;状态栏会显示这个版本号,方便确认加载的到底是不是最新代码。
|
// 才会生效;状态栏会显示这个版本号,方便确认加载的到底是不是最新代码。
|
||||||
const VERSION = 'v72';
|
const VERSION = 'v73';
|
||||||
const SHOW_DEV_VERSION = true;
|
const SHOW_DEV_VERSION = true;
|
||||||
|
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|||||||
@@ -176,6 +176,11 @@ function isTextureFile(name) {
|
|||||||
return TEXTURE_EXTS.indexOf(ext) !== -1;
|
return TEXTURE_EXTS.indexOf(ext) !== -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function textureFormatOf(name) {
|
||||||
|
const ext = extOf(name);
|
||||||
|
return ext === '.jpg' || ext === '.jpeg' ? 'jpeg' : ext;
|
||||||
|
}
|
||||||
|
|
||||||
/** 去掉文件名中的扩展名 */
|
/** 去掉文件名中的扩展名 */
|
||||||
function stemOf(name) {
|
function stemOf(name) {
|
||||||
const ext = extOf(name);
|
const ext = extOf(name);
|
||||||
@@ -749,6 +754,8 @@ function discoverAssets(filePath, options) {
|
|||||||
const pageFileName = path.posix.basename(pn);
|
const pageFileName = path.posix.basename(pn);
|
||||||
let cands = textureFiles.filter((f) => f.name.toLowerCase() === pageFileName.toLowerCase());
|
let cands = textureFiles.filter((f) => f.name.toLowerCase() === pageFileName.toLowerCase());
|
||||||
if (cands.length === 0) cands = textureFiles.filter((f) => normalizeStem(f.name) === normalizeStem(pageFileName));
|
if (cands.length === 0) cands = textureFiles.filter((f) => normalizeStem(f.name) === normalizeStem(pageFileName));
|
||||||
|
const sameFormat = cands.filter((f) => textureFormatOf(f.name) === textureFormatOf(pageFileName));
|
||||||
|
if (sameFormat.length > 0) cands = sameFormat;
|
||||||
let hit = selectBest(cands, atlas.fullPath);
|
let hit = selectBest(cands, atlas.fullPath);
|
||||||
if (strictStem && hit && Math.abs(importTimeOf(hit.fullPath) - importTimeOf(atlas.fullPath)) > allowedImportDelta) hit = null;
|
if (strictStem && hit && Math.abs(importTimeOf(hit.fullPath) - importTimeOf(atlas.fullPath)) > allowedImportDelta) hit = null;
|
||||||
if (hit) texturePaths[pn] = hit.fullPath;
|
if (hit) texturePaths[pn] = hit.fullPath;
|
||||||
@@ -830,6 +837,7 @@ const spineUtilsApi = {
|
|||||||
isSkeletonFile,
|
isSkeletonFile,
|
||||||
isAtlasFile,
|
isAtlasFile,
|
||||||
isTextureFile,
|
isTextureFile,
|
||||||
|
textureFormatOf,
|
||||||
stemOf,
|
stemOf,
|
||||||
normalizeStem,
|
normalizeStem,
|
||||||
DEFAULT_SUFFIXES,
|
DEFAULT_SUFFIXES,
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const assert = require('node:assert/strict');
|
||||||
|
const fs = require('node:fs');
|
||||||
|
const os = require('node:os');
|
||||||
|
const path = require('node:path');
|
||||||
|
const utils = require('../js/spine-utils');
|
||||||
|
|
||||||
|
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'spine-mixed-atlas-'));
|
||||||
|
try {
|
||||||
|
const images = path.join(root, 'images');
|
||||||
|
fs.mkdirSync(images);
|
||||||
|
fs.writeFileSync(path.join(root, 'metadata.json'), JSON.stringify({ folders: [] }));
|
||||||
|
const makeItem = (id, name, body) => {
|
||||||
|
const directory = path.join(images, id + '.info');
|
||||||
|
fs.mkdirSync(directory);
|
||||||
|
fs.writeFileSync(path.join(directory, name), body);
|
||||||
|
fs.writeFileSync(path.join(directory, 'metadata.json'), JSON.stringify({ folders: [] }));
|
||||||
|
return path.join(directory, name);
|
||||||
|
};
|
||||||
|
const png = makeItem('png', 'hero.png', 'png');
|
||||||
|
const atlas = makeItem('atlas', 'hero.atlas', [
|
||||||
|
'hero.png',
|
||||||
|
'size: 64,64',
|
||||||
|
'format: RGBA8888',
|
||||||
|
'filter: Linear,Linear',
|
||||||
|
'repeat: none',
|
||||||
|
'',
|
||||||
|
'hero.jpeg',
|
||||||
|
'size: 32,32',
|
||||||
|
'format: RGBA8888',
|
||||||
|
'filter: Linear,Linear',
|
||||||
|
'repeat: none',
|
||||||
|
'',
|
||||||
|
].join('\n'));
|
||||||
|
const jpeg = makeItem('jpg', 'hero.jpg', 'jpg');
|
||||||
|
const assets = utils.discoverAssets(atlas, {
|
||||||
|
strictStem: true,
|
||||||
|
searchRoots: [path.dirname(png), path.dirname(atlas), path.dirname(jpeg)],
|
||||||
|
});
|
||||||
|
assert.equal(assets.texturePaths['hero.png'], png);
|
||||||
|
assert.equal(assets.texturePaths['hero.jpeg'], jpeg, 'JPEG atlas page must prefer .jpg over same-stem .png');
|
||||||
|
assert.equal(utils.textureFormatOf('photo.JPEG'), utils.textureFormatOf('photo.jpg'));
|
||||||
|
console.log('PASS: mixed PNG/JPEG atlas pages resolve to matching texture formats');
|
||||||
|
} finally {
|
||||||
|
fs.rmSync(root, { recursive: true, force: true });
|
||||||
|
}
|
||||||
@@ -173,6 +173,11 @@ function isTextureFile(name) {
|
|||||||
return TEXTURE_EXTS.indexOf(ext) !== -1;
|
return TEXTURE_EXTS.indexOf(ext) !== -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function textureFormatOf(name) {
|
||||||
|
const ext = extOf(name);
|
||||||
|
return ext === '.jpg' || ext === '.jpeg' ? 'jpeg' : ext;
|
||||||
|
}
|
||||||
|
|
||||||
/** 去掉文件名中的扩展名 */
|
/** 去掉文件名中的扩展名 */
|
||||||
function stemOf(name) {
|
function stemOf(name) {
|
||||||
const ext = extOf(name);
|
const ext = extOf(name);
|
||||||
@@ -726,6 +731,8 @@ function discoverAssets(filePath, options) {
|
|||||||
const pageFileName = path.posix.basename(pn);
|
const pageFileName = path.posix.basename(pn);
|
||||||
let cands = textureFiles.filter((f) => f.name.toLowerCase() === pageFileName.toLowerCase());
|
let cands = textureFiles.filter((f) => f.name.toLowerCase() === pageFileName.toLowerCase());
|
||||||
if (cands.length === 0) cands = textureFiles.filter((f) => normalizeStem(f.name) === normalizeStem(pageFileName));
|
if (cands.length === 0) cands = textureFiles.filter((f) => normalizeStem(f.name) === normalizeStem(pageFileName));
|
||||||
|
const sameFormat = cands.filter((f) => textureFormatOf(f.name) === textureFormatOf(pageFileName));
|
||||||
|
if (sameFormat.length > 0) cands = sameFormat;
|
||||||
let hit = selectBest(cands, atlas.fullPath);
|
let hit = selectBest(cands, atlas.fullPath);
|
||||||
if (strictStem && hit && Math.abs(importTimeOf(hit.fullPath) - importTimeOf(atlas.fullPath)) > allowedImportDelta) hit = null;
|
if (strictStem && hit && Math.abs(importTimeOf(hit.fullPath) - importTimeOf(atlas.fullPath)) > allowedImportDelta) hit = null;
|
||||||
if (hit) texturePaths[pn] = hit.fullPath;
|
if (hit) texturePaths[pn] = hit.fullPath;
|
||||||
@@ -807,6 +814,7 @@ module.exports = {
|
|||||||
isSkeletonFile,
|
isSkeletonFile,
|
||||||
isAtlasFile,
|
isAtlasFile,
|
||||||
isTextureFile,
|
isTextureFile,
|
||||||
|
textureFormatOf,
|
||||||
stemOf,
|
stemOf,
|
||||||
normalizeStem,
|
normalizeStem,
|
||||||
DEFAULT_SUFFIXES,
|
DEFAULT_SUFFIXES,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
// 每次改动递增。Eagle 里的 service 插件是启动时加载并常驻的,改完代码必须重新加载插件
|
// 每次改动递增。Eagle 里的 service 插件是启动时加载并常驻的,改完代码必须重新加载插件
|
||||||
// 才会生效;状态栏会显示这个版本号,方便确认加载的到底是不是最新代码。
|
// 才会生效;状态栏会显示这个版本号,方便确认加载的到底是不是最新代码。
|
||||||
const VERSION = 'v72';
|
const VERSION = 'v73';
|
||||||
const SHOW_DEV_VERSION = false;
|
const SHOW_DEV_VERSION = false;
|
||||||
|
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|||||||
@@ -176,6 +176,11 @@ function isTextureFile(name) {
|
|||||||
return TEXTURE_EXTS.indexOf(ext) !== -1;
|
return TEXTURE_EXTS.indexOf(ext) !== -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function textureFormatOf(name) {
|
||||||
|
const ext = extOf(name);
|
||||||
|
return ext === '.jpg' || ext === '.jpeg' ? 'jpeg' : ext;
|
||||||
|
}
|
||||||
|
|
||||||
/** 去掉文件名中的扩展名 */
|
/** 去掉文件名中的扩展名 */
|
||||||
function stemOf(name) {
|
function stemOf(name) {
|
||||||
const ext = extOf(name);
|
const ext = extOf(name);
|
||||||
@@ -749,6 +754,8 @@ function discoverAssets(filePath, options) {
|
|||||||
const pageFileName = path.posix.basename(pn);
|
const pageFileName = path.posix.basename(pn);
|
||||||
let cands = textureFiles.filter((f) => f.name.toLowerCase() === pageFileName.toLowerCase());
|
let cands = textureFiles.filter((f) => f.name.toLowerCase() === pageFileName.toLowerCase());
|
||||||
if (cands.length === 0) cands = textureFiles.filter((f) => normalizeStem(f.name) === normalizeStem(pageFileName));
|
if (cands.length === 0) cands = textureFiles.filter((f) => normalizeStem(f.name) === normalizeStem(pageFileName));
|
||||||
|
const sameFormat = cands.filter((f) => textureFormatOf(f.name) === textureFormatOf(pageFileName));
|
||||||
|
if (sameFormat.length > 0) cands = sameFormat;
|
||||||
let hit = selectBest(cands, atlas.fullPath);
|
let hit = selectBest(cands, atlas.fullPath);
|
||||||
if (strictStem && hit && Math.abs(importTimeOf(hit.fullPath) - importTimeOf(atlas.fullPath)) > allowedImportDelta) hit = null;
|
if (strictStem && hit && Math.abs(importTimeOf(hit.fullPath) - importTimeOf(atlas.fullPath)) > allowedImportDelta) hit = null;
|
||||||
if (hit) texturePaths[pn] = hit.fullPath;
|
if (hit) texturePaths[pn] = hit.fullPath;
|
||||||
@@ -830,6 +837,7 @@ const spineUtilsApi = {
|
|||||||
isSkeletonFile,
|
isSkeletonFile,
|
||||||
isAtlasFile,
|
isAtlasFile,
|
||||||
isTextureFile,
|
isTextureFile,
|
||||||
|
textureFormatOf,
|
||||||
stemOf,
|
stemOf,
|
||||||
normalizeStem,
|
normalizeStem,
|
||||||
DEFAULT_SUFFIXES,
|
DEFAULT_SUFFIXES,
|
||||||
|
|||||||
@@ -173,6 +173,11 @@ function isTextureFile(name) {
|
|||||||
return TEXTURE_EXTS.indexOf(ext) !== -1;
|
return TEXTURE_EXTS.indexOf(ext) !== -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function textureFormatOf(name) {
|
||||||
|
const ext = extOf(name);
|
||||||
|
return ext === '.jpg' || ext === '.jpeg' ? 'jpeg' : ext;
|
||||||
|
}
|
||||||
|
|
||||||
/** 去掉文件名中的扩展名 */
|
/** 去掉文件名中的扩展名 */
|
||||||
function stemOf(name) {
|
function stemOf(name) {
|
||||||
const ext = extOf(name);
|
const ext = extOf(name);
|
||||||
@@ -726,6 +731,8 @@ function discoverAssets(filePath, options) {
|
|||||||
const pageFileName = path.posix.basename(pn);
|
const pageFileName = path.posix.basename(pn);
|
||||||
let cands = textureFiles.filter((f) => f.name.toLowerCase() === pageFileName.toLowerCase());
|
let cands = textureFiles.filter((f) => f.name.toLowerCase() === pageFileName.toLowerCase());
|
||||||
if (cands.length === 0) cands = textureFiles.filter((f) => normalizeStem(f.name) === normalizeStem(pageFileName));
|
if (cands.length === 0) cands = textureFiles.filter((f) => normalizeStem(f.name) === normalizeStem(pageFileName));
|
||||||
|
const sameFormat = cands.filter((f) => textureFormatOf(f.name) === textureFormatOf(pageFileName));
|
||||||
|
if (sameFormat.length > 0) cands = sameFormat;
|
||||||
let hit = selectBest(cands, atlas.fullPath);
|
let hit = selectBest(cands, atlas.fullPath);
|
||||||
if (strictStem && hit && Math.abs(importTimeOf(hit.fullPath) - importTimeOf(atlas.fullPath)) > allowedImportDelta) hit = null;
|
if (strictStem && hit && Math.abs(importTimeOf(hit.fullPath) - importTimeOf(atlas.fullPath)) > allowedImportDelta) hit = null;
|
||||||
if (hit) texturePaths[pn] = hit.fullPath;
|
if (hit) texturePaths[pn] = hit.fullPath;
|
||||||
@@ -807,6 +814,7 @@ module.exports = {
|
|||||||
isSkeletonFile,
|
isSkeletonFile,
|
||||||
isAtlasFile,
|
isAtlasFile,
|
||||||
isTextureFile,
|
isTextureFile,
|
||||||
|
textureFormatOf,
|
||||||
stemOf,
|
stemOf,
|
||||||
normalizeStem,
|
normalizeStem,
|
||||||
DEFAULT_SUFFIXES,
|
DEFAULT_SUFFIXES,
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const assert = require('node:assert/strict');
|
||||||
|
const fs = require('node:fs');
|
||||||
|
const os = require('node:os');
|
||||||
|
const path = require('node:path');
|
||||||
|
const utils = require('../js/spine-utils');
|
||||||
|
|
||||||
|
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'spineviewer-mixed-atlas-'));
|
||||||
|
try {
|
||||||
|
const images = path.join(root, 'images');
|
||||||
|
fs.mkdirSync(images);
|
||||||
|
fs.writeFileSync(path.join(root, 'metadata.json'), JSON.stringify({ folders: [] }));
|
||||||
|
const makeItem = (id, name, body) => {
|
||||||
|
const directory = path.join(images, id + '.info');
|
||||||
|
fs.mkdirSync(directory);
|
||||||
|
fs.writeFileSync(path.join(directory, name), body);
|
||||||
|
fs.writeFileSync(path.join(directory, 'metadata.json'), JSON.stringify({ folders: [] }));
|
||||||
|
return path.join(directory, name);
|
||||||
|
};
|
||||||
|
const png = makeItem('png', 'hero.png', 'png');
|
||||||
|
const atlas = makeItem('atlas', 'hero.atlas', [
|
||||||
|
'hero.png',
|
||||||
|
'size: 64,64',
|
||||||
|
'format: RGBA8888',
|
||||||
|
'filter: Linear,Linear',
|
||||||
|
'repeat: none',
|
||||||
|
'',
|
||||||
|
'hero.jpeg',
|
||||||
|
'size: 32,32',
|
||||||
|
'format: RGBA8888',
|
||||||
|
'filter: Linear,Linear',
|
||||||
|
'repeat: none',
|
||||||
|
'',
|
||||||
|
].join('\n'));
|
||||||
|
const jpeg = makeItem('jpg', 'hero.jpg', 'jpg');
|
||||||
|
const assets = utils.discoverAssets(atlas, {
|
||||||
|
strictStem: true,
|
||||||
|
searchRoots: [path.dirname(png), path.dirname(atlas), path.dirname(jpeg)],
|
||||||
|
});
|
||||||
|
assert.equal(assets.texturePaths['hero.png'], png);
|
||||||
|
assert.equal(assets.texturePaths['hero.jpeg'], jpeg, 'JPEG atlas page must prefer .jpg over same-stem .png');
|
||||||
|
assert.equal(utils.textureFormatOf('photo.JPEG'), utils.textureFormatOf('photo.jpg'));
|
||||||
|
console.log('PASS: SpineViewer resolves mixed PNG/JPEG atlas pages by texture format');
|
||||||
|
} finally {
|
||||||
|
fs.rmSync(root, { recursive: true, force: true });
|
||||||
|
}
|
||||||
Reference in new issue
Block a user