diff options
| author | Roy Ben-Shabat <Roy@Twine-s.com> | 2019-03-06 14:23:47 +0200 |
|---|---|---|
| committer | Roy Ben-Shabat <Roy@Twine-s.com> | 2019-03-06 14:23:47 +0200 |
| commit | 1d0a3a5c47a2ba4cdabb9f8a4fab694d4987083f (patch) | |
| tree | 9500aca3038e50b9a8e0120dfcd183b4a81f5011 /Software/Visual_Studio/Tango.Pulse | |
| parent | 745cb5da6ddf2418258892fa49f4e03b28645bed (diff) | |
| download | Tango-1d0a3a5c47a2ba4cdabb9f8a4fab694d4987083f.tar.gz Tango-1d0a3a5c47a2ba4cdabb9f8a4fab694d4987083f.zip | |
Implemented pulse TWN file.
Diffstat (limited to 'Software/Visual_Studio/Tango.Pulse')
| -rw-r--r-- | Software/Visual_Studio/Tango.Pulse/Properties/AssemblyInfo.cs | 7 | ||||
| -rw-r--r-- | Software/Visual_Studio/Tango.Pulse/SpoolingMethods.cs | 15 | ||||
| -rw-r--r-- | Software/Visual_Studio/Tango.Pulse/Tango.Pulse.csproj | 60 | ||||
| -rw-r--r-- | Software/Visual_Studio/Tango.Pulse/Twine TWN Spec.pdf | bin | 0 -> 54304 bytes | |||
| -rw-r--r-- | Software/Visual_Studio/Tango.Pulse/TwnFile.cs | 118 | ||||
| -rw-r--r-- | Software/Visual_Studio/Tango.Pulse/TwnFileReader.cs | 109 | ||||
| -rw-r--r-- | Software/Visual_Studio/Tango.Pulse/TwnFileWriter.cs | 128 | ||||
| -rw-r--r-- | Software/Visual_Studio/Tango.Pulse/TwnSegment.cs | 35 | ||||
| -rw-r--r-- | Software/Visual_Studio/Tango.Pulse/TwnStop.cs | 67 |
9 files changed, 539 insertions, 0 deletions
diff --git a/Software/Visual_Studio/Tango.Pulse/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Tango.Pulse/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..f05da7191 --- /dev/null +++ b/Software/Visual_Studio/Tango.Pulse/Properties/AssemblyInfo.cs @@ -0,0 +1,7 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("Tango - Pulse TWN format library")] +[assembly: AssemblyVersion("2.0.29.1608")] +[assembly: ComVisible(false)]
\ No newline at end of file diff --git a/Software/Visual_Studio/Tango.Pulse/SpoolingMethods.cs b/Software/Visual_Studio/Tango.Pulse/SpoolingMethods.cs new file mode 100644 index 000000000..3677e0ce7 --- /dev/null +++ b/Software/Visual_Studio/Tango.Pulse/SpoolingMethods.cs @@ -0,0 +1,15 @@ +namespace Tango.Pulse +{ + /// <summary> + /// Represents a twn file spooling method. + /// </summary> + public enum SpoolingMethods + { + //Spool per segment. (default) + SpoolPerSegment = 0, + //Spool per copy. + SpoolPerCopy = 1, + //Single spool for all segments. + SingleSpool = 2, + } +} diff --git a/Software/Visual_Studio/Tango.Pulse/Tango.Pulse.csproj b/Software/Visual_Studio/Tango.Pulse/Tango.Pulse.csproj new file mode 100644 index 000000000..fe041bd58 --- /dev/null +++ b/Software/Visual_Studio/Tango.Pulse/Tango.Pulse.csproj @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProjectGuid>{8435223D-DB6B-45E3-A08B-45B7416F8481}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>Tango.Pulse</RootNamespace> + <AssemblyName>Tango.Pulse</AssemblyName> + <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + <Deterministic>true</Deterministic> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>..\Build\Core\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>..\Build\Core\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + <Reference Include="System.Core" /> + <Reference Include="System.Drawing" /> + <Reference Include="System.Xml.Linq" /> + <Reference Include="System.Data.DataSetExtensions" /> + <Reference Include="Microsoft.CSharp" /> + <Reference Include="System.Data" /> + <Reference Include="System.Net.Http" /> + <Reference Include="System.Xml" /> + </ItemGroup> + <ItemGroup> + <Compile Include="..\Versioning\GlobalVersionInfo.cs"> + <Link>GlobalVersionInfo.cs</Link> + </Compile> + <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="TwnSegment.cs" /> + <Compile Include="SpoolingMethods.cs" /> + <Compile Include="TwnStop.cs" /> + <Compile Include="TwnFile.cs" /> + <Compile Include="TwnFileReader.cs" /> + <Compile Include="TwnFileWriter.cs" /> + </ItemGroup> + <ItemGroup> + <None Include="Twine TWN Spec.pdf" /> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> +</Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/Tango.Pulse/Twine TWN Spec.pdf b/Software/Visual_Studio/Tango.Pulse/Twine TWN Spec.pdf Binary files differnew file mode 100644 index 000000000..bc38981a4 --- /dev/null +++ b/Software/Visual_Studio/Tango.Pulse/Twine TWN Spec.pdf diff --git a/Software/Visual_Studio/Tango.Pulse/TwnFile.cs b/Software/Visual_Studio/Tango.Pulse/TwnFile.cs new file mode 100644 index 000000000..75653c03e --- /dev/null +++ b/Software/Visual_Studio/Tango.Pulse/TwnFile.cs @@ -0,0 +1,118 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Pulse +{ + /// <summary> + /// Represents a Pulse, twn embroidery file. + /// </summary> + public class TwnFile + { + /// <summary> + /// Format Version (Default is 1.0). + /// </summary> + public float Version { get; set; } + + /// <summary> + /// The name of the design or other labeling information as UTF-8 text. + /// </summary> + public String Name { get; set; } + + /// <summary> + /// Number of copies. (The number 0 will be treated as 1, so the default is 0) + /// </summary> + public int NumberOfCopies { get; set; } + + /// <summary> + /// 0 - Spool per segment. (default) + /// 1 - Spool per copy. + /// 2 - Single spool for all segments. + /// </summary> + public SpoolingMethods SpoolingMethod { get; set; } + + /// <summary> + /// A unique code representing an optional media ID from Twine’s recommended media list + /// </summary> + public int MediaID { get; set; } + + /// <summary> + /// 3 ASCII characters representing the embedded embroidery file extension (e.g dst, pes). + /// </summary> + public String EmbroideryFileFormat { get; set; } + + /// <summary> + /// preview image in + /// PNG format(transparent background). The size of the PNG byte array must be defined in the header. + /// Recommended image width is 1280 pixels while maintaining aspect ratio. + /// </summary> + public Bitmap Thumbnail { get; set; } + + /// <summary> + /// Array of Brush Segment. The number of brush segments must be defined in the header. + /// </summary> + public List<TwnSegment> Segments { get; set; } + + /// <summary> + /// Byte array representing the standard embroidery file which can be extracted and inserted into an embroidery machine. + /// </summary> + public byte[] EmbroideryFile { get; set; } + + /// <summary> + /// Initializes a new instance of the <see cref="TwnFile"/> class. + /// </summary> + public TwnFile() + { + Version = 1.0f; + Segments = new List<TwnSegment>(); + } + + /// <summary> + /// Writes the <see cref="TwnFile"/> to the specified output stream. + /// </summary> + /// <param name="output">The output stream.</param> + public void ToStream(Stream output) + { + new TwnFileWriter().Write(this, output); + } + + /// <summary> + /// Writes the <see cref="TwnFile"/> to the specified file path. + /// </summary> + /// <param name="filePath">The file path.</param> + public void ToFile(String filePath) + { + using (FileStream fs = new FileStream(filePath, FileMode.Create)) + { + ToStream(fs); + } + } + + /// <summary> + /// Loads a <see cref="TwnFile"/> from the specified stream. + /// </summary> + /// <param name="twnStream">The TWN stream.</param> + /// <returns></returns> + public static TwnFile FromStream(Stream twnStream) + { + return new TwnFileReader().Read(twnStream); + } + + /// <summary> + /// Loads a <see cref="TwnFile"/> from the specified file path. + /// </summary> + /// <param name="twnFilePath">The TWN file path.</param> + /// <returns></returns> + public static TwnFile FromFile(String twnFilePath) + { + using (FileStream fs = new FileStream(twnFilePath, FileMode.Open)) + { + return FromStream(fs); + } + } + } +} diff --git a/Software/Visual_Studio/Tango.Pulse/TwnFileReader.cs b/Software/Visual_Studio/Tango.Pulse/TwnFileReader.cs new file mode 100644 index 000000000..2efa94936 --- /dev/null +++ b/Software/Visual_Studio/Tango.Pulse/TwnFileReader.cs @@ -0,0 +1,109 @@ +using System; +using System.Drawing; +using System.IO; +using System.Text; + +namespace Tango.Pulse +{ + /// <summary> + /// Represents a Pulse, twn file reader. + /// </summary> + public class TwnFileReader + { + /// <summary> + /// Reads the specified TWN stream. + /// </summary> + /// <param name="twnStream">The TWN stream.</param> + /// <returns></returns> + public TwnFile Read(Stream twnStream) + { + TwnFile twnFile = new TwnFile(); + + BinaryReader reader = new BinaryReader(twnStream); + + //Format Version (Default is 1.0). + twnFile.Version = reader.ReadSingle(); + + + //The name of the design or other labeling information as UTF - 8 text padded with white spaces and limited to 50 bytes. + twnFile.Name = Encoding.UTF8.GetString(reader.ReadBytes(50)).Trim(); + + + //The embedded preview image size in byte length as a 32 bit unsigned integer. + UInt32 thumbnail_size = reader.ReadUInt32(); + + + //The total number of brush segments as a 32 bit unsigned integer. + UInt32 segments_count = reader.ReadUInt32(); + + + //Number of copies. (The number 0 will be treated as 1, so the default is 0) + twnFile.NumberOfCopies = (int)reader.ReadUInt32(); + + + //0 - Spool per segment. (default) + //1 - Spool per copy. + //2 - Single spool for all segments. + twnFile.SpoolingMethod = (SpoolingMethods)(int)reader.ReadByte(); + + + //A unique code representing an optional media ID from Twine’s recommended media list. + twnFile.MediaID = (int)reader.ReadUInt32(); + + + //3 ASCII characters representing the embedded embroidery file extension (e.g dst, pes). + twnFile.EmbroideryFileFormat = Encoding.ASCII.GetString(reader.ReadBytes(3)); + + + //The byte array length of the embedded embroidery file. + UInt32 emb_file_size = reader.ReadUInt32(); + + + //Array of bytes representing the design preview image in PNG format(transparent background). + //The size of the PNG byte array must be defined in the header. Recommended image width is 1280 + //pixels while maintaining aspect ratio. + MemoryStream ms = new MemoryStream(reader.ReadBytes((int)thumbnail_size)); + twnFile.Thumbnail = new Bitmap(ms); + + + //Array of Brush Segment. The number of brush segments must be defined in the header. + for (int i = 0; i < segments_count; i++) + { + TwnSegment segment = new TwnSegment(); + + //Required thread length in centimeters. + segment.Length = reader.ReadSingle(); + + //Number of brush stops. + UInt32 stop_count = reader.ReadUInt32(); + + //Array of brush stops. + for (int j = 0; j < stop_count; j++) + { + TwnStop stop = new TwnStop(); + + //The RGB red component. + stop.R = reader.ReadByte(); + + //The RGB green component. + stop.G = reader.ReadByte(); + + //The RGB blue component. + stop.B = reader.ReadByte(); + + //The Brush stop offset position within the parent brush length in percentage (0-1). + stop.Offset = reader.ReadSingle(); + + segment.BrushStops.Add(stop); + } + + twnFile.Segments.Add(segment); + } + + //Byte array representing the standard embroidery file which can be extracted and inserted into an embroidery machine. + twnFile.EmbroideryFile = reader.ReadBytes((int)emb_file_size); + + return twnFile; + } + } +} diff --git a/Software/Visual_Studio/Tango.Pulse/TwnFileWriter.cs b/Software/Visual_Studio/Tango.Pulse/TwnFileWriter.cs new file mode 100644 index 000000000..1b173851a --- /dev/null +++ b/Software/Visual_Studio/Tango.Pulse/TwnFileWriter.cs @@ -0,0 +1,128 @@ +using System; +using System.Drawing.Imaging; +using System.IO; +using System.Text; + +namespace Tango.Pulse +{ + /// <summary> + /// Represents a Pulse, twn file writer. + /// </summary> + public class TwnFileWriter + { + /// <summary> + /// Writes the specified TWN file. + /// </summary> + /// <param name="twnFile">The TWN file.</param> + /// <param name="output">The output.</param> + /// <exception cref="System.ArgumentOutOfRangeException">Invalid design name length.</exception> + /// <exception cref="System.NullReferenceException"> + /// Thumbnail image is null. + /// or + /// Could not serialize a null embroidery file. + /// </exception> + /// <exception cref="System.ArgumentException">The embroidery format must contain exactly 3 characters.</exception> + public void Write(TwnFile twnFile, Stream output) + { + BinaryWriter writer = new BinaryWriter(output); + + //Format Version (Default is 1.0). + writer.Write(twnFile.Version); + + + //The name of the design or other labeling information as UTF - 8 text padded with white spaces and limited to 50 bytes. + byte[] nameBytes = Encoding.UTF8.GetBytes(twnFile.Name.PadRight(50, ' ')); + + if (nameBytes.Length < 50) + { + throw new ArgumentOutOfRangeException("Invalid design name length."); + } + writer.Write(nameBytes, 0, 50); + + + //The embedded preview image size in byte length as a 32 bit unsigned integer. + if (twnFile.Thumbnail == null) + { + throw new NullReferenceException("Thumbnail image is null."); + } + + byte[] thumbnailBytes = null; //For later use. + using (MemoryStream ms = new MemoryStream()) + { + twnFile.Thumbnail.Save(ms, ImageFormat.Png); + writer.Write((UInt32)ms.Length); + thumbnailBytes = ms.ToArray(); + } + + //The total number of brush segments as a 32 bit unsigned integer. + writer.Write((UInt32)twnFile.Segments.Count); + + + //Number of copies. (The number 0 will be treated as 1, so the default is 0) + writer.Write((UInt32)twnFile.NumberOfCopies); + + + //0 - Spool per segment. (default) + //1 - Spool per copy. + //2 - Single spool for all segments. + writer.Write((byte)twnFile.SpoolingMethod); + + + //A unique code representing an optional media ID from Twine’s recommended media list. + writer.Write((UInt32)twnFile.MediaID); + + + //3 ASCII characters representing the embedded embroidery file extension (e.g dst, pes). + if (twnFile.EmbroideryFileFormat.Length != 3) + { + throw new ArgumentException("The embroidery format must contain exactly 3 characters."); + } + writer.Write(Encoding.ASCII.GetBytes(twnFile.EmbroideryFileFormat)); + + + //The byte array length of the embedded embroidery file. + if (twnFile.EmbroideryFile == null) + { + throw new NullReferenceException("Could not serialize a null embroidery file."); + } + writer.Write((UInt32)twnFile.EmbroideryFile.Length); + + + //Array of bytes representing the design preview image in PNG format(transparent background). + //The size of the PNG byte array must be defined in the header. Recommended image width is 1280 + //pixels while maintaining aspect ratio. + writer.Write(thumbnailBytes); + + + //Array of Brush Segment. The number of brush segments must be defined in the header. + foreach (var segment in twnFile.Segments) + { + //Required thread length in centimeters. + writer.Write(segment.Length); + + //Number of brush stops. + writer.Write((UInt32)segment.BrushStops.Count); + + //Array of brush stops. + foreach (var stop in segment.BrushStops) + { + //The RGB red component. + writer.Write(stop.R); + + //The RGB green component. + writer.Write(stop.G); + + //The RGB blue component. + writer.Write(stop.B); + + //The Brush stop offset position within the parent brush length in percentage (0-1). + writer.Write(stop.Offset); + } + } + + + //Byte array representing the standard embroidery file which can be extracted and inserted into an embroidery machine. + writer.Write(twnFile.EmbroideryFile); + } + } +} diff --git a/Software/Visual_Studio/Tango.Pulse/TwnSegment.cs b/Software/Visual_Studio/Tango.Pulse/TwnSegment.cs new file mode 100644 index 000000000..07d4368d5 --- /dev/null +++ b/Software/Visual_Studio/Tango.Pulse/TwnSegment.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; + +namespace Tango.Pulse +{ + /// <summary> + /// Represents a twn file brush segment. + /// </summary> + /// <remarks> + /// The “Brush Segment” structure supports + /// both solid and gradient segments. + /// Solid segments are defined using a “Brush + /// Segment” with a single “Brush Stop” with + /// zero offset. + /// </remarks> + public class TwnSegment + { + /// <summary> + /// Required thread length in centimeters. + /// </summary> + public float Length { get; set; } + + /// <summary> + /// Array of brush stops. + /// </summary> + public List<TwnStop> BrushStops { get; set; } + + /// <summary> + /// Initializes a new instance of the <see cref="TwnSegment"/> class. + /// </summary> + public TwnSegment() + { + BrushStops = new List<TwnStop>(); + } + } +} diff --git a/Software/Visual_Studio/Tango.Pulse/TwnStop.cs b/Software/Visual_Studio/Tango.Pulse/TwnStop.cs new file mode 100644 index 000000000..af50531cc --- /dev/null +++ b/Software/Visual_Studio/Tango.Pulse/TwnStop.cs @@ -0,0 +1,67 @@ +using System.Drawing; + +namespace Tango.Pulse +{ + /// <summary> + /// Represents a twn file brush stop. + /// </summary> + public class TwnStop + { + /// <summary> + /// The RGB red component. + /// </summary> + public byte R { get; set; } + + /// <summary> + /// The RGB green component. + /// </summary> + public byte G { get; set; } + + /// <summary> + /// The RGB blue component. + /// </summary> + public byte B { get; set; } + + /// <summary> + /// The Brush stop offset position within the parent brush length in percentage (0-1). + /// </summary> + public float Offset { get; set; } + + /// <summary> + /// Gets or sets the stop color. + /// </summary> + public Color Color + { + get { return Color.FromArgb(R, G, B); } + set + { + R = value.R; + G = value.G; + B = value.B; + } + } + + /// <summary> + /// Initializes a new instance of the <see cref="TwnStop"/> class. + /// </summary> + public TwnStop() + { + + } + + /// <summary> + /// Initializes a new instance of the <see cref="TwnStop"/> class. + /// </summary> + /// <param name="r">Red.</param> + /// <param name="g">Green.</param> + /// <param name="b">Blue.</param> + /// <param name="offset">Offset.</param> + public TwnStop(byte r, byte g, byte b, float offset) : this() + { + R = r; + G = g; + B = b; + Offset = offset; + } + } +} |
