Code Monkey home page Code Monkey logo

swflib's People

Contributors

dependabot[bot] avatar drawbackz avatar savchuksergey avatar zingballyhoo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

swflib's Issues

How to replace defineBitsLossless2Tag.ZlibBitmapData

`DefineBitsLossless2Tag defineBitsLossless2Tag = (DefineBitsLossless2Tag)tag;

FileStream fileStream = File.OpenRead(startupPath + "\library\1.png");
Image image = Image.FromStream(fileStream);
Bitmap bitmap = new Bitmap(image);
ImageConverter converter = new ImageConverter();
defineBitsLossless2Tag.ZlibBitmapData = (byte[])converter.ConvertTo(bitmap, typeof(byte[]));`

ZlibBitmapData replacing not working.

Export DefineShape4Tag

Hello,
I just added this class to export DefineShape4Tag

`using SwfLib.Shapes.FillStyles;
using SwfLib.Shapes.LineStyles;
using SwfLib.Shapes.Records;
using SwfLib.Tags.ShapeTags;
using EdgeMap = System.Collections.Generic.Dictionary<int, System.Collections.Generic.List<SwfShapeExporter.IEdge>>;
using CoordMap = System.Collections.Generic.Dictionary<SixLabors.ImageSharp.Point, System.Collections.Generic.List<SwfShapeExporter.IEdge>>;
using Path = System.Collections.Generic.List<SwfShapeExporter.IEdge>;

namespace SwfShapeExporter;

public class SwfShapeEx : ISwfShape
{
    public List<IShapeRecordEx> RecordsEx { get; set; } = new();
    public List<FillStyleRGBA> FillStyles { get; set; } = new();
    public List<LineStyleEx> LineStylesEx { get; set; } = new();

    public List<EdgeMap> FillEdgeMaps { get; set; } = new();
    public EdgeMap CurrentFillEdgeMap { get; set; } = new();
    public List<EdgeMap> LineEdgeMaps { get; set; } = new();
    public EdgeMap CurrentLineEdgeMap { get; set; } = new();
    public int NumGroups { get; set; } = 0;
    public CoordMap CoordMap { get; set; } = new();
    public CoordMap ReverseCoordMap { get; set; } = new();
    public bool EdgeMapsCreated { get; private set; } = false;

    public SwfShapeEx(IList<IShapeRecordEx> records, IList<FillStyleRGBA> fillStyles, IList<LineStyleEx> lineStyles)
    {
        RecordsEx = records.ToList();
        FillStyles = fillStyles.ToList();
        LineStylesEx = lineStyles.ToList();
    }
    public SwfShapeEx(DefineShape4Tag shape) : this(shape.ShapeRecords, shape.FillStyles, shape.LineStyles) { }
    public void Export(IShapeHandler handler)
    {
        CreateEdgeMaps();
        handler.BeginShape();
        for (int i = 0; i < NumGroups; ++i)
        {
            ExportFillPath(handler, i);
            ExportLinePath(handler, i);
        }
        handler.EndShape();
    }

    public void ExportFillPath(IShapeHandler handler, int i)
    {
        var path = PathFromEdgeMap(FillEdgeMaps[i]);
        if (path.Count == 0) return;
        var pos = new Point(int.MaxValue, int.MaxValue);
        var fillStyleIdx = int.MaxValue;
        handler.BeginFills();
        foreach (var edge in path)
        {
            if (fillStyleIdx != edge.FillStyleIdx)
            {
                if (fillStyleIdx != int.MaxValue) handler.EndFill();

                fillStyleIdx = edge.FillStyleIdx;
                pos = new Point(int.MaxValue, int.MaxValue);
                var fillStyle = (fillStyleIdx == 0) ? null : FillStyles[fillStyleIdx - 1];

                if (fillStyle is null) handler.BeginFill(Color.Black);
                else switch (fillStyle.Type)
                    {
                        case FillStyleType.SolidColor:
                            var solidFillStyle = (SolidFillStyleRGBA)fillStyle;
                            handler.BeginFill(solidFillStyle.Color.ToImageSharpColor());
                            break;
                        case FillStyleType.LinearGradient:
                        case FillStyleType.RadialGradient:
                        case FillStyleType.FocalGradient:
                        case FillStyleType.RepeatingBitmap:
                        case FillStyleType.ClippedBitmap:
                        case FillStyleType.NonSmoothedRepeatingBitmap:
                        case FillStyleType.NonSmoothedClippedBitmap:
                            throw new NotImplementedException($"Unsupported fill style type {fillStyle.Type}");
                        default:
                            throw new ArgumentException($"Invalid fill style type {fillStyle.Type}");
                    }
            }

            if (pos != edge.From)
                handler.MoveTo(edge.From);

            if (edge is CurvedEdge cedge)
                handler.CurveTo(cedge.Control, cedge.To);
            else
                handler.LineTo(edge.To);

            pos = edge.To;
        }

        if (fillStyleIdx != int.MaxValue) handler.EndFill();
        handler.EndFills();
    }

    public void ExportLinePath(IShapeHandler handler, int i)
    {
        var path = PathFromEdgeMap(LineEdgeMaps[i]);
        if (path.Count == 0) return;
        var pos = new Point(int.MaxValue, int.MaxValue);
        var lastMove = pos;
        var lineStyleIdx = int.MaxValue;

        handler.BeginLines();
        foreach (var edge in path)
        {
            if (lineStyleIdx != edge.LineStyleIdx)
            {
                lineStyleIdx = edge.LineStyleIdx;
                pos = new Point(int.MaxValue, int.MaxValue);

                if (lineStyleIdx == 0) handler.LineStyle(0, Color.Black);
                else
                {
                    var lineStyle = LineStylesEx[lineStyleIdx - 1];
                    handler.LineStyle(lineStyle.Width, lineStyle.Color.ToImageSharpColor());
                }
            }

            if (pos != edge.From)
            {
                handler.MoveTo(edge.From);
                lastMove = edge.From;
            }

            if (edge is CurvedEdge cedge)
                handler.CurveTo(cedge.Control, cedge.To);
            else
                handler.LineTo(edge.To);

            pos = edge.To;
        }
        handler.EndLines(pos == lastMove);
    }
    public void CreateEdgeMaps()
    {
        if (EdgeMapsCreated) return;
        Point pos = Point.Empty;
        Point from = Point.Empty;
        Point to = Point.Empty;
        Point control = Point.Empty;
        int fillStyleIdxOffset = 0;
        int lineStyleIdxOffset = 0;
        int currentFillStyleIdx0 = 0;
        int currentFillStyleIdx1 = 0;
        int currentLineStyleIdx = 0;
        Path subPath = new();
        NumGroups = 0;
        FillEdgeMaps.Clear();
        LineEdgeMaps.Clear();
        CurrentFillEdgeMap.Clear();
        CurrentLineEdgeMap.Clear();

        for (int i = 0; i < RecordsEx.Count; ++i)
        {
            var shapeRecord = RecordsEx[i];
            switch (shapeRecord.Type)
            {
                case ShapeRecordType.StyleChangeRecord:
                    var styleChangeRecord = (StyleChangeShapeRecordEx)shapeRecord;
                    if (styleChangeRecord.LineStyle is not null || styleChangeRecord.FillStyle0 is not null || styleChangeRecord.FillStyle1 is not null)
                    {
                        ProcessSubPath(subPath, currentLineStyleIdx, currentFillStyleIdx0, currentFillStyleIdx1);
                        subPath.Clear();
                    }

                    if (styleChangeRecord.StateNewStyles)
                    {
                        fillStyleIdxOffset = FillStyles.Count;
                        lineStyleIdxOffset = LineStylesEx.Count;
                        FillStyles.AddRange(styleChangeRecord.FillStyles);
                        LineStylesEx.AddRange(styleChangeRecord.LineStyles);
                    }

                    if (styleChangeRecord.LineStyle is not null && styleChangeRecord.LineStyle == 0 &&
                        styleChangeRecord.FillStyle0 is not null && styleChangeRecord.FillStyle0 == 0 &&
                        styleChangeRecord.FillStyle1 is not null && styleChangeRecord.FillStyle1 == 0)
                    {
                        CleanEdgeMap(CurrentFillEdgeMap);
                        CleanEdgeMap(CurrentLineEdgeMap);
                        FillEdgeMaps.Add(CurrentFillEdgeMap);
                        LineEdgeMaps.Add(CurrentLineEdgeMap);
                        //we must create new instead of Clear because the edge map lists hold a reference
                        CurrentFillEdgeMap = new EdgeMap();
                        CurrentLineEdgeMap = new EdgeMap();
                        currentLineStyleIdx = 0;
                        currentFillStyleIdx0 = 0;
                        currentFillStyleIdx1 = 0;
                        NumGroups++;
                    }
                    else
                    {
                        if (styleChangeRecord.LineStyle is not null)
                        {
                            currentLineStyleIdx = (int)styleChangeRecord.LineStyle;
                            if (currentLineStyleIdx > 0) currentLineStyleIdx += lineStyleIdxOffset;
                        }
                        if (styleChangeRecord.FillStyle0 is not null)
                        {
                            currentFillStyleIdx0 = (int)styleChangeRecord.FillStyle0;
                            if (currentFillStyleIdx0 > 0) currentFillStyleIdx0 += fillStyleIdxOffset;
                        }
                        if (styleChangeRecord.FillStyle1 is not null)
                        {
                            currentFillStyleIdx1 = (int)styleChangeRecord.FillStyle1;
                            if (currentFillStyleIdx1 > 0) currentFillStyleIdx1 += fillStyleIdxOffset;
                        }
                    }

                    if (styleChangeRecord.StateMoveTo)
                    {
                        pos = new Point(styleChangeRecord.MoveDeltaX, styleChangeRecord.MoveDeltaY);
                    }
                    break;
                case ShapeRecordType.StraightEdge:
                    var straightEdgeRecord = (StraightEdgeShapeRecord)shapeRecord;
                    from = new Point(pos.X, pos.Y);
                    Size delta = new(straightEdgeRecord.DeltaX, straightEdgeRecord.DeltaY);
                    pos += delta;
                    to = new Point(pos.X, pos.Y);
                    subPath.Add(new StraightEdge { From = from, To = to, LineStyleIdx = currentLineStyleIdx, FillStyleIdx = currentFillStyleIdx1 });
                    break;
                case ShapeRecordType.CurvedEdgeRecord:
                    var curvedEdgeRecord = (CurvedEdgeShapeRecord)shapeRecord;
                    from = new Point(pos.X, pos.Y);
                    Size controlDelta = new(curvedEdgeRecord.ControlDeltaX, curvedEdgeRecord.ControlDeltaY);
                    control = pos + controlDelta;
                    Size anchorDelta = new(curvedEdgeRecord.AnchorDeltaX, curvedEdgeRecord.AnchorDeltaY);
                    pos = control + anchorDelta;
                    to = new Point(pos.X, pos.Y);
                    subPath.Add(new CurvedEdge { From = from, Control = control, To = to, LineStyleIdx = currentLineStyleIdx, FillStyleIdx = currentFillStyleIdx1 });
                    break;
                case ShapeRecordType.EndRecord:
                    ProcessSubPath(subPath, currentLineStyleIdx, currentFillStyleIdx0, currentFillStyleIdx1);
                    CleanEdgeMap(CurrentFillEdgeMap);
                    CleanEdgeMap(CurrentLineEdgeMap);
                    FillEdgeMaps.Add(CurrentFillEdgeMap);
                    LineEdgeMaps.Add(CurrentLineEdgeMap);
                    NumGroups++;
                    break;
                default:
                    throw new ArgumentException($"Invalid record type {shapeRecord.Type}");
            }
        }

        EdgeMapsCreated = true;
    }
    public void ProcessSubPath(Path subPath, int lineStyleIdx, int fillStyleIdx0, int fillStyleIdx1)
    {
        if (fillStyleIdx0 != 0)
        {
            if (!CurrentFillEdgeMap.ContainsKey(fillStyleIdx0)) CurrentFillEdgeMap[fillStyleIdx0] = new();
            CurrentFillEdgeMap[fillStyleIdx0].AddRange(
                subPath.Select(e => e.ReverseWithStyle(fillStyleIdx0)).Reverse()
            );
        }

        if (fillStyleIdx1 != 0)
        {
            if (!CurrentFillEdgeMap.ContainsKey(fillStyleIdx1)) CurrentFillEdgeMap[fillStyleIdx1] = new();

            CurrentFillEdgeMap[fillStyleIdx1].AddRange(subPath);
        }

        if (lineStyleIdx != 0)
        {
            if (!CurrentLineEdgeMap.ContainsKey(lineStyleIdx)) CurrentLineEdgeMap[lineStyleIdx] = new();

            CurrentLineEdgeMap[lineStyleIdx].AddRange(subPath);
        }
    }
    public void CleanEdgeMap(EdgeMap edgeMap)
    {
        foreach (var (styleIdx, subPath) in edgeMap)
        {
            if (subPath.Count == 0) continue;
            IEdge? prevEdge = null;
            IEdge? edge = null;
            Path tmpPath = new();
            CreateCoordMap(subPath);
            CreateReverseCoordMap(subPath);
            while (subPath.Count > 0)
            {
                var idx = 0;
                while (idx < subPath.Count)
                {
                    if (prevEdge is not null)
                    {
                        if (prevEdge.To != subPath[idx].From)
                        {
                            edge = FindNextEdgeInCoordMap(prevEdge);
                            if (edge is not null)
                            {
                                idx = subPath.IndexOf(edge);
                            }
                            else
                            {
                                var revEdge = FindNextEdgeInReverseCoordMap(prevEdge);
                                if (revEdge is not null)
                                {
                                    idx = subPath.IndexOf(revEdge);
                                    var r = revEdge.ReverseWithStyle(revEdge.FillStyleIdx);
                                    UpdateEdgeInCoordMap(revEdge, r);
                                    UpdateEdgeInReverseCoordMap(revEdge, r);
                                    subPath[idx] = r;
                                }
                                else
                                {
                                    idx = 0;
                                    prevEdge = null;
                                }
                            }

                            continue;
                        }
                    }

                    edge = subPath[idx];
                    subPath.RemoveAt(idx);
                    tmpPath.Add(edge);
                    RemoveEdgeFromCoordMap(edge);
                    RemoveEdgeFromReverseCoordMap(edge);
                    prevEdge = edge;
                }
            }
            edgeMap[styleIdx] = tmpPath;
        }
    }
    public IEdge? FindNextEdgeInCoordMap(IEdge edge)
    {
        var key = edge.To;
        Path? path = null;
        if (!CoordMap.TryGetValue(key, out path))
            return null;
        if (path.Count == 0)
            return null;
        return path[0];
    }

    public IEdge? FindNextEdgeInReverseCoordMap(IEdge edge)
    {
        var key = edge.To;
        Path? path = null;
        if (!ReverseCoordMap.TryGetValue(key, out path))
            return null;
        if (path.Count == 0)
            return null;
        return path[0];
    }

    public void RemoveEdgeFromCoordMap(IEdge edge)
    {
        var key = edge.From;
        if (CoordMap.ContainsKey(key))
        {
            if (CoordMap[key].Count == 1) CoordMap.Remove(key);
            else CoordMap[key].Remove(edge);
        }
    }

    public void RemoveEdgeFromReverseCoordMap(IEdge edge)
    {
        var key = edge.To;
        if (ReverseCoordMap.ContainsKey(key))
        {
            if (ReverseCoordMap[key].Count == 1) ReverseCoordMap.Remove(key);
            else ReverseCoordMap[key].Remove(edge);
        }
    }

    public void CreateCoordMap(Path path)
    {
        CoordMap.Clear();
        for (int i = 0; i < path.Count; ++i)
        {
            var key = path[i].From;
            if (!CoordMap.ContainsKey(key)) CoordMap[key] = new();
            CoordMap[key].Add(path[i]);
        }
    }

    public void CreateReverseCoordMap(Path path)
    {
        ReverseCoordMap.Clear();
        for (int i = 0; i < path.Count; ++i)
        {
            var key = path[i].To;
            if (!ReverseCoordMap.ContainsKey(key)) ReverseCoordMap[key] = new();
            ReverseCoordMap[key].Add(path[i]);
        }
    }

    public void UpdateEdgeInCoordMap(IEdge edge, IEdge newEdge)
    {
        var key1 = edge.From;
        CoordMap[key1].Remove(edge);
        var key2 = newEdge.From;
        if (!CoordMap.ContainsKey(key2)) CoordMap[key2] = new();
        CoordMap[key2].Add(newEdge);
    }

    public void UpdateEdgeInReverseCoordMap(IEdge edge, IEdge newEdge)
    {
        var key1 = edge.To;
        ReverseCoordMap[key1].Remove(edge);
        var key2 = newEdge.To;
        if (!ReverseCoordMap.ContainsKey(key2)) ReverseCoordMap[key2] = new();
        ReverseCoordMap[key2].Add(newEdge);
    }

    public Path PathFromEdgeMap(EdgeMap edgeMap) =>
        edgeMap.Keys.OrderBy(i => i).SelectMany(i => edgeMap[i]).ToList();
}

`

Library needs to interpret strings as SHIFT_JIS encoded strings for swf versions <6

Per SWF specification, all strings are encoded in SHIFT_JIS (which is a superset of ASCII) prior to version 6, However the library assumes all strings to be UTF-8 (which is the correct behaviour for >= version 6, however not for ones prior to that) which causes the reader/writer to produce invalid characters when non-ASCII characters are read.

Missing license

Hi,

Thank's for this nice library.

This project has no license, so theoretically / strictly legally nobody is allowed to use it, except to study the code and fork it here on github (but then you can't do anything with the fork). Even contributors can't use the library since they all share exclusive copyright for the code and should always ask permission from all other contributors before using the code in any way.

More details: https://choosealicense.com/no-license/

Could you add a licence please?

Thank's in advance :)

swf or xml to video

this is wonderful library .
i would like to export video file from swf or xml structure. do you have any method for convert to video?
how can i do that?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.