From 4c8d1401c6a9979df0ba4cf6ef5dc51539d1dbc6 Mon Sep 17 00:00:00 2001 From: space-nuko Date: Fri, 25 Mar 2022 22:29:58 -0700 Subject: [PATCH 1/4] construct correct type for Sprite children with RTTI --- src/swf/exporters/animate/AnimateTimeline.hx | 40 ++++++++++++++++---- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/src/swf/exporters/animate/AnimateTimeline.hx b/src/swf/exporters/animate/AnimateTimeline.hx index b021779..0c0c426 100644 --- a/src/swf/exporters/animate/AnimateTimeline.hx +++ b/src/swf/exporters/animate/AnimateTimeline.hx @@ -18,6 +18,7 @@ import openfl.filters.DisplacementMapFilter; import openfl.filters.DropShadowFilter; import openfl.filters.GlowFilter; import openfl.geom.ColorTransform; +import haxe.rtti.Rtti; #if hscript import hscript.Interp; import hscript.Parser; @@ -51,6 +52,7 @@ class AnimateTimeline extends Timeline @:noCompletion private var __previousFrame:Int; @:noCompletion private var __sprite:Sprite; @:noCompletion private var __symbol:AnimateSpriteSymbol; + @:noCompletion private var __fieldNameToType:Map; public function new(library:AnimateLibrary, symbol:AnimateSpriteSymbol) { @@ -345,12 +347,30 @@ class AnimateTimeline extends Timeline __currentInstancesByFrameObjectID = new Map(); __lastUpdated = new Map(); - var frame:Int; - var frameData:AnimateFrame; - var instance:FrameSymbolInstance; - var duplicate:Bool; - var symbol:AnimateSymbol; - var displayObject:DisplayObject; + __fieldNameToType = new Map(); + + switch Type.typeof(__sprite) { + case TClass(c): + if (Rtti.hasRtti(c)) { + var s = Reflect.field(c, "__rtti"); + var rtti = Rtti.getRtti(c); + for (field in rtti.fields) { + switch (field.type) { + case CClass(cname, params): + __fieldNameToType.set(field.name, cname); + default: + } + } + } + default: + } + + var frame:Int; + var frameData:AnimateFrame; + var instance:FrameSymbolInstance; + var duplicate:Bool; + var symbol:AnimateSymbol; + var displayObject:DisplayObject; // TODO: Create later? @@ -394,7 +414,11 @@ class AnimateTimeline extends Timeline if (symbol != null) { - displayObject = symbol.__createObject(__library); + if (frameObject.name != null && __fieldNameToType.exists(frameObject.name)) { + symbol.className = __fieldNameToType.get(frameObject.name); + } + + displayObject = symbol.__createObject(__library); if (displayObject != null) { @@ -539,7 +563,7 @@ class AnimateTimeline extends Timeline var child = __sprite.getChildAt(i); if (child.name == field) { - Reflect.setField(__sprite, field, child); + Reflect.setField(__sprite, field, child); break; } } From 0ae92bdf76c32b6884974968d7a44ce7b6263627 Mon Sep 17 00:00:00 2001 From: space-nuko Date: Sat, 26 Mar 2022 21:53:59 -0700 Subject: [PATCH 2/4] preliminary MorphShape support in animate exporter --- scripts/Tools.hx | 21 +- src/swf/SWFData.hx | 4 +- src/swf/data/SWFMorphFillStyle.hx | 4 +- src/swf/data/SWFShape.hx | 23 +- src/swf/exporters/AnimateLibraryExporter.hx | 661 +++++++++++++----- .../exporters/animate/AnimateFrameObject.hx | 1 + src/swf/exporters/animate/AnimateLibrary.hx | 97 +++ .../exporters/animate/AnimateMorphShape.hx | 165 +++++ .../animate/AnimateMorphShapeCommand.hx | 43 ++ .../animate/AnimateMorphShapeSymbol.hx | 37 + src/swf/exporters/animate/AnimateTimeline.hx | 5 +- src/swf/tags/TagDefineMorphShape.hx | 5 +- src/swf/timeline/Frame.hx | 2 +- src/swf/timeline/FrameObject.hx | 7 +- 14 files changed, 879 insertions(+), 196 deletions(-) create mode 100644 src/swf/exporters/animate/AnimateMorphShape.hx create mode 100644 src/swf/exporters/animate/AnimateMorphShapeCommand.hx create mode 100644 src/swf/exporters/animate/AnimateMorphShapeSymbol.hx diff --git a/scripts/Tools.hx b/scripts/Tools.hx index 28f2895..872b850 100644 --- a/scripts/Tools.hx +++ b/scripts/Tools.hx @@ -292,11 +292,14 @@ class Tools { className = "openfl.display.BitmapData"; } - else if (#if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end (childSymbol, TagDefineShape) - || #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end (childSymbol, TagDefineMorphShape)) + else if (#if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end (childSymbol, TagDefineShape)) { className = "openfl.display.Shape"; } + else if (#if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end (childSymbol, TagDefineMorphShape)) + { + className = "swf.exporters.animate.AnimateMorphShape"; + } else if (#if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end (childSymbol, TagDefineText) || #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end (childSymbol, TagDefineEditText)) { @@ -622,8 +625,8 @@ class Tools } else if (words.length > 2) { - try - { + // try + // { var projectData = File.getContent(inputPath); var unserializer = new Unserializer(projectData); @@ -636,11 +639,11 @@ class Tools { File.saveContent(outputPath, Serializer.run(output)); } - } - catch (e:Dynamic) - { - Log.error(e); - } + // } + // catch (e:Dynamic) + // { + // Log.error(e); + // } } } } diff --git a/src/swf/SWFData.hx b/src/swf/SWFData.hx index d234b9b..dd4a192 100644 --- a/src/swf/SWFData.hx +++ b/src/swf/SWFData.hx @@ -513,9 +513,9 @@ import swf.utils.BitArray; ///////////////////////////////////////////////////////// // Shape and shape records ///////////////////////////////////////////////////////// - public function readSHAPE(unitDivisor:Float = 20):SWFShape + public function readSHAPE(unitDivisor:Float = 20, noStyleInfo:Bool = false):SWFShape { - return new SWFShape(this, 1, unitDivisor); + return new SWFShape(this, 1, unitDivisor, noStyleInfo); } public function writeSHAPE(value:SWFShape):Void diff --git a/src/swf/data/SWFMorphFillStyle.hx b/src/swf/data/SWFMorphFillStyle.hx index 56412e8..2fba066 100644 --- a/src/swf/data/SWFMorphFillStyle.hx +++ b/src/swf/data/SWFMorphFillStyle.hx @@ -82,12 +82,14 @@ class SWFMorphFillStyle { case 0x00: fillStyle.rgb = ColorUtils.interpolate(startColor, endColor, ratio); - case 0x10, 0x12: + case 0x10, 0x12, 0x13: fillStyle.gradientMatrix = MatrixUtils.interpolate(startGradientMatrix, endGradientMatrix, ratio); fillStyle.gradient = gradient.getMorphedGradient(ratio); case 0x40, 0x41, 0x42, 0x43: fillStyle.bitmapId = bitmapId; fillStyle.bitmapMatrix = MatrixUtils.interpolate(startBitmapMatrix, endBitmapMatrix, ratio); + default: + throw(new Error("Unknown fill style type: 0x" + StringTools.hex(type))); } return fillStyle; } diff --git a/src/swf/data/SWFShape.hx b/src/swf/data/SWFShape.hx index 18765c4..2efa671 100644 --- a/src/swf/data/SWFShape.hx +++ b/src/swf/data/SWFShape.hx @@ -25,6 +25,7 @@ class SWFShape public var fillStyles(default, null):Array; public var lineStyles(default, null):Array; public var referencePoint(default, null):Point; + public var noStyleInfo(default, null):Bool; private var fillEdgeMaps:Array>>; private var lineEdgeMaps:Array>>; @@ -35,13 +36,14 @@ class SWFShape private var unitDivisor:Float; private var edgeMapsCreated:Bool = false; - public function new(data:SWFData = null, level:Int = 1, unitDivisor:Float = 20) + public function new(data:SWFData = null, level:Int = 1, unitDivisor:Float = 20, noStyleInfo: Bool = false) { records = new Array(); fillStyles = new Array(); lineStyles = new Array(); referencePoint = new Point(0, 0); this.unitDivisor = unitDivisor; + this.noStyleInfo = noStyleInfo; if (data != null) { parse(data, level); @@ -248,7 +250,10 @@ class SWFShape // TODO: This is a temporary bug fix. edgeMaps shouldn't need to be recreated for subsequent exports edgeMapsCreated = false; // Create edge maps - createEdgeMaps(); + // "noStyleInfo" means this shape is the endEdges of a MorphShape + // MorphShape endEdges have no styling info, only edges, so we want to export them even when there's + // no styling info + createEdgeMaps(noStyleInfo); // If no handler is passed, default to DefaultShapeExporter (does nothing) if (handler == null) { @@ -268,7 +273,7 @@ class SWFShape handler.endShape(); } - private function createEdgeMaps():Void + private function createEdgeMaps(noStyleInfo: Bool = false):Void { if (!edgeMapsCreated) { @@ -295,9 +300,9 @@ class SWFShape { case SWFShapeRecord.TYPE_STYLECHANGE: var styleChangeRecord:SWFShapeRecordStyleChange = cast(shapeRecord, SWFShapeRecordStyleChange); - if (styleChangeRecord.stateLineStyle || styleChangeRecord.stateFillStyle0 || styleChangeRecord.stateFillStyle1) + if (styleChangeRecord.stateLineStyle || styleChangeRecord.stateFillStyle0 || styleChangeRecord.stateFillStyle1 || noStyleInfo) { - processSubPath(subPath, currentLineStyleIdx, currentFillStyleIdx0, currentFillStyleIdx1); + processSubPath(subPath, currentLineStyleIdx, currentFillStyleIdx0, currentFillStyleIdx1, noStyleInfo); subPath = new Array(); } if (styleChangeRecord.stateNewStyles) @@ -388,7 +393,7 @@ class SWFShape subPath.push(new CurvedEdge(from, control, to, currentLineStyleIdx, currentFillStyleIdx1)); case SWFShapeRecord.TYPE_END: // We're done. Process the last subpath, if any - processSubPath(subPath, currentLineStyleIdx, currentFillStyleIdx0, currentFillStyleIdx1); + processSubPath(subPath, currentLineStyleIdx, currentFillStyleIdx0, currentFillStyleIdx1, noStyleInfo); cleanEdgeMap(currentFillEdgeMap); cleanEdgeMap(currentLineEdgeMap); fillEdgeMaps.push(currentFillEdgeMap); @@ -400,10 +405,10 @@ class SWFShape } } - private function processSubPath(subPath:Array, lineStyleIdx:Int, fillStyleIdx0:Int, fillStyleIdx1:Int):Void + private function processSubPath(subPath:Array, lineStyleIdx:Int, fillStyleIdx0:Int, fillStyleIdx1:Int, noStyleInfo: Bool = false):Void { var path:Array; - if (fillStyleIdx0 != 0) + if (fillStyleIdx0 != 0 || noStyleInfo) { path = currentFillEdgeMap.get(fillStyleIdx0); if (path == null) @@ -428,7 +433,7 @@ class SWFShape } appendEdges(path, subPath); } - if (lineStyleIdx != 0) + if (lineStyleIdx != 0 || noStyleInfo) { path = currentLineEdgeMap.get(lineStyleIdx); if (path == null) diff --git a/src/swf/exporters/AnimateLibraryExporter.hx b/src/swf/exporters/AnimateLibraryExporter.hx index 48608ca..214b155 100644 --- a/src/swf/exporters/AnimateLibraryExporter.hx +++ b/src/swf/exporters/AnimateLibraryExporter.hx @@ -6,7 +6,18 @@ import swf.data.consts.BitmapFormat; import swf.data.consts.BlendMode; import swf.data.filters.IFilter; import swf.data.SWFButtonRecord; +import swf.data.SWFMatrix; +import swf.data.SWFMorphFillStyle; +import swf.data.SWFMorphFocalGradient; +import swf.data.SWFMorphGradient; +import swf.data.SWFMorphLineStyle; +import swf.data.SWFMorphLineStyle2; import swf.data.SWFSymbol; +import swf.data.SWFShape; +import swf.data.SWFShapeRecord; +import swf.data.SWFShapeRecordCurvedEdge; +import swf.data.SWFShapeRecordStraightEdge; +import swf.data.SWFShapeRecordStyleChange; import swf.exporters.ShapeBitmapExporter; import swf.exporters.ShapeCommandExporter; import swf.tags.IDefinitionTag; @@ -20,6 +31,7 @@ import swf.tags.TagDefineEditText; import swf.tags.TagDefineFont; import swf.tags.TagDefineFont2; import swf.tags.TagDefineFont4; +import swf.tags.TagDefineMorphShape; import swf.tags.TagDefineScalingGrid; import swf.tags.TagDefineShape; import swf.tags.TagDefineSound; @@ -30,6 +42,7 @@ import swf.tags.TagSymbolClass; import swf.SWFRoot; import swf.SWFTimelineContainer; import haxe.Template; +import haxe.rtti.Rtti; import hxp.Haxelib; import hxp.Log; import hxp.Path; @@ -92,7 +105,8 @@ class AnimateLibraryExporter libraryData = new SWFDocument(); outputList = new List(); - var uuid = StringTools.generateUUID(20); + // var uuid = StringTools.generateUUID(20); + var uuid = "sdthx-lib"; manifestData.libraryType = "swf.exporters.animate.AnimateLibrary"; manifestData.libraryArgs = ["data.json", uuid]; @@ -212,11 +226,7 @@ class AnimateLibraryExporter if (object.placeMatrix != null) { - var matrix = object.placeMatrix.matrix.clone(); - matrix.tx *= (1 / 20); - matrix.ty *= (1 / 20); - - frameObject.matrix = serializeMatrix(matrix); + frameObject.matrix = serializeSWFMatrix(object.placeMatrix); } if (object.colorTransform != null) @@ -573,86 +583,36 @@ class AnimateLibraryExporter symbol.type = SWFSymbolType.SHAPE; symbol.id = tag.characterId; - var commands:Array = []; - - for (command in handler.commands) - { - switch (command) - { - case LineStyle(thickness, color, alpha, pixelHinting, scaleMode, startCaps, joints, miterLimit): - if (thickness == null && color == null && alpha == null) - { - commands.push(SWFShapeCommandType.CLEAR_LINE_STYLE); - } - else - { - commands = commands.concat([ - SWFShapeCommandType.LINE_STYLE, - thickness, - color, - alpha, - pixelHinting, - scaleMode, - startCaps, - joints, - miterLimit - ]); - } - - case BeginFill(color, alpha): - commands = commands.concat([SWFShapeCommandType.BEGIN_FILL, color, alpha]); - - case BeginGradientFill(type, colors, alphas, ratios, matrix, spreadMethod, interpolationMethod, focalPointRatio): - commands = commands.concat([ - SWFShapeCommandType.BEGIN_GRADIENT_FILL, - type, - colors, - alphas, - ratios, - serializeMatrix(matrix), - spreadMethod, - interpolationMethod, - focalPointRatio - ]); - - case BeginBitmapFill(bitmapID, matrix, repeat, smooth): - commands = commands.concat([ - SWFShapeCommandType.BEGIN_BITMAP_FILL, - bitmapID, - serializeMatrix(matrix), - repeat, - smooth - ]); - processTag(cast swfData.getCharacter(bitmapID)); - - case EndFill: - commands.push(SWFShapeCommandType.END_FILL); - - case MoveTo(x, y): - commands = commands.concat([SWFShapeCommandType.MOVE_TO, twip(x), twip(y)]); - - case LineTo(x, y): - commands = commands.concat([SWFShapeCommandType.LINE_TO, twip(x), twip(y)]); - - case CurveTo(controlX, controlY, anchorX, anchorY): - commands = commands.concat([ - SWFShapeCommandType.CURVE_TO, - twip(controlX), - twip(controlY), - twip(anchorX), - twip(anchorY) - ]); - - default: - } - } - - symbol.commands = commands; + symbol.commands = serializeShape(handler); libraryData.symbols.set(symbol.id, symbol); return symbol; } } + private function addMorphShape(tag:TagDefineMorphShape):Dynamic + { + var symbol:Dynamic = {}; + symbol.type = SWFSymbolType.MORPH_SHAPE; + symbol.id = tag.characterId; + + var handler = new ShapeCommandExporter(swfData); + tag.exportHandler = handler; + tag.export(0); + symbol.startCommands = serializeShape(handler); + + var handler = new ShapeCommandExporter(swfData); + tag.exportHandler = handler; + tag.export(1.0); + symbol.endCommands = serializeShape(handler); + + if (symbol.startCommands.length != symbol.endCommands.length) { + throw "Morph shape edges don't have the same number of commands: " + symbol.startCommands.length + " != " + symbol.endCommands.length; + } + + libraryData.symbols.set(symbol.id, symbol); + return symbol; + } + private function addSprite(tag:SWFTimelineContainer, root:Bool = false):Dynamic { var symbol:Dynamic = {}; @@ -725,11 +685,7 @@ class AnimateLibraryExporter if (placeTag.matrix != null) { - var matrix = placeTag.matrix.matrix.clone(); - matrix.tx *= (1 / 20); - matrix.ty *= (1 / 20); - - frameObject.matrix = serializeMatrix(matrix); + frameObject.matrix = serializeSWFMatrix(placeTag.matrix); } if (placeTag.colorTransform != null) @@ -761,6 +717,11 @@ class AnimateLibraryExporter frameObject.cacheAsBitmap = placeTag.bitmapCache != 0; } + if (placeTag.hasRatio) + { + frameObject.ratio = placeTag.ratio; + } + lastModified.set(object.placedAtIndex, object.lastModifiedAtIndex); if (frame.objects == null) @@ -1038,12 +999,7 @@ class AnimateLibraryExporter } symbol.records = records; - - var matrix = tag.textMatrix.matrix.clone(); - matrix.tx *= (1 / 20); - matrix.ty *= (1 / 20); - - symbol.matrix = serializeMatrix(matrix); + symbol.matrix = serializeSWFMatrix(tag.textMatrix); libraryData.symbols.set(symbol.id, symbol); @@ -1293,9 +1249,9 @@ class AnimateLibraryExporter if (className != null) { - objectReferences[object.name] = true; - classProperties.push({name: object.name, type: className, hidden: true}); - } + objectReferences[object.name] = true; + classProperties.push({name: object.name, type: className, hidden: true}); + } } } } @@ -1383,6 +1339,10 @@ class AnimateLibraryExporter { return addShape(cast tag); } + else if (#if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end (tag, TagDefineMorphShape)) + { + return addMorphShape(cast tag); + } else if (#if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end (tag, TagDefineFont) || #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end (tag, TagDefineFont4)) { @@ -1415,6 +1375,85 @@ class AnimateLibraryExporter ]; } + private function serializeShape(handler: ShapeCommandExporter) : Array + { + var commands = new Array(); + + for (command in handler.commands) + { + switch (command) + { + case LineStyle(thickness, color, alpha, pixelHinting, scaleMode, startCaps, joints, miterLimit): + if (thickness == null && color == null && alpha == null) + { + commands.push(SWFShapeCommandType.CLEAR_LINE_STYLE); + } + else + { + commands = commands.concat([ + SWFShapeCommandType.LINE_STYLE, + thickness, + color, + alpha, + pixelHinting, + scaleMode, + startCaps, + joints, + miterLimit + ]); + } + + case BeginFill(color, alpha): + commands = commands.concat([SWFShapeCommandType.BEGIN_FILL, color, alpha]); + + case BeginGradientFill(type, colors, alphas, ratios, matrix, spreadMethod, interpolationMethod, focalPointRatio): + commands = commands.concat([ + SWFShapeCommandType.BEGIN_GRADIENT_FILL, + type, + colors, + alphas, + ratios, + serializeMatrix(matrix), + spreadMethod, + interpolationMethod, + focalPointRatio + ]); + + case BeginBitmapFill(bitmapID, matrix, repeat, smooth): + commands = commands.concat([ + SWFShapeCommandType.BEGIN_BITMAP_FILL, + bitmapID, + serializeMatrix(matrix), + repeat, + smooth + ]); + processTag(cast swfData.getCharacter(bitmapID)); + + case EndFill: + commands.push(SWFShapeCommandType.END_FILL); + + case MoveTo(x, y): + commands = commands.concat([SWFShapeCommandType.MOVE_TO, twip(x), twip(y)]); + + case LineTo(x, y): + commands = commands.concat([SWFShapeCommandType.LINE_TO, twip(x), twip(y)]); + + case CurveTo(controlX, controlY, anchorX, anchorY): + commands = commands.concat([ + SWFShapeCommandType.CURVE_TO, + twip(controlX), + twip(controlY), + twip(anchorX), + twip(anchorY) + ]); + + default: + } + } + + return commands; + } + private function serializeFilters(filters:Array):Array> { if (filters == null || filters.length == 0) return null; @@ -1465,108 +1504,390 @@ class AnimateLibraryExporter return [matrix.a, matrix.b, matrix.c, matrix.d, twip(matrix.tx), twip(matrix.ty)]; } - private function serializeRect(rect:Rectangle):Array + private function serializeSWFMatrix(swfMatrix:SWFMatrix):Array { - return [twip(rect.x), twip(rect.y), twip(rect.width), twip(rect.height)]; + var matrix = swfMatrix.matrix.clone(); + matrix.tx *= (1 / 20); + matrix.ty *= (1 / 20); + + return serializeMatrix(matrix); } - private inline function twip(value:Float):Int + private function serializeRect(rect:Rectangle):Array { - return Math.round(value * 20); + return [twip(rect.x), twip(rect.y), twip(rect.width), twip(rect.height)]; } + + // private function serializeMorphShapeEdges(startEdges: SWFShape, endEdges: SWFShape):Array + // { + // var result: Array = []; + // var numEdges:Int = startEdges.records.length; + + // var i = 0; + // var j = 0; + // while (i < numEdges) + // { + // var record: Array = []; + + // var startX = 0; + // var startY = 0; + // var endX = 0; + // var endY = 0; + + // var startRecord = startEdges.records[i]; + // var endRecord = endEdges.records[j]; + + // if (endRecord == null) { + // throw("End record is null! " + i + ", " + j); + // } + + // if (startRecord.type == SWFShapeRecord.TYPE_STYLECHANGE && endRecord.type == SWFShapeRecord.TYPE_STYLECHANGE) + // { + // var startStyleChange: SWFShapeRecordStyleChange = cast startRecord; + // var endStyleChange: SWFShapeRecordStyleChange = cast endRecord; + + // record = serializeStyleChange(startStyleChange); + + // if (startStyleChange.moveTo || endStyleChange.moveTo) + // { + // if (startStyleChange.moveTo) { + // startX = startStyleChange.moveDeltaX; + // startY = startStyleChange.moveDeltaY; + // } + // if (endStyleChange.moveTo) { + // endX = endStyleChange.moveDeltaX; + // endY = endStyleChange.moveDeltaY; + // } + + // record.push([[twip(startX), twip(startY)], [twip(endX), twip(endY)]]); + // } + + // i++; + // j++; + // } + // else if (startRecord.type == SWFShapeRecord.TYPE_STYLECHANGE) + // { + // var startStyleChange: SWFShapeRecordStyleChange = cast startRecord; + + // record = serializeStyleChange(startStyleChange); + + // if (startStyleChange.moveTo) + // { + // startX = startStyleChange.moveDeltaX; + // startY = startStyleChange.moveDeltaY; + + // record.push([[twip(startX), twip(startY)], [twip(endX), twip(endY)]]); + // } + + // i++; + // } + // else if (endRecord.type == SWFShapeRecord.TYPE_STYLECHANGE) + // { + // record = serializeStyleChange(endStyleChange); + + // var endStyleChange: SWFShapeRecordStyleChange = cast endRecord; + + // if (endStyleChange.moveTo) + // { + // endX = endStyleChange.moveDeltaX; + // endY = endStyleChange.moveDeltaY; + + // record.push([[twip(startX), twip(startY)], [twip(endX), twip(endY)]]); + // } + + // j++; + // } + // else if (startRecord.type == SWFShapeRecord.TYPE_END && endRecord.type == SWFShapeRecord.TYPE_END) { + // record = [SWFShapeRecord.TYPE_END]; + // i++; + // j++; + // } + // else { + // record = serializeMorphShapeEdge(startRecord, endRecord); + // i++; + // j++; + // } + + // result.push(record); + // } + + // return result; + // } + + // private function serializeMorphShapeEdge(startRecord: SWFShapeRecord, endRecord: SWFShapeRecord): Array + // { + // if (startRecord.type == SWFShapeRecord.TYPE_STRAIGHTEDGE && endRecord.type == SWFShapeRecord.TYPE_STRAIGHTEDGE) + // { + // var sse:SWFShapeRecordStraightEdge = cast startRecord; + // var ese:SWFShapeRecordStraightEdge = cast endRecord; + // return [SWFShapeRecord.TYPE_STRAIGHTEDGE, [twip(sse.deltaX), twip(sse.deltaY)], [twip(ese.deltaX), twip(ese.deltaY)]]; + // } + // else if (startRecord.type == SWFShapeRecord.TYPE_STRAIGHTEDGE && endRecord.type == SWFShapeRecord.TYPE_CURVEDEDGE) + // { + // var sse:SWFShapeRecordStraightEdge = cast startRecord; + // var ece:SWFShapeRecordCurvedEdge = cast endRecord; + // return [SWFShapeRecord.TYPE_CURVEDEDGE, straightToCurved(sse), serializeCurvedRecord(ece)]; + // } + // else if (startRecord.type == SWFShapeRecord.TYPE_CURVEDEDGE && endRecord.type == SWFShapeRecord.TYPE_STRAIGHTEDGE) + // { + // var sce:SWFShapeRecordCurvedEdge = cast startRecord; + // var ese:SWFShapeRecordStraightEdge = cast endRecord; + // return [SWFShapeRecord.TYPE_CURVEDEDGE, serializeCurvedRecord(sce), straightToCurved(ese)]; + // } + // else if (startRecord.type == SWFShapeRecord.TYPE_CURVEDEDGE && endRecord.type == SWFShapeRecord.TYPE_CURVEDEDGE) + // { + // var sce:SWFShapeRecordCurvedEdge = cast startRecord; + // var ece:SWFShapeRecordCurvedEdge = cast endRecord; + // return [SWFShapeRecord.TYPE_CURVEDEDGE, serializeCurvedRecord(sce), + // serializeCurvedRecord(ece)]; + // } + // else + // { + // throw "Invalid morph shape edge pairs!"; + // } + // } + + // private function serializeCurvedRecord(cr: SWFShapeRecordCurvedEdge): Array + // { + // return [twip(cr.controlDeltaX), twip(cr.controlDeltaY), twip(cr.anchorDeltaX), twip(cr.anchorDeltaY)]; + // } + + // private function straightToCurved(sc: SWFShapeRecordStraightEdge): Array + // { + // return [twip(sc.deltaX / 2), twip(sc.deltaY / 2), twip(sc.deltaX / 2), twip(sc.deltaY / 2)]; + // } + + // private function serializeStyleChange(sc: SWFShapeRecordStyleChange): Array + // { + // return [SWFShapeRecord.TYPE_STYLECHANGE, sc.stateNewStyles, sc.stateLineStyle, sc.stateFillStyle1, sc.stateFillStyle0, sc.fillStyle0, sc.fillStyle1, sc.lineStyle, sc.numFillBits, sc.numLineBits, serializeFillStyles(sc.fillStyles), serializeLineStyles(sc.lineStyles)]; + // } + + // private function serializeFillStyles(fillStyles: Array): Array + // { + // var result: Array = []; + + // for (fs in fillStyles) { + // if (type != null) + // { + // switch (type) + // { + // case SWFMorphFillType.SOLID: + // result.push([fs.type, fs.rgb]); + // case SWFMorphFillType.LINEAR_GRADIENT: + // case SWFMorphFillType.RADIAL_GRADIENT: + // case SWFMorphFillType.FOCAL_RADIAL_GRADIENT: + // result.push([fs.type, serializeSWFMatrix(fs.gradientMatrix), serializeGradient(fs.gradient)]); + // case SWFMorphFillType.REPEATING_BITMAP: + // case SWFMorphFillType.CLIPPED_BITMAP: + // case SWFMorphFillType.REPEATING_BITMAP_NON_SMOOTHED: + // case SWFMorphFillType.CLIPPED_BITMAP_NON_SMOOTHED: + // result.push([fs.type, fs.bitmapId, serializeSWFMatrix(fs.bitmapMatrix)]); + // default: + // throw "Invalid fill style! " + fs.type; + // } + // } + // } + + // return result; + // } + + // private function serializeLineStyles(lineStyles: Array): Array + // { + // var result: Array = []; + // for (ls in lineStyles) { + // if (#if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end (mls, SWFLineStyle2)) { + // return [SWFLineStyleType.V2, mls.startWidth, mls.endWidth, mls.startColor, mls.endColor, + // mls.startCapsStyle, mls.endCapsStyle, mls.jointStyle, mls.hasFillFlag, mls.noHScaleFlag, mls.noVScaleFlag, + // mls.pixelHintingFlag, mls.noClose, mls.miterLimitFactor, serializeMorphFillStyle(mls.fillType)]; + // } + + // return [SWFLineStyleType.V1, mls.startWidth, mls.endWidth, mls.startColor, mls.endColor]; + // } + // return result; + // } + + // private function serializeMorphFillStyle(mfs:SWFMorphFillStyle):Array + // { + // if (mfs == null) { + // return null; + // } + + // var type = mfs.type; + + // if (type != null) + // { + // switch (type) + // { + // case SWFMorphFillType.SOLID: + // return [mfs.type, mfs.startColor, mfs.endColor]; + // case SWFMorphFillType.LINEAR_GRADIENT: + // case SWFMorphFillType.RADIAL_GRADIENT: + // case SWFMorphFillType.FOCAL_RADIAL_GRADIENT: + // return [mfs.type, serializeSWFMatrix(mfs.startGradientMatrix), serializeSWFMatrix(mfs.endGradientMatrix), serializeMorphGradient(mfs.gradient)]; + // case SWFMorphFillType.REPEATING_BITMAP: + // case SWFMorphFillType.CLIPPED_BITMAP: + // case SWFMorphFillType.REPEATING_BITMAP_NON_SMOOTHED: + // case SWFMorphFillType.CLIPPED_BITMAP_NON_SMOOTHED: + // return [mfs.type, + // mfs.bitmapId, + // serializeSWFMatrix(mfs.startBitmapMatrix), + // serializeSWFMatrix(mfs.endBitmapMatrix)]; + // default: + // throw "Invalid fill style!"; + // } + // } + + // return null; + // } + + // private function serializeMorphLineStyle(mls:SWFMorphLineStyle):Array + // { + // if (#if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end (mls, SWFMorphLineStyle2)) { + // return [SWFLineStyleType.V2, mls.startWidth, mls.endWidth, mls.startColor, mls.endColor, + // mls.startCapsStyle, mls.endCapsStyle, mls.jointStyle, mls.hasFillFlag, mls.noHScaleFlag, mls.noVScaleFlag, + // mls.pixelHintingFlag, mls.noClose, mls.miterLimitFactor, serializeMorphFillStyle(mls.fillType)]; + // } + + // return [SWFLineStyleType.V1, mls.startWidth, mls.endWidth, mls.startColor, mls.endColor]; + // } + + // private function serializeMorphGradient(mg:SWFMorphGradient):Array + // { + // var records: Array = []; + + // for (record in mg.records) { + // records.push([record.startRatio, record.startColor, record.endRatio, record.endColor]); + // } + + // if (#if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end (mg, SWFMorphFocalGradient)) { + // return [SWFMorphGradientType.FOCAL, mg.spreadMode, mg.interpolationMode, records, mg.startFocalPoint, mg.endFocalPoint]; + // } + + // return [SWFMorphGradientType.NORMAL, mg.spreadMode, mg.interpolationMode, records]; + // } + + private inline function twip(value:Float):Int + { + return Math.round(value * 20); + } } private enum BitmapType { - PNG; - JPEG_ALPHA; - JPEG; + PNG; + JPEG_ALPHA; + JPEG; } private enum SoundType { - UNCOMPRESSED_NATIVE_ENDIAN; - ADPCM; - MP3; - UNCOMPRESSED_LITTLE_ENDIAN; - NELLYMOSER_16_KHZ; - NELLYMOSER_8_KHZ; - NELLYMOSER; - SPEEX; + UNCOMPRESSED_NATIVE_ENDIAN; + ADPCM; + MP3; + UNCOMPRESSED_LITTLE_ENDIAN; + NELLYMOSER_16_KHZ; + NELLYMOSER_8_KHZ; + NELLYMOSER; + SPEEX; } private class SWFDocument { - public var frameRate:Float; - public var uuid:String; - public var root:Dynamic; - public var symbols:Map; - - // public var version:Int; - - public function new() - { - symbols = new Map(); - } - - public function serialize():Dynamic - { - var output:Dynamic = {}; - output.frameRate = frameRate; - output.uuid = uuid; - output.root = 0; - output.version = 0.1; - - var symbolArray = new Array(); - symbolArray.push(root); - - for (key in symbols.keys()) - { - symbolArray.push(symbols.get(key)); - } - - output.symbols = symbolArray; - - return Json.stringify(output); - } + public var frameRate:Float; + public var uuid:String; + public var root:Dynamic; + public var symbols:Map; + + // public var version:Int; + + public function new() + { + symbols = new Map(); + } + + public function serialize():Dynamic + { + var output:Dynamic = {}; + output.frameRate = frameRate; + output.uuid = uuid; + output.root = 0; + output.version = 0.1; + + var symbolArray = new Array(); + symbolArray.push(root); + + for (key in symbols.keys()) + { + symbolArray.push(symbols.get(key)); + } + + output.symbols = symbolArray; + + return Json.stringify(output); + } } @:enum private abstract SWFFrameObjectType(Int) from Int to Int -{ - public var CREATE = 0; - public var UPDATE = 1; - public var DESTROY = 2; + { + public var CREATE = 0; + public var UPDATE = 1; + public var DESTROY = 2; } @:enum private abstract SWFShapeCommandType(Int) from Int to Int -{ - public var BEGIN_BITMAP_FILL = 0; - public var BEGIN_FILL = 1; - public var BEGIN_GRADIENT_FILL = 2; - public var CLEAR_LINE_STYLE = 3; - public var CURVE_TO = 4; - public var END_FILL = 5; - public var LINE_STYLE = 6; - public var LINE_TO = 7; - public var MOVE_TO = 8; + { + public var BEGIN_BITMAP_FILL = 0; + public var BEGIN_FILL = 1; + public var BEGIN_GRADIENT_FILL = 2; + public var CLEAR_LINE_STYLE = 3; + public var CURVE_TO = 4; + public var END_FILL = 5; + public var LINE_STYLE = 6; + public var LINE_TO = 7; + public var MOVE_TO = 8; } @:enum private abstract SWFSymbolType(Int) from Int to Int -{ - public var BITMAP = 0; - public var BUTTON = 1; - public var DYNAMIC_TEXT = 2; - public var FONT = 3; - public var SHAPE = 4; - public var SPRITE = 5; - public var STATIC_TEXT = 6; + { + public var BITMAP = 0; + public var BUTTON = 1; + public var DYNAMIC_TEXT = 2; + public var FONT = 3; + public var SHAPE = 4; + public var SPRITE = 5; + public var STATIC_TEXT = 6; + public var MORPH_SHAPE = 7; } @:enum private abstract SWFFilterType(Int) from Int to Int -{ - public var BLUR = 0; - public var COLOR_MATRIX = 1; - public var DROP_SHADOW = 2; - public var GLOW = 3; - // TODO: More + { + public var BLUR = 0; + public var COLOR_MATRIX = 1; + public var DROP_SHADOW = 2; + public var GLOW = 3; + // TODO: More +} + +@:enum private abstract SWFMorphFillType(Int) from Int to Int + { + public var SOLID = 0x00; + public var LINEAR_GRADIENT = 0x10; + public var RADIAL_GRADIENT = 0x12; + public var FOCAL_RADIAL_GRADIENT = 0x13; + public var REPEATING_BITMAP = 0x40; + public var CLIPPED_BITMAP = 0x41; + public var REPEATING_BITMAP_NON_SMOOTHED = 0x42; + public var CLIPPED_BITMAP_NON_SMOOTHED = 0x43; +} + +@:enum private abstract SWFLineStyleType(Int) from Int to Int + { + public var V1 = 0; + public var V2 = 1; +} + +@:enum private abstract SWFGradientType(Int) from Int to Int + { + public var NORMAL = 0; + public var FOCAL = 1; } diff --git a/src/swf/exporters/animate/AnimateFrameObject.hx b/src/swf/exporters/animate/AnimateFrameObject.hx index 2ce57ec..5f8b206 100644 --- a/src/swf/exporters/animate/AnimateFrameObject.hx +++ b/src/swf/exporters/animate/AnimateFrameObject.hx @@ -23,6 +23,7 @@ class AnimateFrameObject public var symbol:Int; public var type:AnimateFrameObjectType; public var visible:Null; + public var ratio:Null; public function new() {} } diff --git a/src/swf/exporters/animate/AnimateLibrary.hx b/src/swf/exporters/animate/AnimateLibrary.hx index faf4227..cbc4824 100644 --- a/src/swf/exporters/animate/AnimateLibrary.hx +++ b/src/swf/exporters/animate/AnimateLibrary.hx @@ -267,6 +267,8 @@ import openfl.filters.GlowFilter; symbol = spriteSymbol; case STATIC_TEXT: symbol = __parseStaticText(data); + case MORPH_SHAPE: + symbol = __parseMorphShape(data); default: } @@ -668,6 +670,75 @@ import openfl.filters.GlowFilter; return symbol; } + private function __parseMorphShape(data:Dynamic):AnimateMorphShapeSymbol + { + var symbol = new AnimateMorphShapeSymbol(); + symbol.id = data.id; + symbol.commands = []; + + var startData:Array = data.startCommands; + var endData:Array = data.endCommands; + var commands = symbol.commands; + var i = 0; + + while (i < startData.length) + { + switch (startData[i]) + { + case BEGIN_BITMAP_FILL: + commands.push(BeginBitmapFill(startData[i + 1], + __parseMatrix(startData[i + 2]), __parseMatrix(endData[i + 2]), + startData[i + 3], startData[i + 4])); + i += 5; + case BEGIN_FILL: + commands.push(BeginFill(startData[i + 1], endData[i + 1], + startData[i + 2], endData[i + 2])); + i += 3; + case BEGIN_GRADIENT_FILL: + commands.push(BeginGradientFill(startData[i + 1], + startData[i + 2], endData[i + 2], + startData[i + 3], endData[i + 3], + startData[i + 4], endData[i + 4], + __parseMatrix(startData[i + 5]), __parseMatrix(endData[i + 5]), + startData[i + 6], + startData[i + 7], + startData[i + 8])); + i += 9; + case CLEAR_LINE_STYLE: + commands.push(LineStyle(null, null, null, null, null, null, null, null, null, null, null)); + i++; + case CURVE_TO: + commands.push(CurveTo(__pixel(startData[i + 1]), __pixel(startData[i + 2]), __pixel(startData[i + 3]), __pixel(startData[i + 4]), + __pixel(endData[i + 1]), __pixel(endData[i + 2]), __pixel(endData[i + 3]), __pixel(endData[i + 4]))); + i += 5; + case END_FILL: + commands.push(EndFill); + i++; + case LINE_STYLE: + commands.push(LineStyle(startData[i + 1], endData[i + 1], + startData[i + 2], endData[i + 2], + startData[i + 3], endData[i + 3], + startData[i + 4], + startData[i + 5], + startData[i + 6], + startData[i + 7], + startData[i + 8])); + i += 9; + case LINE_TO: + commands.push(LineTo(__pixel(startData[i + 1]), __pixel(startData[i + 2]), + __pixel(endData[i + 1]), __pixel(endData[i + 2]))); + i += 3; + case MOVE_TO: + commands.push(MoveTo(__pixel(startData[i + 1]), __pixel(startData[i + 2]), + __pixel(endData[i + 1]), __pixel(endData[i + 2]))); + i += 3; + default: + i++; + } + } + return symbol; + } + private function __parseSprite(data:Dynamic):AnimateSpriteSymbol { if (data == null) return null; @@ -720,6 +791,7 @@ import openfl.filters.GlowFilter; object.symbol = objectData.symbol; object.type = objectData.type; object.visible = objectData.visible; + object.ratio = objectData.ratio; frame.objects.push(object); } } @@ -765,4 +837,29 @@ import openfl.filters.GlowFilter; public var SHAPE = 4; public var SPRITE = 5; public var STATIC_TEXT = 6; + public var MORPH_SHAPE = 7; +} + +@:enum abstract SWFMorphFillType(Int) from Int to Int +{ + public var SOLID = 0x00; + public var LINEAR_GRADIENT = 0x10; + public var RADIAL_GRADIENT = 0x12; + public var FOCAL_RADIAL_GRADIENT = 0x13; + public var REPEATING_BITMAP = 0x40; + public var CLIPPED_BITMAP = 0x41; + public var REPEATING_BITMAP_NON_SMOOTHED = 0x42; + public var CLIPPED_BITMAP_NON_SMOOTHED = 0x43; +} + +@:enum abstract SWFMorphLineStyleType(Int) from Int to Int +{ + public var V1 = 0; + public var V2 = 1; +} + +@:enum abstract SWFMorphGradientType(Int) from Int to Int +{ + public var NORMAL = 0; + public var FOCAL = 1; } diff --git a/src/swf/exporters/animate/AnimateMorphShape.hx b/src/swf/exporters/animate/AnimateMorphShape.hx new file mode 100644 index 0000000..5a40fe1 --- /dev/null +++ b/src/swf/exporters/animate/AnimateMorphShape.hx @@ -0,0 +1,165 @@ +package swf.exporters.animate; + +import openfl.display.BitmapData; +import openfl.display.CapsStyle; +import openfl.display.JointStyle; +import openfl.display.LineScaleMode; +import openfl.display.Shape; +import openfl.geom.Matrix; +import swf.utils.ColorUtils; + +@:access(swf.exporters.animate.AnimateLibrary) +@:access(openfl.display.CapsStyle) +@:access(openfl.display.GradientType) +@:access(openfl.display.InterpolationMethod) +@:access(openfl.display.JointStyle) +@:access(openfl.display.LineScaleMode) +@:access(openfl.display.SpreadMethod) +class AnimateMorphShape extends openfl.display.Shape +{ + public var ratio(default, null): Int; + + private var symbol: AnimateMorphShapeSymbol; + private var library: AnimateLibrary; + + private var __colors: Array = []; + private var __alphas: Array = []; + private var __ratios: Array = []; + private var __matrix = new Matrix(); + + public function new(symbol: AnimateMorphShapeSymbol, library: AnimateLibrary, ratio: Int = 0) + { + super(); + + this.symbol = symbol; + this.library = library; + this.ratio = ratio; + + render(this.ratio); + } + + public function render(ratio:Int = 0) + { + this.ratio = ratio; + graphics.clear(); + + if (symbol.rendered.exists(ratio)) { + graphics.copyFrom(symbol.rendered[ratio].graphics); + return; + } + + var a = ratio / 65535.0; + var b = 1.0 - ratio; + + for (command in symbol.commands) + { + switch (command) + { + case BeginFill(startColor, endColor, startAlpha, endAlpha): + graphics.beginFill(ColorUtils.interpolate(startColor, endColor, a), lerpf(startAlpha, endAlpha, a, b)); + + case BeginBitmapFill(bitmapID, startMatrix, endMatrix, repeat, smooth): + #if lime + var bitmapSymbol:AnimateBitmapSymbol = cast library.symbols.get(bitmapID); + var bitmap = library.getImage(bitmapSymbol.path); + + if (bitmap != null) + { + graphics.beginBitmapFill(BitmapData.fromImage(bitmap), + lerpMatrix(startMatrix, endMatrix, a, b), + repeat, smooth); + } + #end + + case BeginGradientFill(fillType, startColors, endColors, startAlphas, endAlphas, startRatios, endRatios, startMatrix, endMatrix, + spreadMethod, interpolationMethod, focalPointRatio): + // #if flash + // var colors:Array = cast colors; + // #end + + graphics.beginGradientFill(GradientType.fromInt(fillType), + lerpColors(startColors, endColors, a, b), + lerpAlphas(startAlphas, endAlphas, a, b), + lerpRatios(startRatios, endRatios, a, b), + lerpMatrix(startMatrix, endMatrix, a, b), + SpreadMethod.fromInt(spreadMethod), + InterpolationMethod.fromInt(interpolationMethod), + focalPointRatio); + + case CurveTo(startControlX, startControlY, startAnchorX, startAnchorY, endControlX, endControlY, endAnchorX, endAnchorY): + graphics.curveTo(lerpf(startControlX, endControlX, a, b), + lerpf(startControlY, endControlY, a, b), + lerpf(startAnchorX, endAnchorX, a, b), + lerpf(startAnchorY, endAnchorY, a, b)); + + case EndFill: + graphics.endFill(); + + case LineStyle(startThickness, endThickness, startColor, endColor, startAlpha, endAlpha, pixelHinting, scaleMode, caps, joints, miterLimit): + if (startThickness != null) + { + graphics.lineStyle(lerpf(startThickness, endThickness, a, b), + ColorUtils.interpolate(startColor, endColor, a), + lerpf(startAlpha, endAlpha, a, b), + pixelHinting, + LineScaleMode.fromInt(scaleMode), + CapsStyle.fromInt(caps), + JointStyle.fromInt(joints), + miterLimit); + } + else + { + graphics.lineStyle(); + } + + case LineTo(startX, startY, endX, endY): + graphics.lineTo(lerpf(startX, startY, a, b), lerpf(endX, endY, a, b)); + + case MoveTo(startX, startY, endX, endY): + graphics.moveTo(lerpf(startX, startY, a, b), lerpf(endX, endY, a, b)); + } + } + + var rendered = new Shape(); + rendered.graphics.copyFrom(graphics); + symbol.rendered[ratio] = rendered; + } + + private inline function lerpf(start:Float, end:Float, a:Float, b:Float): Float { + return start * a + end * b; + } + + private inline function lerpColors(start:Array, end:Array, a:Float, b:Float): Array { + __colors.resize(start.length); + for (i in 0...start.length) { + __colors[i] = ColorUtils.interpolate(start[i], end[i], a); + } + return __colors; + } + + private inline function lerpAlphas(start:Array, end:Array, a:Float, b:Float): Array { + __alphas.resize(start.length); + for (i in 0...start.length) { + __alphas[i] = lerpf(start[i], end[i], a, b); + } + return __alphas; + } + + private inline function lerpRatios(start:Array, end:Array, a:Float, b:Float): Array { + __ratios.resize(start.length); + for (i in 0...start.length) { + __ratios[i] = Std.int(lerpf(start[i], end[i], a, b)); + } + return __ratios; + } + + private inline function lerpMatrix(matrix1:Matrix, matrix2:Matrix, a:Float, b:Float): Matrix { + __matrix.a = matrix1.a * a + matrix2.a * b; + __matrix.b = matrix1.b * a + matrix2.b * b; + __matrix.c = matrix1.c * a + matrix2.c * b; + __matrix.d = matrix1.d * a + matrix2.d * b; + __matrix.tx = Std.int(matrix1.tx * a + matrix2.tx * b); + __matrix.ty = Std.int(matrix1.ty * a + matrix2.ty * b); + return __matrix; + } +} diff --git a/src/swf/exporters/animate/AnimateMorphShapeCommand.hx b/src/swf/exporters/animate/AnimateMorphShapeCommand.hx new file mode 100644 index 0000000..b9597d8 --- /dev/null +++ b/src/swf/exporters/animate/AnimateMorphShapeCommand.hx @@ -0,0 +1,43 @@ +package swf.exporters.animate; + +import openfl.geom.Matrix; + +enum AnimateMorphShapeCommand +{ + BeginBitmapFill(bitmap:Int, + startMatrix:Matrix, endMatrix: Matrix, + repeat:Bool, + smooth:Bool); + BeginFill(startColor:Int, endColor:Int, + startAlpha:Float, endAlpha:Float); + BeginGradientFill(fillType:Null /*GradientType*/, + beginColors:Array, endColors:Array, + beginAlphas:Array, endAlphas:Array, + beginRatios:Array, endRatios:Array, + beginMatrix:Matrix, endMatrix:Matrix, + spreadMethod:Null /*SpreadMethod*/, + interpolationMethod:Null /*InterpolationMethod*/, + focalPointRatio:Float); + // CubicCurveTo (controlX1:Float, controlY1:Float, controlX2:Float, controlY2:Float, anchorX:Float, anchorY:Float); + CurveTo(beginControlX:Float, beginControlY:Float, + beginAnchorX:Float, beginAnchorY:Float, + endControlX:Float, endControlY:Float, + endAnchorX:Float, endAnchorY:Float); + // DrawCircle (x:Float, y:Float, radius:Float); + // DrawEllipse (x:Float, y:Float, width:Float, height:Float); + // DrawRect (x:Float, y:Float, width:Float, height:Float); + // DrawRoundRect (x:Float, y:Float, width:Float, height:Float, rx:Float, ry:Float); + // DrawTiles (sheet:Tilesheet, tileData:Array, smooth:Bool, flags:Int, count:Int); + // DrawTriangles (vertices:Vector, indices:Vector, uvtData:Vector, culling:TriangleCulling); + EndFill; + LineStyle(beginThickness:Null, endThickness:Null, + beginColor:Null, endColor:Null, + beginAlpha:Null, endAlpha:Null, + pixelHinting:Null, + scaleMode:Null /*LineScaleMode*/, + caps:Null /*CapsStyle*/, + joints:Null /*JointStyle*/, + miterLimit:Null); + LineTo(beginX:Float, beginY:Float, endX:Float, endY:Float); + MoveTo(beginX:Float, beginY:Float, endX:Float, endY:Float); +} diff --git a/src/swf/exporters/animate/AnimateMorphShapeSymbol.hx b/src/swf/exporters/animate/AnimateMorphShapeSymbol.hx new file mode 100644 index 0000000..85cf509 --- /dev/null +++ b/src/swf/exporters/animate/AnimateMorphShapeSymbol.hx @@ -0,0 +1,37 @@ +package swf.exporters.animate; + +import openfl.display.BitmapData; +import openfl.display.CapsStyle; +import openfl.display.GradientType; +import openfl.display.InterpolationMethod; +import openfl.display.JointStyle; +import openfl.display.LineScaleMode; +import openfl.display.Shape; +import openfl.display.SpreadMethod; + +#if !openfl_debug +@:fileXml('tags="haxe,release"') +@:noDebug +#end +@:access(swf.exporters.animate.AnimateLibrary) +@:access(openfl.display.CapsStyle) +@:access(openfl.display.GradientType) +@:access(openfl.display.InterpolationMethod) +@:access(openfl.display.JointStyle) +@:access(openfl.display.LineScaleMode) +@:access(openfl.display.SpreadMethod) +class AnimateMorphShapeSymbol extends AnimateSymbol +{ + public var commands:Array = []; + public var rendered:Map = new Map(); + + public function new() + { + super(); + } + + private override function __createObject(library:AnimateLibrary):Shape + { + return new AnimateMorphShape(this, library); + } +} diff --git a/src/swf/exporters/animate/AnimateTimeline.hx b/src/swf/exporters/animate/AnimateTimeline.hx index 0c0c426..f43f181 100644 --- a/src/swf/exporters/animate/AnimateTimeline.hx +++ b/src/swf/exporters/animate/AnimateTimeline.hx @@ -352,7 +352,6 @@ class AnimateTimeline extends Timeline switch Type.typeof(__sprite) { case TClass(c): if (Rtti.hasRtti(c)) { - var s = Reflect.field(c, "__rtti"); var rtti = Rtti.getRtti(c); for (field in rtti.fields) { switch (field.type) { @@ -546,6 +545,10 @@ class AnimateTimeline extends Timeline displayObject.cacheAsBitmap = frameObject.cacheAsBitmap; } + if (frameObject.ratio != null && #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end (displayObject, AnimateMorphShape)) { + cast(displayObject, AnimateMorphShape).render(frameObject.ratio); + } + #if openfljs Reflect.setField(__sprite, displayObject.name, displayObject); #end diff --git a/src/swf/tags/TagDefineMorphShape.hx b/src/swf/tags/TagDefineMorphShape.hx index eaba3d8..12718bf 100644 --- a/src/swf/tags/TagDefineMorphShape.hx +++ b/src/swf/tags/TagDefineMorphShape.hx @@ -75,7 +75,10 @@ class TagDefineMorphShape implements IDefinitionTag morphLineStyles.push(data.readMORPHLINESTYLE()); } startEdges = data.readSHAPE(); - endEdges = data.readSHAPE(); + // endEdges are a special kind of shape, they only contain edge data + // and no style info, which messes up the exporter if it doesn't understand + // the difference + endEdges = data.readSHAPE(true); } public function publish(data:SWFData, version:Int):Void diff --git a/src/swf/timeline/Frame.hx b/src/swf/timeline/Frame.hx index 3e1df56..d780787 100644 --- a/src/swf/timeline/Frame.hx +++ b/src/swf/timeline/Frame.hx @@ -92,7 +92,7 @@ class Frame else { // No character defined at specified depth. Create one. - objects.set(tag.depth, new FrameObject(tag.depth, tag.clipDepth, tag.characterId, tag.className, tagIndex, 0, true)); + objects.set(tag.depth, new FrameObject(tag.depth, tag.clipDepth, tag.characterId, tag.className, tagIndex, 0, true, tag.ratio)); } _objectsSortedByDepth = null; } diff --git a/src/swf/timeline/FrameObject.hx b/src/swf/timeline/FrameObject.hx index cd488d8..a77bf5a 100644 --- a/src/swf/timeline/FrameObject.hx +++ b/src/swf/timeline/FrameObject.hx @@ -21,8 +21,10 @@ class FrameObject public var isKeyframe:Bool; // The index of the layer this object resides on public var layer:Int = -1; + // The ratio of this object if it's a MorphShape + public var ratio:Int = 0; - public function new(depth:Int, clipDepth:Int, characterId:Int, className:String, placedAtIndex:Int, lastModifiedAtIndex:Int = 0, isKeyframe:Bool = false) + public function new(depth:Int, clipDepth:Int, characterId:Int, className:String, placedAtIndex:Int, lastModifiedAtIndex:Int = 0, isKeyframe:Bool = false, ratio:Int = 0) { this.depth = depth; this.clipDepth = clipDepth; @@ -32,11 +34,12 @@ class FrameObject this.lastModifiedAtIndex = lastModifiedAtIndex; this.isKeyframe = isKeyframe; this.layer = -1; + this.ratio = ratio; } public function clone():FrameObject { - return new FrameObject(depth, clipDepth, characterId, className, placedAtIndex, lastModifiedAtIndex, false); + return new FrameObject(depth, clipDepth, characterId, className, placedAtIndex, lastModifiedAtIndex, false, ratio); } public function toString( /*indent:Int = 0*/):String From 3c27e795c7676a9a7d3a1e66c120a37746f96c8c Mon Sep 17 00:00:00 2001 From: space-nuko Date: Sun, 27 Mar 2022 07:31:59 -0700 Subject: [PATCH 3/4] fix morphshape animation --- src/swf/exporters/animate/AnimateMorphShape.hx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/swf/exporters/animate/AnimateMorphShape.hx b/src/swf/exporters/animate/AnimateMorphShape.hx index 5a40fe1..35a20b7 100644 --- a/src/swf/exporters/animate/AnimateMorphShape.hx +++ b/src/swf/exporters/animate/AnimateMorphShape.hx @@ -48,8 +48,8 @@ class AnimateMorphShape extends openfl.display.Shape return; } - var a = ratio / 65535.0; - var b = 1.0 - ratio; + var b = ratio / 65535.0; + var a = 1.0 - b; for (command in symbol.commands) { @@ -113,10 +113,10 @@ class AnimateMorphShape extends openfl.display.Shape } case LineTo(startX, startY, endX, endY): - graphics.lineTo(lerpf(startX, startY, a, b), lerpf(endX, endY, a, b)); + graphics.lineTo(lerpf(startX, endX, a, b), lerpf(startY, endY, a, b)); case MoveTo(startX, startY, endX, endY): - graphics.moveTo(lerpf(startX, startY, a, b), lerpf(endX, endY, a, b)); + graphics.moveTo(lerpf(startX, endX, a, b), lerpf(startY, endY, a, b)); } } From 653394ca2961189a3d8e42b306e630378e7e1c28 Mon Sep 17 00:00:00 2001 From: space-nuko Date: Sun, 27 Mar 2022 23:43:49 -0700 Subject: [PATCH 4/4] Cleanup unused things --- scripts/Tools.hx | 14 +- src/swf/SWFData.hx | 4 +- src/swf/data/SWFShape.hx | 23 +- src/swf/exporters/AnimateLibraryExporter.hx | 275 +------------------- src/swf/exporters/animate/AnimateLibrary.hx | 24 -- src/swf/tags/TagDefineMorphShape.hx | 5 +- 6 files changed, 20 insertions(+), 325 deletions(-) diff --git a/scripts/Tools.hx b/scripts/Tools.hx index 872b850..a5368d0 100644 --- a/scripts/Tools.hx +++ b/scripts/Tools.hx @@ -625,8 +625,8 @@ class Tools } else if (words.length > 2) { - // try - // { + try + { var projectData = File.getContent(inputPath); var unserializer = new Unserializer(projectData); @@ -639,11 +639,11 @@ class Tools { File.saveContent(outputPath, Serializer.run(output)); } - // } - // catch (e:Dynamic) - // { - // Log.error(e); - // } + } + catch (e:Dynamic) + { + Log.error(e); + } } } } diff --git a/src/swf/SWFData.hx b/src/swf/SWFData.hx index dd4a192..d234b9b 100644 --- a/src/swf/SWFData.hx +++ b/src/swf/SWFData.hx @@ -513,9 +513,9 @@ import swf.utils.BitArray; ///////////////////////////////////////////////////////// // Shape and shape records ///////////////////////////////////////////////////////// - public function readSHAPE(unitDivisor:Float = 20, noStyleInfo:Bool = false):SWFShape + public function readSHAPE(unitDivisor:Float = 20):SWFShape { - return new SWFShape(this, 1, unitDivisor, noStyleInfo); + return new SWFShape(this, 1, unitDivisor); } public function writeSHAPE(value:SWFShape):Void diff --git a/src/swf/data/SWFShape.hx b/src/swf/data/SWFShape.hx index 2efa671..18765c4 100644 --- a/src/swf/data/SWFShape.hx +++ b/src/swf/data/SWFShape.hx @@ -25,7 +25,6 @@ class SWFShape public var fillStyles(default, null):Array; public var lineStyles(default, null):Array; public var referencePoint(default, null):Point; - public var noStyleInfo(default, null):Bool; private var fillEdgeMaps:Array>>; private var lineEdgeMaps:Array>>; @@ -36,14 +35,13 @@ class SWFShape private var unitDivisor:Float; private var edgeMapsCreated:Bool = false; - public function new(data:SWFData = null, level:Int = 1, unitDivisor:Float = 20, noStyleInfo: Bool = false) + public function new(data:SWFData = null, level:Int = 1, unitDivisor:Float = 20) { records = new Array(); fillStyles = new Array(); lineStyles = new Array(); referencePoint = new Point(0, 0); this.unitDivisor = unitDivisor; - this.noStyleInfo = noStyleInfo; if (data != null) { parse(data, level); @@ -250,10 +248,7 @@ class SWFShape // TODO: This is a temporary bug fix. edgeMaps shouldn't need to be recreated for subsequent exports edgeMapsCreated = false; // Create edge maps - // "noStyleInfo" means this shape is the endEdges of a MorphShape - // MorphShape endEdges have no styling info, only edges, so we want to export them even when there's - // no styling info - createEdgeMaps(noStyleInfo); + createEdgeMaps(); // If no handler is passed, default to DefaultShapeExporter (does nothing) if (handler == null) { @@ -273,7 +268,7 @@ class SWFShape handler.endShape(); } - private function createEdgeMaps(noStyleInfo: Bool = false):Void + private function createEdgeMaps():Void { if (!edgeMapsCreated) { @@ -300,9 +295,9 @@ class SWFShape { case SWFShapeRecord.TYPE_STYLECHANGE: var styleChangeRecord:SWFShapeRecordStyleChange = cast(shapeRecord, SWFShapeRecordStyleChange); - if (styleChangeRecord.stateLineStyle || styleChangeRecord.stateFillStyle0 || styleChangeRecord.stateFillStyle1 || noStyleInfo) + if (styleChangeRecord.stateLineStyle || styleChangeRecord.stateFillStyle0 || styleChangeRecord.stateFillStyle1) { - processSubPath(subPath, currentLineStyleIdx, currentFillStyleIdx0, currentFillStyleIdx1, noStyleInfo); + processSubPath(subPath, currentLineStyleIdx, currentFillStyleIdx0, currentFillStyleIdx1); subPath = new Array(); } if (styleChangeRecord.stateNewStyles) @@ -393,7 +388,7 @@ class SWFShape subPath.push(new CurvedEdge(from, control, to, currentLineStyleIdx, currentFillStyleIdx1)); case SWFShapeRecord.TYPE_END: // We're done. Process the last subpath, if any - processSubPath(subPath, currentLineStyleIdx, currentFillStyleIdx0, currentFillStyleIdx1, noStyleInfo); + processSubPath(subPath, currentLineStyleIdx, currentFillStyleIdx0, currentFillStyleIdx1); cleanEdgeMap(currentFillEdgeMap); cleanEdgeMap(currentLineEdgeMap); fillEdgeMaps.push(currentFillEdgeMap); @@ -405,10 +400,10 @@ class SWFShape } } - private function processSubPath(subPath:Array, lineStyleIdx:Int, fillStyleIdx0:Int, fillStyleIdx1:Int, noStyleInfo: Bool = false):Void + private function processSubPath(subPath:Array, lineStyleIdx:Int, fillStyleIdx0:Int, fillStyleIdx1:Int):Void { var path:Array; - if (fillStyleIdx0 != 0 || noStyleInfo) + if (fillStyleIdx0 != 0) { path = currentFillEdgeMap.get(fillStyleIdx0); if (path == null) @@ -433,7 +428,7 @@ class SWFShape } appendEdges(path, subPath); } - if (lineStyleIdx != 0 || noStyleInfo) + if (lineStyleIdx != 0) { path = currentLineEdgeMap.get(lineStyleIdx); if (path == null) diff --git a/src/swf/exporters/AnimateLibraryExporter.hx b/src/swf/exporters/AnimateLibraryExporter.hx index 214b155..e7bdbdb 100644 --- a/src/swf/exporters/AnimateLibraryExporter.hx +++ b/src/swf/exporters/AnimateLibraryExporter.hx @@ -105,8 +105,7 @@ class AnimateLibraryExporter libraryData = new SWFDocument(); outputList = new List(); - // var uuid = StringTools.generateUUID(20); - var uuid = "sdthx-lib"; + var uuid = StringTools.generateUUID(20); manifestData.libraryType = "swf.exporters.animate.AnimateLibrary"; manifestData.libraryArgs = ["data.json", uuid]; @@ -1518,254 +1517,6 @@ class AnimateLibraryExporter return [twip(rect.x), twip(rect.y), twip(rect.width), twip(rect.height)]; } - // private function serializeMorphShapeEdges(startEdges: SWFShape, endEdges: SWFShape):Array - // { - // var result: Array = []; - // var numEdges:Int = startEdges.records.length; - - // var i = 0; - // var j = 0; - // while (i < numEdges) - // { - // var record: Array = []; - - // var startX = 0; - // var startY = 0; - // var endX = 0; - // var endY = 0; - - // var startRecord = startEdges.records[i]; - // var endRecord = endEdges.records[j]; - - // if (endRecord == null) { - // throw("End record is null! " + i + ", " + j); - // } - - // if (startRecord.type == SWFShapeRecord.TYPE_STYLECHANGE && endRecord.type == SWFShapeRecord.TYPE_STYLECHANGE) - // { - // var startStyleChange: SWFShapeRecordStyleChange = cast startRecord; - // var endStyleChange: SWFShapeRecordStyleChange = cast endRecord; - - // record = serializeStyleChange(startStyleChange); - - // if (startStyleChange.moveTo || endStyleChange.moveTo) - // { - // if (startStyleChange.moveTo) { - // startX = startStyleChange.moveDeltaX; - // startY = startStyleChange.moveDeltaY; - // } - // if (endStyleChange.moveTo) { - // endX = endStyleChange.moveDeltaX; - // endY = endStyleChange.moveDeltaY; - // } - - // record.push([[twip(startX), twip(startY)], [twip(endX), twip(endY)]]); - // } - - // i++; - // j++; - // } - // else if (startRecord.type == SWFShapeRecord.TYPE_STYLECHANGE) - // { - // var startStyleChange: SWFShapeRecordStyleChange = cast startRecord; - - // record = serializeStyleChange(startStyleChange); - - // if (startStyleChange.moveTo) - // { - // startX = startStyleChange.moveDeltaX; - // startY = startStyleChange.moveDeltaY; - - // record.push([[twip(startX), twip(startY)], [twip(endX), twip(endY)]]); - // } - - // i++; - // } - // else if (endRecord.type == SWFShapeRecord.TYPE_STYLECHANGE) - // { - // record = serializeStyleChange(endStyleChange); - - // var endStyleChange: SWFShapeRecordStyleChange = cast endRecord; - - // if (endStyleChange.moveTo) - // { - // endX = endStyleChange.moveDeltaX; - // endY = endStyleChange.moveDeltaY; - - // record.push([[twip(startX), twip(startY)], [twip(endX), twip(endY)]]); - // } - - // j++; - // } - // else if (startRecord.type == SWFShapeRecord.TYPE_END && endRecord.type == SWFShapeRecord.TYPE_END) { - // record = [SWFShapeRecord.TYPE_END]; - // i++; - // j++; - // } - // else { - // record = serializeMorphShapeEdge(startRecord, endRecord); - // i++; - // j++; - // } - - // result.push(record); - // } - - // return result; - // } - - // private function serializeMorphShapeEdge(startRecord: SWFShapeRecord, endRecord: SWFShapeRecord): Array - // { - // if (startRecord.type == SWFShapeRecord.TYPE_STRAIGHTEDGE && endRecord.type == SWFShapeRecord.TYPE_STRAIGHTEDGE) - // { - // var sse:SWFShapeRecordStraightEdge = cast startRecord; - // var ese:SWFShapeRecordStraightEdge = cast endRecord; - // return [SWFShapeRecord.TYPE_STRAIGHTEDGE, [twip(sse.deltaX), twip(sse.deltaY)], [twip(ese.deltaX), twip(ese.deltaY)]]; - // } - // else if (startRecord.type == SWFShapeRecord.TYPE_STRAIGHTEDGE && endRecord.type == SWFShapeRecord.TYPE_CURVEDEDGE) - // { - // var sse:SWFShapeRecordStraightEdge = cast startRecord; - // var ece:SWFShapeRecordCurvedEdge = cast endRecord; - // return [SWFShapeRecord.TYPE_CURVEDEDGE, straightToCurved(sse), serializeCurvedRecord(ece)]; - // } - // else if (startRecord.type == SWFShapeRecord.TYPE_CURVEDEDGE && endRecord.type == SWFShapeRecord.TYPE_STRAIGHTEDGE) - // { - // var sce:SWFShapeRecordCurvedEdge = cast startRecord; - // var ese:SWFShapeRecordStraightEdge = cast endRecord; - // return [SWFShapeRecord.TYPE_CURVEDEDGE, serializeCurvedRecord(sce), straightToCurved(ese)]; - // } - // else if (startRecord.type == SWFShapeRecord.TYPE_CURVEDEDGE && endRecord.type == SWFShapeRecord.TYPE_CURVEDEDGE) - // { - // var sce:SWFShapeRecordCurvedEdge = cast startRecord; - // var ece:SWFShapeRecordCurvedEdge = cast endRecord; - // return [SWFShapeRecord.TYPE_CURVEDEDGE, serializeCurvedRecord(sce), - // serializeCurvedRecord(ece)]; - // } - // else - // { - // throw "Invalid morph shape edge pairs!"; - // } - // } - - // private function serializeCurvedRecord(cr: SWFShapeRecordCurvedEdge): Array - // { - // return [twip(cr.controlDeltaX), twip(cr.controlDeltaY), twip(cr.anchorDeltaX), twip(cr.anchorDeltaY)]; - // } - - // private function straightToCurved(sc: SWFShapeRecordStraightEdge): Array - // { - // return [twip(sc.deltaX / 2), twip(sc.deltaY / 2), twip(sc.deltaX / 2), twip(sc.deltaY / 2)]; - // } - - // private function serializeStyleChange(sc: SWFShapeRecordStyleChange): Array - // { - // return [SWFShapeRecord.TYPE_STYLECHANGE, sc.stateNewStyles, sc.stateLineStyle, sc.stateFillStyle1, sc.stateFillStyle0, sc.fillStyle0, sc.fillStyle1, sc.lineStyle, sc.numFillBits, sc.numLineBits, serializeFillStyles(sc.fillStyles), serializeLineStyles(sc.lineStyles)]; - // } - - // private function serializeFillStyles(fillStyles: Array): Array - // { - // var result: Array = []; - - // for (fs in fillStyles) { - // if (type != null) - // { - // switch (type) - // { - // case SWFMorphFillType.SOLID: - // result.push([fs.type, fs.rgb]); - // case SWFMorphFillType.LINEAR_GRADIENT: - // case SWFMorphFillType.RADIAL_GRADIENT: - // case SWFMorphFillType.FOCAL_RADIAL_GRADIENT: - // result.push([fs.type, serializeSWFMatrix(fs.gradientMatrix), serializeGradient(fs.gradient)]); - // case SWFMorphFillType.REPEATING_BITMAP: - // case SWFMorphFillType.CLIPPED_BITMAP: - // case SWFMorphFillType.REPEATING_BITMAP_NON_SMOOTHED: - // case SWFMorphFillType.CLIPPED_BITMAP_NON_SMOOTHED: - // result.push([fs.type, fs.bitmapId, serializeSWFMatrix(fs.bitmapMatrix)]); - // default: - // throw "Invalid fill style! " + fs.type; - // } - // } - // } - - // return result; - // } - - // private function serializeLineStyles(lineStyles: Array): Array - // { - // var result: Array = []; - // for (ls in lineStyles) { - // if (#if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end (mls, SWFLineStyle2)) { - // return [SWFLineStyleType.V2, mls.startWidth, mls.endWidth, mls.startColor, mls.endColor, - // mls.startCapsStyle, mls.endCapsStyle, mls.jointStyle, mls.hasFillFlag, mls.noHScaleFlag, mls.noVScaleFlag, - // mls.pixelHintingFlag, mls.noClose, mls.miterLimitFactor, serializeMorphFillStyle(mls.fillType)]; - // } - - // return [SWFLineStyleType.V1, mls.startWidth, mls.endWidth, mls.startColor, mls.endColor]; - // } - // return result; - // } - - // private function serializeMorphFillStyle(mfs:SWFMorphFillStyle):Array - // { - // if (mfs == null) { - // return null; - // } - - // var type = mfs.type; - - // if (type != null) - // { - // switch (type) - // { - // case SWFMorphFillType.SOLID: - // return [mfs.type, mfs.startColor, mfs.endColor]; - // case SWFMorphFillType.LINEAR_GRADIENT: - // case SWFMorphFillType.RADIAL_GRADIENT: - // case SWFMorphFillType.FOCAL_RADIAL_GRADIENT: - // return [mfs.type, serializeSWFMatrix(mfs.startGradientMatrix), serializeSWFMatrix(mfs.endGradientMatrix), serializeMorphGradient(mfs.gradient)]; - // case SWFMorphFillType.REPEATING_BITMAP: - // case SWFMorphFillType.CLIPPED_BITMAP: - // case SWFMorphFillType.REPEATING_BITMAP_NON_SMOOTHED: - // case SWFMorphFillType.CLIPPED_BITMAP_NON_SMOOTHED: - // return [mfs.type, - // mfs.bitmapId, - // serializeSWFMatrix(mfs.startBitmapMatrix), - // serializeSWFMatrix(mfs.endBitmapMatrix)]; - // default: - // throw "Invalid fill style!"; - // } - // } - - // return null; - // } - - // private function serializeMorphLineStyle(mls:SWFMorphLineStyle):Array - // { - // if (#if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end (mls, SWFMorphLineStyle2)) { - // return [SWFLineStyleType.V2, mls.startWidth, mls.endWidth, mls.startColor, mls.endColor, - // mls.startCapsStyle, mls.endCapsStyle, mls.jointStyle, mls.hasFillFlag, mls.noHScaleFlag, mls.noVScaleFlag, - // mls.pixelHintingFlag, mls.noClose, mls.miterLimitFactor, serializeMorphFillStyle(mls.fillType)]; - // } - - // return [SWFLineStyleType.V1, mls.startWidth, mls.endWidth, mls.startColor, mls.endColor]; - // } - - // private function serializeMorphGradient(mg:SWFMorphGradient):Array - // { - // var records: Array = []; - - // for (record in mg.records) { - // records.push([record.startRatio, record.startColor, record.endRatio, record.endColor]); - // } - - // if (#if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end (mg, SWFMorphFocalGradient)) { - // return [SWFMorphGradientType.FOCAL, mg.spreadMode, mg.interpolationMode, records, mg.startFocalPoint, mg.endFocalPoint]; - // } - - // return [SWFMorphGradientType.NORMAL, mg.spreadMode, mg.interpolationMode, records]; - // } - private inline function twip(value:Float):Int { return Math.round(value * 20); @@ -1867,27 +1618,3 @@ private class SWFDocument public var GLOW = 3; // TODO: More } - -@:enum private abstract SWFMorphFillType(Int) from Int to Int - { - public var SOLID = 0x00; - public var LINEAR_GRADIENT = 0x10; - public var RADIAL_GRADIENT = 0x12; - public var FOCAL_RADIAL_GRADIENT = 0x13; - public var REPEATING_BITMAP = 0x40; - public var CLIPPED_BITMAP = 0x41; - public var REPEATING_BITMAP_NON_SMOOTHED = 0x42; - public var CLIPPED_BITMAP_NON_SMOOTHED = 0x43; -} - -@:enum private abstract SWFLineStyleType(Int) from Int to Int - { - public var V1 = 0; - public var V2 = 1; -} - -@:enum private abstract SWFGradientType(Int) from Int to Int - { - public var NORMAL = 0; - public var FOCAL = 1; -} diff --git a/src/swf/exporters/animate/AnimateLibrary.hx b/src/swf/exporters/animate/AnimateLibrary.hx index cbc4824..d7f03bf 100644 --- a/src/swf/exporters/animate/AnimateLibrary.hx +++ b/src/swf/exporters/animate/AnimateLibrary.hx @@ -839,27 +839,3 @@ import openfl.filters.GlowFilter; public var STATIC_TEXT = 6; public var MORPH_SHAPE = 7; } - -@:enum abstract SWFMorphFillType(Int) from Int to Int -{ - public var SOLID = 0x00; - public var LINEAR_GRADIENT = 0x10; - public var RADIAL_GRADIENT = 0x12; - public var FOCAL_RADIAL_GRADIENT = 0x13; - public var REPEATING_BITMAP = 0x40; - public var CLIPPED_BITMAP = 0x41; - public var REPEATING_BITMAP_NON_SMOOTHED = 0x42; - public var CLIPPED_BITMAP_NON_SMOOTHED = 0x43; -} - -@:enum abstract SWFMorphLineStyleType(Int) from Int to Int -{ - public var V1 = 0; - public var V2 = 1; -} - -@:enum abstract SWFMorphGradientType(Int) from Int to Int -{ - public var NORMAL = 0; - public var FOCAL = 1; -} diff --git a/src/swf/tags/TagDefineMorphShape.hx b/src/swf/tags/TagDefineMorphShape.hx index 12718bf..eaba3d8 100644 --- a/src/swf/tags/TagDefineMorphShape.hx +++ b/src/swf/tags/TagDefineMorphShape.hx @@ -75,10 +75,7 @@ class TagDefineMorphShape implements IDefinitionTag morphLineStyles.push(data.readMORPHLINESTYLE()); } startEdges = data.readSHAPE(); - // endEdges are a special kind of shape, they only contain edge data - // and no style info, which messes up the exporter if it doesn't understand - // the difference - endEdges = data.readSHAPE(true); + endEdges = data.readSHAPE(); } public function publish(data:SWFData, version:Int):Void