@openfairygui/cli 0.2.0-alpha.21 → 0.2.0-alpha.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +135 -0
- package/package.json +4 -4
package/dist/cli.mjs
CHANGED
|
@@ -9368,6 +9368,137 @@ function ensureArray(v) {
|
|
|
9368
9368
|
return Array.isArray(v) ? v : [v];
|
|
9369
9369
|
}
|
|
9370
9370
|
//#endregion
|
|
9371
|
+
//#region ../core/src/utils/jta-parser.ts
|
|
9372
|
+
/**
|
|
9373
|
+
* Parser for FairyGUI `.jta` animation files.
|
|
9374
|
+
*
|
|
9375
|
+
* Extracts individual frame textures (PNG/JPG byte arrays) from the binary format.
|
|
9376
|
+
* Used by the atlas packer to include MovieClip frames in texture atlases.
|
|
9377
|
+
*
|
|
9378
|
+
* @internal
|
|
9379
|
+
*/
|
|
9380
|
+
const FILE_MARK = "yytou";
|
|
9381
|
+
/**
|
|
9382
|
+
* Parse a `.jta` binary buffer into frame and texture data.
|
|
9383
|
+
*/
|
|
9384
|
+
function parseJta(data) {
|
|
9385
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
9386
|
+
let pos = 0;
|
|
9387
|
+
const markLen = view.getUint16(pos);
|
|
9388
|
+
pos += 2;
|
|
9389
|
+
if (pos + markLen > data.length) throw new Error("Invalid .jta file: truncated file mark");
|
|
9390
|
+
const mark = new TextDecoder("utf-8").decode(data.subarray(pos, pos + markLen));
|
|
9391
|
+
pos += markLen;
|
|
9392
|
+
if (mark !== FILE_MARK) throw new Error(`Invalid .jta file: expected "${FILE_MARK}", got "${mark}"`);
|
|
9393
|
+
const version = view.getInt32(pos);
|
|
9394
|
+
pos += 4;
|
|
9395
|
+
if (version < 100 || version > 102) throw new Error(`Unsupported .jta version: ${version}`);
|
|
9396
|
+
let fps = view.getInt8(pos);
|
|
9397
|
+
pos += 1;
|
|
9398
|
+
if (fps === 0) fps = 24;
|
|
9399
|
+
pos += 3;
|
|
9400
|
+
let boundsWidth = 0, boundsHeight = 0;
|
|
9401
|
+
if (version >= 102) {
|
|
9402
|
+
pos += 4;
|
|
9403
|
+
boundsWidth = view.getUint16(pos);
|
|
9404
|
+
pos += 2;
|
|
9405
|
+
boundsHeight = view.getUint16(pos);
|
|
9406
|
+
pos += 2;
|
|
9407
|
+
}
|
|
9408
|
+
const speed = view.getUint8(pos);
|
|
9409
|
+
pos += 1;
|
|
9410
|
+
const repeatDelay = view.getUint8(pos);
|
|
9411
|
+
pos += 1;
|
|
9412
|
+
const swing = view.getInt8(pos) === 1;
|
|
9413
|
+
pos += 1;
|
|
9414
|
+
const frameCount = view.getInt16(pos);
|
|
9415
|
+
pos += 2;
|
|
9416
|
+
if (frameCount < 0) throw new Error("Invalid .jta file: negative frame count");
|
|
9417
|
+
const frames = [];
|
|
9418
|
+
for (let i = 0; i < frameCount; i++) {
|
|
9419
|
+
const delay = view.getInt16(pos);
|
|
9420
|
+
pos += 2;
|
|
9421
|
+
const rectX = view.getInt16(pos);
|
|
9422
|
+
pos += 2;
|
|
9423
|
+
const rectY = view.getInt16(pos);
|
|
9424
|
+
pos += 2;
|
|
9425
|
+
const rectWidth = view.getInt16(pos);
|
|
9426
|
+
pos += 2;
|
|
9427
|
+
const rectHeight = view.getInt16(pos);
|
|
9428
|
+
pos += 2;
|
|
9429
|
+
const textureIndex = view.getInt16(pos);
|
|
9430
|
+
pos += 2;
|
|
9431
|
+
frames.push({
|
|
9432
|
+
delay,
|
|
9433
|
+
rectX,
|
|
9434
|
+
rectY,
|
|
9435
|
+
rectWidth,
|
|
9436
|
+
rectHeight,
|
|
9437
|
+
textureIndex
|
|
9438
|
+
});
|
|
9439
|
+
}
|
|
9440
|
+
const textureCount = view.getInt16(pos);
|
|
9441
|
+
pos += 2;
|
|
9442
|
+
if (textureCount < 0) throw new Error("Invalid .jta file: negative texture count");
|
|
9443
|
+
const textures = [];
|
|
9444
|
+
for (let i = 0; i < textureCount; i++) {
|
|
9445
|
+
const rawLen = view.getInt32(pos);
|
|
9446
|
+
pos += 4;
|
|
9447
|
+
if (rawLen < 0 || pos + rawLen > data.length) throw new Error("Invalid .jta file: truncated texture data");
|
|
9448
|
+
let raw;
|
|
9449
|
+
if (rawLen > 0) {
|
|
9450
|
+
raw = data.subarray(pos, pos + rawLen);
|
|
9451
|
+
pos += rawLen;
|
|
9452
|
+
} else raw = new Uint8Array(0);
|
|
9453
|
+
textures.push({ raw });
|
|
9454
|
+
}
|
|
9455
|
+
if (version === 101) {
|
|
9456
|
+
pos += 4;
|
|
9457
|
+
boundsWidth = view.getUint16(pos);
|
|
9458
|
+
pos += 2;
|
|
9459
|
+
boundsHeight = view.getUint16(pos);
|
|
9460
|
+
pos += 2;
|
|
9461
|
+
} else if (version === 100) {
|
|
9462
|
+
let minX = Number.POSITIVE_INFINITY;
|
|
9463
|
+
let minY = Number.POSITIVE_INFINITY;
|
|
9464
|
+
let maxX = Number.NEGATIVE_INFINITY;
|
|
9465
|
+
let maxY = Number.NEGATIVE_INFINITY;
|
|
9466
|
+
for (const frame of frames) {
|
|
9467
|
+
if (frame.rectWidth <= 0 || frame.rectHeight <= 0) continue;
|
|
9468
|
+
minX = Math.min(minX, frame.rectX);
|
|
9469
|
+
minY = Math.min(minY, frame.rectY);
|
|
9470
|
+
maxX = Math.max(maxX, frame.rectX + frame.rectWidth);
|
|
9471
|
+
maxY = Math.max(maxY, frame.rectY + frame.rectHeight);
|
|
9472
|
+
}
|
|
9473
|
+
if (Number.isFinite(minX)) {
|
|
9474
|
+
boundsWidth = maxX - Math.min(minX, 0);
|
|
9475
|
+
boundsHeight = maxY - Math.min(minY, 0);
|
|
9476
|
+
}
|
|
9477
|
+
}
|
|
9478
|
+
return {
|
|
9479
|
+
version,
|
|
9480
|
+
fps,
|
|
9481
|
+
speed,
|
|
9482
|
+
repeatDelay,
|
|
9483
|
+
swing,
|
|
9484
|
+
boundsWidth,
|
|
9485
|
+
boundsHeight,
|
|
9486
|
+
frames,
|
|
9487
|
+
textures
|
|
9488
|
+
};
|
|
9489
|
+
}
|
|
9490
|
+
function tryReadJtaSize(data) {
|
|
9491
|
+
try {
|
|
9492
|
+
const parsed = parseJta(data);
|
|
9493
|
+
return {
|
|
9494
|
+
width: parsed.boundsWidth,
|
|
9495
|
+
height: parsed.boundsHeight
|
|
9496
|
+
};
|
|
9497
|
+
} catch {
|
|
9498
|
+
return null;
|
|
9499
|
+
}
|
|
9500
|
+
}
|
|
9501
|
+
//#endregion
|
|
9371
9502
|
//#region ../core/src/document.ts
|
|
9372
9503
|
/**
|
|
9373
9504
|
* Wraps a FairyGUI project and its resources for easier modification.
|
|
@@ -12131,6 +12262,10 @@ var ProjectReader = class {
|
|
|
12131
12262
|
const data = new Uint8Array(await fs.readFileRaw(filePath));
|
|
12132
12263
|
const buffer = doc.createBuffer().setURI(sourcePath).setData(data);
|
|
12133
12264
|
this._asSourceDataResource(resource).setSourceData(buffer);
|
|
12265
|
+
if (resource.propertyType === "MovieClipResource") {
|
|
12266
|
+
const size = tryReadJtaSize(data);
|
|
12267
|
+
if (size) resource.setWidth(size.width).setHeight(size.height);
|
|
12268
|
+
}
|
|
12134
12269
|
} catch {}
|
|
12135
12270
|
}
|
|
12136
12271
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openfairygui/cli",
|
|
3
|
-
"version": "0.2.0-alpha.
|
|
3
|
+
"version": "0.2.0-alpha.22",
|
|
4
4
|
"description": "FairyGUI Headless Authoring SDK — command-line interface.",
|
|
5
5
|
"author": "OpenFairyGUI Contributors",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,13 +33,13 @@
|
|
|
33
33
|
"restore"
|
|
34
34
|
],
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@openfairygui/
|
|
37
|
-
"@openfairygui/
|
|
36
|
+
"@openfairygui/functions": "0.2.0-alpha.22",
|
|
37
|
+
"@openfairygui/core": "0.2.0-alpha.22"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"commander": "^14.0.2",
|
|
41
41
|
"jiti": "^2.7.0",
|
|
42
|
-
"@openfairygui/backend": "0.2.0-alpha.
|
|
42
|
+
"@openfairygui/backend": "0.2.0-alpha.22"
|
|
43
43
|
},
|
|
44
44
|
"optionalDependencies": {
|
|
45
45
|
"sharp": ">=0.33.0"
|