mirror of
https://github.com/scratchfoundation/scratch-vm.git
synced 2025-07-09 12:33:58 -04:00
Merge pull request #1126 from fsih/fixQuirksOnLoadCostume
Run quirks mode fixes on costumes loaded from sb2s
This commit is contained in:
commit
5c003641f9
4 changed files with 40 additions and 5 deletions
src
|
@ -917,6 +917,14 @@ class Runtime extends EventEmitter {
|
||||||
this.renderer = renderer;
|
this.renderer = renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the svg adapter, which converts scratch 2 svgs to scratch 3 svgs
|
||||||
|
* @param {!SvgRenderer} svgAdapter The adapter to attach
|
||||||
|
*/
|
||||||
|
attachV2SVGAdapter (svgAdapter) {
|
||||||
|
this.v2SvgAdapter = svgAdapter;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attach the storage module
|
* Attach the storage module
|
||||||
* @param {!ScratchStorage} storage The storage module to attach
|
* @param {!ScratchStorage} storage The storage module to attach
|
||||||
|
|
|
@ -11,9 +11,11 @@ const log = require('../util/log');
|
||||||
* @property {number} [bitmapResolution] - the resolution scale for a bitmap costume.
|
* @property {number} [bitmapResolution] - the resolution scale for a bitmap costume.
|
||||||
* @param {!Asset} costumeAsset - the asset of the costume loaded from storage.
|
* @param {!Asset} costumeAsset - the asset of the costume loaded from storage.
|
||||||
* @param {!Runtime} runtime - Scratch runtime, used to access the storage module.
|
* @param {!Runtime} runtime - Scratch runtime, used to access the storage module.
|
||||||
|
* @param {?int} optVersion - Version of Scratch that the costume comes from. If this is set
|
||||||
|
* to 2, scratch 3 will perform an upgrade step to handle quirks in SVGs from Scratch 2.0.
|
||||||
* @returns {?Promise} - a promise which will resolve after skinId is set, or null on error.
|
* @returns {?Promise} - a promise which will resolve after skinId is set, or null on error.
|
||||||
*/
|
*/
|
||||||
const loadCostumeFromAsset = function (costume, costumeAsset, runtime) {
|
const loadCostumeFromAsset = function (costume, costumeAsset, runtime, optVersion) {
|
||||||
costume.assetId = costumeAsset.assetId;
|
costume.assetId = costumeAsset.assetId;
|
||||||
const renderer = runtime.renderer;
|
const renderer = runtime.renderer;
|
||||||
if (!renderer) {
|
if (!renderer) {
|
||||||
|
@ -29,9 +31,24 @@ const loadCostumeFromAsset = function (costume, costumeAsset, runtime) {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
if (costumeAsset.assetType === AssetType.ImageVector) {
|
if (costumeAsset.assetType === AssetType.ImageVector) {
|
||||||
|
let svgString = costumeAsset.decodeText();
|
||||||
|
// SVG Renderer load fixes "quirks" associated with Scratch 2 projects
|
||||||
|
if (optVersion && optVersion === 2 && runtime.v2SvgAdapter) {
|
||||||
|
runtime.v2SvgAdapter.loadString(svgString);
|
||||||
|
svgString = runtime.v2SvgAdapter.toString();
|
||||||
|
// Put back into storage
|
||||||
|
const storage = runtime.storage;
|
||||||
|
costumeAsset.encodeTextData(svgString, storage.DataFormat.SVG);
|
||||||
|
costume.assetId = storage.builtinHelper.cache(
|
||||||
|
storage.AssetType.ImageVector,
|
||||||
|
storage.DataFormat.SVG,
|
||||||
|
costumeAsset.data
|
||||||
|
);
|
||||||
|
costume.md5 = `${costume.assetId}.${costume.dataFormat}`;
|
||||||
|
}
|
||||||
// createSVGSkin does the right thing if rotationCenter isn't provided, so it's okay if it's
|
// createSVGSkin does the right thing if rotationCenter isn't provided, so it's okay if it's
|
||||||
// undefined here
|
// undefined here
|
||||||
costume.skinId = renderer.createSVGSkin(costumeAsset.decodeText(), rotationCenter);
|
costume.skinId = renderer.createSVGSkin(svgString, rotationCenter);
|
||||||
costume.size = renderer.getSkinSize(costume.skinId);
|
costume.size = renderer.getSkinSize(costume.skinId);
|
||||||
// Now we should have a rotationCenter even if we didn't before
|
// Now we should have a rotationCenter even if we didn't before
|
||||||
if (!rotationCenter) {
|
if (!rotationCenter) {
|
||||||
|
@ -86,9 +103,11 @@ const loadCostumeFromAsset = function (costume, costumeAsset, runtime) {
|
||||||
* @property {number} rotationCenterY - the Y component of the costume's origin.
|
* @property {number} rotationCenterY - the Y component of the costume's origin.
|
||||||
* @property {number} [bitmapResolution] - the resolution scale for a bitmap costume.
|
* @property {number} [bitmapResolution] - the resolution scale for a bitmap costume.
|
||||||
* @param {!Runtime} runtime - Scratch runtime, used to access the storage module.
|
* @param {!Runtime} runtime - Scratch runtime, used to access the storage module.
|
||||||
|
* @param {?int} optVersion - Version of Scratch that the costume comes from. If this is set
|
||||||
|
* to 2, scratch 3 will perform an upgrade step to handle quirks in SVGs from Scratch 2.0.
|
||||||
* @returns {?Promise} - a promise which will resolve after skinId is set, or null on error.
|
* @returns {?Promise} - a promise which will resolve after skinId is set, or null on error.
|
||||||
*/
|
*/
|
||||||
const loadCostume = function (md5ext, costume, runtime) {
|
const loadCostume = function (md5ext, costume, runtime, optVersion) {
|
||||||
if (!runtime.storage) {
|
if (!runtime.storage) {
|
||||||
log.error('No storage module present; cannot load costume asset: ', md5ext);
|
log.error('No storage module present; cannot load costume asset: ', md5ext);
|
||||||
return Promise.resolve(costume);
|
return Promise.resolve(costume);
|
||||||
|
@ -102,7 +121,7 @@ const loadCostume = function (md5ext, costume, runtime) {
|
||||||
|
|
||||||
return runtime.storage.load(assetType, md5, ext).then(costumeAsset => {
|
return runtime.storage.load(assetType, md5, ext).then(costumeAsset => {
|
||||||
costume.dataFormat = ext;
|
costume.dataFormat = ext;
|
||||||
return loadCostumeFromAsset(costume, costumeAsset, runtime);
|
return loadCostumeFromAsset(costume, costumeAsset, runtime, optVersion);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -360,7 +360,7 @@ const parseScratchObject = function (object, runtime, extensions, topLevel, zip)
|
||||||
// the file name of the costume should be the baseLayerID followed by the file ext
|
// the file name of the costume should be the baseLayerID followed by the file ext
|
||||||
const assetFileName = `${costumeSource.baseLayerID}.${ext}`;
|
const assetFileName = `${costumeSource.baseLayerID}.${ext}`;
|
||||||
costumePromises.push(deserializeCostume(costume, runtime, zip, assetFileName)
|
costumePromises.push(deserializeCostume(costume, runtime, zip, assetFileName)
|
||||||
.then(() => loadCostume(costume.md5, costume, runtime)));
|
.then(() => loadCostume(costume.md5, costume, runtime, 2 /* optVersion */)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Sounds from JSON
|
// Sounds from JSON
|
||||||
|
|
|
@ -826,6 +826,14 @@ class VirtualMachine extends EventEmitter {
|
||||||
this.runtime.attachRenderer(renderer);
|
this.runtime.attachRenderer(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the svg adapter for the VM/runtime, which converts scratch 2 svgs to scratch 3 svgs
|
||||||
|
* @param {!SvgRenderer} svgAdapter The adapter to attach
|
||||||
|
*/
|
||||||
|
attachV2SVGAdapter (svgAdapter) {
|
||||||
|
this.runtime.attachV2SVGAdapter(svgAdapter);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the storage module for the VM/runtime
|
* Set the storage module for the VM/runtime
|
||||||
* @param {!ScratchStorage} storage The storage module to attach
|
* @param {!ScratchStorage} storage The storage module to attach
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue