diff --git a/Build/N20/FontAtlas/FontAtlas.csproj b/Build/N20/FontAtlas/FontAtlas.csproj deleted file mode 100644 index 9ec8f2d6..00000000 --- a/Build/N20/FontAtlas/FontAtlas.csproj +++ /dev/null @@ -1,59 +0,0 @@ - - - - - Debug - AnyCPU - {B2667A10-2969-493F-8E7B-23F21CBFB886} - Library - Properties - FontAtlas - FontAtlas - v2.0 - 512 - - - true - full - false - bin\Debug\ - TRACE;DEBUG;NET20 - prompt - 4 - true - - - pdbonly - true - bin\Release\ - TRACE;NET20 - prompt - 4 - true - - - - - - - - - - {fb5f78f5-c921-405d-8f21-42f7c15c2ad9} - PixelFarm.MiniAgg.One - - - {c6807d05-09be-4313-9f8b-bd2d51c55819} - Typography.GlyphLayout - - - {f7d71e61-9342-4dd7-9afd-69045f2ec98b} - Typography.OpenFont - - - {bc10cc51-a795-40d0-96f0-f87585d59d02} - Typography.TextBreak - - - - \ No newline at end of file diff --git a/Build/N20/FontAtlas/Properties/AssemblyInfo.cs b/Build/N20/FontAtlas/Properties/AssemblyInfo.cs deleted file mode 100644 index 73f45f1e..00000000 --- a/Build/N20/FontAtlas/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("FontAtlas")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("FontAtlas")] -[assembly: AssemblyCopyright("Copyright © 2018")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("b2667a10-2969-493f-8e7b-23f21cbfb886")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Build/N20/Typography.Contours/Properties/AssemblyInfo.cs b/Build/N20/Typography.Contours/Properties/AssemblyInfo.cs deleted file mode 100644 index 82860c2d..00000000 --- a/Build/N20/Typography.Contours/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Typography.Contours")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Typography.Contours")] -[assembly: AssemblyCopyright("Copyright © 2018")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("b999f927-08c5-4328-b07e-69acc1392da4")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Build/N20/Typography.Contours/Typography.Contours.csproj b/Build/N20/Typography.Contours/Typography.Contours.csproj deleted file mode 100644 index 94363907..00000000 --- a/Build/N20/Typography.Contours/Typography.Contours.csproj +++ /dev/null @@ -1,56 +0,0 @@ - - - - - Debug - AnyCPU - {B999F927-08C5-4328-B07E-69ACC1392DA4} - Library - Properties - Typography.Contours - Typography.Contours - v2.0 - 512 - - - true - full - false - bin\Debug\ - TRACE;DEBUG;NET20 - prompt - 4 - true - - - pdbonly - true - bin\Release\ - TRACE;NET20 - prompt - 4 - true - - - - - - - - - - {c5e5802d-6a45-4fe9-bae7-5f0ae91d72c1} - BackEnd.Triangulation - - - {c6807d05-09be-4313-9f8b-bd2d51c55819} - Typography.GlyphLayout - - - {f7d71e61-9342-4dd7-9afd-69045f2ec98b} - Typography.OpenFont - - - - - \ No newline at end of file diff --git a/Build/N20/Typography.GlyphLayout/Properties/AssemblyInfo.cs b/Build/N20/Typography.GlyphLayout/Properties/AssemblyInfo.cs deleted file mode 100644 index 2326984f..00000000 --- a/Build/N20/Typography.GlyphLayout/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("PixelFarm.GlyphLayout")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -[assembly: AssemblyProduct("PixelFarm.GlyphLayout")] -[assembly: AssemblyCopyright("Copyright © Microsoft 2017")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("c6807d05-09be-4313-9f8b-bd2d51c55819")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Build/N20/Typography.GlyphLayout/Typography.GlyphLayout.csproj b/Build/N20/Typography.GlyphLayout/Typography.GlyphLayout.csproj deleted file mode 100644 index f3d083e6..00000000 --- a/Build/N20/Typography.GlyphLayout/Typography.GlyphLayout.csproj +++ /dev/null @@ -1,50 +0,0 @@ - - - - - Debug - AnyCPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819} - Library - Typography.GlyphLayout - Typography.GlyphLayout - v2.0 - 512 - - - AnyCPU - true - full - false - bin\Debug\ - TRACE;DEBUG;NET20 - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE;NET20 - prompt - 4 - - - - - - - - - - - - - {f7d71e61-9342-4dd7-9afd-69045f2ec98b} - Typography.OpenFont - - - - - \ No newline at end of file diff --git a/Build/N20/Typography.MsdfGen/Properties/AssemblyInfo.cs b/Build/N20/Typography.MsdfGen/Properties/AssemblyInfo.cs deleted file mode 100644 index 2a7225ba..00000000 --- a/Build/N20/Typography.MsdfGen/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Typography.MsdfGen")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Typography.MsdfGen")] -[assembly: AssemblyCopyright("Copyright © 2018")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("9a3b8b84-56be-4aa1-8d90-1b3b3fef1f71")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Build/N20/Typography.MsdfGen/Typography.MsdfGen.csproj b/Build/N20/Typography.MsdfGen/Typography.MsdfGen.csproj deleted file mode 100644 index a2868d01..00000000 --- a/Build/N20/Typography.MsdfGen/Typography.MsdfGen.csproj +++ /dev/null @@ -1,57 +0,0 @@ - - - - - Debug - AnyCPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71} - Library - Properties - Typography.MsdfGen - Typography.MsdfGen - v2.0 - 512 - - - true - full - false - bin\Debug\ - TRACE;DEBUG;NET20 - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE;NET20 - prompt - 4 - - - - BasicElements.cs - - - EdgeColor.cs - - - EdgeColoring.cs - - - EdgeSegment.cs - - - EquationSolver.cs - - - MsdfGen.cs - - - SignedDistance.cs - - - - - \ No newline at end of file diff --git a/Build/N20/Typography.OpenFont/Properties/AssemblyInfo.cs b/Build/N20/Typography.OpenFont/Properties/AssemblyInfo.cs deleted file mode 100644 index 551fe386..00000000 --- a/Build/N20/Typography.OpenFont/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Typography.OpenFont")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -[assembly: AssemblyProduct("Typography.OpenFont")] -[assembly: AssemblyCopyright("Copyright © Microsoft 2017")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("f7d71e61-9342-4dd7-9afd-69045f2ec98b")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Build/N20/Typography.OpenFont/Typography.OpenFont.csproj b/Build/N20/Typography.OpenFont/Typography.OpenFont.csproj deleted file mode 100644 index 0e33626f..00000000 --- a/Build/N20/Typography.OpenFont/Typography.OpenFont.csproj +++ /dev/null @@ -1,44 +0,0 @@ - - - - - Debug - AnyCPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B} - Library - Properties - Typography.OpenFont - Typography.OpenFont - v2.0 - 512 - - - true - full - false - bin\Debug\ - TRACE;DEBUG;NET20 - prompt - 4 - true - - - pdbonly - true - bin\Release\ - TRACE;NET20 - prompt - 4 - true - - - - - - - - - - - - \ No newline at end of file diff --git a/Build/N20/Typography.TextBreak/ExtensionAttribute.cs b/Build/N20/Typography.TextBreak/ExtensionAttribute.cs deleted file mode 100644 index b460eeca..00000000 --- a/Build/N20/Typography.TextBreak/ExtensionAttribute.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace System.Runtime.CompilerServices -{ - public partial class ExtensionAttribute : Attribute { } -} \ No newline at end of file diff --git a/Build/N20/Typography.TextBreak/Properties/AssemblyInfo.cs b/Build/N20/Typography.TextBreak/Properties/AssemblyInfo.cs deleted file mode 100644 index 1a7f3f24..00000000 --- a/Build/N20/Typography.TextBreak/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Typography.TextBreak")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Typography.TextBreak")] -[assembly: AssemblyCopyright("Copyright © 2018")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("bc10cc51-a795-40d0-96f0-f87585d59d02")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Build/N20/Typography.TextBreak/Typography.TextBreak.csproj b/Build/N20/Typography.TextBreak/Typography.TextBreak.csproj deleted file mode 100644 index a07808cb..00000000 --- a/Build/N20/Typography.TextBreak/Typography.TextBreak.csproj +++ /dev/null @@ -1,41 +0,0 @@ - - - - - Debug - AnyCPU - {BC10CC51-A795-40D0-96F0-F87585D59D02} - Library - Properties - Typography.TextBreak - Typography.TextBreak - v2.0 - 512 - - - true - full - false - bin\Debug\ - TRACE;DEBUG;NET20 - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE;NET20 - prompt - 4 - - - - - - - - - - - \ No newline at end of file diff --git a/Build/N20/Typography.TextFlow/Properties/AssemblyInfo.cs b/Build/N20/Typography.TextFlow/Properties/AssemblyInfo.cs deleted file mode 100644 index b33a54de..00000000 --- a/Build/N20/Typography.TextFlow/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Typography.TextFlow")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Typography.TextFlow")] -[assembly: AssemblyCopyright("Copyright © 2018")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("333f3209-8da9-4d33-a560-299ed4c6dfa5")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Build/N20/Typography.TextFlow/Typography.TextFlow.csproj b/Build/N20/Typography.TextFlow/Typography.TextFlow.csproj deleted file mode 100644 index e1a3326c..00000000 --- a/Build/N20/Typography.TextFlow/Typography.TextFlow.csproj +++ /dev/null @@ -1,50 +0,0 @@ - - - - - Debug - AnyCPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5} - Library - Properties - Typography.TextFlow - Typography.TextFlow - v2.0 - 512 - - - true - full - false - bin\Debug\ - TRACE;DEBUG;NET20 - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE;NET20 - prompt - 4 - - - - - - - - - - {c6807d05-09be-4313-9f8b-bd2d51c55819} - Typography.GlyphLayout - - - {f7d71e61-9342-4dd7-9afd-69045f2ec98b} - Typography.OpenFont - - - - - \ No newline at end of file diff --git a/Build/N20/Typography.TextServices/Properties/AssemblyInfo.cs b/Build/N20/Typography.TextServices/Properties/AssemblyInfo.cs deleted file mode 100644 index 1be60487..00000000 --- a/Build/N20/Typography.TextServices/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Typography.TextServices")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Typography.TextServices")] -[assembly: AssemblyCopyright("Copyright © 2018")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("6b0e034b-0ebd-4907-ad7f-437de66d78d4")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Build/N20/Typography.TextServices/Typography.TextServices.csproj b/Build/N20/Typography.TextServices/Typography.TextServices.csproj deleted file mode 100644 index e5c23520..00000000 --- a/Build/N20/Typography.TextServices/Typography.TextServices.csproj +++ /dev/null @@ -1,52 +0,0 @@ - - - - - Debug - AnyCPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4} - Library - Properties - Typography.TextServices - Typography.TextServices - v2.0 - 512 - - - true - full - false - bin\Debug\ - TRACE;DEBUG;NET20 - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE;NET20 - prompt - 4 - - - - - - - - - - {c6807d05-09be-4313-9f8b-bd2d51c55819} - Typography.GlyphLayout - - - {f7d71e61-9342-4dd7-9afd-69045f2ec98b} - Typography.OpenFont - - - - - - - \ No newline at end of file diff --git a/Build/N20/Unpack/Unpack.csproj b/Build/N20/Unpack/Unpack.csproj deleted file mode 100644 index 4cf0da83..00000000 --- a/Build/N20/Unpack/Unpack.csproj +++ /dev/null @@ -1,43 +0,0 @@ - - - - - Debug - AnyCPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D} - Library - Properties - Unpack - Unpack - v2.0 - 512 - true - - - true - full - false - bin\Debug\ - TRACE;DEBUG;NET20 - prompt - 4 - true - - - pdbonly - true - bin\Release\ - TRACE;NET20 - prompt - 4 - true - - - - - - - - - - \ No newline at end of file diff --git a/Build/N20/Typography.OpenFont/ExtensionAttribute.cs b/Build/NET20/ExtensionAttribute.cs similarity index 100% rename from Build/N20/Typography.OpenFont/ExtensionAttribute.cs rename to Build/NET20/ExtensionAttribute.cs diff --git a/PixelFarm/PixelFarm.Painter/0_Base/ForNet20.cs b/Build/NET20/ForNet20.cs similarity index 96% rename from PixelFarm/PixelFarm.Painter/0_Base/ForNet20.cs rename to Build/NET20/ForNet20.cs index d7cea46b..6a72ef72 100644 --- a/PixelFarm/PixelFarm.Painter/0_Base/ForNet20.cs +++ b/Build/NET20/ForNet20.cs @@ -1,12 +1,10 @@ - -//for .NET 2.0 +//for .NET 2.0 namespace System { //public delegate R Func(); //public delegate R Func(T t1); //public delegate R Func(T1 t1, T2 t2); //public delegate R Func(T1 t1, T2 t2, T3 t3); -#if !NETSTANDARD public delegate void Action(T1 arg1, T2 arg2); public delegate void Action(T1 arg1, T2 arg2, T3 arg3); public delegate void Action(T1 arg1, T2 arg2, T3 arg3, T4 arg4); @@ -24,7 +22,6 @@ namespace System public delegate TResult Func(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6); public delegate TResult Func(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7); public delegate TResult Func(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8); -#endif } namespace System.Runtime.InteropServices @@ -43,7 +40,7 @@ public partial class ExtensionAttribute : Attribute { } namespace System.Collections.Generic { - public class HashSet : IEnumerable, ICollection + public class HashSet : IEnumerable, ICollection where T : notnull { //for .NET 2.0 Dictionary _dic = new Dictionary(); @@ -173,9 +170,9 @@ public static System.Collections.Generic.Dictionary ToDictionary } public static bool Contains(this T[] arr, T elem) { - for (int i = 0; i < arr.Length; ++i) + foreach (T v in arr) { - if (arr[i].Equals(elem)) + if (v == null && elem == null || v != null && v.Equals(elem)) { return true; } @@ -183,11 +180,11 @@ public static bool Contains(this T[] arr, T elem) return false; } - public static bool Contains(this IEnumerable list, T value) + public static bool Contains(this IEnumerable list, T elem) { - foreach (T elem in list) + foreach (T v in list) { - if (elem.Equals(value)) + if (v == null && elem == null || v != null && v.Equals(elem)) { return true; } @@ -284,6 +281,7 @@ public static int Max(this IEnumerable list, Func evalFunc) } return max; } + [return: System.Diagnostics.CodeAnalysis.MaybeNull] public static T ElementAt(this IEnumerable list, int index) { if (list is T[] arr) @@ -406,6 +404,7 @@ public static bool Any(this IEnumerable list, Func predicate) } return false; } + [return: System.Diagnostics.CodeAnalysis.MaybeNull] public static T FirstOrDefault(this IEnumerable list, Func predicate) { foreach (T t in list) @@ -417,6 +416,7 @@ public static T FirstOrDefault(this IEnumerable list, Func predic } return default(T); } + [return: System.Diagnostics.CodeAnalysis.MaybeNull] public static T First(this T[] arr, Func predicate) { for (int i = 0; i < arr.Length; ++i) @@ -432,6 +432,7 @@ public static T Last(this T[] arr) { return arr[arr.Length - 1]; } + [return: System.Diagnostics.CodeAnalysis.MaybeNull] public static T First(this IEnumerable list, Func predicate) { foreach (T t in list) @@ -443,6 +444,7 @@ public static T First(this IEnumerable list, Func predicate) } return default(T); } + [return: System.Diagnostics.CodeAnalysis.MaybeNull] public static T First(this IEnumerable list) { @@ -491,6 +493,7 @@ public static T First(this IEnumerable list) } } + [return: System.Diagnostics.CodeAnalysis.MaybeNull] public static T Last(this IEnumerable list) { if (list is T[] arr) @@ -537,6 +540,7 @@ public static T Last(this IEnumerable list) return lastOne; } } + [return: System.Diagnostics.CodeAnalysis.MaybeNull] public static T LastOrDefault(this IEnumerable list) { if (list is T[] arr) @@ -691,6 +695,7 @@ public static T[] ToArray(IEnumerable list) { return list.ToArray(); } + [return: System.Diagnostics.CodeAnalysis.MaybeNull] public static T ElementAt(IEnumerable list, int index) { return list.ElementAt(index); @@ -719,5 +724,4 @@ public static IEnumerable Where(IEnumerable list, Func validat } -} - +} \ No newline at end of file diff --git a/Build/NET20/HashCode.cs b/Build/NET20/HashCode.cs new file mode 100644 index 00000000..76a8b0f2 --- /dev/null +++ b/Build/NET20/HashCode.cs @@ -0,0 +1,462 @@ +// https://github.com/dotnet/runtime/blob/master/src/libraries/System.Private.CoreLib/src/System/HashCode.cs + +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/* + +The xxHash32 implementation is based on the code published by Yann Collet: +https://raw.githubusercontent.com/Cyan4973/xxHash/5c174cfa4e45a42f94082dc0d4539b39696afea1/xxhash.c + + xxHash - Fast Hash algorithm + Copyright (C) 2012-2016, Yann Collet + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - xxHash homepage: http://www.xxhash.com + - xxHash source repository : https://github.com/Cyan4973/xxHash + +*/ + +using System.Collections.Generic; +using System.ComponentModel; +using System.Numerics; +using System.Runtime.CompilerServices; + +namespace System +{ + // xxHash32 is used for the hash code. + // https://github.com/Cyan4973/xxHash + + public struct HashCode + { + private static readonly uint s_seed = GenerateGlobalSeed(); + + private const uint Prime1 = 2654435761U; + private const uint Prime2 = 2246822519U; + private const uint Prime3 = 3266489917U; + private const uint Prime4 = 668265263U; + private const uint Prime5 = 374761393U; + + private uint _v1, _v2, _v3, _v4; + private uint _queue1, _queue2, _queue3; + private uint _length; + + private static uint GenerateGlobalSeed() + { + return (uint)new Random().Next(); + } + + public static int Combine(T1 value1) + { + // Provide a way of diffusing bits from something with a limited + // input hash space. For example, many enums only have a few + // possible hashes, only using the bottom few bits of the code. Some + // collections are built on the assumption that hashes are spread + // over a larger space, so diffusing the bits may help the + // collection work more efficiently. + + uint hc1 = (uint)(value1?.GetHashCode() ?? 0); + + uint hash = MixEmptyState(); + hash += 4; + + hash = QueueRound(hash, hc1); + + hash = MixFinal(hash); + return (int)hash; + } + + public static int Combine(T1 value1, T2 value2) + { + uint hc1 = (uint)(value1?.GetHashCode() ?? 0); + uint hc2 = (uint)(value2?.GetHashCode() ?? 0); + + uint hash = MixEmptyState(); + hash += 8; + + hash = QueueRound(hash, hc1); + hash = QueueRound(hash, hc2); + + hash = MixFinal(hash); + return (int)hash; + } + + public static int Combine(T1 value1, T2 value2, T3 value3) + { + uint hc1 = (uint)(value1?.GetHashCode() ?? 0); + uint hc2 = (uint)(value2?.GetHashCode() ?? 0); + uint hc3 = (uint)(value3?.GetHashCode() ?? 0); + + uint hash = MixEmptyState(); + hash += 12; + + hash = QueueRound(hash, hc1); + hash = QueueRound(hash, hc2); + hash = QueueRound(hash, hc3); + + hash = MixFinal(hash); + return (int)hash; + } + + public static int Combine(T1 value1, T2 value2, T3 value3, T4 value4) + { + uint hc1 = (uint)(value1?.GetHashCode() ?? 0); + uint hc2 = (uint)(value2?.GetHashCode() ?? 0); + uint hc3 = (uint)(value3?.GetHashCode() ?? 0); + uint hc4 = (uint)(value4?.GetHashCode() ?? 0); + + Initialize(out uint v1, out uint v2, out uint v3, out uint v4); + + v1 = Round(v1, hc1); + v2 = Round(v2, hc2); + v3 = Round(v3, hc3); + v4 = Round(v4, hc4); + + uint hash = MixState(v1, v2, v3, v4); + hash += 16; + + hash = MixFinal(hash); + return (int)hash; + } + + public static int Combine(T1 value1, T2 value2, T3 value3, T4 value4, T5 value5) + { + uint hc1 = (uint)(value1?.GetHashCode() ?? 0); + uint hc2 = (uint)(value2?.GetHashCode() ?? 0); + uint hc3 = (uint)(value3?.GetHashCode() ?? 0); + uint hc4 = (uint)(value4?.GetHashCode() ?? 0); + uint hc5 = (uint)(value5?.GetHashCode() ?? 0); + + Initialize(out uint v1, out uint v2, out uint v3, out uint v4); + + v1 = Round(v1, hc1); + v2 = Round(v2, hc2); + v3 = Round(v3, hc3); + v4 = Round(v4, hc4); + + uint hash = MixState(v1, v2, v3, v4); + hash += 20; + + hash = QueueRound(hash, hc5); + + hash = MixFinal(hash); + return (int)hash; + } + + public static int Combine(T1 value1, T2 value2, T3 value3, T4 value4, T5 value5, T6 value6) + { + uint hc1 = (uint)(value1?.GetHashCode() ?? 0); + uint hc2 = (uint)(value2?.GetHashCode() ?? 0); + uint hc3 = (uint)(value3?.GetHashCode() ?? 0); + uint hc4 = (uint)(value4?.GetHashCode() ?? 0); + uint hc5 = (uint)(value5?.GetHashCode() ?? 0); + uint hc6 = (uint)(value6?.GetHashCode() ?? 0); + + Initialize(out uint v1, out uint v2, out uint v3, out uint v4); + + v1 = Round(v1, hc1); + v2 = Round(v2, hc2); + v3 = Round(v3, hc3); + v4 = Round(v4, hc4); + + uint hash = MixState(v1, v2, v3, v4); + hash += 24; + + hash = QueueRound(hash, hc5); + hash = QueueRound(hash, hc6); + + hash = MixFinal(hash); + return (int)hash; + } + + public static int Combine(T1 value1, T2 value2, T3 value3, T4 value4, T5 value5, T6 value6, T7 value7) + { + uint hc1 = (uint)(value1?.GetHashCode() ?? 0); + uint hc2 = (uint)(value2?.GetHashCode() ?? 0); + uint hc3 = (uint)(value3?.GetHashCode() ?? 0); + uint hc4 = (uint)(value4?.GetHashCode() ?? 0); + uint hc5 = (uint)(value5?.GetHashCode() ?? 0); + uint hc6 = (uint)(value6?.GetHashCode() ?? 0); + uint hc7 = (uint)(value7?.GetHashCode() ?? 0); + + Initialize(out uint v1, out uint v2, out uint v3, out uint v4); + + v1 = Round(v1, hc1); + v2 = Round(v2, hc2); + v3 = Round(v3, hc3); + v4 = Round(v4, hc4); + + uint hash = MixState(v1, v2, v3, v4); + hash += 28; + + hash = QueueRound(hash, hc5); + hash = QueueRound(hash, hc6); + hash = QueueRound(hash, hc7); + + hash = MixFinal(hash); + return (int)hash; + } + + public static int Combine(T1 value1, T2 value2, T3 value3, T4 value4, T5 value5, T6 value6, T7 value7, T8 value8) + { + uint hc1 = (uint)(value1?.GetHashCode() ?? 0); + uint hc2 = (uint)(value2?.GetHashCode() ?? 0); + uint hc3 = (uint)(value3?.GetHashCode() ?? 0); + uint hc4 = (uint)(value4?.GetHashCode() ?? 0); + uint hc5 = (uint)(value5?.GetHashCode() ?? 0); + uint hc6 = (uint)(value6?.GetHashCode() ?? 0); + uint hc7 = (uint)(value7?.GetHashCode() ?? 0); + uint hc8 = (uint)(value8?.GetHashCode() ?? 0); + + Initialize(out uint v1, out uint v2, out uint v3, out uint v4); + + v1 = Round(v1, hc1); + v2 = Round(v2, hc2); + v3 = Round(v3, hc3); + v4 = Round(v4, hc4); + + v1 = Round(v1, hc5); + v2 = Round(v2, hc6); + v3 = Round(v3, hc7); + v4 = Round(v4, hc8); + + uint hash = MixState(v1, v2, v3, v4); + hash += 32; + + hash = MixFinal(hash); + return (int)hash; + } + + private static void Initialize(out uint v1, out uint v2, out uint v3, out uint v4) + { + v1 = s_seed + Prime1 + Prime2; + v2 = s_seed + Prime2; + v3 = s_seed; + v4 = s_seed - Prime1; + } + + private static uint Round(uint hash, uint input) + { + return RotateLeft(hash + input * Prime2, 13) * Prime1; + } + + private static uint QueueRound(uint hash, uint queuedValue) + { + return RotateLeft(hash + queuedValue * Prime3, 17) * Prime4; + } + + private static uint MixState(uint v1, uint v2, uint v3, uint v4) + { + return RotateLeft(v1, 1) + RotateLeft(v2, 7) + RotateLeft(v3, 12) + RotateLeft(v4, 18); + } + + private static uint MixEmptyState() + { + return s_seed + Prime5; + } + + private static uint MixFinal(uint hash) + { + hash ^= hash >> 15; + hash *= Prime2; + hash ^= hash >> 13; + hash *= Prime3; + hash ^= hash >> 16; + return hash; + } + + public void Add(T value) + { + Add(value?.GetHashCode() ?? 0); + } + + public void Add(T value, IEqualityComparer? comparer) + { + Add(value is null ? 0 : (comparer?.GetHashCode(value) ?? value.GetHashCode())); + } + + private void Add(int value) + { + // The original xxHash works as follows: + // 0. Initialize immediately. We can't do this in a struct (no + // default ctor). + // 1. Accumulate blocks of length 16 (4 uints) into 4 accumulators. + // 2. Accumulate remaining blocks of length 4 (1 uint) into the + // hash. + // 3. Accumulate remaining blocks of length 1 into the hash. + + // There is no need for #3 as this type only accepts ints. _queue1, + // _queue2 and _queue3 are basically a buffer so that when + // ToHashCode is called we can execute #2 correctly. + + // We need to initialize the xxHash32 state (_v1 to _v4) lazily (see + // #0) nd the last place that can be done if you look at the + // original code is just before the first block of 16 bytes is mixed + // in. The xxHash32 state is never used for streams containing fewer + // than 16 bytes. + + // To see what's really going on here, have a look at the Combine + // methods. + + uint val = (uint)value; + + // Storing the value of _length locally shaves of quite a few bytes + // in the resulting machine code. + uint previousLength = _length++; + uint position = previousLength % 4; + + // Switch can't be inlined. + + if (position == 0) + _queue1 = val; + else if (position == 1) + _queue2 = val; + else if (position == 2) + _queue3 = val; + else // position == 3 + { + if (previousLength == 3) + Initialize(out _v1, out _v2, out _v3, out _v4); + + _v1 = Round(_v1, _queue1); + _v2 = Round(_v2, _queue2); + _v3 = Round(_v3, _queue3); + _v4 = Round(_v4, val); + } + } + + public int ToHashCode() + { + // Storing the value of _length locally shaves of quite a few bytes + // in the resulting machine code. + uint length = _length; + + // position refers to the *next* queue position in this method, so + // position == 1 means that _queue1 is populated; _queue2 would have + // been populated on the next call to Add. + uint position = length % 4; + + // If the length is less than 4, _v1 to _v4 don't contain anything + // yet. xxHash32 treats this differently. + + uint hash = length < 4 ? MixEmptyState() : MixState(_v1, _v2, _v3, _v4); + + // _length is incremented once per Add(Int32) and is therefore 4 + // times too small (xxHash length is in bytes, not ints). + + hash += length * 4; + + // Mix what remains in the queue + + // Switch can't be inlined right now, so use as few branches as + // possible by manually excluding impossible scenarios (position > 1 + // is always false if position is not > 0). + if (position > 0) + { + hash = QueueRound(hash, _queue1); + if (position > 1) + { + hash = QueueRound(hash, _queue2); + if (position > 2) + hash = QueueRound(hash, _queue3); + } + } + + hash = MixFinal(hash); + return (int)hash; + } + +#pragma warning disable 0809 + // Obsolete member 'memberA' overrides non-obsolete member 'memberB'. + // Disallowing GetHashCode and Equals is by design + + // * We decided to not override GetHashCode() to produce the hash code + // as this would be weird, both naming-wise as well as from a + // behavioral standpoint (GetHashCode() should return the object's + // hash code, not the one being computed). + + // * Even though ToHashCode() can be called safely multiple times on + // this implementation, it is not part of the contract. If the + // implementation has to change in the future we don't want to worry + // about people who might have incorrectly used this type. + + [Obsolete("HashCode is a mutable struct and should not be compared with other HashCodes. Use ToHashCode to retrieve the computed hash code.", error: true)] + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() => throw new NotSupportedException("HashCode is a mutable struct and should not be compared with other HashCodes. Use ToHashCode to retrieve the computed hash code."); + + [Obsolete("HashCode is a mutable struct and should not be compared with other HashCodes.", error: true)] + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object? obj) => throw new NotSupportedException("HashCode is a mutable struct and should not be compared with other HashCodes."); +#pragma warning restore 0809 + + /// + /// Rotates the specified value left by the specified number of bits. + /// Similar in behavior to the x86 instruction ROL. + /// + /// The value to rotate. + /// The number of bits to rotate by. + /// Any value outside the range [0..31] is treated as congruent mod 32. + /// The rotated value. + private static uint RotateLeft(uint value, int offset) + => (value << offset) | (value >> (32 - offset)); + + /// + /// Rotates the specified value left by the specified number of bits. + /// Similar in behavior to the x86 instruction ROL. + /// + /// The value to rotate. + /// The number of bits to rotate by. + /// Any value outside the range [0..63] is treated as congruent mod 64. + /// The rotated value. + private static ulong RotateLeft(ulong value, int offset) + => (value << offset) | (value >> (64 - offset)); + + /// + /// Rotates the specified value right by the specified number of bits. + /// Similar in behavior to the x86 instruction ROR. + /// + /// The value to rotate. + /// The number of bits to rotate by. + /// Any value outside the range [0..31] is treated as congruent mod 32. + /// The rotated value. + private static uint RotateRight(uint value, int offset) + => (value >> offset) | (value << (32 - offset)); + + /// + /// Rotates the specified value right by the specified number of bits. + /// Similar in behavior to the x86 instruction ROR. + /// + /// The value to rotate. + /// The number of bits to rotate by. + /// Any value outside the range [0..63] is treated as congruent mod 64. + /// The rotated value. + private static ulong RotateRight(ulong value, int offset) + => (value >> offset) | (value << (64 - offset)); + } +} \ No newline at end of file diff --git a/Build/N20/Typography.OpenFont/System.Numerics.ForNet20.cs b/Build/NET20/System.Numerics.ForNet20.cs similarity index 100% rename from Build/N20/Typography.OpenFont/System.Numerics.ForNet20.cs rename to Build/NET20/System.Numerics.ForNet20.cs diff --git a/Build/NET20/TupleElementNames.cs b/Build/NET20/TupleElementNames.cs new file mode 100644 index 00000000..541069b6 --- /dev/null +++ b/Build/NET20/TupleElementNames.cs @@ -0,0 +1,58 @@ +// https://github.com/dotnet/runtime/blob/master/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/TupleElementNamesAttribute.cs + +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; + +namespace System.Runtime.CompilerServices +{ + /// + /// Indicates that the use of on a member is meant to be treated as a tuple with element names. + /// + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Event)] + public sealed class TupleElementNamesAttribute : Attribute + { + private readonly string?[] _transformNames; + + /// + /// Initializes a new instance of the class. + /// + /// + /// Specifies, in a pre-order depth-first traversal of a type's + /// construction, which occurrences are + /// meant to carry element names. + /// + /// + /// This constructor is meant to be used on types that contain an + /// instantiation of that contains + /// element names. For instance, if C is a generic type with + /// two type parameters, then a use of the constructed type C{, might be intended to + /// treat the first type argument as a tuple with element names and the + /// second as a tuple without element names. In which case, the + /// appropriate attribute specification should use a + /// transformNames value of { "name1", "name2", null, null, + /// null }. + /// + public TupleElementNamesAttribute(string?[] transformNames) + { + if (transformNames == null) + { + throw new ArgumentNullException(nameof(transformNames)); + } + + _transformNames = transformNames; + } + + /// + /// Specifies, in a pre-order depth-first traversal of a type's + /// construction, which elements are + /// meant to carry element names. + /// + public IList TransformNames => _transformNames; + } +} \ No newline at end of file diff --git a/Build/NET20/ValueTuple.cs b/Build/NET20/ValueTuple.cs new file mode 100644 index 00000000..81601112 --- /dev/null +++ b/Build/NET20/ValueTuple.cs @@ -0,0 +1,1691 @@ +// https://github.com/dotnet/runtime/blob/master/src/libraries/System.Private.CoreLib/src/System/ValueTuple.cs + +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#pragma warning disable SA1141 // explicitly not using tuple syntax in tuple implementation + +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; + +namespace System +{ + /// + /// Helper so we can call some tuple methods recursively without knowing the underlying types. + /// + internal interface IValueTupleInternal + { + int Length { get; } + int GetHashCode(IEqualityComparer comparer); + string ToStringEnd(); + } + + /// + /// The ValueTuple types (from arity 0 to 8) comprise the runtime implementation that underlies tuples in C# and struct tuples in F#. + /// Aside from created via language syntax, they are most easily created via the ValueTuple.Create factory methods. + /// The System.ValueTuple types differ from the System.Tuple types in that: + /// - they are structs rather than classes, + /// - they are mutable rather than readonly, and + /// - their members (such as Item1, Item2, etc) are fields rather than properties. + /// + [Serializable] + public struct ValueTuple + : IEquatable, IComparable, IComparable, IValueTupleInternal + { + /// + /// Returns a value that indicates whether the current instance is equal to a specified object. + /// + /// The object to compare with this instance. + /// if is a . + public override bool Equals(object? obj) + { + return obj is ValueTuple; + } + + /// Returns a value indicating whether this instance is equal to a specified value. + /// An instance to compare to this instance. + /// true if has the same value as this instance; otherwise, false. + public bool Equals(ValueTuple other) + { + return true; + } + + int IComparable.CompareTo(object? other) + { + if (other == null) return 1; + + if (!(other is ValueTuple)) + { + throw new ArgumentException("Object to compare is not a ValueTuple", nameof(other)); + } + + return 0; + } + + /// Compares this instance to a specified instance and returns an indication of their relative values. + /// An instance to compare. + /// + /// A signed number indicating the relative values of this instance and . + /// Returns less than zero if this instance is less than , zero if this + /// instance is equal to , and greater than zero if this instance is greater + /// than . + /// + public int CompareTo(ValueTuple other) + { + return 0; + } + + /// Returns the hash code for this instance. + /// A 32-bit signed integer hash code. + public override int GetHashCode() + { + return 0; + } + + int IValueTupleInternal.Length => 0; + int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) + { + return 0; + } + + /// + /// Returns a string that represents the value of this instance. + /// + /// The string representation of this instance. + /// + /// The string returned by this method takes the form (). + /// + public override string ToString() + { + return "()"; + } + + string IValueTupleInternal.ToStringEnd() + { + return ")"; + } + + /// Creates a new struct 0-tuple. + /// A 0-tuple. + public static ValueTuple Create() => + default; + + /// Creates a new struct 1-tuple, or singleton. + /// The type of the first component of the tuple. + /// The value of the first component of the tuple. + /// A 1-tuple (singleton) whose value is (item1). + public static ValueTuple Create(T1 item1) => + new ValueTuple(item1); + + /// Creates a new struct 2-tuple, or pair. + /// The type of the first component of the tuple. + /// The type of the second component of the tuple. + /// The value of the first component of the tuple. + /// The value of the second component of the tuple. + /// A 2-tuple (pair) whose value is (item1, item2). + public static ValueTuple Create(T1 item1, T2 item2) => + new ValueTuple(item1, item2); + + /// Creates a new struct 3-tuple, or triple. + /// The type of the first component of the tuple. + /// The type of the second component of the tuple. + /// The type of the third component of the tuple. + /// The value of the first component of the tuple. + /// The value of the second component of the tuple. + /// The value of the third component of the tuple. + /// A 3-tuple (triple) whose value is (item1, item2, item3). + public static ValueTuple Create(T1 item1, T2 item2, T3 item3) => + new ValueTuple(item1, item2, item3); + + /// Creates a new struct 4-tuple, or quadruple. + /// The type of the first component of the tuple. + /// The type of the second component of the tuple. + /// The type of the third component of the tuple. + /// The type of the fourth component of the tuple. + /// The value of the first component of the tuple. + /// The value of the second component of the tuple. + /// The value of the third component of the tuple. + /// The value of the fourth component of the tuple. + /// A 4-tuple (quadruple) whose value is (item1, item2, item3, item4). + public static ValueTuple Create(T1 item1, T2 item2, T3 item3, T4 item4) => + new ValueTuple(item1, item2, item3, item4); + + /// Creates a new struct 5-tuple, or quintuple. + /// The type of the first component of the tuple. + /// The type of the second component of the tuple. + /// The type of the third component of the tuple. + /// The type of the fourth component of the tuple. + /// The type of the fifth component of the tuple. + /// The value of the first component of the tuple. + /// The value of the second component of the tuple. + /// The value of the third component of the tuple. + /// The value of the fourth component of the tuple. + /// The value of the fifth component of the tuple. + /// A 5-tuple (quintuple) whose value is (item1, item2, item3, item4, item5). + public static ValueTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) => + new ValueTuple(item1, item2, item3, item4, item5); + + /// Creates a new struct 6-tuple, or sextuple. + /// The type of the first component of the tuple. + /// The type of the second component of the tuple. + /// The type of the third component of the tuple. + /// The type of the fourth component of the tuple. + /// The type of the fifth component of the tuple. + /// The type of the sixth component of the tuple. + /// The value of the first component of the tuple. + /// The value of the second component of the tuple. + /// The value of the third component of the tuple. + /// The value of the fourth component of the tuple. + /// The value of the fifth component of the tuple. + /// The value of the sixth component of the tuple. + /// A 6-tuple (sextuple) whose value is (item1, item2, item3, item4, item5, item6). + public static ValueTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) => + new ValueTuple(item1, item2, item3, item4, item5, item6); + + /// Creates a new struct 7-tuple, or septuple. + /// The type of the first component of the tuple. + /// The type of the second component of the tuple. + /// The type of the third component of the tuple. + /// The type of the fourth component of the tuple. + /// The type of the fifth component of the tuple. + /// The type of the sixth component of the tuple. + /// The type of the seventh component of the tuple. + /// The value of the first component of the tuple. + /// The value of the second component of the tuple. + /// The value of the third component of the tuple. + /// The value of the fourth component of the tuple. + /// The value of the fifth component of the tuple. + /// The value of the sixth component of the tuple. + /// The value of the seventh component of the tuple. + /// A 7-tuple (septuple) whose value is (item1, item2, item3, item4, item5, item6, item7). + public static ValueTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) => + new ValueTuple(item1, item2, item3, item4, item5, item6, item7); + + /// Creates a new struct 8-tuple, or octuple. + /// The type of the first component of the tuple. + /// The type of the second component of the tuple. + /// The type of the third component of the tuple. + /// The type of the fourth component of the tuple. + /// The type of the fifth component of the tuple. + /// The type of the sixth component of the tuple. + /// The type of the seventh component of the tuple. + /// The type of the eighth component of the tuple. + /// The value of the first component of the tuple. + /// The value of the second component of the tuple. + /// The value of the third component of the tuple. + /// The value of the fourth component of the tuple. + /// The value of the fifth component of the tuple. + /// The value of the sixth component of the tuple. + /// The value of the seventh component of the tuple. + /// The value of the eighth component of the tuple. + /// An 8-tuple (octuple) whose value is (item1, item2, item3, item4, item5, item6, item7, item8). + public static ValueTuple> Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8) => + new ValueTuple>(item1, item2, item3, item4, item5, item6, item7, ValueTuple.Create(item8)); + } + + /// Represents a 1-tuple, or singleton, as a value type. + /// The type of the tuple's only component. + [Serializable] + public struct ValueTuple + : IEquatable>, IComparable, IComparable>, IValueTupleInternal + { + /// + /// The current instance's first component. + /// + public T1 Item1; + + /// + /// Initializes a new instance of the value type. + /// + /// The value of the tuple's first component. + public ValueTuple(T1 item1) + { + Item1 = item1; + } + + /// + /// Returns a value that indicates whether the current instance is equal to a specified object. + /// + /// The object to compare with this instance. + /// if the current instance is equal to the specified object; otherwise, . + /// + /// The parameter is considered to be equal to the current instance under the following conditions: + /// + /// It is a value type. + /// Its components are of the same types as those of the current instance. + /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. + /// + /// + public override bool Equals(object? obj) + { + return obj is ValueTuple && Equals((ValueTuple)obj); + } + + /// + /// Returns a value that indicates whether the current + /// instance is equal to a specified . + /// + /// The tuple to compare with this instance. + /// if the current instance is equal to the specified tuple; otherwise, . + /// + /// The parameter is considered to be equal to the current instance if each of its field + /// is equal to that of the current instance, using the default comparer for that field's type. + /// + public bool Equals(ValueTuple other) + { + return EqualityComparer.Default.Equals(Item1, other.Item1); + } + + int IComparable.CompareTo(object? other) + { + if (other == null) return 1; + + if (!(other is ValueTuple)) + { + throw new ArgumentException("Object to compare is not a ValueTuple", nameof(other)); + } + + var objTuple = (ValueTuple)other; + + return Comparer.Default.Compare(Item1, objTuple.Item1); + } + + /// Compares this instance to a specified instance and returns an indication of their relative values. + /// An instance to compare. + /// + /// A signed number indicating the relative values of this instance and . + /// Returns less than zero if this instance is less than , zero if this + /// instance is equal to , and greater than zero if this instance is greater + /// than . + /// + public int CompareTo(ValueTuple other) + { + return Comparer.Default.Compare(Item1, other.Item1); + } + + /// + /// Returns the hash code for the current instance. + /// + /// A 32-bit signed integer hash code. + public override int GetHashCode() + { + return Item1?.GetHashCode() ?? 0; + } + + int IValueTupleInternal.Length => 1; + int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) + { + return comparer.GetHashCode(Item1!); + } + + /// + /// Returns a string that represents the value of this instance. + /// + /// The string representation of this instance. + /// + /// The string returned by this method takes the form (Item1), + /// where Item1 represents the value of . If the field is , + /// it is represented as . + /// + public override string ToString() + { + return "(" + Item1?.ToString() + ")"; + } + + string IValueTupleInternal.ToStringEnd() + { + return Item1?.ToString() + ")"; + } + } + + /// + /// Represents a 2-tuple, or pair, as a value type. + /// + /// The type of the tuple's first component. + /// The type of the tuple's second component. + [Serializable] + [StructLayout(LayoutKind.Auto)] + public struct ValueTuple + : IEquatable>, IComparable, IComparable>, IValueTupleInternal + { + /// + /// The current instance's first component. + /// + public T1 Item1; + + /// + /// The current instance's second component. + /// + public T2 Item2; + + /// + /// Initializes a new instance of the value type. + /// + /// The value of the tuple's first component. + /// The value of the tuple's second component. + public ValueTuple(T1 item1, T2 item2) + { + Item1 = item1; + Item2 = item2; + } + + /// + /// Returns a value that indicates whether the current instance is equal to a specified object. + /// + /// The object to compare with this instance. + /// if the current instance is equal to the specified object; otherwise, . + /// + /// + /// The parameter is considered to be equal to the current instance under the following conditions: + /// + /// It is a value type. + /// Its components are of the same types as those of the current instance. + /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. + /// + /// + public override bool Equals(object? obj) + { + return obj is ValueTuple && Equals((ValueTuple)obj); + } + + /// + /// Returns a value that indicates whether the current instance is equal to a specified . + /// + /// The tuple to compare with this instance. + /// if the current instance is equal to the specified tuple; otherwise, . + /// + /// The parameter is considered to be equal to the current instance if each of its fields + /// are equal to that of the current instance, using the default comparer for that field's type. + /// + public bool Equals(ValueTuple other) + { + return EqualityComparer.Default.Equals(Item1, other.Item1) + && EqualityComparer.Default.Equals(Item2, other.Item2); + } + + int IComparable.CompareTo(object? other) + { + if (other == null) return 1; + + if (!(other is ValueTuple)) + { + throw new ArgumentException("Object to compare is not a ValueTuple", nameof(other)); + } + + return CompareTo((ValueTuple)other); + } + + /// Compares this instance to a specified instance and returns an indication of their relative values. + /// An instance to compare. + /// + /// A signed number indicating the relative values of this instance and . + /// Returns less than zero if this instance is less than , zero if this + /// instance is equal to , and greater than zero if this instance is greater + /// than . + /// + public int CompareTo(ValueTuple other) + { + int c = Comparer.Default.Compare(Item1, other.Item1); + if (c != 0) return c; + + return Comparer.Default.Compare(Item2, other.Item2); + } + + /// + /// Returns the hash code for the current instance. + /// + /// A 32-bit signed integer hash code. + public override int GetHashCode() + { + return HashCode.Combine(Item1?.GetHashCode() ?? 0, + Item2?.GetHashCode() ?? 0); + } + + private int GetHashCodeCore(IEqualityComparer comparer) + { + return HashCode.Combine(comparer.GetHashCode(Item1!), + comparer.GetHashCode(Item2!)); + } + + int IValueTupleInternal.Length => 1; + int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) + { + return GetHashCodeCore(comparer); + } + + /// + /// Returns a string that represents the value of this instance. + /// + /// The string representation of this instance. + /// + /// The string returned by this method takes the form (Item1, Item2), + /// where Item1 and Item2 represent the values of the + /// and fields. If either field value is , + /// it is represented as . + /// + public override string ToString() + { + return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ")"; + } + + string IValueTupleInternal.ToStringEnd() + { + return Item1?.ToString() + ", " + Item2?.ToString() + ")"; + } + } + + /// + /// Represents a 3-tuple, or triple, as a value type. + /// + /// The type of the tuple's first component. + /// The type of the tuple's second component. + /// The type of the tuple's third component. + [Serializable] + [StructLayout(LayoutKind.Auto)] + public struct ValueTuple + : IEquatable>, IComparable, IComparable>, IValueTupleInternal + { + /// + /// The current instance's first component. + /// + public T1 Item1; + /// + /// The current instance's second component. + /// + public T2 Item2; + /// + /// The current instance's third component. + /// + public T3 Item3; + + /// + /// Initializes a new instance of the value type. + /// + /// The value of the tuple's first component. + /// The value of the tuple's second component. + /// The value of the tuple's third component. + public ValueTuple(T1 item1, T2 item2, T3 item3) + { + Item1 = item1; + Item2 = item2; + Item3 = item3; + } + + /// + /// Returns a value that indicates whether the current instance is equal to a specified object. + /// + /// The object to compare with this instance. + /// if the current instance is equal to the specified object; otherwise, . + /// + /// The parameter is considered to be equal to the current instance under the following conditions: + /// + /// It is a value type. + /// Its components are of the same types as those of the current instance. + /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. + /// + /// + public override bool Equals(object? obj) + { + return obj is ValueTuple && Equals((ValueTuple)obj); + } + + /// + /// Returns a value that indicates whether the current + /// instance is equal to a specified . + /// + /// The tuple to compare with this instance. + /// if the current instance is equal to the specified tuple; otherwise, . + /// + /// The parameter is considered to be equal to the current instance if each of its fields + /// are equal to that of the current instance, using the default comparer for that field's type. + /// + public bool Equals(ValueTuple other) + { + return EqualityComparer.Default.Equals(Item1, other.Item1) + && EqualityComparer.Default.Equals(Item2, other.Item2) + && EqualityComparer.Default.Equals(Item3, other.Item3); + } + + int IComparable.CompareTo(object? other) + { + if (other == null) return 1; + + if (!(other is ValueTuple)) + { + throw new ArgumentException("Object to compare is not a ValueTuple", nameof(other)); + } + + return CompareTo((ValueTuple)other); + } + + /// Compares this instance to a specified instance and returns an indication of their relative values. + /// An instance to compare. + /// + /// A signed number indicating the relative values of this instance and . + /// Returns less than zero if this instance is less than , zero if this + /// instance is equal to , and greater than zero if this instance is greater + /// than . + /// + public int CompareTo(ValueTuple other) + { + int c = Comparer.Default.Compare(Item1, other.Item1); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item2, other.Item2); + if (c != 0) return c; + + return Comparer.Default.Compare(Item3, other.Item3); + } + + /// + /// Returns the hash code for the current instance. + /// + /// A 32-bit signed integer hash code. + public override int GetHashCode() + { + return HashCode.Combine(Item1?.GetHashCode() ?? 0, + Item2?.GetHashCode() ?? 0, + Item3?.GetHashCode() ?? 0); + } + + private int GetHashCodeCore(IEqualityComparer comparer) + { + return HashCode.Combine(comparer.GetHashCode(Item1!), + comparer.GetHashCode(Item2!), + comparer.GetHashCode(Item3!)); + } + + int IValueTupleInternal.Length => 2; + int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) + { + return GetHashCodeCore(comparer); + } + + /// + /// Returns a string that represents the value of this instance. + /// + /// The string representation of this instance. + /// + /// The string returned by this method takes the form (Item1, Item2, Item3). + /// If any field value is , it is represented as . + /// + public override string ToString() + { + return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ")"; + } + + string IValueTupleInternal.ToStringEnd() + { + return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ")"; + } + } + + /// + /// Represents a 4-tuple, or quadruple, as a value type. + /// + /// The type of the tuple's first component. + /// The type of the tuple's second component. + /// The type of the tuple's third component. + /// The type of the tuple's fourth component. + [Serializable] + [StructLayout(LayoutKind.Auto)] + public struct ValueTuple + : IEquatable>, IComparable, IComparable>, IValueTupleInternal + { + /// + /// The current instance's first component. + /// + public T1 Item1; + /// + /// The current instance's second component. + /// + public T2 Item2; + /// + /// The current instance's third component. + /// + public T3 Item3; + /// + /// The current instance's fourth component. + /// + public T4 Item4; + + /// + /// Initializes a new instance of the value type. + /// + /// The value of the tuple's first component. + /// The value of the tuple's second component. + /// The value of the tuple's third component. + /// The value of the tuple's fourth component. + public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4) + { + Item1 = item1; + Item2 = item2; + Item3 = item3; + Item4 = item4; + } + + /// + /// Returns a value that indicates whether the current instance is equal to a specified object. + /// + /// The object to compare with this instance. + /// if the current instance is equal to the specified object; otherwise, . + /// + /// The parameter is considered to be equal to the current instance under the following conditions: + /// + /// It is a value type. + /// Its components are of the same types as those of the current instance. + /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. + /// + /// + public override bool Equals(object? obj) + { + return obj is ValueTuple && Equals((ValueTuple)obj); + } + + /// + /// Returns a value that indicates whether the current + /// instance is equal to a specified . + /// + /// The tuple to compare with this instance. + /// if the current instance is equal to the specified tuple; otherwise, . + /// + /// The parameter is considered to be equal to the current instance if each of its fields + /// are equal to that of the current instance, using the default comparer for that field's type. + /// + public bool Equals(ValueTuple other) + { + return EqualityComparer.Default.Equals(Item1, other.Item1) + && EqualityComparer.Default.Equals(Item2, other.Item2) + && EqualityComparer.Default.Equals(Item3, other.Item3) + && EqualityComparer.Default.Equals(Item4, other.Item4); + } + + int IComparable.CompareTo(object? other) + { + if (other == null) return 1; + + if (!(other is ValueTuple)) + { + throw new ArgumentException("Object to compare is not a ValueTuple", nameof(other)); + } + + return CompareTo((ValueTuple)other); + } + + /// Compares this instance to a specified instance and returns an indication of their relative values. + /// An instance to compare. + /// + /// A signed number indicating the relative values of this instance and . + /// Returns less than zero if this instance is less than , zero if this + /// instance is equal to , and greater than zero if this instance is greater + /// than . + /// + public int CompareTo(ValueTuple other) + { + int c = Comparer.Default.Compare(Item1, other.Item1); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item2, other.Item2); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item3, other.Item3); + if (c != 0) return c; + + return Comparer.Default.Compare(Item4, other.Item4); + } + + /// + /// Returns the hash code for the current instance. + /// + /// A 32-bit signed integer hash code. + public override int GetHashCode() + { + return HashCode.Combine(Item1?.GetHashCode() ?? 0, + Item2?.GetHashCode() ?? 0, + Item3?.GetHashCode() ?? 0, + Item4?.GetHashCode() ?? 0); + } + + private int GetHashCodeCore(IEqualityComparer comparer) + { + return HashCode.Combine(comparer.GetHashCode(Item1!), + comparer.GetHashCode(Item2!), + comparer.GetHashCode(Item3!), + comparer.GetHashCode(Item4!)); + } + + int IValueTupleInternal.Length => 3; + int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) + { + return GetHashCodeCore(comparer); + } + + /// + /// Returns a string that represents the value of this instance. + /// + /// The string representation of this instance. + /// + /// The string returned by this method takes the form (Item1, Item2, Item3, Item4). + /// If any field value is , it is represented as . + /// + public override string ToString() + { + return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ")"; + } + + string IValueTupleInternal.ToStringEnd() + { + return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ")"; + } + } + + /// + /// Represents a 5-tuple, or quintuple, as a value type. + /// + /// The type of the tuple's first component. + /// The type of the tuple's second component. + /// The type of the tuple's third component. + /// The type of the tuple's fourth component. + /// The type of the tuple's fifth component. + [Serializable] + [StructLayout(LayoutKind.Auto)] + public struct ValueTuple + : IEquatable>, IComparable, IComparable>, IValueTupleInternal + { + /// + /// The current instance's first component. + /// + public T1 Item1; + /// + /// The current instance's second component. + /// + public T2 Item2; + /// + /// The current instance's third component. + /// + public T3 Item3; + /// + /// The current instance's fourth component. + /// + public T4 Item4; + /// + /// The current instance's fifth component. + /// + public T5 Item5; + + /// + /// Initializes a new instance of the value type. + /// + /// The value of the tuple's first component. + /// The value of the tuple's second component. + /// The value of the tuple's third component. + /// The value of the tuple's fourth component. + /// The value of the tuple's fifth component. + public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) + { + Item1 = item1; + Item2 = item2; + Item3 = item3; + Item4 = item4; + Item5 = item5; + } + + /// + /// Returns a value that indicates whether the current instance is equal to a specified object. + /// + /// The object to compare with this instance. + /// if the current instance is equal to the specified object; otherwise, . + /// + /// The parameter is considered to be equal to the current instance under the following conditions: + /// + /// It is a value type. + /// Its components are of the same types as those of the current instance. + /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. + /// + /// + public override bool Equals(object? obj) + { + return obj is ValueTuple && Equals((ValueTuple)obj); + } + + /// + /// Returns a value that indicates whether the current + /// instance is equal to a specified . + /// + /// The tuple to compare with this instance. + /// if the current instance is equal to the specified tuple; otherwise, . + /// + /// The parameter is considered to be equal to the current instance if each of its fields + /// are equal to that of the current instance, using the default comparer for that field's type. + /// + public bool Equals(ValueTuple other) + { + return EqualityComparer.Default.Equals(Item1, other.Item1) + && EqualityComparer.Default.Equals(Item2, other.Item2) + && EqualityComparer.Default.Equals(Item3, other.Item3) + && EqualityComparer.Default.Equals(Item4, other.Item4) + && EqualityComparer.Default.Equals(Item5, other.Item5); + } + + int IComparable.CompareTo(object? other) + { + if (other == null) return 1; + + if (!(other is ValueTuple)) + { + throw new ArgumentException("Object to compare is not a ValueTuple", nameof(other)); + } + + return CompareTo((ValueTuple)other); + } + + /// Compares this instance to a specified instance and returns an indication of their relative values. + /// An instance to compare. + /// + /// A signed number indicating the relative values of this instance and . + /// Returns less than zero if this instance is less than , zero if this + /// instance is equal to , and greater than zero if this instance is greater + /// than . + /// + public int CompareTo(ValueTuple other) + { + int c = Comparer.Default.Compare(Item1, other.Item1); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item2, other.Item2); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item3, other.Item3); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item4, other.Item4); + if (c != 0) return c; + + return Comparer.Default.Compare(Item5, other.Item5); + } + + /// + /// Returns the hash code for the current instance. + /// + /// A 32-bit signed integer hash code. + public override int GetHashCode() + { + return HashCode.Combine(Item1?.GetHashCode() ?? 0, + Item2?.GetHashCode() ?? 0, + Item3?.GetHashCode() ?? 0, + Item4?.GetHashCode() ?? 0, + Item5?.GetHashCode() ?? 0); + } + + private int GetHashCodeCore(IEqualityComparer comparer) + { + return HashCode.Combine(comparer.GetHashCode(Item1!), + comparer.GetHashCode(Item2!), + comparer.GetHashCode(Item3!), + comparer.GetHashCode(Item4!), + comparer.GetHashCode(Item5!)); + } + + int IValueTupleInternal.Length => 4; + int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) + { + return GetHashCodeCore(comparer); + } + + /// + /// Returns a string that represents the value of this instance. + /// + /// The string representation of this instance. + /// + /// The string returned by this method takes the form (Item1, Item2, Item3, Item4, Item5). + /// If any field value is , it is represented as . + /// + public override string ToString() + { + return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ")"; + } + + string IValueTupleInternal.ToStringEnd() + { + return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ")"; + } + } + + /// + /// Represents a 6-tuple, or sixtuple, as a value type. + /// + /// The type of the tuple's first component. + /// The type of the tuple's second component. + /// The type of the tuple's third component. + /// The type of the tuple's fourth component. + /// The type of the tuple's fifth component. + /// The type of the tuple's sixth component. + [Serializable] + [StructLayout(LayoutKind.Auto)] + public struct ValueTuple + : IEquatable>, IComparable, IComparable>, IValueTupleInternal + { + /// + /// The current instance's first component. + /// + public T1 Item1; + /// + /// The current instance's second component. + /// + public T2 Item2; + /// + /// The current instance's third component. + /// + public T3 Item3; + /// + /// The current instance's fourth component. + /// + public T4 Item4; + /// + /// The current instance's fifth component. + /// + public T5 Item5; + /// + /// The current instance's sixth component. + /// + public T6 Item6; + + /// + /// Initializes a new instance of the value type. + /// + /// The value of the tuple's first component. + /// The value of the tuple's second component. + /// The value of the tuple's third component. + /// The value of the tuple's fourth component. + /// The value of the tuple's fifth component. + /// The value of the tuple's sixth component. + public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) + { + Item1 = item1; + Item2 = item2; + Item3 = item3; + Item4 = item4; + Item5 = item5; + Item6 = item6; + } + + /// + /// Returns a value that indicates whether the current instance is equal to a specified object. + /// + /// The object to compare with this instance. + /// if the current instance is equal to the specified object; otherwise, . + /// + /// The parameter is considered to be equal to the current instance under the following conditions: + /// + /// It is a value type. + /// Its components are of the same types as those of the current instance. + /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. + /// + /// + public override bool Equals(object? obj) + { + return obj is ValueTuple && Equals((ValueTuple)obj); + } + + /// + /// Returns a value that indicates whether the current + /// instance is equal to a specified . + /// + /// The tuple to compare with this instance. + /// if the current instance is equal to the specified tuple; otherwise, . + /// + /// The parameter is considered to be equal to the current instance if each of its fields + /// are equal to that of the current instance, using the default comparer for that field's type. + /// + public bool Equals(ValueTuple other) + { + return EqualityComparer.Default.Equals(Item1, other.Item1) + && EqualityComparer.Default.Equals(Item2, other.Item2) + && EqualityComparer.Default.Equals(Item3, other.Item3) + && EqualityComparer.Default.Equals(Item4, other.Item4) + && EqualityComparer.Default.Equals(Item5, other.Item5) + && EqualityComparer.Default.Equals(Item6, other.Item6); + } + + int IComparable.CompareTo(object? other) + { + if (other == null) return 1; + + if (!(other is ValueTuple)) + { + throw new ArgumentException("Object to compare is not a ValueTuple", nameof(other)); + } + + return CompareTo((ValueTuple)other); + } + + /// Compares this instance to a specified instance and returns an indication of their relative values. + /// An instance to compare. + /// + /// A signed number indicating the relative values of this instance and . + /// Returns less than zero if this instance is less than , zero if this + /// instance is equal to , and greater than zero if this instance is greater + /// than . + /// + public int CompareTo(ValueTuple other) + { + int c = Comparer.Default.Compare(Item1, other.Item1); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item2, other.Item2); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item3, other.Item3); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item4, other.Item4); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item5, other.Item5); + if (c != 0) return c; + + return Comparer.Default.Compare(Item6, other.Item6); + } + + /// + /// Returns the hash code for the current instance. + /// + /// A 32-bit signed integer hash code. + public override int GetHashCode() + { + return HashCode.Combine(Item1?.GetHashCode() ?? 0, + Item2?.GetHashCode() ?? 0, + Item3?.GetHashCode() ?? 0, + Item4?.GetHashCode() ?? 0, + Item5?.GetHashCode() ?? 0, + Item6?.GetHashCode() ?? 0); + } + + private int GetHashCodeCore(IEqualityComparer comparer) + { + return HashCode.Combine(comparer.GetHashCode(Item1!), + comparer.GetHashCode(Item2!), + comparer.GetHashCode(Item3!), + comparer.GetHashCode(Item4!), + comparer.GetHashCode(Item5!), + comparer.GetHashCode(Item6!)); + } + + int IValueTupleInternal.Length => 6; + int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) + { + return GetHashCodeCore(comparer); + } + + /// + /// Returns a string that represents the value of this instance. + /// + /// The string representation of this instance. + /// + /// The string returned by this method takes the form (Item1, Item2, Item3, Item4, Item5, Item6). + /// If any field value is , it is represented as . + /// + public override string ToString() + { + return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ")"; + } + + string IValueTupleInternal.ToStringEnd() + { + return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ")"; + } + } + + /// + /// Represents a 7-tuple, or sentuple, as a value type. + /// + /// The type of the tuple's first component. + /// The type of the tuple's second component. + /// The type of the tuple's third component. + /// The type of the tuple's fourth component. + /// The type of the tuple's fifth component. + /// The type of the tuple's sixth component. + /// The type of the tuple's seventh component. + [Serializable] + [StructLayout(LayoutKind.Auto)] + public struct ValueTuple + : IEquatable>, IComparable, IComparable>, IValueTupleInternal + { + /// + /// The current instance's first component. + /// + public T1 Item1; + /// + /// The current instance's second component. + /// + public T2 Item2; + /// + /// The current instance's third component. + /// + public T3 Item3; + /// + /// The current instance's fourth component. + /// + public T4 Item4; + /// + /// The current instance's fifth component. + /// + public T5 Item5; + /// + /// The current instance's sixth component. + /// + public T6 Item6; + /// + /// The current instance's seventh component. + /// + public T7 Item7; + + /// + /// Initializes a new instance of the value type. + /// + /// The value of the tuple's first component. + /// The value of the tuple's second component. + /// The value of the tuple's third component. + /// The value of the tuple's fourth component. + /// The value of the tuple's fifth component. + /// The value of the tuple's sixth component. + /// The value of the tuple's seventh component. + public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) + { + Item1 = item1; + Item2 = item2; + Item3 = item3; + Item4 = item4; + Item5 = item5; + Item6 = item6; + Item7 = item7; + } + + /// + /// Returns a value that indicates whether the current instance is equal to a specified object. + /// + /// The object to compare with this instance. + /// if the current instance is equal to the specified object; otherwise, . + /// + /// The parameter is considered to be equal to the current instance under the following conditions: + /// + /// It is a value type. + /// Its components are of the same types as those of the current instance. + /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. + /// + /// + public override bool Equals(object? obj) + { + return obj is ValueTuple && Equals((ValueTuple)obj); + } + + /// + /// Returns a value that indicates whether the current + /// instance is equal to a specified . + /// + /// The tuple to compare with this instance. + /// if the current instance is equal to the specified tuple; otherwise, . + /// + /// The parameter is considered to be equal to the current instance if each of its fields + /// are equal to that of the current instance, using the default comparer for that field's type. + /// + public bool Equals(ValueTuple other) + { + return EqualityComparer.Default.Equals(Item1, other.Item1) + && EqualityComparer.Default.Equals(Item2, other.Item2) + && EqualityComparer.Default.Equals(Item3, other.Item3) + && EqualityComparer.Default.Equals(Item4, other.Item4) + && EqualityComparer.Default.Equals(Item5, other.Item5) + && EqualityComparer.Default.Equals(Item6, other.Item6) + && EqualityComparer.Default.Equals(Item7, other.Item7); + } + + int IComparable.CompareTo(object? other) + { + if (other == null) return 1; + + if (!(other is ValueTuple)) + { + throw new ArgumentException("Object to compare is not a ValueTuple", nameof(other)); + } + + return CompareTo((ValueTuple)other); + } + + /// Compares this instance to a specified instance and returns an indication of their relative values. + /// An instance to compare. + /// + /// A signed number indicating the relative values of this instance and . + /// Returns less than zero if this instance is less than , zero if this + /// instance is equal to , and greater than zero if this instance is greater + /// than . + /// + public int CompareTo(ValueTuple other) + { + int c = Comparer.Default.Compare(Item1, other.Item1); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item2, other.Item2); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item3, other.Item3); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item4, other.Item4); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item5, other.Item5); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item6, other.Item6); + if (c != 0) return c; + + return Comparer.Default.Compare(Item7, other.Item7); + } + + /// + /// Returns the hash code for the current instance. + /// + /// A 32-bit signed integer hash code. + public override int GetHashCode() + { + return HashCode.Combine(Item1?.GetHashCode() ?? 0, + Item2?.GetHashCode() ?? 0, + Item3?.GetHashCode() ?? 0, + Item4?.GetHashCode() ?? 0, + Item5?.GetHashCode() ?? 0, + Item6?.GetHashCode() ?? 0, + Item7?.GetHashCode() ?? 0); + } + + private int GetHashCodeCore(IEqualityComparer comparer) + { + return HashCode.Combine(comparer.GetHashCode(Item1!), + comparer.GetHashCode(Item2!), + comparer.GetHashCode(Item3!), + comparer.GetHashCode(Item4!), + comparer.GetHashCode(Item5!), + comparer.GetHashCode(Item6!), + comparer.GetHashCode(Item7!)); + } + + int IValueTupleInternal.Length => 7; + int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) + { + return GetHashCodeCore(comparer); + } + + /// + /// Returns a string that represents the value of this instance. + /// + /// The string representation of this instance. + /// + /// The string returned by this method takes the form (Item1, Item2, Item3, Item4, Item5, Item6, Item7). + /// If any field value is , it is represented as . + /// + public override string ToString() + { + return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ")"; + } + + string IValueTupleInternal.ToStringEnd() + { + return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ")"; + } + } + + /// + /// Represents an 8-tuple, or octuple, as a value type. + /// + /// The type of the tuple's first component. + /// The type of the tuple's second component. + /// The type of the tuple's third component. + /// The type of the tuple's fourth component. + /// The type of the tuple's fifth component. + /// The type of the tuple's sixth component. + /// The type of the tuple's seventh component. + /// The type of the tuple's eighth component. + [Serializable] + [StructLayout(LayoutKind.Auto)] + public struct ValueTuple + : IEquatable>, IComparable, IComparable>, IValueTupleInternal + where TRest : struct + { + /// + /// The current instance's first component. + /// + public T1 Item1; + /// + /// The current instance's second component. + /// + public T2 Item2; + /// + /// The current instance's third component. + /// + public T3 Item3; + /// + /// The current instance's fourth component. + /// + public T4 Item4; + /// + /// The current instance's fifth component. + /// + public T5 Item5; + /// + /// The current instance's sixth component. + /// + public T6 Item6; + /// + /// The current instance's seventh component. + /// + public T7 Item7; + /// + /// The current instance's eighth component. + /// + public TRest Rest; + + /// + /// Initializes a new instance of the value type. + /// + /// The value of the tuple's first component. + /// The value of the tuple's second component. + /// The value of the tuple's third component. + /// The value of the tuple's fourth component. + /// The value of the tuple's fifth component. + /// The value of the tuple's sixth component. + /// The value of the tuple's seventh component. + /// The value of the tuple's eight component. + public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) + { + if (!(rest is IValueTupleInternal)) + { + throw new ArgumentException("Last argument of an 8-tuple is not a ValueTuple", nameof(rest)); + } + + Item1 = item1; + Item2 = item2; + Item3 = item3; + Item4 = item4; + Item5 = item5; + Item6 = item6; + Item7 = item7; + Rest = rest; + } + + /// + /// Returns a value that indicates whether the current instance is equal to a specified object. + /// + /// The object to compare with this instance. + /// if the current instance is equal to the specified object; otherwise, . + /// + /// The parameter is considered to be equal to the current instance under the following conditions: + /// + /// It is a value type. + /// Its components are of the same types as those of the current instance. + /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. + /// + /// + public override bool Equals(object? obj) + { + return obj is ValueTuple && Equals((ValueTuple)obj); + } + + /// + /// Returns a value that indicates whether the current + /// instance is equal to a specified . + /// + /// The tuple to compare with this instance. + /// if the current instance is equal to the specified tuple; otherwise, . + /// + /// The parameter is considered to be equal to the current instance if each of its fields + /// are equal to that of the current instance, using the default comparer for that field's type. + /// + public bool Equals(ValueTuple other) + { + return EqualityComparer.Default.Equals(Item1, other.Item1) + && EqualityComparer.Default.Equals(Item2, other.Item2) + && EqualityComparer.Default.Equals(Item3, other.Item3) + && EqualityComparer.Default.Equals(Item4, other.Item4) + && EqualityComparer.Default.Equals(Item5, other.Item5) + && EqualityComparer.Default.Equals(Item6, other.Item6) + && EqualityComparer.Default.Equals(Item7, other.Item7) + && EqualityComparer.Default.Equals(Rest, other.Rest); + } + + int IComparable.CompareTo(object? other) + { + if (other == null) return 1; + + if (!(other is ValueTuple)) + { + throw new ArgumentException("Object to compare is not a ValueTuple", nameof(other)); + } + + return CompareTo((ValueTuple)other); + } + + /// Compares this instance to a specified instance and returns an indication of their relative values. + /// An instance to compare. + /// + /// A signed number indicating the relative values of this instance and . + /// Returns less than zero if this instance is less than , zero if this + /// instance is equal to , and greater than zero if this instance is greater + /// than . + /// + public int CompareTo(ValueTuple other) + { + int c = Comparer.Default.Compare(Item1, other.Item1); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item2, other.Item2); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item3, other.Item3); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item4, other.Item4); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item5, other.Item5); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item6, other.Item6); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item7, other.Item7); + if (c != 0) return c; + + return Comparer.Default.Compare(Rest, other.Rest); + } + + /// + /// Returns the hash code for the current instance. + /// + /// A 32-bit signed integer hash code. + public override int GetHashCode() + { + // We want to have a limited hash in this case. We'll use the first 7 elements of the tuple + if (!(Rest is IValueTupleInternal)) + { + return HashCode.Combine(Item1?.GetHashCode() ?? 0, + Item2?.GetHashCode() ?? 0, + Item3?.GetHashCode() ?? 0, + Item4?.GetHashCode() ?? 0, + Item5?.GetHashCode() ?? 0, + Item6?.GetHashCode() ?? 0, + Item7?.GetHashCode() ?? 0); + } + + int size = ((IValueTupleInternal)Rest).Length; + int restHashCode = Rest.GetHashCode(); + if (size >= 8) + { + return restHashCode; + } + + // In this case, the rest member has less than 8 elements so we need to combine some of our elements with the elements in rest + int k = 8 - size; + switch (k) + { + case 1: + return HashCode.Combine(Item7?.GetHashCode() ?? 0, + restHashCode); + case 2: + return HashCode.Combine(Item6?.GetHashCode() ?? 0, + Item7?.GetHashCode() ?? 0, + restHashCode); + case 3: + return HashCode.Combine(Item5?.GetHashCode() ?? 0, + Item6?.GetHashCode() ?? 0, + Item7?.GetHashCode() ?? 0, + restHashCode); + case 4: + return HashCode.Combine(Item4?.GetHashCode() ?? 0, + Item5?.GetHashCode() ?? 0, + Item6?.GetHashCode() ?? 0, + Item7?.GetHashCode() ?? 0, + restHashCode); + case 5: + return HashCode.Combine(Item3?.GetHashCode() ?? 0, + Item4?.GetHashCode() ?? 0, + Item5?.GetHashCode() ?? 0, + Item6?.GetHashCode() ?? 0, + Item7?.GetHashCode() ?? 0, + restHashCode); + case 6: + return HashCode.Combine(Item2?.GetHashCode() ?? 0, + Item3?.GetHashCode() ?? 0, + Item4?.GetHashCode() ?? 0, + Item5?.GetHashCode() ?? 0, + Item6?.GetHashCode() ?? 0, + Item7?.GetHashCode() ?? 0, + restHashCode); + case 7: + case 8: + return HashCode.Combine(Item1?.GetHashCode() ?? 0, + Item2?.GetHashCode() ?? 0, + Item3?.GetHashCode() ?? 0, + Item4?.GetHashCode() ?? 0, + Item5?.GetHashCode() ?? 0, + Item6?.GetHashCode() ?? 0, + Item7?.GetHashCode() ?? 0, + restHashCode); + } + + Debug.Fail("Missed all cases for computing ValueTuple hash code"); + return -1; + } + + private int GetHashCodeCore(IEqualityComparer comparer) + { + // We want to have a limited hash in this case. We'll use the first 7 elements of the tuple + if (!(Rest is IValueTupleInternal rest)) + { + return HashCode.Combine(comparer.GetHashCode(Item1!), comparer.GetHashCode(Item2!), comparer.GetHashCode(Item3!), + comparer.GetHashCode(Item4!), comparer.GetHashCode(Item5!), comparer.GetHashCode(Item6!), + comparer.GetHashCode(Item7!)); + } + + int size = rest.Length; + int restHashCode = rest.GetHashCode(comparer); + if (size >= 8) + { + return restHashCode; + } + + // In this case, the rest member has less than 8 elements so we need to combine some our elements with the elements in rest + int k = 8 - size; + switch (k) + { + case 1: + return HashCode.Combine(comparer.GetHashCode(Item7!), + restHashCode); + case 2: + return HashCode.Combine(comparer.GetHashCode(Item6!), + comparer.GetHashCode(Item7!), + restHashCode); + case 3: + return HashCode.Combine(comparer.GetHashCode(Item5!), + comparer.GetHashCode(Item6!), + comparer.GetHashCode(Item7!), + restHashCode); + case 4: + return HashCode.Combine(comparer.GetHashCode(Item4!), + comparer.GetHashCode(Item5!), + comparer.GetHashCode(Item6!), + comparer.GetHashCode(Item7!), + restHashCode); + case 5: + return HashCode.Combine(comparer.GetHashCode(Item3!), + comparer.GetHashCode(Item4!), + comparer.GetHashCode(Item5!), + comparer.GetHashCode(Item6!), + comparer.GetHashCode(Item7!), + restHashCode); + case 6: + return HashCode.Combine(comparer.GetHashCode(Item2!), + comparer.GetHashCode(Item3!), + comparer.GetHashCode(Item4!), + comparer.GetHashCode(Item5!), + comparer.GetHashCode(Item6!), + comparer.GetHashCode(Item7!), + restHashCode); + case 7: + case 8: + return HashCode.Combine(comparer.GetHashCode(Item1!), + comparer.GetHashCode(Item2!), + comparer.GetHashCode(Item3!), + comparer.GetHashCode(Item4!), + comparer.GetHashCode(Item5!), + comparer.GetHashCode(Item6!), + comparer.GetHashCode(Item7!), + restHashCode); + } + + Debug.Fail("Missed all cases for computing ValueTuple hash code"); + return -1; + } + + int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) + { + return GetHashCodeCore(comparer); + } + + /// + /// Returns a string that represents the value of this instance. + /// + /// The string representation of this instance. + /// + /// The string returned by this method takes the form (Item1, Item2, Item3, Item4, Item5, Item6, Item7, Rest). + /// If any field value is , it is represented as . + /// + public override string ToString() + { + if (Rest is IValueTupleInternal) + { + return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + ((IValueTupleInternal)Rest).ToStringEnd(); + } + + return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + Rest.ToString() + ")"; + } + + string IValueTupleInternal.ToStringEnd() + { + if (Rest is IValueTupleInternal) + { + return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + ((IValueTupleInternal)Rest).ToStringEnd(); + } + + return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + Rest.ToString() + ")"; + } + + /// + /// The number of positions in this data structure. + /// + int IValueTupleInternal.Length => Rest is IValueTupleInternal ? 7 + ((IValueTupleInternal)Rest).Length : 8; + } +} \ No newline at end of file diff --git a/Build/NetStandard/FontAtlas/FontAtlas.csproj b/Build/NetStandard/FontAtlas/FontAtlas.csproj deleted file mode 100644 index 59b64d8b..00000000 --- a/Build/NetStandard/FontAtlas/FontAtlas.csproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - netstandard2.0 - - - - true - - - - true - - - - - - - - - - - - - diff --git a/Build/NetStandard/Typography.Contours/Typography.Contours.csproj b/Build/NetStandard/Typography.Contours/Typography.Contours.csproj deleted file mode 100644 index 2910c5ac..00000000 --- a/Build/NetStandard/Typography.Contours/Typography.Contours.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - netstandard2.0 - true - - - - - - - - - - - - diff --git a/Build/NetStandard/Typography.GlyphLayout/Typography.GlyphLayout.csproj b/Build/NetStandard/Typography.GlyphLayout/Typography.GlyphLayout.csproj deleted file mode 100644 index 5f38d170..00000000 --- a/Build/NetStandard/Typography.GlyphLayout/Typography.GlyphLayout.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - netstandard2.0 - - - - TRACE;DEBUG;NETSTANDARD1_6;NETSTANDARD1_3 - - - - - - - - - diff --git a/Build/NetStandard/Typography.MsdfGen/Typography.MsdfGen.csproj b/Build/NetStandard/Typography.MsdfGen/Typography.MsdfGen.csproj deleted file mode 100644 index f02394b2..00000000 --- a/Build/NetStandard/Typography.MsdfGen/Typography.MsdfGen.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - netstandard2.0 - - - - - - - - - - - - - diff --git a/Build/NetStandard/Typography.One/Typography.One.csproj b/Build/NetStandard/Typography.One/Typography.One.csproj deleted file mode 100644 index 15ce7707..00000000 --- a/Build/NetStandard/Typography.One/Typography.One.csproj +++ /dev/null @@ -1,37 +0,0 @@ - - - - netstandard2.0 - - - - true - TRACE;NETSTANDARD1_6;NETSTANDARD1_6;NETSTANDARD1_3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Build/NetStandard/Typography.OpenFont/Typography.OpenFont.csproj b/Build/NetStandard/Typography.OpenFont/Typography.OpenFont.csproj deleted file mode 100644 index bf4ef48b..00000000 --- a/Build/NetStandard/Typography.OpenFont/Typography.OpenFont.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - netstandard2.0 - true - - - - TRACE;DEBUG;NETSTANDARD1_6;NETSTANDARD1_6;NETSTANDARD1_3 - - - - - - - - - diff --git a/Build/NetStandard/Typography.TextBreak/Typography.TextBreak.csproj b/Build/NetStandard/Typography.TextBreak/Typography.TextBreak.csproj deleted file mode 100644 index 02609766..00000000 --- a/Build/NetStandard/Typography.TextBreak/Typography.TextBreak.csproj +++ /dev/null @@ -1,10 +0,0 @@ - - - - netstandard2.0 - - - - - - diff --git a/Build/NetStandard/Typography.TextFlow/Typography.TextFlow.csproj b/Build/NetStandard/Typography.TextFlow/Typography.TextFlow.csproj deleted file mode 100644 index 21ac1bd7..00000000 --- a/Build/NetStandard/Typography.TextFlow/Typography.TextFlow.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - - netstandard2.0 - - - - - - - - - - diff --git a/Build/NetStandard/Typography.TextServices/Typography.TextServices.csproj b/Build/NetStandard/Typography.TextServices/Typography.TextServices.csproj deleted file mode 100644 index 0aedc8d5..00000000 --- a/Build/NetStandard/Typography.TextServices/Typography.TextServices.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - netstandard2.0 - - - - - - - - - - - - - - - diff --git a/Build/NetStandard/Unpack/Unpack.csproj b/Build/NetStandard/Unpack/Unpack.csproj deleted file mode 100644 index a687d65b..00000000 --- a/Build/NetStandard/Unpack/Unpack.csproj +++ /dev/null @@ -1,22 +0,0 @@ - - - - netstandard2.0 - - - - true - - - - true - TRACE - - - - - - - - - diff --git a/x_autogen2/PixelFarm.MiniAgg.One/PixelFarm.MiniAgg.One.csproj b/Build/PixelFarm.MiniAgg.One/PixelFarm.MiniAgg.One.csproj similarity index 96% rename from x_autogen2/PixelFarm.MiniAgg.One/PixelFarm.MiniAgg.One.csproj rename to Build/PixelFarm.MiniAgg.One/PixelFarm.MiniAgg.One.csproj index cd4aad51..d5206df3 100644 --- a/x_autogen2/PixelFarm.MiniAgg.One/PixelFarm.MiniAgg.One.csproj +++ b/Build/PixelFarm.MiniAgg.One/PixelFarm.MiniAgg.One.csproj @@ -1,37 +1,13 @@ - - + - Debug - AnyCPU - 2.0 - Library - v2.0 - 512 - PixelFarm.MiniAgg.One - - - true - prompt - 4 - bin\Debug\ - false - full - true - TRACE; DEBUG; PIXEL_FARM; PIXEL_FARM_NET20; - - + net20;netstandard2.0 + 8.0 + PIXEL_FARM; PIXEL_FARM_NET20 true - prompt - 4 - bin\Release\ - true - pdbonly - TRACE; PIXEL_FARM; PIXEL_FARM_NET20; + CS8632 - - - + PixelFarm\BackEnd.BurningMineCurve\curveutils\CubicBezier.cs @@ -311,7 +287,7 @@ PixelFarm\PixelFarm.DrawingCore\Drawing\VertexStore.cs - + PixelFarm\PixelFarm.Painter\0_Base\ForNet20.cs @@ -732,5 +708,4 @@ PixelFarm\PixelFarm.Drawing\7_BitmapAtlas\SimpleBitmapAtlasBuilder.cs - - \ No newline at end of file + diff --git a/Build/PixelFarm.One.HtmlRenderer/PixelFarm.One.HtmlRenderer.csproj b/Build/PixelFarm.One.HtmlRenderer/PixelFarm.One.HtmlRenderer.csproj new file mode 100644 index 00000000..d33f17aa --- /dev/null +++ b/Build/PixelFarm.One.HtmlRenderer/PixelFarm.One.HtmlRenderer.csproj @@ -0,0 +1,34 @@ + + + net20;netstandard2.0 + 8.0 + PIXEL_FARM; PIXEL_FARM_NET20; MINIMAL; GLES; WIN32; GL_ENABLE; SHARPZIPLIB; + true + CS8632 + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Build/Typography.GlyphLayout/Typography.GlyphLayout.csproj b/Build/Typography.GlyphLayout/Typography.GlyphLayout.csproj new file mode 100644 index 00000000..8d56e4b8 --- /dev/null +++ b/Build/Typography.GlyphLayout/Typography.GlyphLayout.csproj @@ -0,0 +1,16 @@ + + + + net20;netstandard2.0;netcoreapp3.1 + 8.0 + enable + nullable + + + + + + + + + diff --git a/Build/Typography.MsdfGen/Typography.MsdfGen.csproj b/Build/Typography.MsdfGen/Typography.MsdfGen.csproj new file mode 100644 index 00000000..977b5483 --- /dev/null +++ b/Build/Typography.MsdfGen/Typography.MsdfGen.csproj @@ -0,0 +1,15 @@ + + + + net20;netstandard2.0;netcoreapp3.1 + 8.0 + enable + nullable + + + + + + + + diff --git a/Build/Typography.One/Typography.One.csproj b/Build/Typography.One/Typography.One.csproj new file mode 100644 index 00000000..fa27194b --- /dev/null +++ b/Build/Typography.One/Typography.One.csproj @@ -0,0 +1,25 @@ + + + + net20;netstandard2.0;netcoreapp3.1 + 8.0 + enable + true + nullable + + + + + + + + + + + + + + + + + diff --git a/Build/Typography.OpenFont/Typography.OpenFont.csproj b/Build/Typography.OpenFont/Typography.OpenFont.csproj new file mode 100644 index 00000000..a452196e --- /dev/null +++ b/Build/Typography.OpenFont/Typography.OpenFont.csproj @@ -0,0 +1,19 @@ + + + + net20;netstandard2.0;netcoreapp3.1 + 8.0 + enable + true + nullable + + + + + + + + + + + diff --git a/Build/Typography.TextBreak/Typography.TextBreak.csproj b/Build/Typography.TextBreak/Typography.TextBreak.csproj new file mode 100644 index 00000000..6d8fa315 --- /dev/null +++ b/Build/Typography.TextBreak/Typography.TextBreak.csproj @@ -0,0 +1,16 @@ + + + + net20;netstandard2.0;netcoreapp3.1 + 8.0 + enable + nullable + + + + + + + + + diff --git a/Build/Typography.TextFlow/Typography.TextFlow.csproj b/Build/Typography.TextFlow/Typography.TextFlow.csproj new file mode 100644 index 00000000..9d242825 --- /dev/null +++ b/Build/Typography.TextFlow/Typography.TextFlow.csproj @@ -0,0 +1,18 @@ + + + + net20;netstandard2.0;netcoreapp3.1 + 8.0 + enable + nullable + + + + + + + + + + + diff --git a/Build/Typography.TextServices/Typography.TextServices.csproj b/Build/Typography.TextServices/Typography.TextServices.csproj new file mode 100644 index 00000000..65c795a6 --- /dev/null +++ b/Build/Typography.TextServices/Typography.TextServices.csproj @@ -0,0 +1,21 @@ + + + + net20;netstandard2.0;netcoreapp3.1 + 8.0 + enable + nullable + + + + + + + + + + + + + + diff --git a/Build/Unpack/Unpack.csproj b/Build/Unpack/Unpack.csproj new file mode 100644 index 00000000..b5e6136f --- /dev/null +++ b/Build/Unpack/Unpack.csproj @@ -0,0 +1,20 @@ + + + + net20;netstandard2.0 + 8.0 + true + + + + TRACE + + + + + + + + + + diff --git a/Demo/Android/Xamarin.OpenGL/Xamarin.Android.OpenGL.csproj b/Demo/Android/Xamarin.OpenGL/Xamarin.Android.OpenGL.csproj index 2cdb6f5d..96a920a5 100644 --- a/Demo/Android/Xamarin.OpenGL/Xamarin.Android.OpenGL.csproj +++ b/Demo/Android/Xamarin.OpenGL/Xamarin.Android.OpenGL.csproj @@ -16,6 +16,8 @@ Resources\Resource.Designer.cs v9.0 Properties\AndroidManifest.xml + latest + CS8632 True @@ -51,6 +53,12 @@ + + DevTextPrinter\FontManagement.cs + + + GlyphOutlineBuilder\GlyphOutlineBuilderBase.cs + @@ -75,16 +83,8 @@ - - - - {8ce29063-ca6c-4913-bf2d-764ce857da06} - Typography.GlyphLayout - - - {280d17d5-4435-4ead-839a-33c5a8990e7e} - Typography.OpenFont - + + diff --git a/Demo/Shared/DevTextPrinter/FontManagement.cs b/Demo/Shared/DevTextPrinter/FontManagement.cs deleted file mode 100644 index 25b8679a..00000000 --- a/Demo/Shared/DevTextPrinter/FontManagement.cs +++ /dev/null @@ -1,500 +0,0 @@ -//MIT, 2016-present, WinterDev -using System; -using System.Collections.Generic; -using System.IO; -using Typography.OpenFont; - -namespace Typography.TextServices -{ - - - public class InstalledFont - { - internal InstalledFont(string fontName, - string fontSubFamily, - string typographicFontName, - string typographicfontSubFamily, - string fontPath, - ushort weight) - { - FontName = fontName; - FontSubFamily = fontSubFamily; - TypographicFontName = typographicFontName; - TypographicFontSubFamily = typographicfontSubFamily; - - FontPath = fontPath; - Weight = weight; - } - - public string FontName { get; internal set; } - public string FontSubFamily { get; internal set; } - public string TypographicFontName { get; internal set; } - public string TypographicFontSubFamily { get; internal set; } - - public ushort Weight { get; internal set; } - - public string FontPath { get; internal set; } - public int StreamOffset { get; internal set; } - -#if DEBUG - public override string ToString() - { - return FontName + " " + FontSubFamily; - } -#endif - } - - - public interface FontStreamSource - { - Stream ReadFontStream(); - string PathName { get; } - } - - public class FontFileStreamProvider : FontStreamSource - { - public FontFileStreamProvider(string filename) - { - this.PathName = filename; - } - public string PathName { get; private set; } - public Stream ReadFontStream() - { - //TODO: don't forget to dispose this stream when not use - return new FileStream(this.PathName, FileMode.Open, FileAccess.Read); - - } - } - - - - [Flags] - public enum InstalledFontStyle - { - Normal = 0, - Bold = 1 << 1, - Italic = 1 << 2, - } - - public delegate InstalledFont FontNotFoundHandler(InstalledFontCollection fontCollection, string fontName, string fontSubFam, InstalledFontStyle wellknownStyle); - public delegate FontNameDuplicatedDecision FontNameDuplicatedHandler(InstalledFont existing, InstalledFont newAddedFont); - public enum FontNameDuplicatedDecision - { - /// - /// use existing, skip latest font - /// - Skip, - /// - /// replace with existing with the new one - /// - Replace - } - - - public class TypefaceStore - { - - FontNotFoundHandler _fontNotFoundHandler; - Dictionary _loadedTypefaces = new Dictionary(); - /// - /// font collection of the store - /// - public InstalledFontCollection FontCollection { get; set; } - public void SetFontNotFoundHandler(FontNotFoundHandler fontNotFoundHandler) - { - _fontNotFoundHandler = fontNotFoundHandler; - } - public Typeface GetTypeface(InstalledFont installedFont) - { - return GetTypefaceOrCreateNew(installedFont); - } - public Typeface GetTypeface(string fontname, string fontSubFam) - { - - InstalledFont installedFont = FontCollection.GetFont(fontname, fontSubFam); - //convert from - if (installedFont == null && _fontNotFoundHandler != null) - { - installedFont = _fontNotFoundHandler(this.FontCollection, fontname, fontSubFam, FontCollection.GetWellknownFontStyle(fontSubFam)); - } - if (installedFont == null) - { - return null; - } - return GetTypefaceOrCreateNew(installedFont); - } - /// - /// get typeface from wellknown style - /// - /// - /// - /// - public Typeface GetTypeface(string fontname, InstalledFontStyle style) - { - InstalledFont installedFont = FontCollection.GetFont(fontname, style); - if (installedFont == null && _fontNotFoundHandler != null) - { - installedFont = _fontNotFoundHandler(this.FontCollection, fontname, null, style); - } - if (installedFont == null) - { - return null; - } - return GetTypefaceOrCreateNew(installedFont); - } - Typeface GetTypefaceOrCreateNew(InstalledFont installedFont) - { - //load - //check if we have create this typeface or not - Typeface typeface; - if (!_loadedTypefaces.TryGetValue(installedFont, out typeface)) - { - //TODO: review how to load font here - using (var fs = new FileStream(installedFont.FontPath, FileMode.Open, FileAccess.Read)) - { - var reader = new OpenFontReader(); - typeface = reader.Read(fs, installedFont.StreamOffset); - } - return _loadedTypefaces[installedFont] = typeface; - } - return typeface; - } - } - - public class InstalledFontCollection - { - - - class FontGroup - { - - internal Dictionary _members = new Dictionary(); - public void AddFont(InstalledFont installedFont) - { - - _members.Add(installedFont.FontName.ToUpper(), installedFont); - } - public bool TryGetValue(string fontName, out InstalledFont found) - { - return _members.TryGetValue(fontName, out found); - } - public void Replace(InstalledFont newone) - { - _members[newone.FontName.ToUpper()] = newone; - } - } - - /// - /// map from font subfam to internal group name - /// - Dictionary _subFamToFontGroup = new Dictionary(); - - FontGroup _normal, _bold, _italic, _bold_italic; - List _allFontGroups = new List(); - FontNameDuplicatedHandler fontNameDuplicatedHandler; - - - public InstalledFontCollection() - { - - //----------------------------------------------------- - //init wellknown subfam - _normal = CreateNewFontGroup(InstalledFontStyle.Normal, "regular", "normal"); - _italic = CreateNewFontGroup(InstalledFontStyle.Italic, "Italic", "italique"); - // - _bold = CreateNewFontGroup(InstalledFontStyle.Bold, "bold"); - // - _bold_italic = CreateNewFontGroup(InstalledFontStyle.Bold | InstalledFontStyle.Italic, "bold italic"); - // - } - public InstalledFontStyle GetWellknownFontStyle(string subFamName) - { - switch (subFamName.ToUpper()) - { - default: - case "NORMAL": - case "REGULAR": - return InstalledFontStyle.Normal; - case "BOLD": - return InstalledFontStyle.Bold; - case "ITALIC": - case "ITALIQUE": - return InstalledFontStyle.Italic; - case "BOLD ITALIC": - return (InstalledFontStyle.Bold | InstalledFontStyle.Italic); - } - } - FontGroup CreateNewFontGroup(InstalledFontStyle installedFontStyle, params string[] names) - { - //create font group - var fontGroup = new FontGroup(); - //single dic may be called by many names - foreach (string name in names) - { - string upperCaseName = name.ToUpper(); - //register name - //should not duplicate - _subFamToFontGroup.Add(upperCaseName, fontGroup); - } - _allFontGroups.Add(fontGroup); - return fontGroup; - } - - public void SetFontNameDuplicatedHandler(FontNameDuplicatedHandler handler) - { - fontNameDuplicatedHandler = handler; - } - public bool AddFont(FontStreamSource src) - { - //preview data of font - using (Stream stream = src.ReadFontStream()) - { - var reader = new OpenFontReader(); - PreviewFontInfo previewFont = reader.ReadPreview(stream); - if (previewFont == null || string.IsNullOrEmpty(previewFont.Name)) - { - //err! - return false; - } - //*** - if (previewFont.IsFontCollection) - { - int mbCount = previewFont.MemberCount; - bool passAll = true; - for (int i = 0; i < mbCount; ++i) - { - PreviewFontInfo member = previewFont.GetMember(i); - - if (!RegisterFont(new InstalledFont( - member.Name, - member.SubFamilyName, - member.TypographicFamilyName, - member.TypographicSubFamilyName, - src.PathName, - member.Weight) - { StreamOffset = member.ActualStreamOffset })) - { - passAll = false; - } - - } - return passAll; - } - else - { - return RegisterFont(new InstalledFont( - previewFont.Name, - previewFont.SubFamilyName, - previewFont.TypographicFamilyName, - previewFont.TypographicSubFamilyName, - src.PathName, - previewFont.Weight)); - } - - } - } - bool RegisterFont(InstalledFont newfont) - { - FontGroup selectedFontGroup; - string fontsubFamUpperCaseName = newfont.FontSubFamily.ToUpper(); - if (!_subFamToFontGroup.TryGetValue(fontsubFamUpperCaseName, out selectedFontGroup)) - { - //create new group, we don't known this font group before - //so we add to 'other group' list - selectedFontGroup = new FontGroup(); - _subFamToFontGroup.Add(fontsubFamUpperCaseName, selectedFontGroup); - _allFontGroups.Add(selectedFontGroup); - } - - if(newfont.TypographicFontName != newfont.FontName) - { - - } - - // - string fontNameUpper = newfont.FontName.ToUpper(); - if (selectedFontGroup.TryGetValue(fontNameUpper, out InstalledFont found)) - { - //TODO: - //we already have this font name - //(but may be different file - //we let user to handle it - switch (fontNameDuplicatedHandler(found, newfont)) - { - default: throw new NotSupportedException(); - case FontNameDuplicatedDecision.Skip: - return false; - case FontNameDuplicatedDecision.Replace: - selectedFontGroup.Replace(newfont); - return true; - } - } - else - { - selectedFontGroup.AddFont(newfont); - return true; - } - } - - public InstalledFont GetFont(string fontName, string subFamName) - { - string upperCaseFontName = fontName.ToUpper(); - string upperCaseSubFamName = subFamName.ToUpper(); - - //find font group - if (_subFamToFontGroup.TryGetValue(upperCaseSubFamName, out FontGroup foundFontGroup)) - { - InstalledFont foundInstalledFont; - foundFontGroup.TryGetValue(upperCaseFontName, out foundInstalledFont); - return foundInstalledFont; - } - return null; //not found - } - - public InstalledFont GetFont(string fontName, InstalledFontStyle wellknownSubFam) - { - //not auto resolve - FontGroup selectedFontGroup; - switch (wellknownSubFam) - { - default: return null; - case InstalledFontStyle.Normal: selectedFontGroup = _normal; break; - case InstalledFontStyle.Bold: selectedFontGroup = _bold; break; - case InstalledFontStyle.Italic: selectedFontGroup = _italic; break; - case (InstalledFontStyle.Bold | InstalledFontStyle.Italic): selectedFontGroup = _bold_italic; break; - } - selectedFontGroup.TryGetValue(fontName.ToUpper(), out InstalledFont _found); - return _found; - } - //public FindResult GetFont(string fontName, InstalledFontStyle style, out InstalledFont found) - //{ - // //request font from installed font - // string upperCaseFontName = fontName.ToUpper(); - // FindResult result = FindResult.Matched; - // switch (style) - // { - // case (InstalledFontStyle.Bold | InstalledFontStyle.Italic): - // { - // //check if we have bold & italic - // //version of this font ? - // if (!_bold_italic.TryGetValue(upperCaseFontName, out found)) - // { - // //if not found then goto italic - // result = FindResult.Nearest; - // goto case InstalledFontStyle.Italic; - // } - // return result; - // } - // case InstalledFontStyle.Bold: - // { - - // if (!_bold.TryGetValue(upperCaseFontName, out found)) - // { - // //goto regular - // result = FindResult.Nearest; - // goto default; - // } - // return result; - // } - // case InstalledFontStyle.Italic: - // { - // //if not found then choose regular - // if (!_italic.TryGetValue(upperCaseFontName, out found)) - // { - // result = FindResult.Nearest; - // goto default; - // } - // return result; - // } - // default: - // { - // //we skip gras style ? - // if (!_normal.TryGetValue(upperCaseFontName, out found)) - // { - // if (fontNotFoundHandler != null) - // { - // result = FindResult.Nearest; - // found = fontNotFoundHandler( - // this, - // fontName, - // style); - // return (found == null) ? FindResult.NotFound : FindResult.Nearest; - // } - // return FindResult.NotFound; - // } - // return result; - // } - // } - //} - - - public IEnumerable GetInstalledFontIter() - { - foreach (FontGroup fontgroup in _allFontGroups) - { - foreach (InstalledFont f in fontgroup._members.Values) - { - yield return f; - } - } - } - } - - - public static class InstalledFontCollectionExtension - { - public static void LoadFontsFromFolder(this InstalledFontCollection fontCollection, string folder, bool recursive = false) - { - try - { - // 1. font dir - foreach (string file in Directory.GetFiles(folder)) - { - //eg. this is our custom font folder - string ext = Path.GetExtension(file).ToLower(); - switch (ext) - { - default: break; - case ".ttf": - case ".otf": - case ".ttc": - case ".otc": - case ".woff": - case ".woff2": - fontCollection.AddFont(new FontFileStreamProvider(file)); - break; - } - } - - //2. browse recursively; on Linux, fonts are organised in subdirectories - if (recursive) - { - foreach (string subfolder in Directory.GetDirectories(folder)) - { - LoadFontsFromFolder(fontCollection, subfolder, recursive); - } - } - - } - catch (DirectoryNotFoundException e) - { - return; - } - } - public static void LoadSystemFonts(this InstalledFontCollection fontCollection) - { - // Windows system fonts - LoadFontsFromFolder(fontCollection, "c:\\Windows\\Fonts"); - - // These are reasonable places to look for fonts on Linux - LoadFontsFromFolder(fontCollection, "/usr/share/fonts", true); - LoadFontsFromFolder(fontCollection, "/usr/share/wine/fonts", true); - LoadFontsFromFolder(fontCollection, "/usr/share/texlive/texmf-dist/fonts", true); - LoadFontsFromFolder(fontCollection, "/usr/share/texmf/fonts", true); - - // OS X system fonts (https://support.apple.com/en-us/HT201722) - LoadFontsFromFolder(fontCollection, "/System/Library/Fonts"); - LoadFontsFromFolder(fontCollection, "/Library/Fonts"); - } - } -} \ No newline at end of file diff --git a/Demo/Shared/DrawingGL.Common.projitems b/Demo/Shared/DrawingGL.Common.projitems index 852db0ab..136a4e82 100644 --- a/Demo/Shared/DrawingGL.Common.projitems +++ b/Demo/Shared/DrawingGL.Common.projitems @@ -9,15 +9,13 @@ DrawingGL.Common - - - + diff --git a/Demo/Shared/DrawingGL.Text/TextPrinter.cs b/Demo/Shared/DrawingGL.Text/TextPrinter.cs index c248e835..8ceaf243 100644 --- a/Demo/Shared/DrawingGL.Text/TextPrinter.cs +++ b/Demo/Shared/DrawingGL.Text/TextPrinter.cs @@ -57,7 +57,7 @@ public override void DrawFromGlyphPlans(GlyphPlanSequence glyphPlanList, int sta { throw new System.NotImplementedException(); } - public override GlyphLayout GlyphLayoutMan { get; } = new GlyphLayout(); + public override GlyphLayout GlyphLayoutMan { get; } = new GlyphLayout(null); // Refactor please public override Typeface Typeface { diff --git a/Demo/Shared/GlyphOutlineBuilder/GlyphOutlineBuilder.cs b/Demo/Shared/GlyphOutlineBuilder/GlyphOutlineBuilder.cs index 16845211..327ad4b5 100644 --- a/Demo/Shared/GlyphOutlineBuilder/GlyphOutlineBuilder.cs +++ b/Demo/Shared/GlyphOutlineBuilder/GlyphOutlineBuilder.cs @@ -1,4 +1,4 @@ -//MIT, 2016-present, WinterDev +//MIT, 2016-present, WinterDev diff --git a/Demo/Shared/GlyphPathBuilder/GlyphOutlineBuilder.cs b/Demo/Shared/GlyphPathBuilder/GlyphOutlineBuilder.cs deleted file mode 100644 index 16845211..00000000 --- a/Demo/Shared/GlyphPathBuilder/GlyphOutlineBuilder.cs +++ /dev/null @@ -1,15 +0,0 @@ -//MIT, 2016-present, WinterDev - - - -namespace Typography.Contours -{ - //----------------------------------- - //sample GlyphPathBuilder : - //for your flexiblity of glyph path builder. - //----------------------------------- - public class GlyphOutlineBuilder : GlyphOutlineBuilderBase - { - public GlyphOutlineBuilder(Typography.OpenFont.Typeface typeface) : base(typeface) { } - } -} \ No newline at end of file diff --git a/Demo/Shared/GlyphPathBuilder/GlyphOutlineBuilderBase.cs b/Demo/Shared/GlyphPathBuilder/GlyphOutlineBuilderBase.cs deleted file mode 100644 index c4c43c17..00000000 --- a/Demo/Shared/GlyphPathBuilder/GlyphOutlineBuilderBase.cs +++ /dev/null @@ -1,195 +0,0 @@ -//MIT, 2016-present, WinterDev - -using Typography.OpenFont; - -namespace Typography.Contours -{ - //----------------------------------- - //sample GlyphPathBuilder : - //for your flexiblity of glyph path builder. - //----------------------------------- - - - public abstract class GlyphOutlineBuilderBase - { - readonly Typeface _typeface; - TrueTypeInterpreter _trueTypeInterpreter; - protected GlyphPointF[] _outputGlyphPoints; - protected ushort[] _outputContours; - - protected OpenFont.CFF.Cff1Font _ownerCff; - protected OpenFont.CFF.Cff1GlyphData _cffGlyphData; - - /// - /// scale for converting latest glyph points to latest request font size - /// - float _recentPixelScale; - - Typography.OpenFont.CFF.CffEvaluationEngine _cffEvalEngine; - - public GlyphOutlineBuilderBase(Typeface typeface) - { - _typeface = typeface; - this.UseTrueTypeInstructions = true;//default? - _recentPixelScale = 1; - - if (typeface.IsCffFont) - { - _cffEvalEngine = new OpenFont.CFF.CffEvaluationEngine(); - } - } - public Typeface Typeface => _typeface; - /// - /// use Maxim's Agg Vertical Hinting - /// - public bool UseVerticalHinting { get; set; } - /// - /// process glyph with true type instructions - /// - public bool UseTrueTypeInstructions { get; set; } - - /// - /// build glyph shape from glyphIndex to be read - /// - /// - /// - public void BuildFromGlyphIndex(ushort glyphIndex, float sizeInPoints) - { - BuildFromGlyph(_typeface.GetGlyph(glyphIndex), sizeInPoints); - } - /// - /// build glyph shape from glyph to be read - /// - /// - /// - public void BuildFromGlyph(Glyph glyph, float sizeInPoints) - { - //for true type font - _outputGlyphPoints = glyph.GlyphPoints; - _outputContours = glyph.EndPoints; - - - //------------ - //temp fix for Cff Font - if (glyph.IsCffGlyph) - { - _cffGlyphData = glyph.GetCff1GlyphData(); - _ownerCff = glyph.GetOwnerCff(); - } - - //--------------- - - - - if ((RecentFontSizeInPixels = Typeface.ConvPointsToPixels(sizeInPoints)) < 0) - { - //convert to pixel size - //if size< 0 then set _recentPixelScale = 1; - //mean that no scaling at all, we use original point value - _recentPixelScale = 1; - } - else - { - _recentPixelScale = Typeface.CalculateScaleToPixel(RecentFontSizeInPixels); - HasSizeChanged = true; - } - //------------------------------------- - FitCurrentGlyph(glyph); - } - protected bool HasSizeChanged { get; set; } - protected float RecentFontSizeInPixels { get; private set; } - protected virtual void FitCurrentGlyph(Glyph glyph) - { - try - { - if (RecentFontSizeInPixels > 0 && UseTrueTypeInstructions && - _typeface.HasPrepProgramBuffer && - glyph.HasGlyphInstructions) - { - if (_trueTypeInterpreter == null) - { - _trueTypeInterpreter = new TrueTypeInterpreter(); - _trueTypeInterpreter.Typeface = _typeface; - } - _trueTypeInterpreter.UseVerticalHinting = this.UseVerticalHinting; - //output as points, - _outputGlyphPoints = _trueTypeInterpreter.HintGlyph(glyph.GlyphIndex, RecentFontSizeInPixels); - //*** - //all points are scaled from _trueTypeInterpreter, - //so not need further scale.=> set _recentPixelScale=1 - _recentPixelScale = 1; - } - } - catch (System.Exception ex) - { - - } - } - - public virtual void ReadShapes(IGlyphTranslator tx) - { - //read output from glyph points - if (_cffGlyphData != null) - { - _cffEvalEngine.Run(tx, _ownerCff, _cffGlyphData, _recentPixelScale); - } - else - { - tx.Read(_outputGlyphPoints, _outputContours, _recentPixelScale); - } - } - } - - public static class GlyphPathBuilderExtensions - { - public static void Build(this GlyphOutlineBuilderBase builder, char c, float sizeInPoints) - { - builder.BuildFromGlyphIndex((ushort)builder.Typeface.GetGlyphIndex(c), sizeInPoints); - } - public static void SetHintTechnique(this GlyphOutlineBuilderBase builder, HintTechnique hintTech) - { - - builder.UseTrueTypeInstructions = false;//reset - builder.UseVerticalHinting = false;//reset - switch (hintTech) - { - case HintTechnique.TrueTypeInstruction: - builder.UseTrueTypeInstructions = true; - break; - case HintTechnique.TrueTypeInstruction_VerticalOnly: - builder.UseTrueTypeInstructions = true; - builder.UseVerticalHinting = true; - break; - case HintTechnique.CustomAutoFit: - //custom agg autofit - builder.UseVerticalHinting = true; - break; - } - } - } - public enum HintTechnique : byte - { - /// - /// no hinting - /// - None, - /// - /// truetype instruction - /// - TrueTypeInstruction, - /// - /// truetype instruction vertical only - /// - TrueTypeInstruction_VerticalOnly, - /// - /// custom hint - /// - CustomAutoFit, - - /// - /// Cff instruction hint - /// - CffHintInstruction - - } -} \ No newline at end of file diff --git a/Demo/Windows/GdiPlusSample.WinForms/Form1.cs b/Demo/Windows/GdiPlusSample.WinForms/Form1.cs index 368ad699..d800bf64 100644 --- a/Demo/Windows/GdiPlusSample.WinForms/Form1.cs +++ b/Demo/Windows/GdiPlusSample.WinForms/Form1.cs @@ -6,7 +6,7 @@ // using Typography.TextLayout; using Typography.Contours; -using Typography.TextServices; +using Typography.FontManagement; using Typography.OpenFont; using Typography.OpenFont.Extensions; namespace SampleWinForms @@ -17,7 +17,7 @@ public partial class Form1 : Form //for this sample code, //create text printer env for developer. DevGdiTextPrinter _currentTextPrinter = new DevGdiTextPrinter(); - InstalledFontCollection installedFontCollection; + InstalledTypefaceCollection installedFontCollection; TypefaceStore _typefaceStore; public Form1() { @@ -51,7 +51,7 @@ public Form1() // //1. create font collection - installedFontCollection = new InstalledFontCollection(); + installedFontCollection = new InstalledTypefaceCollection(); //2. set some essential handler installedFontCollection.SetFontNameDuplicatedHandler((f1, f2) => FontNameDuplicatedDecision.Skip); @@ -61,11 +61,11 @@ public Form1() //---------- //show result - InstalledFont selectedFF = null; + InstalledTypeface selectedFF = null; int selected_index = 0; int ffcount = 0; bool found = false; - foreach (InstalledFont ff in installedFontCollection.GetInstalledFontIter()) + foreach (InstalledTypeface ff in installedFontCollection.GetInstalledFontIter()) { if (!found && ff.FontName == "Source Sans Pro") { @@ -78,8 +78,7 @@ public Form1() } //set default font for current text printer // - _typefaceStore = new TypefaceStore(); - _typefaceStore.FontCollection = installedFontCollection; + _typefaceStore = new TypefaceStore(installedFontCollection); //set default font for current text printer _currentTextPrinter.Typeface = _typefaceStore.GetTypeface(selectedFF); //---------- @@ -89,7 +88,7 @@ public Form1() lstFontList.SelectedIndex = selected_index; lstFontList.SelectedIndexChanged += (s, e) => { - InstalledFont ff = lstFontList.SelectedItem as InstalledFont; + InstalledTypeface ff = lstFontList.SelectedItem as InstalledTypeface; if (ff != null) { _currentTextPrinter.Typeface = _typefaceStore.GetTypeface(ff); diff --git a/Demo/Windows/GdiPlusSample.WinForms/GdiPlus/DevGdiTextPrinter.cs b/Demo/Windows/GdiPlusSample.WinForms/GdiPlus/DevGdiTextPrinter.cs index 379536ac..4f92e0ab 100644 --- a/Demo/Windows/GdiPlusSample.WinForms/GdiPlus/DevGdiTextPrinter.cs +++ b/Demo/Windows/GdiPlusSample.WinForms/GdiPlus/DevGdiTextPrinter.cs @@ -21,7 +21,7 @@ class DevGdiTextPrinter : TextPrinterBase Typeface _currentTypeface; GlyphOutlineBuilder _currentGlyphPathBuilder; GlyphTranslatorToGdiPath _txToGdiPath; - GlyphLayout _glyphLayout = new GlyphLayout(); + GlyphLayout _glyphLayout = new GlyphLayout(null); // To be refactored SolidBrush _fillBrush = new SolidBrush(Color.Black); Pen _outlinePen = new Pen(Color.Green); // diff --git a/Demo/Windows/GdiPlusSample.WinForms/GdiPlusSample.WinForms.csproj b/Demo/Windows/GdiPlusSample.WinForms/GdiPlusSample.WinForms.csproj index 288f833c..51e0b2bf 100644 --- a/Demo/Windows/GdiPlusSample.WinForms/GdiPlusSample.WinForms.csproj +++ b/Demo/Windows/GdiPlusSample.WinForms/GdiPlusSample.WinForms.csproj @@ -11,6 +11,8 @@ GdiPlusSample.WinForms v2.0 512 + 8.0 + CS8632 AnyCPU @@ -50,9 +52,6 @@ DevTextPrinter\TextBaseline.cs - - DevTextPrinter\FontManagement.cs - GlyphPathBuilder\GlyphOutlineBuilder.cs @@ -88,16 +87,11 @@ Settings.settings True - - - - {c6807d05-09be-4313-9f8b-bd2d51c55819} - Typography.GlyphLayout - - - {f7d71e61-9342-4dd7-9afd-69045f2ec98b} - Typography.OpenFont - + + + + + - \ No newline at end of file + diff --git a/Demo/Windows/PixelFarmTextBox.WinForms/Form1.cs b/Demo/Windows/PixelFarmTextBox.WinForms/Form1.cs index 55133933..b027f312 100644 --- a/Demo/Windows/PixelFarmTextBox.WinForms/Form1.cs +++ b/Demo/Windows/PixelFarmTextBox.WinForms/Form1.cs @@ -161,9 +161,8 @@ private void button1_Click(object sender, EventArgs e) _devVxsTextPrinter.UpdateGlyphLayoutSettings(); //------- - var editableTextBlockLayoutEngine = new EditableTextBlockLayoutEngine(); - editableTextBlockLayoutEngine.DefaultTypeface = _basicOptions.Typeface; - editableTextBlockLayoutEngine.FontSizeInPts = _basicOptions.FontSizeInPoints; + var editableTextBlockLayoutEngine = + new EditableTextBlockLayoutEngine(_basicOptions.Typeface, _basicOptions.FontSizeInPoints); editableTextBlockLayoutEngine.LoadText("ABCD\r\n EFGH!"); editableTextBlockLayoutEngine.DoLayout(); diff --git a/Demo/Windows/PixelFarmTextBox.WinForms/PixelFarmTextBox.WinForms.csproj b/Demo/Windows/PixelFarmTextBox.WinForms/PixelFarmTextBox.WinForms.csproj index ed2c82a5..1830d2b5 100644 --- a/Demo/Windows/PixelFarmTextBox.WinForms/PixelFarmTextBox.WinForms.csproj +++ b/Demo/Windows/PixelFarmTextBox.WinForms/PixelFarmTextBox.WinForms.csproj @@ -10,6 +10,7 @@ PixelFarmTextBox.WinForms v2.0 512 + 8.0 AnyCPU @@ -37,6 +38,19 @@ + + + + + + + {540a2ea6-dae3-4625-8951-b2c3118603a4} + PixelFarm.Typography + + + {9d2f3501-7705-4401-be13-a7613ca0c4bd} + TypographyTest.WinForms + @@ -93,31 +107,5 @@ True - - - {c6807d05-09be-4313-9f8b-bd2d51c55819} - Typography.GlyphLayout - - - {f7d71e61-9342-4dd7-9afd-69045f2ec98b} - Typography.OpenFont - - - {6b0e034b-0ebd-4907-ad7f-437de66d78d4} - Typography.TextServices - - - {540a2ea6-dae3-4625-8951-b2c3118603a4} - PixelFarm.Typography - - - {fb5f78f5-c921-405d-8f21-42f7c15c2ad9} - PixelFarm.MiniAgg.One - - - {9d2f3501-7705-4401-be13-a7613ca0c4bd} - TypographyTest.WinForms - - \ No newline at end of file diff --git a/Demo/Windows/TextBoxSample.WinForms/Form2.cs b/Demo/Windows/TextBoxSample.WinForms/Form2.cs index c81de073..58ff246b 100644 --- a/Demo/Windows/TextBoxSample.WinForms/Form2.cs +++ b/Demo/Windows/TextBoxSample.WinForms/Form2.cs @@ -7,7 +7,7 @@ using Typography.OpenFont; using Typography.TextLayout; using Typography.Contours; -using Typography.TextServices; +using Typography.FontManagement; namespace SampleWinForms @@ -19,7 +19,7 @@ public partial class Form2 : Form //create text printer env for developer. DevGdiTextPrinter _currentTextPrinter = new DevGdiTextPrinter(); SampleWinForms.UI.SampleTextBoxControllerForGdi _textBoxControllerForGdi = new UI.SampleTextBoxControllerForGdi(); - InstalledFontCollection installedFontCollection; + InstalledTypefaceCollection installedFontCollection; TypefaceStore _typefaceStore; public Form2() { @@ -60,25 +60,24 @@ public Form2() //---------- txtInputChar.TextChanged += (s, e) => UpdateRenderOutput(); //1. create font collection - installedFontCollection = new InstalledFontCollection(); + installedFontCollection = new InstalledTypefaceCollection(); //set some essential handler installedFontCollection.SetFontNameDuplicatedHandler((f1, f2) => FontNameDuplicatedDecision.Skip); foreach (string file in Directory.GetFiles("../../../TestFonts", "*.ttf")) { //eg. this is our custom font folder - installedFontCollection.AddFont(new FontFileStreamProvider(file)); + installedFontCollection.AddFontStreamSource(new FontFileStreamProvider(file)); } // - _typefaceStore = new TypefaceStore(); - _typefaceStore.FontCollection = installedFontCollection; + _typefaceStore = new TypefaceStore(installedFontCollection); //---------- //show result - InstalledFont selectedFF = null; + InstalledTypeface selectedFF = null; int selected_index = 0; int ffcount = 0; bool found = false; - foreach (InstalledFont ff in installedFontCollection.GetInstalledFontIter()) + foreach (InstalledTypeface ff in installedFontCollection.GetInstalledFontIter()) { if (!found && ff.FontName == "Source Sans Pro") { @@ -97,7 +96,7 @@ public Form2() lstFontList.SelectedIndex = selected_index; lstFontList.SelectedIndexChanged += (s, e) => { - InstalledFont ff = lstFontList.SelectedItem as InstalledFont; + InstalledTypeface ff = lstFontList.SelectedItem as InstalledTypeface; if (ff != null) { //direct set diff --git a/Demo/Windows/TextBoxSample.WinForms/TextBoxSample.WinForms.csproj b/Demo/Windows/TextBoxSample.WinForms/TextBoxSample.WinForms.csproj index 03b84df3..4a2c35af 100644 --- a/Demo/Windows/TextBoxSample.WinForms/TextBoxSample.WinForms.csproj +++ b/Demo/Windows/TextBoxSample.WinForms/TextBoxSample.WinForms.csproj @@ -10,6 +10,8 @@ TextBoxSample.WinForms v2.0 512 + 8.0 + CS8632 AnyCPU @@ -34,6 +36,11 @@ + + + + + @@ -48,9 +55,6 @@ DevTextPrinter\TextBaseline.cs - - DevTextPrinter\FontManagement.cs - GlyphOutlineBuilder\GlyphOutlineBuilder.cs @@ -105,19 +109,5 @@ True - - - {c6807d05-09be-4313-9f8b-bd2d51c55819} - Typography.GlyphLayout - - - {29ed0dfe-373c-4e98-bd4b-43f8e5fb16f6} - Typography.OpenFont - - - {333f3209-8da9-4d33-a560-299ed4c6dfa5} - Typography.TextFlow - - \ No newline at end of file diff --git a/Demo/Windows/TypographyTest.WinForms/BasicFontOptions.cs b/Demo/Windows/TypographyTest.WinForms/BasicFontOptions.cs index c3e17190..6fa1aca4 100644 --- a/Demo/Windows/TypographyTest.WinForms/BasicFontOptions.cs +++ b/Demo/Windows/TypographyTest.WinForms/BasicFontOptions.cs @@ -1,4 +1,4 @@ -//MIT, 2017-present, WinterDev +//MIT, 2017-present, WinterDev using System; using System.Collections.Generic; using System.IO; @@ -35,11 +35,6 @@ public BasicFontOptions() SelectedTypefaceStyle = TypefaceStyle.Regular; FontSizeInPoints = 10; this.RenderChoice = RenderChoice.RenderWithTextPrinterAndMiniAgg; - _textServices = new TextServices(); - _textServices.InstalledFontCollection = new InstalledTypefaceCollection(); - - _textServices.InstalledFontCollection.SetFontNameDuplicatedHandler( - (f0, f1) => FontNameDuplicatedDecision.Skip); } public RenderChoice RenderChoice @@ -49,6 +44,8 @@ public RenderChoice RenderChoice } public void LoadFontList() { + var collection = new InstalledTypefaceCollection(); + collection.SetFontNameDuplicatedHandler((f0, f1) => FontNameDuplicatedDecision.Skip); PositionTech = PositionTechnique.OpenFont; ////---------- ////1. create font collection @@ -78,7 +75,7 @@ public void LoadFontList() case ".otc": case ".ttf": case ".otf": - _textServices.InstalledFontCollection.AddFontStreamSource(new Typography.FontManagement.FontFileStreamProvider(file)); + collection.AddFontStreamSource(new Typography.FontManagement.FontFileStreamProvider(file)); break; } @@ -90,7 +87,7 @@ public void LoadFontList() index++; } - + _textServices = new TextServices(collection, ScriptLangs.Latin); } public PositionTechnique PositionTech { get; set; } diff --git a/Demo/Windows/TypographyTest.WinForms/TypographyTest.WinForms.csproj b/Demo/Windows/TypographyTest.WinForms/TypographyTest.WinForms.csproj index d0d08db1..f45b27c1 100644 --- a/Demo/Windows/TypographyTest.WinForms/TypographyTest.WinForms.csproj +++ b/Demo/Windows/TypographyTest.WinForms/TypographyTest.WinForms.csproj @@ -11,6 +11,7 @@ TypographyTest.WinForms v2.0 512 + 8.0 true @@ -75,26 +76,14 @@ - - {c6807d05-09be-4313-9f8b-bd2d51c55819} - Typography.GlyphLayout - - - {f7d71e61-9342-4dd7-9afd-69045f2ec98b} - Typography.OpenFont - - - {6b0e034b-0ebd-4907-ad7f-437de66d78d4} - Typography.TextServices - + + + + {540a2ea6-dae3-4625-8951-b2c3118603a4} PixelFarm.Typography - - {fb5f78f5-c921-405d-8f21-42f7c15c2ad9} - PixelFarm.MiniAgg.One - diff --git a/Demo/iOS/Xamarin.iOS.GLES2/Xamarin.IOS.GLES2.csproj b/Demo/iOS/Xamarin.iOS.GLES2/Xamarin.IOS.GLES2.csproj index 46c611ac..e6963ad9 100644 --- a/Demo/iOS/Xamarin.iOS.GLES2/Xamarin.IOS.GLES2.csproj +++ b/Demo/iOS/Xamarin.iOS.GLES2/Xamarin.IOS.GLES2.csproj @@ -9,6 +9,8 @@ Xamarin.iOS.GLES2 Resources Xamarin.iOS.GLES2 + latest + CS8632 true @@ -90,6 +92,12 @@ + + DevTextPrinter\FontManagement.cs + + + GlyphOutlineBuilder\GlyphOutlineBuilderBase.cs + @@ -115,18 +123,10 @@ + + - - - {c161ddea-0711-4d59-887c-c6a2fda2d74c} - Typography.GlyphLayout - - - {82d701b5-d844-4d5c-8643-26945adc2c5a} - Typography.OpenFont - - \ No newline at end of file diff --git a/PixelFarm.Typography/1_General/OpenFontTextService.cs b/PixelFarm.Typography/1_General/OpenFontTextService.cs index 1d011d80..9c3ac144 100644 --- a/PixelFarm.Typography/1_General/OpenFontTextService.cs +++ b/PixelFarm.Typography/1_General/OpenFontTextService.cs @@ -1,4 +1,4 @@ -//Apache2, 2014-present, WinterDev +//Apache2, 2014-present, WinterDev using System; using System.Collections.Generic; @@ -18,6 +18,7 @@ public class OpenFontTextService : ITextService /// instance of Typography lib's text service /// TextServices _txtServices; + ScriptLang _scLang; Dictionary _resolvedTypefaceCache = new Dictionary(); readonly int _system_id; // @@ -27,16 +28,6 @@ public OpenFontTextService(ScriptLang scLang = null) { _system_id = PixelFarm.Drawing.Internal.RequestFontCacheAccess.GetNewCacheSystemId(); - //set up typography text service - _txtServices = new TextServices(); - //default, user can set this later - - _txtServices.InstalledFontCollection = InstalledTypefaceCollection.GetSharedTypefaceCollection(collection => - { - collection.SetFontNameDuplicatedHandler((f0, f1) => FontNameDuplicatedDecision.Skip); - - }); - //create typography service //you can implement this service on your own @@ -61,10 +52,7 @@ public OpenFontTextService(ScriptLang scLang = null) { //TODO: handle error here } - - _txtServices.SetDefaultScriptLang(scLang); - _txtServices.CurrentScriptLang = scLang; - + _scLang = scLang; // ... or specific the scriptlang manully, eg. ... //_shapingServices.SetDefaultScriptLang(scLang); //_shapingServices.SetCurrentScriptLang(scLang); @@ -72,12 +60,22 @@ public OpenFontTextService(ScriptLang scLang = null) } public void LoadSystemFonts() { - _txtServices.InstalledFontCollection.LoadSystemFonts(); + var collection = InstalledTypefaceCollection.GetSharedTypefaceCollection(collection => + { + collection.SetFontNameDuplicatedHandler((f0, f1) => FontNameDuplicatedDecision.Skip); + }); + collection.LoadSystemFonts(); + _txtServices = new TextServices(collection, _scLang); } public void LoadFontsFromFolder(string folder) { - _txtServices.InstalledFontCollection.LoadFontsFromFolder(folder); + var collection = InstalledTypefaceCollection.GetSharedTypefaceCollection(collection => + { + collection.SetFontNameDuplicatedHandler((f0, f1) => FontNameDuplicatedDecision.Skip); + }); + collection.LoadFontsFromFolder(folder); + _txtServices = new TextServices(collection, _scLang); } static bool TryGetScriptLangFromCurrentThreadCultureInfo(out Typography.OpenFont.ScriptLang scLang) { @@ -118,7 +116,7 @@ public void CalculateUserCharGlyphAdvancePos(ref TextBufferSpan textBufferSpan, ref measureResult); } // - ReusableTextBuffer _reusableTextBuffer = new ReusableTextBuffer(); + ReusableTextBuffer _reusableTextBuffer; // public void CalculateUserCharGlyphAdvancePos(ref TextBufferSpan textBufferSpan, ILineSegmentList lineSegs, @@ -138,7 +136,9 @@ public void CalculateUserCharGlyphAdvancePos(ref TextBufferSpan textBufferSpan, int j = mylineSegs.Count; int pos = 0; //start at 0 - _reusableTextBuffer.SetRawCharBuffer(textBufferSpan.GetRawCharBuffer()); + if(_reusableTextBuffer == null) + _reusableTextBuffer = new ReusableTextBuffer(textBufferSpan.GetRawCharBuffer()); + else _reusableTextBuffer.SetRawCharBuffer(textBufferSpan.GetRawCharBuffer()); short minOffsetY = 0; short maxOffsetY = 0; @@ -225,7 +225,7 @@ public Typeface ResolveTypeface(RequestFont font) { //not found ask the typeface store to load that font //.... - typeface = _txtServices.GetTypeface(font.Name, PixelFarm.Drawing.FontStyleExtensions.ConvToInstalledFontStyle(font.Style)); + typeface = _txtServices?.GetTypeface(font.Name, PixelFarm.Drawing.FontStyleExtensions.ConvToInstalledFontStyle(font.Style)); if (typeface == null) { throw new NotSupportedException(font.Name); @@ -269,7 +269,9 @@ public GlyphPlanSequence CreateGlyphPlanSeq(ref TextBufferSpan textBufferSpan, R Typeface typeface = ResolveTypeface(font); _txtServices.SetCurrentFont(typeface, font.SizeInPoints); - _reusableTextBuffer.SetRawCharBuffer(textBufferSpan.GetRawCharBuffer()); + if (_reusableTextBuffer == null) + _reusableTextBuffer = new ReusableTextBuffer(textBufferSpan.GetRawCharBuffer()); + else _reusableTextBuffer.SetRawCharBuffer(textBufferSpan.GetRawCharBuffer()); return _txtServices.GetUnscaledGlyphPlanSequence(_reusableTextBuffer, textBufferSpan.start, textBufferSpan.len); } diff --git a/PixelFarm.Typography/1_General/VxsTextPrinter.cs b/PixelFarm.Typography/1_General/VxsTextPrinter.cs index b72d086d..cbfeaac4 100644 --- a/PixelFarm.Typography/1_General/VxsTextPrinter.cs +++ b/PixelFarm.Typography/1_General/VxsTextPrinter.cs @@ -36,6 +36,7 @@ public VxsTextPrinter(Painter painter, OpenFontTextService textService) this.PositionTechnique = PositionTechnique.OpenFont; // _textServices = textService; + textService.LoadFontsFromFolder("../../../TestFonts"); ChangeFont(new RequestFont("Source Sans Pro", 10)); _glyphBitmapStore = new GlyphBitmapStore(); diff --git a/PixelFarm.Typography/3_Typography_Contours/GlyphMeshCollection.cs b/PixelFarm.Typography/3_Typography_Contours/GlyphMeshCollection.cs index fcf7c037..1fc2e478 100644 --- a/PixelFarm.Typography/3_Typography_Contours/GlyphMeshCollection.cs +++ b/PixelFarm.Typography/3_Typography_Contours/GlyphMeshCollection.cs @@ -13,7 +13,7 @@ public class GlyphMeshCollection { //hint glyph collection //per typeface - Dictionary _currentGlyphDic = null; + Dictionary? _currentGlyphDic = null; Dictionary> _registerGlyphCollection = new Dictionary>(); public void SetCacheInfo(Typeface typeface, float sizeInPts, HintTechnique hintTech) @@ -31,10 +31,14 @@ public void SetCacheInfo(Typeface typeface, float sizeInPts, HintTechnique hintT } public bool TryGetCacheGlyph(ushort glyphIndex, out T vxs) { + if (_currentGlyphDic == null) + throw new System.InvalidOperationException(nameof(SetCacheInfo) + " not called"); return _currentGlyphDic.TryGetValue(glyphIndex, out vxs); } public void RegisterCachedGlyph(ushort glyphIndex, T vxs) { + if (_currentGlyphDic == null) + throw new System.InvalidOperationException(nameof(SetCacheInfo) + " not called"); _currentGlyphDic[glyphIndex] = vxs; } public void ClearAll() diff --git a/PixelFarm.Typography/3_Typography_Contours/GlyphOutlineBuilderBase.cs b/PixelFarm.Typography/3_Typography_Contours/GlyphOutlineBuilderBase.cs index c4c43c17..310ca5f2 100644 --- a/PixelFarm.Typography/3_Typography_Contours/GlyphOutlineBuilderBase.cs +++ b/PixelFarm.Typography/3_Typography_Contours/GlyphOutlineBuilderBase.cs @@ -1,5 +1,5 @@ //MIT, 2016-present, WinterDev - +#nullable enable using Typography.OpenFont; namespace Typography.Contours @@ -12,33 +12,26 @@ namespace Typography.Contours public abstract class GlyphOutlineBuilderBase { - readonly Typeface _typeface; - TrueTypeInterpreter _trueTypeInterpreter; - protected GlyphPointF[] _outputGlyphPoints; - protected ushort[] _outputContours; + TrueTypeInterpreter? _trueTypeInterpreter; + protected GlyphPointF[]? _outputGlyphPoints; + protected ushort[]? _outputContours; - protected OpenFont.CFF.Cff1Font _ownerCff; - protected OpenFont.CFF.Cff1GlyphData _cffGlyphData; + protected OpenFont.CFF.Cff1GlyphData? _cff; /// /// scale for converting latest glyph points to latest request font size /// float _recentPixelScale; - Typography.OpenFont.CFF.CffEvaluationEngine _cffEvalEngine; + Typography.OpenFont.CFF.CffEvaluationEngine? _cffEvalEngine; public GlyphOutlineBuilderBase(Typeface typeface) { - _typeface = typeface; + Typeface = typeface; this.UseTrueTypeInstructions = true;//default? _recentPixelScale = 1; - - if (typeface.IsCffFont) - { - _cffEvalEngine = new OpenFont.CFF.CffEvaluationEngine(); - } } - public Typeface Typeface => _typeface; + public Typeface Typeface { get; private set; } /// /// use Maxim's Agg Vertical Hinting /// @@ -55,7 +48,7 @@ public GlyphOutlineBuilderBase(Typeface typeface) /// public void BuildFromGlyphIndex(ushort glyphIndex, float sizeInPoints) { - BuildFromGlyph(_typeface.GetGlyph(glyphIndex), sizeInPoints); + BuildFromGlyph(Typeface.GetGlyph(glyphIndex), sizeInPoints); } /// /// build glyph shape from glyph to be read @@ -65,20 +58,17 @@ public void BuildFromGlyphIndex(ushort glyphIndex, float sizeInPoints) public void BuildFromGlyph(Glyph glyph, float sizeInPoints) { //for true type font - _outputGlyphPoints = glyph.GlyphPoints; - _outputContours = glyph.EndPoints; - - - //------------ - //temp fix for Cff Font - if (glyph.IsCffGlyph) + if (glyph.TtfWoffInfo is { } ttf) + (_outputContours, _outputGlyphPoints) = ttf; + else if (glyph.CffInfo is { } cff) { - _cffGlyphData = glyph.GetCff1GlyphData(); - _ownerCff = glyph.GetOwnerCff(); - } - - //--------------- + //------------ + //temp fix for Cff Font + _cff = cff; + //--------------- + } + else throw new System.NotImplementedException("Bitmap and SVG glyphs not implemented"); if ((RecentFontSizeInPixels = Typeface.ConvPointsToPixels(sizeInPoints)) < 0) @@ -103,13 +93,16 @@ protected virtual void FitCurrentGlyph(Glyph glyph) try { if (RecentFontSizeInPixels > 0 && UseTrueTypeInstructions && - _typeface.HasPrepProgramBuffer && + Typeface.HasPrepProgramBuffer && glyph.HasGlyphInstructions) { if (_trueTypeInterpreter == null) { - _trueTypeInterpreter = new TrueTypeInterpreter(); - _trueTypeInterpreter.Typeface = _typeface; + _trueTypeInterpreter = new TrueTypeInterpreter(Typeface); + } + else if (_trueTypeInterpreter.Typeface != Typeface) + { + _trueTypeInterpreter.Typeface = Typeface; } _trueTypeInterpreter.UseVerticalHinting = this.UseVerticalHinting; //output as points, @@ -120,7 +113,7 @@ protected virtual void FitCurrentGlyph(Glyph glyph) _recentPixelScale = 1; } } - catch (System.Exception ex) + catch { } @@ -129,14 +122,16 @@ protected virtual void FitCurrentGlyph(Glyph glyph) public virtual void ReadShapes(IGlyphTranslator tx) { //read output from glyph points - if (_cffGlyphData != null) + if (_cff is { } cff) { - _cffEvalEngine.Run(tx, _ownerCff, _cffGlyphData, _recentPixelScale); + _cffEvalEngine ??= new OpenFont.CFF.CffEvaluationEngine(); + _cffEvalEngine.Run(tx, cff, _recentPixelScale); } - else + else if (_outputGlyphPoints is { } points && _outputContours is { } contours) { - tx.Read(_outputGlyphPoints, _outputContours, _recentPixelScale); + tx.Read(points, contours, _recentPixelScale); } + else throw new System.InvalidOperationException($"{nameof(BuildFromGlyph)} not called"); } } diff --git a/PixelFarm.Typography/PixelFarm.Typography.csproj b/PixelFarm.Typography/PixelFarm.Typography.csproj index 7c8b30b3..b68bb6c2 100644 --- a/PixelFarm.Typography/PixelFarm.Typography.csproj +++ b/PixelFarm.Typography/PixelFarm.Typography.csproj @@ -11,6 +11,8 @@ PixelFarm.Typography v2.0 512 + 8.0 + CS8632 true @@ -34,28 +36,15 @@ - - - {c48f2c17-3c32-4f27-a96c-60a9d86df9cf} - Typography.GlyphLayout - - - {29ed0dfe-373c-4e98-bd4b-43f8e5fb16f6} - Typography.OpenFont - - - {6b0e034b-0ebd-4907-ad7f-437de66d78d4} - Typography.TextServices - - - {fb5f78f5-c921-405d-8f21-42f7c15c2ad9} - PixelFarm.MiniAgg.One - - + + + + + diff --git a/PixelFarm/BackEnd.BurningMineCurve/BurningMineCurve.csproj b/PixelFarm/BackEnd.BurningMineCurve/BurningMineCurve.csproj index 5254457f..1a7d281a 100644 --- a/PixelFarm/BackEnd.BurningMineCurve/BurningMineCurve.csproj +++ b/PixelFarm/BackEnd.BurningMineCurve/BurningMineCurve.csproj @@ -12,6 +12,8 @@ v4.7.2 512 + 8.0 + CS8632 true diff --git a/PixelFarm/BackEnd.PaintFx/PdnPixelEffectPixelFarm/BackEnd.PaintFx.csproj b/PixelFarm/BackEnd.PaintFx/PdnPixelEffectPixelFarm/BackEnd.PaintFx.csproj index c558a382..f998e201 100644 --- a/PixelFarm/BackEnd.PaintFx/PdnPixelEffectPixelFarm/BackEnd.PaintFx.csproj +++ b/PixelFarm/BackEnd.PaintFx/PdnPixelEffectPixelFarm/BackEnd.PaintFx.csproj @@ -11,6 +11,8 @@ PdnPixelEffectPixelFarm v2.0 512 + 8.0 + CS8632 true diff --git a/PixelFarm/BackEnd.Tesselate/BackEnd.Tesselate.csproj b/PixelFarm/BackEnd.Tesselate/BackEnd.Tesselate.csproj index f03b60fe..034dd492 100644 --- a/PixelFarm/BackEnd.Tesselate/BackEnd.Tesselate.csproj +++ b/PixelFarm/BackEnd.Tesselate/BackEnd.Tesselate.csproj @@ -33,6 +33,8 @@ 0.8.2 v2.0 + 8.0 + CS8632 True diff --git a/PixelFarm/BackEnd.Triangulation/BackEnd.Triangulation.csproj b/PixelFarm/BackEnd.Triangulation/BackEnd.Triangulation.csproj index d749cf45..02939932 100644 --- a/PixelFarm/BackEnd.Triangulation/BackEnd.Triangulation.csproj +++ b/PixelFarm/BackEnd.Triangulation/BackEnd.Triangulation.csproj @@ -17,6 +17,8 @@ 3.5 + 8.0 + CS8632 true diff --git a/PixelFarm/PaintLab.CssBase/PaintLab.CssBase.csproj b/PixelFarm/PaintLab.CssBase/PaintLab.CssBase.csproj index f8000104..af351757 100644 --- a/PixelFarm/PaintLab.CssBase/PaintLab.CssBase.csproj +++ b/PixelFarm/PaintLab.CssBase/PaintLab.CssBase.csproj @@ -12,6 +12,8 @@ v2.0 512 + 8.0 + CS8632 true diff --git a/PixelFarm/PaintLab.PaintFx/PaintLab.PaintFx.MiniAgg.csproj b/PixelFarm/PaintLab.PaintFx/PaintLab.PaintFx.MiniAgg.csproj index 995a6951..dff77d48 100644 --- a/PixelFarm/PaintLab.PaintFx/PaintLab.PaintFx.MiniAgg.csproj +++ b/PixelFarm/PaintLab.PaintFx/PaintLab.PaintFx.MiniAgg.csproj @@ -52,7 +52,7 @@ - + {fb5f78f5-c921-405d-8f21-42f7c15c2ad9} PixelFarm.MiniAgg.One diff --git a/PixelFarm/PaintLab.Svg/PaintLab.Svg.csproj b/PixelFarm/PaintLab.Svg/PaintLab.Svg.csproj index 26719275..1e199684 100644 --- a/PixelFarm/PaintLab.Svg/PaintLab.Svg.csproj +++ b/PixelFarm/PaintLab.Svg/PaintLab.Svg.csproj @@ -12,6 +12,8 @@ v2.0 512 + 8.0 + CS8632 true @@ -128,9 +130,6 @@ 0_REF_PaintLab.WebLexer\XmlLexer_debug.cs - - 0_REF_PaintLab.WebDom\Net20\ExtensionAttribute.cs - @@ -146,7 +145,7 @@ - + {fb5f78f5-c921-405d-8f21-42f7c15c2ad9} PixelFarm.MiniAgg.One @@ -156,4 +155,4 @@ - \ No newline at end of file + diff --git a/PixelFarm/PaintLab.WebDom/PaintLab.WebDom.csproj b/PixelFarm/PaintLab.WebDom/PaintLab.WebDom.csproj index 7fb93b92..a4a1e4cc 100644 --- a/PixelFarm/PaintLab.WebDom/PaintLab.WebDom.csproj +++ b/PixelFarm/PaintLab.WebDom/PaintLab.WebDom.csproj @@ -12,6 +12,8 @@ v2.0 512 + 8.0 + CS8632 true diff --git a/PixelFarm/PaintLab.WebLexer/PaintLab.WebLexer.csproj b/PixelFarm/PaintLab.WebLexer/PaintLab.WebLexer.csproj index 5026bac2..7ead8d76 100644 --- a/PixelFarm/PaintLab.WebLexer/PaintLab.WebLexer.csproj +++ b/PixelFarm/PaintLab.WebLexer/PaintLab.WebLexer.csproj @@ -12,6 +12,8 @@ v2.0 512 + 8.0 + CS8632 true diff --git a/PixelFarm/PixelFarm.CpuBlit/PixelFarm.CpuBlit.csproj b/PixelFarm/PixelFarm.CpuBlit/PixelFarm.CpuBlit.csproj index 84439ad2..0b36068f 100644 --- a/PixelFarm/PixelFarm.CpuBlit/PixelFarm.CpuBlit.csproj +++ b/PixelFarm/PixelFarm.CpuBlit/PixelFarm.CpuBlit.csproj @@ -13,6 +13,8 @@ v2.0 512 + 8.0 + CS8632 true @@ -114,4 +116,4 @@ --> - \ No newline at end of file + diff --git a/PixelFarm/PixelFarm.Drawing/PixelFarm.Drawing.csproj b/PixelFarm/PixelFarm.Drawing/PixelFarm.Drawing.csproj index 410034cc..31e95e22 100644 --- a/PixelFarm/PixelFarm.Drawing/PixelFarm.Drawing.csproj +++ b/PixelFarm/PixelFarm.Drawing/PixelFarm.Drawing.csproj @@ -1,6 +1,8 @@  - + + 8.0 + CS8632 Debug AnyCPU 8.0.30703 @@ -24,7 +26,6 @@ 4 true false - 7.3 pdbonly @@ -38,6 +39,7 @@ false + 0_REF_Painter\1_Vectors\4_BurningMineCurves\CubicBezier.cs @@ -251,7 +253,7 @@ 0_REF_DrawingCore\VertexStore.cs - + 0_REF_Painter\0_Base\ForNet20.cs @@ -643,4 +645,4 @@ --> - \ No newline at end of file + diff --git a/PixelFarm/PixelFarm.DrawingCore/PixelFarm.DrawingCore.csproj b/PixelFarm/PixelFarm.DrawingCore/PixelFarm.DrawingCore.csproj index fb31bd81..22e789cd 100644 --- a/PixelFarm/PixelFarm.DrawingCore/PixelFarm.DrawingCore.csproj +++ b/PixelFarm/PixelFarm.DrawingCore/PixelFarm.DrawingCore.csproj @@ -12,6 +12,8 @@ v2.0 512 + 8.0 + CS8632 true @@ -36,6 +38,7 @@ + diff --git a/PixelFarm/PixelFarm.Painter/PixelFarm.Painter.csproj b/PixelFarm/PixelFarm.Painter/PixelFarm.Painter.csproj index f30fd262..7f3652b6 100644 --- a/PixelFarm/PixelFarm.Painter/PixelFarm.Painter.csproj +++ b/PixelFarm/PixelFarm.Painter/PixelFarm.Painter.csproj @@ -12,6 +12,8 @@ v2.0 512 + 8.0 + CS8632 true @@ -155,7 +157,9 @@ 0_REF_Vectors\5_Clipper\ClipLiangBarsky.cs - + + 0_Base\ForNet20.cs + @@ -198,4 +202,4 @@ --> - \ No newline at end of file + diff --git a/PixelFarm/PixelFarm.PrimitiveGeo/PixelFarm.PrimitiveGeo.csproj b/PixelFarm/PixelFarm.PrimitiveGeo/PixelFarm.PrimitiveGeo.csproj index 9f76c3e4..19a7093d 100644 --- a/PixelFarm/PixelFarm.PrimitiveGeo/PixelFarm.PrimitiveGeo.csproj +++ b/PixelFarm/PixelFarm.PrimitiveGeo/PixelFarm.PrimitiveGeo.csproj @@ -11,6 +11,8 @@ PixelFarm.PrimitiveGeo v2.0 512 + 8.0 + CS8632 true diff --git a/PixelFarm/PixelFarm.Vectors/PixelFarm.Vectors.csproj b/PixelFarm/PixelFarm.Vectors/PixelFarm.Vectors.csproj index e7e89f38..391db03c 100644 --- a/PixelFarm/PixelFarm.Vectors/PixelFarm.Vectors.csproj +++ b/PixelFarm/PixelFarm.Vectors/PixelFarm.Vectors.csproj @@ -12,6 +12,8 @@ v2.0 512 + 8.0 + CS8632 true diff --git a/Typography.GlyphLayout/GlyphLayout.cs b/Typography.GlyphLayout/GlyphLayout.cs index 364bbf18..ad75dc8f 100644 --- a/Typography.GlyphLayout/GlyphLayout.cs +++ b/Typography.GlyphLayout/GlyphLayout.cs @@ -176,9 +176,9 @@ public GlyphLayoutPlanKey(Typeface t, int scriptInternameName) } struct GlyphLayoutPlanContext { - public readonly GlyphSubstitution _glyphSub; - public readonly GlyphSetPosition _glyphPos; - public GlyphLayoutPlanContext(GlyphSubstitution glyphSub, GlyphSetPosition glyphPos) + public readonly GlyphSubstitution? _glyphSub; + public readonly GlyphSetPosition? _glyphPos; + public GlyphLayoutPlanContext(GlyphSubstitution? glyphSub, GlyphSetPosition? glyphPos) { _glyphSub = glyphSub; _glyphPos = glyphPos; @@ -216,20 +216,22 @@ public class GlyphLayout GlyphLayoutPlanCollection _layoutPlanCollection = new GlyphLayoutPlanCollection(); Typeface _typeface; ScriptLang _scriptLang; - GlyphSubstitution _gsub; - GlyphSetPosition _gpos; + GlyphSubstitution? _gsub; + GlyphSetPosition? _gpos; bool _needPlanUpdate; GlyphIndexList _inputGlyphs = new GlyphIndexList();//reusable input glyph GlyphPosStream _glyphPositions = new GlyphPosStream(); - public GlyphLayout() + public GlyphLayout(Typeface typeface) { PositionTechnique = PositionTechnique.OpenFont; EnableLigature = true; EnableComposition = true; - ScriptLang = ScriptLangs.Latin; + _scriptLang = ScriptLangs.Latin; + _typeface = typeface; + _needPlanUpdate = true; } @@ -503,7 +505,7 @@ class GlyphPosStream : IGlyphPositions { List _glyphPosList = new List(); - Typeface _typeface; + Typeface? _typeface; public GlyphPosStream() { } public int Count => _glyphPosList.Count; @@ -513,13 +515,14 @@ public void Clear() _typeface = null; _glyphPosList.Clear(); } - public Typeface Typeface + public Typeface? Typeface { get => _typeface; set => _typeface = value; } public void AddGlyph(ushort o_offset, ushort glyphIndex, Glyph glyph) { + if (_typeface is null) throw new InvalidOperationException(nameof(Typeface) + " not set"); if (!glyph.HasOriginalAdvancedWidth) { //TODO: review here, diff --git a/Typography.GlyphLayout/GlyphPosition.cs b/Typography.GlyphLayout/GlyphPosition.cs index 7d7b99ed..2ed6023e 100644 --- a/Typography.GlyphLayout/GlyphPosition.cs +++ b/Typography.GlyphLayout/GlyphPosition.cs @@ -13,8 +13,8 @@ class GlyphSetPosition { readonly Typeface _typeface; - GPOS _gposTable; - internal List _lookupTables; + readonly GPOS? _gposTable; + internal List? _lookupTables; public GlyphSetPosition(Typeface typeface, string lang) { this.Lang = lang; @@ -24,12 +24,12 @@ public GlyphSetPosition(Typeface typeface, string lang) if (_gposTable == null) { return; } - ScriptTable scriptTable = _gposTable.ScriptList[lang]; + var scriptTable = _gposTable.ScriptList[lang]; //--------- if (scriptTable == null) { return; } // early exit if no lookup tables //--------- - ScriptTable.LangSysTable defaultLang = scriptTable.defaultLang; + var defaultLang = scriptTable.defaultLang; if (defaultLang == null) { return; } // early exit if no default language if (defaultLang.HasRequireFeature) diff --git a/Typography.GlyphLayout/GlyphSubstitution.cs b/Typography.GlyphLayout/GlyphSubstitution.cs index f5e0c82e..a352457e 100644 --- a/Typography.GlyphLayout/GlyphSubstitution.cs +++ b/Typography.GlyphLayout/GlyphSubstitution.cs @@ -88,24 +88,26 @@ internal void RebuildTables() _lookupTables.Clear(); // check if this lang has - GSUB gsubTable = _typeface.GSUBTable; - ScriptTable scriptTable = gsubTable.ScriptList[_language]; + var gsubTable = _typeface.GSUBTable; + if (gsubTable == null) return; + var scriptTable = gsubTable.ScriptList[_language]; if (scriptTable == null) { //no script table for request lang-> no lookup process here return; } - ScriptTable.LangSysTable selectedLang = null; + ScriptTable.LangSysTable selectedLang; if (scriptTable.langSysTables != null && scriptTable.langSysTables.Length > 0) { // TODO: review here selectedLang = scriptTable.langSysTables[0]; } - else + else if (scriptTable.defaultLang != null) { selectedLang = scriptTable.defaultLang; } + else return; if (selectedLang.HasRequireFeature) { @@ -184,7 +186,7 @@ static UnicodeLangBits[] FilterOnlySelectedRange(UnicodeLangBits[] inputRanges, } return selectedRanges.ToArray(); } - public static void CollectAllAssociateGlyphIndex(this Typeface typeface, List outputGlyphIndexList, ScriptLang scLang, UnicodeLangBits[] selectedRangs = null) + public static void CollectAllAssociateGlyphIndex(this Typeface typeface, List outputGlyphIndexList, ScriptLang scLang, UnicodeLangBits[]? selectedRangs = null) { //----------- //general glyph index in the unicode range @@ -192,7 +194,7 @@ public static void CollectAllAssociateGlyphIndex(this Typeface typeface, List s_glyphNameToUnicodeScalarValueDic = new Dictionary(); static Dictionary s_unicodeScalarValueToGlyphNameDic = new Dictionary(); static bool s_init = false; - public static string GetGlyphNameByUnicodeValue(int unicodeValue) + public static string? GetGlyphNameByUnicodeValue(int unicodeValue) { if (!s_init) { InitData(); } // - s_unicodeScalarValueToGlyphNameDic.TryGetValue(unicodeValue, out string glyphName); + s_unicodeScalarValueToGlyphNameDic.TryGetValue(unicodeValue, out string? glyphName); return glyphName; } public static int GetUnicodeValueByGlyphName(string glyphName) @@ -81,7 +81,7 @@ static void InitData() { using (StringReader strReader = new StringReader(glyphListTxt)) { - string line = strReader.ReadLine(); + string? line = strReader.ReadLine(); while (line != null) { //parse each line diff --git a/Typography.OpenFont/AdditionalInfo/MacPostFormat1.cs b/Typography.OpenFont/AdditionalInfo/MacPostFormat1.cs index bacca7d1..40558c4e 100644 --- a/Typography.OpenFont/AdditionalInfo/MacPostFormat1.cs +++ b/Typography.OpenFont/AdditionalInfo/MacPostFormat1.cs @@ -8,7 +8,7 @@ static class MacPostFormat1 { - static string[] s_stdMacGlyphNames; + static string[]? s_stdMacGlyphNames; public static string[] GetStdMacGlyphNames() { @@ -19,7 +19,7 @@ public static string[] GetStdMacGlyphNames() { string[] seps = new string[] { " " }; - string line = strReader.ReadLine(); + string? line = strReader.ReadLine(); while (line != null) { diff --git a/Typography.OpenFont/Glyph.cs b/Typography.OpenFont/Glyph.cs index 5e1d6388..2e04a562 100644 --- a/Typography.OpenFont/Glyph.cs +++ b/Typography.OpenFont/Glyph.cs @@ -8,22 +8,13 @@ namespace Typography.OpenFont public class Glyph { - //-------------------- - //ttf - GlyphPointF[] glyphPoints; - ushort[] _contourEndPoints; - ushort _orgAdvWidth; - bool _hasOrgAdvWidth; - - - Bounds _bounds; internal Glyph( GlyphPointF[] glyphPoints, ushort[] contourEndPoints, Bounds bounds, - byte[] glyphInstructions, + byte[]? glyphInstructions, ushort index) { //create from TTF @@ -31,21 +22,15 @@ internal Glyph( #if DEBUG this.dbugId = s_debugTotalId++; #endif - this.glyphPoints = glyphPoints; - _contourEndPoints = contourEndPoints; + TtfWoffInfo = (contourEndPoints, glyphPoints); Bounds = bounds; GlyphInstructions = glyphInstructions; GlyphIndex = index; } - public Bounds Bounds - { - get => _bounds; - internal set => _bounds = value; - } + public Bounds Bounds { get; internal set; } // - public ushort[] EndPoints => _contourEndPoints; - public GlyphPointF[] GlyphPoints => glyphPoints; + public (ushort[] endPoints, GlyphPointF[] glyphPoints)? TtfWoffInfo { get; private set; } // public ushort OriginalAdvanceWidth { @@ -53,37 +38,39 @@ public ushort OriginalAdvanceWidth set { _orgAdvWidth = value; - _hasOrgAdvWidth = true; + HasOriginalAdvancedWidth = true; } } - public bool HasOriginalAdvancedWidth => _hasOrgAdvWidth; + public bool HasOriginalAdvancedWidth { get; private set; } // internal static void OffsetXY(Glyph glyph, short dx, short dy) { - + if (!(glyph.TtfWoffInfo is var (_, glyphPoints))) + throw new NotSupportedException("Only TTF glyphs are supported"); //change data on current glyph - GlyphPointF[] glyphPoints = glyph.glyphPoints; for (int i = glyphPoints.Length - 1; i >= 0; --i) { glyphPoints[i] = glyphPoints[i].Offset(dx, dy); } //------------------------- - Bounds orgBounds = glyph._bounds; - glyph._bounds = new Bounds( + Bounds orgBounds = glyph.Bounds; + glyph.Bounds = new Bounds( (short)(orgBounds.XMin + dx), (short)(orgBounds.YMin + dy), (short)(orgBounds.XMax + dx), (short)(orgBounds.YMax + dy)); } - internal byte[] GlyphInstructions { get; set; } + public byte[]? GlyphInstructions { get; set; } public bool HasGlyphInstructions => this.GlyphInstructions != null; internal static void TransformNormalWith2x2Matrix(Glyph glyph, float m00, float m01, float m10, float m11) { + if (!(glyph.TtfWoffInfo is var (_, glyphPoints))) + throw new ArgumentException("Only TTF/WOFF glyphs are supported", nameof(glyph)); //http://stackoverflow.com/questions/13188156/whats-the-different-between-vector2-transform-and-vector2-transformnormal-i //http://www.technologicalutopia.com/sourcecode/xnageometry/vector2.cs.htm @@ -94,7 +81,6 @@ internal static void TransformNormalWith2x2Matrix(Glyph glyph, float m00, float float new_ymax = 0; - GlyphPointF[] glyphPoints = glyph.glyphPoints; for (int i = glyphPoints.Length - 1; i >= 0; --i) { GlyphPointF p = glyphPoints[i]; @@ -130,19 +116,25 @@ internal static void TransformNormalWith2x2Matrix(Glyph glyph, float m00, float } } //TODO: review here - glyph._bounds = new Bounds( + glyph.Bounds = new Bounds( (short)new_xmin, (short)new_ymin, (short)new_xmax, (short)new_ymax); } internal static Glyph Clone(Glyph original, ushort newGlyphIndex) { - return new Glyph( - Utils.CloneArray(original.glyphPoints), - Utils.CloneArray(original._contourEndPoints), - original.Bounds, - original.GlyphInstructions != null ? Utils.CloneArray(original.GlyphInstructions) : null, - newGlyphIndex); + if (original.TtfWoffInfo is var (endPoints, glyphPoints)) + return new Glyph( + Utils.CloneArray(glyphPoints), + Utils.CloneArray(endPoints), + original.Bounds, + original.GlyphInstructions != null ? Utils.CloneArray(original.GlyphInstructions) : null, + newGlyphIndex); + else if (original.CffInfo is { } data) + return new Glyph(data); + else if (original.BitmapSVGInfo is var (offset, len, format)) + return new Glyph(original.GlyphIndex, offset, len, format); + else throw new NotImplementedException(); } /// @@ -152,40 +144,42 @@ internal static Glyph Clone(Glyph original, ushort newGlyphIndex) /// internal static void AppendGlyph(Glyph dest, Glyph src) { - int org_dest_len = dest._contourEndPoints.Length; -#if DEBUG - int src_contour_count = src._contourEndPoints.Length; -#endif - - ushort org_last_point = (ushort)(dest._contourEndPoints[org_dest_len - 1] + 1); //since start at 0 - - dest.glyphPoints = Utils.ConcatArray(dest.glyphPoints, src.glyphPoints); - dest._contourEndPoints = Utils.ConcatArray(dest._contourEndPoints, src._contourEndPoints); + if (!(src.TtfWoffInfo is var (srcEndPoints, srcGlyphPoints))) + throw new ArgumentException("Only TTF/WOFF glyphs are supported", nameof(src)); + if (!(dest.TtfWoffInfo is var (destEndPoints, destGlyphPoints))) + throw new ArgumentException("Only TTF/WOFF glyphs are supported", nameof(src)); + int org_dest_len = destEndPoints.Length; + int src_contour_count = srcEndPoints.Length; + ushort org_last_point = (ushort)(destEndPoints[org_dest_len - 1] + 1); //since start at 0 + + destEndPoints = Utils.ConcatArray(destEndPoints, srcEndPoints); + destGlyphPoints = Utils.ConcatArray(destGlyphPoints, srcGlyphPoints); + dest.TtfWoffInfo = (destEndPoints, destGlyphPoints); //offset latest append contour end points - int newlen = dest._contourEndPoints.Length; + int newlen = destEndPoints.Length; for (int i = org_dest_len; i < newlen; ++i) { - dest._contourEndPoints[i] += (ushort)org_last_point; + destEndPoints[i] += org_last_point; } //calculate new bounds Bounds destBound = dest.Bounds; Bounds srcBound = src.Bounds; - short newXmin = (short)Math.Min(destBound.XMin, srcBound.XMin); - short newYMin = (short)Math.Min(destBound.YMin, srcBound.YMin); - short newXMax = (short)Math.Max(destBound.XMax, srcBound.XMax); - short newYMax = (short)Math.Max(destBound.YMax, srcBound.YMax); + short newXmin = Math.Min(destBound.XMin, srcBound.XMin); + short newYMin = Math.Min(destBound.YMin, srcBound.YMin); + short newXMax = Math.Max(destBound.XMax, srcBound.XMax); + short newYMax = Math.Max(destBound.YMax, srcBound.YMax); - dest._bounds = new Bounds(newXmin, newYMin, newXMax, newYMax); + dest.Bounds = new Bounds(newXmin, newYMin, newXMax, newYMax); } // public GlyphClassKind GlyphClass { get; set; } internal ushort MarkClassDef { get; set; } - public short MinX => _bounds.XMin; - public short MaxX => _bounds.XMax; - public short MinY => _bounds.YMin; - public short MaxY => _bounds.YMax; + public short MinX => Bounds.XMin; + public short MaxX => Bounds.XMax; + public short MinY => Bounds.YMin; + public short MaxY => Bounds.YMax; #if DEBUG @@ -199,15 +193,23 @@ internal static void AppendGlyph(Glyph dest, Glyph src) public override string ToString() { var stbuilder = new StringBuilder(); - if (IsCffGlyph) + if (CffInfo is { } cff) { stbuilder.Append("cff"); stbuilder.Append(",index=" + GlyphIndex); - stbuilder.Append(",name=" + _cff1GlyphData.Name); + stbuilder.Append(",name=" + cff.Name); + } + else if (BitmapSVGInfo is { } bitmapSvg) + { + stbuilder.Append("bitmapsvg"); + stbuilder.Append(",index=" + GlyphIndex); + stbuilder.Append(",offset=" + bitmapSvg.streamOffset); + stbuilder.Append(",len=" + bitmapSvg.streamLen); + stbuilder.Append(",format=" + bitmapSvg.imgFormat); } else { - stbuilder.Append("ttf"); + stbuilder.Append("ttfwoff"); stbuilder.Append(",index=" + GlyphIndex); stbuilder.Append(",class=" + GlyphClass.ToString()); if (MarkClassDef != 0) @@ -222,43 +224,29 @@ public override string ToString() //-------------------- //cff - internal CFF.Cff1Font _ownerCffFont; - internal CFF.Cff1GlyphData _cff1GlyphData; //temp - internal Glyph(CFF.Cff1Font owner, CFF.Cff1GlyphData cff1Glyph) + public CFF.Cff1GlyphData? CffInfo { get; } + internal Glyph(CFF.Cff1GlyphData cff1Glyph) { #if DEBUG this.dbugId = s_debugTotalId++; #endif - _ownerCffFont = owner; //create from CFF - _cff1GlyphData = cff1Glyph; + CffInfo = cff1Glyph; this.GlyphIndex = cff1Glyph.GlyphIndex; } - public bool IsCffGlyph => _ownerCffFont != null; - public CFF.Cff1Font GetOwnerCff() => _ownerCffFont; - public CFF.Cff1GlyphData GetCff1GlyphData() => _cff1GlyphData; //math glyph info, temp , TODO: review here again - public MathGlyphs.MathGlyphInfo MathGlyphInfo { get; internal set; } - public bool HasMathGlyphInfo { get; internal set; } - - + public MathGlyphs.MathGlyphInfo? MathGlyphInfo { get; internal set; } //-------------------- //Bitmap and Svg - uint _streamOffset; - uint _streamLen; - ushort _imgFormat; + internal (uint streamOffset, uint streamLen, ushort imgFormat)? BitmapSVGInfo { get; private set; } internal Glyph(ushort glyphIndex, uint streamOffset, uint streamLen, ushort imgFormat) { //_bmpGlyphSource = bmpGlyphSource; - _streamOffset = streamOffset; - _streamLen = streamLen; - _imgFormat = imgFormat; + BitmapSVGInfo = (streamOffset, streamLen, imgFormat); this.GlyphIndex = glyphIndex; } - internal uint BitmapStreamOffset => _streamOffset; - internal uint BitmapFormat => _imgFormat; //public void CopyBitmapContent(System.IO.Stream output) //{ diff --git a/Typography.OpenFont/IGlyphTranslator.cs b/Typography.OpenFont/IGlyphTranslator.cs index 4fb37534..17b3be13 100644 --- a/Typography.OpenFont/IGlyphTranslator.cs +++ b/Typography.OpenFont/IGlyphTranslator.cs @@ -412,10 +412,10 @@ static Vector2 GetMidPoint(Vector2 v0, float x1, float y1) } //----------- //for CFF1 - public static void Read(this IGlyphTranslator tx, CFF.Cff1Font cff1Font, CFF.Cff1GlyphData glyphData, float scale = 1) + public static void Read(this IGlyphTranslator tx, CFF.Cff1GlyphData glyphData, float scale = 1) { CFF.CffEvaluationEngine evalEngine = new CFF.CffEvaluationEngine(); - evalEngine.Run(tx, cff1Font, glyphData.GlyphInstructions, scale); + evalEngine.Run(tx, glyphData.GlyphInstructions, scale); } } diff --git a/Typography.OpenFont/OpenFontReader.cs b/Typography.OpenFont/OpenFontReader.cs index c0ba7077..c801c796 100644 --- a/Typography.OpenFont/OpenFontReader.cs +++ b/Typography.OpenFont/OpenFontReader.cs @@ -17,19 +17,20 @@ public enum ReadFlags Variation = 1 << 4 } - - public class PreviewFontInfo + public interface IPreviewFontInfo { + public string? Name { get; } + } + public class PreviewFontInfo : IPreviewFontInfo { - public readonly string Name; - public readonly string SubFamilyName; - public readonly string TypographicFamilyName; - public readonly string TypographicSubFamilyName; - public readonly Extensions.TranslatedOS2FontStyle OS2TranslatedStyle; - public readonly ushort Weight; - PreviewFontInfo[] _ttcfMembers; - - public PreviewFontInfo(string fontName, string fontSubFam, - string tFamilyName, string tSubFamilyName, + public string? Name { get; } + public string? SubFamilyName { get; } + public string? TypographicFamilyName { get; } + public string? TypographicSubFamilyName { get; } + public Extensions.TranslatedOS2FontStyle OS2TranslatedStyle { get; } + public ushort Weight { get; } + + public PreviewFontInfo(string? fontName, string? fontSubFam, + string? tFamilyName, string? tSubFamilyName, ushort weight, Extensions.TranslatedOS2FontStyle os2TranslatedStyle = Extensions.TranslatedOS2FontStyle.UNSET) { @@ -51,35 +52,26 @@ public PreviewFontInfo(string fontName, string fontSubFam, } #endif - Weight = weight; OS2TranslatedStyle = os2TranslatedStyle; } - public PreviewFontInfo(string fontName, PreviewFontInfo[] ttcfMembers) - { - Name = fontName; - SubFamilyName = ""; - _ttcfMembers = ttcfMembers; - } public int ActualStreamOffset { get; internal set; } public bool IsWebFont { get; internal set; } - public bool IsFontCollection => _ttcfMembers != null; - - /// - /// get font collection's member count - /// - public int MemberCount => _ttcfMembers.Length; - /// - /// get font collection's member - /// - /// - /// - public PreviewFontInfo GetMember(int index) => _ttcfMembers[index]; #if DEBUG - public override string ToString() + public override string ToString() => Name + ", " + SubFamilyName + ", " + OS2TranslatedStyle; +#endif + } + public class PreviewFontCollectionInfo : IPreviewFontInfo + { + public PreviewFontCollectionInfo(string fontName, PreviewFontInfo[] members) { - return (IsFontCollection) ? Name : Name + ", " + SubFamilyName + ", " + OS2TranslatedStyle; + Name = fontName; + Fonts = members; } + public string? Name { get; } + public PreviewFontInfo[] Fonts { get; } +#if DEBUG + public override string ToString() => Name ?? ""; #endif } @@ -134,6 +126,14 @@ class FontCollectionHeader public uint dsigTag; public uint dsigLength; public uint dsigOffset; + + public FontCollectionHeader(ushort majorVersion, ushort minorVersion, uint numFonts, int[] offsetTables) + { + this.majorVersion = majorVersion; + this.minorVersion = minorVersion; + this.numFonts = numFonts; + this.offsetTables = offsetTables; + } } static string BuildTtcfName(PreviewFontInfo[] members) @@ -147,6 +147,7 @@ static string BuildTtcfName(PreviewFontInfo[] members) for (uint i = 0; i < members.Length; ++i) { PreviewFontInfo member = members[i]; + if (member.Name is null) continue; if (!uniqueNames.ContainsKey(member.Name)) { uniqueNames.Add(member.Name, true); @@ -162,7 +163,7 @@ static string BuildTtcfName(PreviewFontInfo[] members) /// /// /// - public PreviewFontInfo ReadPreview(Stream stream) + public IPreviewFontInfo? ReadPreview(Stream stream) { //var little = BitConverter.IsLittleEndian; using (var input = new ByteOrderSwappingBinaryReader(stream)) @@ -181,7 +182,7 @@ public PreviewFontInfo ReadPreview(Stream stream) PreviewFontInfo member = members[i] = ReadActualFontPreview(input, false); member.ActualStreamOffset = ttcHeader.offsetTables[i]; } - return new PreviewFontInfo(BuildTtcfName(members), members); + return new PreviewFontCollectionInfo(BuildTtcfName(members), members); } else if (KnownFontFiles.IsWoff(majorVersion, minorVersion)) { @@ -225,10 +226,8 @@ FontCollectionHeader ReadTTCHeader(ByteOrderSwappingBinaryReader input) //uint32 dsigLength The length (in bytes) of the DSIG table (null if no signature) //uint32 dsigOffset The offset (in bytes) of the DSIG table from the beginning of the TTC file (null if no signature) - var ttcHeader = new FontCollectionHeader(); - - ttcHeader.majorVersion = input.ReadUInt16(); - ttcHeader.minorVersion = input.ReadUInt16(); + var majorVersion = input.ReadUInt16(); + var minorVersion = input.ReadUInt16(); uint numFonts = input.ReadUInt32(); int[] offsetTables = new int[numFonts]; for (uint i = 0; i < numFonts; ++i) @@ -236,8 +235,8 @@ FontCollectionHeader ReadTTCHeader(ByteOrderSwappingBinaryReader input) offsetTables[i] = input.ReadInt32(); } - ttcHeader.numFonts = numFonts; - ttcHeader.offsetTables = offsetTables; + var ttcHeader = new FontCollectionHeader(majorVersion, minorVersion, numFonts, offsetTables); + // if (ttcHeader.majorVersion == 2) { @@ -269,11 +268,12 @@ PreviewFontInfo ReadActualFontPreview(ByteOrderSwappingBinaryReader input, bool var tables = new TableEntryCollection(); for (int i = 0; i < tableCount; i++) { - tables.AddEntry(new UnreadTableEntry(ReadTableHeader(input))); + var unreadEntry = new UnreadTableEntry(ReadTableHeader(input)); + tables.AddEntry(unreadEntry.Name, unreadEntry); } return ReadPreviewFontInfo(tables, input); } - public Typeface Read(Stream stream, int streamStartOffset = 0, ReadFlags readFlags = ReadFlags.Full) + public Typeface? Read(Stream stream, int streamStartOffset = 0, ReadFlags readFlags = ReadFlags.Full) { //bool little = BitConverter.IsLittleEndian; @@ -320,7 +320,8 @@ public Typeface Read(Stream stream, int streamStartOffset = 0, ReadFlags readFla var tables = new TableEntryCollection(); for (int i = 0; i < tableCount; i++) { - tables.AddEntry(new UnreadTableEntry(ReadTableHeader(input))); + var unreadEntry = new UnreadTableEntry(ReadTableHeader(input)); + tables.AddEntry(unreadEntry.Name, unreadEntry); } //------------------------------------------------------------------ return ReadTableEntryCollection(tables, input); @@ -329,8 +330,8 @@ public Typeface Read(Stream stream, int streamStartOffset = 0, ReadFlags readFla internal PreviewFontInfo ReadPreviewFontInfo(TableEntryCollection tables, BinaryReader input) { - NameEntry nameEntry = ReadTableIfExists(tables, input, new NameEntry()); - OS2Table os2Table = ReadTableIfExists(tables, input, new OS2Table()); + var os2Table = ReadTableMandatory(tables, input, OS2Table.Name, (h, r) => new OS2Table(h, r)); + var nameEntry = ReadTableMandatory(tables, input, NameEntry.Name, (h, r) => new NameEntry(h, r)); return new PreviewFontInfo( nameEntry.FontName, @@ -342,70 +343,74 @@ internal PreviewFontInfo ReadPreviewFontInfo(TableEntryCollection tables, Binary } internal Typeface ReadTableEntryCollection(TableEntryCollection tables, BinaryReader input) { + // 8 mandatory tables: https://docs.microsoft.com/en-us/typography/opentype/spec/otff#required-tables + // Here, post is not treated as mandatory -> 7 mandatory tables + var os2Table = ReadTableMandatory(tables, input, OS2Table.Name, (h, r) => new OS2Table(h, r)); + var nameEntry = ReadTableMandatory(tables, input, NameEntry.Name, (h, r) => new NameEntry(h, r)); - OS2Table os2Table = ReadTableIfExists(tables, input, new OS2Table()); - NameEntry nameEntry = ReadTableIfExists(tables, input, new NameEntry()); - - Head header = ReadTableIfExists(tables, input, new Head()); - MaxProfile maximumProfile = ReadTableIfExists(tables, input, new MaxProfile()); - HorizontalHeader horizontalHeader = ReadTableIfExists(tables, input, new HorizontalHeader()); - HorizontalMetrics horizontalMetrics = ReadTableIfExists(tables, input, new HorizontalMetrics(horizontalHeader.HorizontalMetricsCount, maximumProfile.GlyphCount)); + var header = ReadTableMandatory(tables, input, Head.Name, (h, r) => new Head(h, r)); + var maximumProfile = ReadTableMandatory(tables, input, MaxProfile.Name, (h, r) => new MaxProfile(h, r)); + var horizontalHeader = ReadTableMandatory(tables, input, HorizontalHeader.Name, (h, r) => new HorizontalHeader(h, r)); + var horizontalMetrics = ReadTableMandatory(tables, input, HorizontalMetrics.Name, + (h, r) => new HorizontalMetrics(horizontalHeader.HorizontalMetricsCount, maximumProfile.GlyphCount, h, r)); //--- - PostTable postTable = ReadTableIfExists(tables, input, new PostTable()); - CFFTable cff = ReadTableIfExists(tables, input, new CFFTable()); + var postTable = ReadTableIfExists(tables, input, PostTable.Name, (h, r) => new PostTable(h, r)); + var cff = ReadTableIfExists(tables, input, CFFTable.Name, (h, r) => new CFFTable(h, r)); //-------------- - Cmap cmaps = ReadTableIfExists(tables, input, new Cmap()); - GlyphLocations glyphLocations = ReadTableIfExists(tables, input, new GlyphLocations(maximumProfile.GlyphCount, header.WideGlyphLocations)); + var cmaps = ReadTableMandatory(tables, input, Cmap.Name, (h, r) => new Cmap(h, r)); + var glyphLocations = ReadTableIfExists(tables, input, GlyphLocations.Name, + (h, r) => new GlyphLocations(maximumProfile.GlyphCount, header.WideGlyphLocations, h, r)); - Glyf glyf = ReadTableIfExists(tables, input, new Glyf(glyphLocations)); + var glyf = glyphLocations != null ? ReadTableIfExists(tables, input, Glyf.Name, (h, r) => new Glyf(glyphLocations, h, r)) : null; //-------------- - Gasp gaspTable = ReadTableIfExists(tables, input, new Gasp()); - VerticalDeviceMetrics vdmx = ReadTableIfExists(tables, input, new VerticalDeviceMetrics()); + var gaspTable = ReadTableIfExists(tables, input, Gasp.Name, (h, r) => new Gasp(h, r)); + var vdmx = ReadTableIfExists(tables, input, VerticalDeviceMetrics.Name, (h, r) => new VerticalDeviceMetrics(h, r)); //-------------- - Kern kern = ReadTableIfExists(tables, input, new Kern()); //deprecated + var kern = ReadTableIfExists(tables, input, Kern.Name, (h, r) => new Kern(h, r)); //deprecated //-------------- //advanced typography - GDEF gdef = ReadTableIfExists(tables, input, new GDEF()); - GSUB gsub = ReadTableIfExists(tables, input, new GSUB()); - GPOS gpos = ReadTableIfExists(tables, input, new GPOS()); - BASE baseTable = ReadTableIfExists(tables, input, new BASE()); - JSTF jstf = ReadTableIfExists(tables, input, new JSTF()); - - COLR colr = ReadTableIfExists(tables, input, new COLR()); - CPAL cpal = ReadTableIfExists(tables, input, new CPAL()); - VerticalHeader vhea = ReadTableIfExists(tables, input, new VerticalHeader()); + var gdef = ReadTableIfExists(tables, input, GDEF.Name, (h, r) => new GDEF(h, r)); + var gsub = ReadTableIfExists(tables, input, GSUB.Name, (h, r) => new GSUB(h, r)); + var gpos = ReadTableIfExists(tables, input, GPOS.Name, (h, r) => new GPOS(h, r)); + var baseTable = ReadTableIfExists(tables, input, BASE.Name, (h, r) => new BASE(h, r)); + var jstf = ReadTableIfExists(tables, input, JSTF.Name, (h, r) => new JSTF(h, r)); + + var colr = ReadTableIfExists(tables, input, COLR.Name, (h, r) => new COLR(h, r)); + var cpal = ReadTableIfExists(tables, input, CPAL.Name, (h, r) => new CPAL(h, r)); + var vhea = ReadTableIfExists(tables, input, VerticalHeader.Name, (h, r) => new VerticalHeader(h, r)); if (vhea != null) { - VerticalMetrics vmtx = ReadTableIfExists(tables, input, new VerticalMetrics(vhea.NumOfLongVerMetrics)); + var vmtx = ReadTableIfExists(tables, input, VerticalMetrics.Name, + (h, r) => new VerticalMetrics(vhea.NumOfLongVerMetrics, h, r)); } - STAT stat = ReadTableIfExists(tables, input, new STAT()); + var stat = ReadTableIfExists(tables, input, STAT.Name, (h, r) => new STAT(h, r)); if (stat != null) { - FVar fvar = ReadTableIfExists(tables, input, new FVar()); + var fvar = ReadTableIfExists(tables, input, FVar.Name, (h, r) => new FVar(h, r)); if (fvar != null) { - GVar gvar = ReadTableIfExists(tables, input, new GVar()); - CVar cvar = ReadTableIfExists(tables, input, new CVar()); - HVar hvar = ReadTableIfExists(tables, input, new HVar()); - MVar mvar = ReadTableIfExists(tables, input, new MVar()); - AVar avar = ReadTableIfExists(tables, input, new AVar()); + var gvar = ReadTableIfExists(tables, input, GVar.Name, (h, r) => new GVar(h, r)); + var cvar = ReadTableIfExists(tables, input, CVar.Name, (h, r) => new CVar(h, r)); + var hvar = ReadTableIfExists(tables, input, HVar.Name, (h, r) => new HVar(h, r)); + var mvar = ReadTableIfExists(tables, input, MVar.Name, (h, r) => new MVar(h, r)); + var avar = ReadTableIfExists(tables, input, AVar.Name, (h, r) => new AVar(h, r)); } } //test math table - MathTable mathtable = ReadTableIfExists(tables, input, new MathTable()); + var mathtable = ReadTableIfExists(tables, input, MathTable.Name, (h, r) => new MathTable(h, r)); //--------------------------------------------- //about truetype instruction init //--------------------------------------------- - Typeface typeface = null; + Typeface typeface; bool isPostScriptOutline = false; bool isBitmapFont = false; if (glyf == null) @@ -415,10 +420,11 @@ internal Typeface ReadTableEntryCollection(TableEntryCollection tables, BinaryRe { //check cbdt/cblc ? - CBLC cblcTable = ReadTableIfExists(tables, input, new CBLC()); + var cblcTable = ReadTableIfExists(tables, input, CBLC.Name, (h, r) => new CBLC(h, r)); if (cblcTable != null) { - CBDT cbdtTable = ReadTableIfExists(tables, input, new CBDT()); + var cbdtTable = ReadTableIfExists(tables, input, CBDT.Name, (h, r) => new CBDT(h, r)); + if (cbdtTable is null) throw new NotImplementedException($"{CBLC.Name} exists but not {CBDT.Name}"); //read cbdt //bitmap font @@ -427,19 +433,23 @@ internal Typeface ReadTableEntryCollection(TableEntryCollection tables, BinaryRe typeface = new Typeface( - nameEntry, - header.Bounds, - header.UnitsPerEm, - bmpFontGlyphSrc, - glyphs, - horizontalMetrics, - os2Table); + os2Table, + nameEntry, + header, + maximumProfile, + horizontalHeader, + horizontalMetrics, + cmaps, + glyphs) + { + BitmapFontGlyphSource = bmpFontGlyphSrc + }; isBitmapFont = true; } else { //TODO: - EBLC fontBmpTable = ReadTableIfExists(tables, input, new EBLC()); + var fontBmpTable = ReadTableIfExists(tables, input, EBLC.Name, (h, r) => new EBLC(h, r)); throw new NotSupportedException(); } } @@ -448,39 +458,46 @@ internal Typeface ReadTableEntryCollection(TableEntryCollection tables, BinaryRe //... //PostScript outline font isPostScriptOutline = true; + if (cff.Cff1FontSet is null) + throw new System.NotImplementedException("CFF2 not implemented"); + var cff1font = cff.Cff1FontSet._fonts[0]; typeface = new Typeface( - nameEntry, - header.Bounds, - header.UnitsPerEm, - cff, - horizontalMetrics, - os2Table); + os2Table, + nameEntry, + header, + maximumProfile, + horizontalHeader, + horizontalMetrics, + cmaps, + cff1font._glyphs) + { + CffTable = cff + }; } } else { typeface = new Typeface( - nameEntry, - header.Bounds, - header.UnitsPerEm, - glyf.Glyphs, - horizontalMetrics, - os2Table); + os2Table, + nameEntry, + header, + maximumProfile, + horizontalHeader, + horizontalMetrics, + cmaps, + glyf.Glyphs); } //---------------------------- - typeface.CmapTable = cmaps; typeface.KernTable = kern; typeface.GaspTable = gaspTable; - typeface.MaxProfile = maximumProfile; - typeface.HheaTable = horizontalHeader; //---------------------------- if (!isPostScriptOutline && !isBitmapFont) { - FpgmTable fpgmTable = ReadTableIfExists(tables, input, new FpgmTable()); + var fpgmTable = ReadTableIfExists(tables, input, FpgmTable.Name, (h, r) => new FpgmTable(h, r)); //control values table - CvtTable cvtTable = ReadTableIfExists(tables, input, new CvtTable()); + var cvtTable = ReadTableIfExists(tables, input, CvtTable.Name, (h, r) => new CvtTable(h, r)); if (cvtTable != null) { typeface.ControlValues = cvtTable._controlValues; @@ -489,7 +506,7 @@ internal Typeface ReadTableEntryCollection(TableEntryCollection tables, BinaryRe { typeface.FpgmProgramBuffer = fpgmTable._programBuffer; } - PrepTable propProgramTable = ReadTableIfExists(tables, input, new PrepTable()); + var propProgramTable = ReadTableIfExists(tables, input, PrepTable.Name, (h, r) => new PrepTable(h, r)); if (propProgramTable != null) { typeface.PrepProgramBuffer = propProgramTable._programBuffer; @@ -506,7 +523,7 @@ internal Typeface ReadTableEntryCollection(TableEntryCollection tables, BinaryRe //------------ { - SvgTable svgTable = ReadTableIfExists(tables, input, new SvgTable()); + var svgTable = ReadTableIfExists(tables, input, SvgTable.Name, (h, r) => new SvgTable(h, r)); if (svgTable != null) { typeface._svgTable = svgTable; @@ -541,34 +558,32 @@ static TableHeader ReadTableHeader(BinaryReader input) input.ReadUInt32(), input.ReadUInt32()); } - static T ReadTableIfExists(TableEntryCollection tables, BinaryReader reader, T resultTable) - where T : TableEntry + internal delegate T TableReader(TableHeader header, BinaryReader reader); + static T ReadTableMandatory(TableEntryCollection tables, BinaryReader reader, string name, TableReader tableReader) + where T : TableEntry => + ReadTableIfExists(tables, reader, name, tableReader) ?? throw new NotSupportedException("Missing mandatory table in font file: " + name); + static T? ReadTableIfExists(TableEntryCollection tables, BinaryReader reader, string name, TableReader tableReader) + where T : notnull, TableEntry { - - if (tables.TryGetTable(resultTable.Name, out TableEntry found)) + if (tables.TryGetTable(name, out TableEntry? found)) { //found table name //check if we have read this table or not if (found is UnreadTableEntry unreadTableEntry) { - //set header before actal read - resultTable.Header = found.Header; - if (unreadTableEntry.HasCustomContentReader) - { - resultTable = unreadTableEntry.CreateTableEntry(reader, resultTable); - } - else - { - resultTable.LoadDataFrom(reader); - } + //set header before actual read + T resultTable = + unreadTableEntry.HasCustomContentReader + ? unreadTableEntry.CreateTableEntry(reader, tableReader) + : tableReader(found.Header, reader); //then replace - tables.ReplaceTable(resultTable); + tables.ReplaceTable(name, resultTable); return resultTable; } else { //we have read this table - throw new NotSupportedException(); + throw new InvalidOperationException("Table cannot be read more than once: " + name); } } //not found diff --git a/Typography.OpenFont/Tables.AdvancedLayout/AttachmentListTable.cs b/Typography.OpenFont/Tables.AdvancedLayout/AttachmentListTable.cs index 73dcf632..4580b888 100644 --- a/Typography.OpenFont/Tables.AdvancedLayout/AttachmentListTable.cs +++ b/Typography.OpenFont/Tables.AdvancedLayout/AttachmentListTable.cs @@ -29,8 +29,8 @@ namespace Typography.OpenFont.Tables class AttachmentListTable { - AttachPoint[] _attachPoints; - public CoverageTable CoverageTable { get; private set; } + AttachPoint[]? _attachPoints; + public CoverageTable? CoverageTable { get; private set; } public static AttachmentListTable CreateFrom(BinaryReader reader, long beginAt) { AttachmentListTable attachmentListTable = new AttachmentListTable(); diff --git a/Typography.OpenFont/Tables.AdvancedLayout/Base.cs b/Typography.OpenFont/Tables.AdvancedLayout/Base.cs index b9defbac..5e0358d8 100644 --- a/Typography.OpenFont/Tables.AdvancedLayout/Base.cs +++ b/Typography.OpenFont/Tables.AdvancedLayout/Base.cs @@ -12,13 +12,12 @@ namespace Typography.OpenFont.Tables { public class BASE : TableEntry { - public const string _N = "BASE"; - public override string Name => _N; + public const string Name = "BASE"; - public AxisTable _horizontalAxis; - public AxisTable _verticalAxis; + public AxisTable? _horizontalAxis; + public AxisTable? _verticalAxis; - protected override void ReadContentFrom(BinaryReader reader) + internal BASE(TableHeader header, BinaryReader reader) : base(header, reader) { //BASE Header @@ -92,8 +91,8 @@ protected override void ReadContentFrom(BinaryReader reader) public class AxisTable { public bool isVerticalAxis; //false = horizontal , true= verical axis - public string[] baseTagList; - public BaseScript[] baseScripts; + public string[]? baseTagList; + public BaseScript[]? baseScripts; #if DEBUG public override string ToString() { @@ -256,8 +255,7 @@ static BaseScript[] ReadBaseScriptList(BinaryReader reader) BaseScriptRecord baseScriptRecord = baseScriptRecord_offsets[i]; reader.BaseStream.Position = baseScriptListStartAt + baseScriptRecord.baseScriptOffset; // - BaseScript baseScipt = ReadBaseScriptTable(reader); - baseScipt.ScriptIdenTag = baseScriptRecord.baseScriptTag; + BaseScript baseScipt = ReadBaseScriptTable(reader, baseScriptRecord.baseScriptTag); baseScripts[i] = baseScipt; } return baseScripts; @@ -287,9 +285,9 @@ public class BaseScript { public string ScriptIdenTag; public BaseValues baseValues; - public BaseLangSysRecord[] baseLangSysRecords; - public MinMax MinMax; - public BaseScript() { } + public BaseLangSysRecord[]? baseLangSysRecords; + public MinMax? MinMax; + public BaseScript(string scriptIdenTag) => ScriptIdenTag = scriptIdenTag; #if DEBUG public override string ToString() @@ -298,7 +296,7 @@ public override string ToString() } #endif } - static BaseScript ReadBaseScriptTable(BinaryReader reader) + static BaseScript ReadBaseScriptTable(BinaryReader reader, string scriptIdenTag) { //BaseScript Table //A BaseScript table organizes and specifies the baseline data and min/max extent data for one script. @@ -321,7 +319,7 @@ static BaseScript ReadBaseScriptTable(BinaryReader reader) ushort baseValueOffset = reader.ReadUInt16(); ushort defaultMinMaxOffset = reader.ReadUInt16(); ushort baseLangSysCount = reader.ReadUInt16(); - BaseLangSysRecord[] baseLangSysRecords = null; + BaseLangSysRecord[]? baseLangSysRecords = null; if (baseLangSysCount > 0) { @@ -341,7 +339,7 @@ static BaseScript ReadBaseScriptTable(BinaryReader reader) } } - BaseScript baseScript = new BaseScript(); + BaseScript baseScript = new BaseScript(scriptIdenTag); baseScript.baseLangSysRecords = baseLangSysRecords; //-------------------- if (baseValueOffset > 0) @@ -559,7 +557,7 @@ static MinMax ReadMinMaxTable(BinaryReader reader) ushort maxCoordOffset = reader.ReadUInt16(); ushort featMinMaxCount = reader.ReadUInt16(); - FeatureMinMaxOffset[] minMaxFeatureOffsets = null; + FeatureMinMaxOffset[]? minMaxFeatureOffsets = null; if (featMinMaxCount > 0) { minMaxFeatureOffsets = new FeatureMinMaxOffset[featMinMaxCount]; @@ -613,7 +611,7 @@ public class MinMax { public BaseCoord minCoord; public BaseCoord maxCoord; - public FeatureMinMax[] featureMinMaxRecords; + public FeatureMinMax[]? featureMinMaxRecords; } public struct FeatureMinMax { diff --git a/Typography.OpenFont/Tables.AdvancedLayout/COLR.cs b/Typography.OpenFont/Tables.AdvancedLayout/COLR.cs index c87c6f7c..6bf10303 100644 --- a/Typography.OpenFont/Tables.AdvancedLayout/COLR.cs +++ b/Typography.OpenFont/Tables.AdvancedLayout/COLR.cs @@ -9,12 +9,11 @@ namespace Typography.OpenFont.Tables { public class COLR : TableEntry { - public const string _N = "COLR"; - public override string Name => _N; + public const string Name = "COLR"; // Read the COLR table // https://www.microsoft.com/typography/otspec/colr.htm - protected override void ReadContentFrom(BinaryReader reader) + internal COLR(TableHeader header, BinaryReader reader) : base(header, reader) { long offset = reader.BaseStream.Position; @@ -42,8 +41,8 @@ protected override void ReadContentFrom(BinaryReader reader) } } - public ushort[] GlyphLayers { get; private set; } - public ushort[] GlyphPalettes { get; private set; } + public ushort[]? GlyphLayers { get; private set; } + public ushort[]? GlyphPalettes { get; private set; } public readonly Dictionary LayerIndices = new Dictionary(); public readonly Dictionary LayerCounts = new Dictionary(); } diff --git a/Typography.OpenFont/Tables.AdvancedLayout/CPAL.cs b/Typography.OpenFont/Tables.AdvancedLayout/CPAL.cs index e9796d99..78a12fa8 100644 --- a/Typography.OpenFont/Tables.AdvancedLayout/CPAL.cs +++ b/Typography.OpenFont/Tables.AdvancedLayout/CPAL.cs @@ -8,14 +8,13 @@ namespace Typography.OpenFont.Tables { public class CPAL : TableEntry { - public const string _N = "CPAL"; - public override string Name => _N; + public const string Name = "CPAL"; // byte[] _colorBGRABuffer; // Read the CPAL table // https://www.microsoft.com/typography/otspec/cpal.htm - protected override void ReadContentFrom(BinaryReader reader) + internal CPAL(TableHeader header, BinaryReader reader) : base(header, reader) { long offset = reader.BaseStream.Position; diff --git a/Typography.OpenFont/Tables.AdvancedLayout/ClassDefTable.cs b/Typography.OpenFont/Tables.AdvancedLayout/ClassDefTable.cs index 4cf78088..be74afb7 100644 --- a/Typography.OpenFont/Tables.AdvancedLayout/ClassDefTable.cs +++ b/Typography.OpenFont/Tables.AdvancedLayout/ClassDefTable.cs @@ -92,14 +92,12 @@ namespace Typography.OpenFont.Tables //--------------------------------------- class ClassDefTable { - public int Format { get; internal set; } //---------------- //format 1 - public ushort startGlyph; - public ushort[] classValueArray; + public (ushort startGlyph, ushort[] classValueArray)? format1; //--------------- //format2 - public ClassRangeRecord[] records; + public ClassRangeRecord[]? format2; public static ClassDefTable CreateFrom(BinaryReader reader, long beginAt) { @@ -107,14 +105,15 @@ public static ClassDefTable CreateFrom(BinaryReader reader, long beginAt) //--------- ClassDefTable classDefTable = new ClassDefTable(); - switch (classDefTable.Format = reader.ReadUInt16()) + switch (reader.ReadUInt16()) { default: throw new NotSupportedException(); case 1: { - classDefTable.startGlyph = reader.ReadUInt16(); + var startGlyph = reader.ReadUInt16(); ushort glyphCount = reader.ReadUInt16(); - classDefTable.classValueArray = Utils.ReadUInt16Array(reader, glyphCount); + var classValueArray = Utils.ReadUInt16Array(reader, glyphCount); + classDefTable.format1 = (startGlyph, classValueArray); } break; case 2: @@ -128,7 +127,7 @@ public static ClassDefTable CreateFrom(BinaryReader reader, long beginAt) reader.ReadUInt16(), //end glyph id reader.ReadUInt16()); //classNo } - classDefTable.records = records; + classDefTable.format2 = records; } break; } @@ -165,41 +164,36 @@ public override string ToString() public int GetClassValue(ushort glyphIndex) { - switch (Format) + if (format1 is var (startGlyph, classValueArray)) { - default: throw new NotSupportedException(); - case 1: + if (glyphIndex >= startGlyph && + glyphIndex < classValueArray.Length) + { + return classValueArray[glyphIndex - startGlyph]; + } + return -1; + } + else if (format2 is { } records) + { + for (int i = 0; i < records?.Length; ++i) + { + //TODO: review a proper method here again + //esp. binary search + ClassRangeRecord rec = records[i]; + if (rec.startGlyphId <= glyphIndex) { - if (glyphIndex >= startGlyph && - glyphIndex < classValueArray.Length) + if (glyphIndex <= rec.endGlyphId) { - return classValueArray[glyphIndex - startGlyph]; + return rec.classNo; } - return -1; } - case 2: + else { - - for (int i = 0; i < records.Length; ++i) - { - //TODO: review a proper method here again - //esp. binary search - ClassRangeRecord rec = records[i]; - if (rec.startGlyphId <= glyphIndex) - { - if (glyphIndex <= rec.endGlyphId) - { - return rec.classNo; - } - } - else - { - return -1;//no need to go further - } - } - return -1; + return -1;//no need to go further } - } + } + return -1; + } else throw new NotImplementedException(); } } diff --git a/Typography.OpenFont/Tables.AdvancedLayout/CoverageTable.cs b/Typography.OpenFont/Tables.AdvancedLayout/CoverageTable.cs index e4570a72..079f3cf4 100644 --- a/Typography.OpenFont/Tables.AdvancedLayout/CoverageTable.cs +++ b/Typography.OpenFont/Tables.AdvancedLayout/CoverageTable.cs @@ -50,7 +50,7 @@ public static CoverageFmt1 CreateFrom(BinaryReader reader) ushort glyphCount = reader.ReadUInt16(); ushort[] glyphs = Utils.ReadUInt16Array(reader, glyphCount); - return new CoverageFmt1() { _orderedGlyphIdList = glyphs }; + return new CoverageFmt1(glyphs); } public override int FindPosition(ushort glyphIndex) @@ -76,6 +76,11 @@ public override string ToString() #endif internal ushort[] _orderedGlyphIdList; + + public CoverageFmt1(ushort[] orderedGlyphIdList) + { + _orderedGlyphIdList = orderedGlyphIdList; + } } public class CoverageFmt2 : CoverageTable @@ -130,12 +135,7 @@ public static CoverageFmt2 CreateFrom(BinaryReader reader) coverageIndices[i] = reader.ReadUInt16(); } - return new CoverageFmt2() - { - _startIndices = startIndices, - _endIndices = endIndices, - _coverageIndices = coverageIndices - }; + return new CoverageFmt2(startIndices, endIndices, coverageIndices); } #if DEBUG @@ -155,6 +155,13 @@ public override string ToString() internal ushort[] _endIndices; internal ushort[] _coverageIndices; + public CoverageFmt2(ushort[] startIndices, ushort[] endIndices, ushort[] coverageIndices) + { + _startIndices = startIndices; + _endIndices = endIndices; + _coverageIndices = coverageIndices; + } + private int RangeCount => _startIndices.Length; } diff --git a/Typography.OpenFont/Tables.AdvancedLayout/FeatureList.cs b/Typography.OpenFont/Tables.AdvancedLayout/FeatureList.cs index 9e94629c..6b389c60 100644 --- a/Typography.OpenFont/Tables.AdvancedLayout/FeatureList.cs +++ b/Typography.OpenFont/Tables.AdvancedLayout/FeatureList.cs @@ -28,8 +28,13 @@ namespace Typography.OpenFont.Tables public class FeatureList { - public FeatureTable[] featureTables; + + public FeatureList(FeatureTable[] featureTables) + { + this.featureTables = featureTables; + } + public static FeatureList CreateFrom(BinaryReader reader, long beginAt) { //https://www.microsoft.com/typography/otspec/chapter2.htm @@ -49,7 +54,6 @@ public static FeatureList CreateFrom(BinaryReader reader, long beginAt) //---------------------------------------------------- reader.BaseStream.Seek(beginAt, SeekOrigin.Begin); // - FeatureList featureList = new FeatureList(); ushort featureCount = reader.ReadUInt16(); FeatureRecord[] featureRecords = new FeatureRecord[featureCount]; for (int i = 0; i < featureCount; ++i) @@ -60,13 +64,13 @@ public static FeatureList CreateFrom(BinaryReader reader, long beginAt) reader.ReadUInt16()); //Offset16 } //read each feature table - FeatureTable[] featureTables = featureList.featureTables = new FeatureTable[featureCount]; + FeatureTable[] featureTables = new FeatureTable[featureCount]; for (int i = 0; i < featureCount; ++i) { FeatureRecord frecord = featureRecords[i]; (featureTables[i] = FeatureTable.CreateFrom(reader, beginAt + frecord.offset)).FeatureTag = frecord.featureTag; } - return featureList; + return new FeatureList(featureTables); } struct FeatureRecord { @@ -133,6 +137,12 @@ public class FeatureTable //-------------------------- ushort[] _lookupListIndices; + + public FeatureTable(ushort[] lookupListIndices) + { + _lookupListIndices = lookupListIndices; + } + public static FeatureTable CreateFrom(BinaryReader reader, long beginAt) { reader.BaseStream.Seek(beginAt, SeekOrigin.Begin); @@ -140,8 +150,7 @@ public static FeatureTable CreateFrom(BinaryReader reader, long beginAt) ushort featureParams = reader.ReadUInt16(); ushort lookupCount = reader.ReadUInt16(); - FeatureTable featureTable = new FeatureTable(); - featureTable._lookupListIndices = Utils.ReadUInt16Array(reader, lookupCount); + FeatureTable featureTable = new FeatureTable(Utils.ReadUInt16Array(reader, lookupCount)); return featureTable; } public ushort[] LookupListIndices => _lookupListIndices; diff --git a/Typography.OpenFont/Tables.AdvancedLayout/GDEF.cs b/Typography.OpenFont/Tables.AdvancedLayout/GDEF.cs index 5ed1bad2..a4aca0a3 100644 --- a/Typography.OpenFont/Tables.AdvancedLayout/GDEF.cs +++ b/Typography.OpenFont/Tables.AdvancedLayout/GDEF.cs @@ -64,11 +64,10 @@ namespace Typography.OpenFont.Tables class GDEF : TableEntry { - public const string _N = "GDEF"; - public override string Name => _N; + public const string Name = "GDEF"; // long _tableStartAt; - protected override void ReadContentFrom(BinaryReader reader) + public GDEF(TableHeader header, BinaryReader reader) : base(header, reader) { _tableStartAt = reader.BaseStream.Position; //----------------------------------------- @@ -164,11 +163,11 @@ protected override void ReadContentFrom(BinaryReader reader) } public int MajorVersion { get; private set; } public int MinorVersion { get; private set; } - public ClassDefTable GlyphClassDef { get; private set; } - public AttachmentListTable AttachmentListTable { get; private set; } - public LigCaretList LigCaretList { get; private set; } - public ClassDefTable MarkAttachmentClassDef { get; private set; } - public MarkGlyphSetsTable MarkGlyphSetsTable { get; private set; } + public ClassDefTable? GlyphClassDef { get; private set; } + public AttachmentListTable? AttachmentListTable { get; private set; } + public LigCaretList? LigCaretList { get; private set; } + public ClassDefTable? MarkAttachmentClassDef { get; private set; } + public MarkGlyphSetsTable? MarkGlyphSetsTable { get; private set; } //------------------------ /// @@ -191,64 +190,55 @@ public void FillGlyphData(Glyph[] inputGlyphs) void FillClassDefs(Glyph[] inputGlyphs) { //1. glyph def - ClassDefTable classDef = GlyphClassDef; + var classDef = GlyphClassDef; if (classDef == null) return; //----------------------------------------- - switch (classDef.Format) + if (classDef.format1 is var (startGlyph, classValues)) { - default: - Utils.WarnUnimplemented("GDEF GlyphClassDef Format {0}", classDef.Format); - break; - case 1: - { - ushort startGlyph = classDef.startGlyph; - ushort[] classValues = classDef.classValueArray; - int gIndex = startGlyph; - for (int i = 0; i < classValues.Length; ++i) - { + int gIndex = startGlyph; + for (int i = 0; i < classValues?.Length; ++i) + { #if DEBUG - ushort classV = classValues[i]; - if (classV > (ushort)GlyphClassKind.Component) - { + ushort classV = classValues[i]; + if (classV > (ushort)GlyphClassKind.Component) + { - } + } #endif - inputGlyphs[gIndex].GlyphClass = (GlyphClassKind)classValues[i]; - gIndex++; - } + inputGlyphs[gIndex].GlyphClass = (GlyphClassKind)classValues[i]; + gIndex++; + } - } - break; - case 2: - { - ClassDefTable.ClassRangeRecord[] records = classDef.records; - for (int n = 0; n < records.Length; ++n) - { - ClassDefTable.ClassRangeRecord rec = records[n]; + } + else if (classDef.format2 is { } records) + { + for (int n = 0; n < records?.Length; ++n) + { + ClassDefTable.ClassRangeRecord rec = records[n]; #if DEBUG - if (rec.classNo > (ushort)GlyphClassKind.Component) - { + if (rec.classNo > (ushort)GlyphClassKind.Component) + { - } + } #endif - GlyphClassKind glyphKind = (GlyphClassKind)rec.classNo; - for (int i = rec.startGlyphId; i <= rec.endGlyphId; ++i) - { - inputGlyphs[i].GlyphClass = glyphKind; - } - } + GlyphClassKind glyphKind = (GlyphClassKind)rec.classNo; + for (int i = rec.startGlyphId; i <= rec.endGlyphId; ++i) + { + inputGlyphs[i].GlyphClass = glyphKind; } - break; + } } + else + throw new NotImplementedException(); } void FillAttachPoints(Glyph[] inputGlyphs) { - AttachmentListTable attachmentListTable = this.AttachmentListTable; + AttachmentListTable? attachmentListTable = this.AttachmentListTable; if (attachmentListTable == null) { return; } //----------------------------------------- @@ -265,50 +255,36 @@ void FillMarkAttachmentClassDefs(Glyph[] inputGlyphs) //that can be used in lookup tables within the GSUB or GPOS table to control how mark glyphs within a glyph sequence are treated by lookups. //For more information on the use of mark attachment classes, //see the description of lookup flags in the “Lookup Table” section of the chapter, OpenType Layout Common Table Formats. - ClassDefTable markAttachmentClassDef = this.MarkAttachmentClassDef; + ClassDefTable? markAttachmentClassDef = this.MarkAttachmentClassDef; if (markAttachmentClassDef == null) return; //----------------------------------------- - switch (markAttachmentClassDef.Format) + if (markAttachmentClassDef.format1 is var (startGlyph, classValues)) { - default: - Utils.WarnUnimplemented("GDEF MarkAttachmentClassDef Table Format {0}", markAttachmentClassDef.Format); - break; - case 1: - { - ushort startGlyph = markAttachmentClassDef.startGlyph; - ushort[] classValues = markAttachmentClassDef.classValueArray; - - int len = classValues.Length; - int gIndex = startGlyph; - for (int i = 0; i < len; ++i) - { + int gIndex = startGlyph; + for (int i = 0; i < classValues.Length; ++i) + { #if DEBUG - Glyph dbugTestGlyph = inputGlyphs[gIndex]; + Glyph dbugTestGlyph = inputGlyphs[gIndex]; #endif - inputGlyphs[gIndex].MarkClassDef = classValues[i]; - gIndex++; - } + inputGlyphs[gIndex].MarkClassDef = classValues[i]; + gIndex++; + } - } - break; - case 2: + } + else if (markAttachmentClassDef.format2 is { } records) + { + for (int n = 0; n < records.Length; ++n) + { + ClassDefTable.ClassRangeRecord rec = records[n]; + for (int i = rec.startGlyphId; i <= rec.endGlyphId; ++i) { - ClassDefTable.ClassRangeRecord[] records = markAttachmentClassDef.records; - int len = records.Length; - for (int n = 0; n < len; ++n) - { - ClassDefTable.ClassRangeRecord rec = records[n]; - for (int i = rec.startGlyphId; i <= rec.endGlyphId; ++i) - { #if DEBUG - Glyph dbugTestGlyph = inputGlyphs[i]; + Glyph dbugTestGlyph = inputGlyphs[i]; #endif - inputGlyphs[i].MarkClassDef = rec.classNo; - } - } + inputGlyphs[i].MarkClassDef = rec.classNo; } - break; + } } } void FillMarkGlyphSets(Glyph[] inputGlyphs) @@ -317,7 +293,7 @@ void FillMarkGlyphSets(Glyph[] inputGlyphs) //A Mark Glyph Sets table is used to define sets of mark glyphs that can be used in lookup tables within the GSUB or GPOS table to control //how mark glyphs within a glyph sequence are treated by lookups. For more information on the use of mark glyph sets, //see the description of lookup flags in the “Lookup Table” section of the chapter, OpenType Layout Common Table Formats. - MarkGlyphSetsTable markGlyphSets = this.MarkGlyphSetsTable; + MarkGlyphSetsTable? markGlyphSets = this.MarkGlyphSetsTable; if (markGlyphSets == null) return; //----------------------------------------- diff --git a/Typography.OpenFont/Tables.AdvancedLayout/GPOS.Others.cs b/Typography.OpenFont/Tables.AdvancedLayout/GPOS.Others.cs index f3892c74..914b1ccc 100644 --- a/Typography.OpenFont/Tables.AdvancedLayout/GPOS.Others.cs +++ b/Typography.OpenFont/Tables.AdvancedLayout/GPOS.Others.cs @@ -35,7 +35,7 @@ static PosLookupRecord[] CreateMultiplePosLookupRecords(BinaryReader reader, int class PairSetTable { - internal PairSet[] _pairSets; + internal PairSet[]? _pairSets; public void ReadFrom(BinaryReader reader, ushort v1format, ushort v2format) { ushort rowCount = reader.ReadUInt16(); @@ -46,16 +46,15 @@ public void ReadFrom(BinaryReader reader, ushort v1format, ushort v2format) //ValueRecord Value1 Positioning data for the first glyph in the pair //ValueRecord Value2 Positioning data for the second glyph in the pair ushort secondGlyph = reader.ReadUInt16(); - ValueRecord v1 = ValueRecord.CreateFrom(reader, v1format); - ValueRecord v2 = ValueRecord.CreateFrom(reader, v2format); + ValueRecord? v1 = ValueRecord.CreateFrom(reader, v1format); + ValueRecord? v2 = ValueRecord.CreateFrom(reader, v2format); // _pairSets[i] = new PairSet(secondGlyph, v1, v2); } } public bool FindPairSet(ushort secondGlyphIndex, out PairSet foundPairSet) { - int j = _pairSets.Length; - for (int i = 0; i < j; ++i) + for (int i = 0; i < _pairSets?.Length; ++i) { //TODO: binary search? if (_pairSets[i].secondGlyph == secondGlyphIndex) @@ -75,9 +74,9 @@ public bool FindPairSet(ushort secondGlyphIndex, out PairSet foundPairSet) struct PairSet { public readonly ushort secondGlyph;//GlyphID of second glyph in the pair-first glyph is listed in the Coverage table - public readonly ValueRecord value1;//Positioning data for the first glyph in the pair - public readonly ValueRecord value2;//Positioning data for the second glyph in the pair - public PairSet(ushort secondGlyph, ValueRecord v1, ValueRecord v2) + public readonly ValueRecord? value1;//Positioning data for the first glyph in the pair + public readonly ValueRecord? value2;//Positioning data for the second glyph in the pair + public PairSet(ushort secondGlyph, ValueRecord? v1, ValueRecord? v2) { this.secondGlyph = secondGlyph; this.value1 = v1; @@ -177,7 +176,7 @@ static bool HasFormat(ushort value, int flags) const int FMT_XAdvDevice = 1 << 6; const int FMT_YAdvDevice = 1 << 7; - public static ValueRecord CreateFrom(BinaryReader reader, ushort valueFormat) + public static ValueRecord? CreateFrom(BinaryReader reader, ushort valueFormat) { if (valueFormat == 0) return null;//empty @@ -401,7 +400,7 @@ public ushort GetMarkClass(int index) { return _records[index].markClass; } - void ReadFrom(BinaryReader reader) + private MarkArrayTable(BinaryReader reader) { long markTableBeginAt = reader.BaseStream.Position; ushort markCount = reader.ReadUInt16(); @@ -434,16 +433,14 @@ void ReadFrom(BinaryReader reader) #if DEBUG public int dbugGetAnchorCount() { - return _anchorPoints.Length; + return _anchorPoints?.Length ?? 0; } #endif public static MarkArrayTable CreateFrom(BinaryReader reader, long beginAt) { reader.BaseStream.Seek(beginAt, SeekOrigin.Begin); // - var markArrTable = new MarkArrayTable(); - markArrTable.ReadFrom(reader); - return markArrTable; + return new MarkArrayTable(reader); } } @@ -544,13 +541,13 @@ public BaseRecord GetBaseRecords(int index) { return _records[index]; } + private BaseArrayTable(BaseRecord[] records) => _records = records; public static BaseArrayTable CreateFrom(BinaryReader reader, long beginAt, ushort classCount) { reader.BaseStream.Seek(beginAt, SeekOrigin.Begin); //--- - var baseArrTable = new BaseArrayTable(); ushort baseCount = reader.ReadUInt16(); - baseArrTable._records = new BaseRecord[baseCount]; + var baseArrTable = new BaseArrayTable(new BaseRecord[baseCount]); // Read all baseAnchorOffsets in one go ushort[] baseAnchorOffsets = Utils.ReadUInt16Array(reader, classCount * baseCount); for (int i = 0; i < baseCount; ++i) @@ -579,7 +576,7 @@ public static BaseArrayTable CreateFrom(BinaryReader reader, long beginAt, ushor #if DEBUG public int dbugGetRecordCount() { - return _records.Length; + return _records?.Length ?? 0; } #endif } @@ -650,7 +647,7 @@ public override string ToString() //Offset16 LigatureAnchor[ClassCount] Array of offsets (one per class) to Anchor tables-from beginning of LigatureAttach table-ordered by class-NULL if a component does not have an attachment for a class-zero-based array class LigatureArrayTable { - LigatureAttachTable[] _ligatures; + LigatureAttachTable[]? _ligatures; public void ReadFrom(BinaryReader reader, ushort classCount) { long startPos = reader.BaseStream.Position; @@ -674,7 +671,7 @@ class LigatureAttachTable //uint16 ComponentCount Number of ComponentRecords in this ligature //struct ComponentRecord[ComponentCount] Array of Component records-ordered in writing direction //------------------------------- - ComponentRecord[] _records; + ComponentRecord[]? _records; public static LigatureAttachTable ReadFrom(BinaryReader reader, ushort classCount) { LigatureAttachTable table = new LigatureAttachTable(); @@ -745,7 +742,7 @@ class PosRuleSetTable //Example 10 at the end of this chapter demonstrates glyph kerning in context with a ContextPosFormat1 subtable. - PosRuleTable[] _posRuleTables; + PosRuleTable[]? _posRuleTables; void ReadFrom(BinaryReader reader) { long tableStartAt = reader.BaseStream.Position; @@ -782,8 +779,8 @@ class PosRuleTable //uint16 PosCount Number of PosLookupRecords //uint16 Input[GlyphCount - 1] Array of input GlyphIDs-starting with the second glyph*** //struct PosLookupRecord[PosCount] Array of positioning lookups-in design order - PosLookupRecord[] _posLookupRecords; - ushort[] _inputGlyphIds; + PosLookupRecord[]? _posLookupRecords; + ushort[]? _inputGlyphIds; public void ReadFrom(BinaryReader reader) { ushort glyphCount = reader.ReadUInt16(); @@ -822,7 +819,7 @@ class PosClassSetTable //struct PosLookupRecord[PosCount] Array of positioning lookups-in design order //---------------------- - PosClassRule[] _posClasses; + PosClassRule[]? _posClasses; void ReadFrom(BinaryReader reader) { long tableStartAt = reader.BaseStream.Position; @@ -850,8 +847,8 @@ public static PosClassSetTable CreateFrom(BinaryReader reader, long beginAt) } class PosClassRule { - PosLookupRecord[] _posLookupRecords; - ushort[] _inputGlyphIds; + PosLookupRecord[]? _posLookupRecords; + ushort[]? _inputGlyphIds; public static PosClassRule CreateFrom(BinaryReader reader, long beginAt) { diff --git a/Typography.OpenFont/Tables.AdvancedLayout/GPOS.cs b/Typography.OpenFont/Tables.AdvancedLayout/GPOS.cs index 324de31a..b191ce0a 100644 --- a/Typography.OpenFont/Tables.AdvancedLayout/GPOS.cs +++ b/Typography.OpenFont/Tables.AdvancedLayout/GPOS.cs @@ -9,8 +9,8 @@ namespace Typography.OpenFont.Tables // https://www.microsoft.com/typography/otspec/GPOS.htm public partial class GPOS : GlyphShapingTableEntry { - public const string _N = "GPOS"; - public override string Name => _N; + public const string Name = "GPOS"; + internal GPOS(TableHeader header, BinaryReader input) : base(header, input) { } // protected override void ReadLookupTable(BinaryReader reader, long lookupTablePos, ushort lookupType, ushort lookupFlags, @@ -42,7 +42,7 @@ protected override void ReadFeatureVariations(BinaryReader reader, long featureV public abstract class LookupSubTable { - public GPOS OwnerGPos; + public GPOS? OwnerGPos; public abstract void DoGlyphPosition(IGlyphPositions inputGlyphs, int startAt, int len); } @@ -124,17 +124,19 @@ public LookupSubTable ReadSubTable(BinaryReader reader, long subTableStartAt) class LkSubTableType1 : LookupSubTable { - ValueRecord _singleValue; - ValueRecord[] _multiValues; - public LkSubTableType1(ValueRecord singleValue) + ValueRecord? _singleValue; + ValueRecord?[]? _multiValues; + public LkSubTableType1(ValueRecord? singleValue, CoverageTable coverage) { this.Format = 1; _singleValue = singleValue; + CoverageTable = coverage; } - public LkSubTableType1(ValueRecord[] valueRecords) + public LkSubTableType1(ValueRecord?[] valueRecords, CoverageTable coverage) { this.Format = 2; _multiValues = valueRecords; + CoverageTable = coverage; } public int Format { get; private set; } public CoverageTable CoverageTable { get; set; } @@ -166,11 +168,8 @@ static LookupSubTable ReadLookupType1(BinaryReader reader, long subTableStartAt) //ValueRecord Value Defines positioning value(s)-applied to all glyphs in the Coverage table ushort coverage = reader.ReadUInt16(); ushort valueFormat = reader.ReadUInt16(); - var subTable = new LkSubTableType1(ValueRecord.CreateFrom(reader, valueFormat)); - //------- - subTable.CoverageTable = CoverageTable.CreateFrom(reader, subTableStartAt + coverage); - //------- - return subTable; + return new LkSubTableType1(ValueRecord.CreateFrom(reader, valueFormat), + CoverageTable.CreateFrom(reader, subTableStartAt + coverage)); } case 2: { @@ -184,15 +183,13 @@ static LookupSubTable ReadLookupType1(BinaryReader reader, long subTableStartAt) ushort coverage = reader.ReadUInt16(); ushort valueFormat = reader.ReadUInt16(); ushort valueCount = reader.ReadUInt16(); - var values = new ValueRecord[valueCount]; + var values = new ValueRecord?[valueCount]; for (int n = 0; n < valueCount; ++n) { values[n] = ValueRecord.CreateFrom(reader, valueFormat); } - var subTable = new LkSubTableType1(values); - subTable.CoverageTable = CoverageTable.CreateFrom(reader, subTableStartAt + coverage); - //------- - return subTable; + return new LkSubTableType1(values, + CoverageTable.CreateFrom(reader, subTableStartAt + coverage)); } } } @@ -203,9 +200,10 @@ static LookupSubTable ReadLookupType1(BinaryReader reader, long subTableStartAt) class LkSubTableType2Fmt1 : LookupSubTable { internal PairSetTable[] _pairSetTables; - public LkSubTableType2Fmt1(PairSetTable[] pairSetTables) + public LkSubTableType2Fmt1(PairSetTable[] pairSetTables, CoverageTable coverage) { _pairSetTables = pairSetTables; + CoverageTable = coverage; } public CoverageTable CoverageTable { get; set; } public override void DoGlyphPosition(IGlyphPositions inputGlyphs, int startAt, int len) @@ -226,8 +224,8 @@ public override void DoGlyphPosition(IGlyphPositions inputGlyphs, int startAt, i if (pairSet.FindPairSet(second_glyph_index, out PairSet foundPairSet)) { - ValueRecord v1 = foundPairSet.value1; - ValueRecord v2 = foundPairSet.value2; + ValueRecord? v1 = foundPairSet.value1; + ValueRecord? v2 = foundPairSet.value2; //TODO: recheck for vertical writing ... (YAdvance) if (v1 != null) { @@ -255,11 +253,12 @@ class LkSubTableType2Fmt2 : LookupSubTable internal readonly ClassDefTable _class1Def; internal readonly ClassDefTable _class2Def; - public LkSubTableType2Fmt2(Lk2Class1Record[] class1records, ClassDefTable class1Def, ClassDefTable class2Def) + public LkSubTableType2Fmt2(Lk2Class1Record[] class1records, ClassDefTable class1Def, ClassDefTable class2Def, CoverageTable coverage) { _class1records = class1records; _class1Def = class1Def; _class2Def = class2Def; + CoverageTable = coverage; } public CoverageTable CoverageTable { get; set; } public override void DoGlyphPosition(IGlyphPositions inputGlyphs, int startAt, int len) @@ -290,8 +289,8 @@ public override void DoGlyphPosition(IGlyphPositions inputGlyphs, int startAt, i //TODO: recheck for vertical writing ... (YAdvance) Lk2Class2Record pair = class1Rec.class2Records[class2_no]; - ValueRecord v1 = pair.value1; - ValueRecord v2 = pair.value2; + ValueRecord? v1 = pair.value1; + ValueRecord? v2 = pair.value2; if (v1 != null && v1.XAdvance != 0) { @@ -365,10 +364,10 @@ class Lk2Class2Record //ValueRecord Value1 Positioning for first glyph-empty if ValueFormat1 = 0 //ValueRecord Value2 Positioning for second glyph-empty if ValueFormat2 = 0 //-------------------------------- - public readonly ValueRecord value1;//null= empty - public readonly ValueRecord value2;//null= empty + public readonly ValueRecord? value1;//null= empty + public readonly ValueRecord? value2;//null= empty - public Lk2Class2Record(ValueRecord value1, ValueRecord value2) + public Lk2Class2Record(ValueRecord? value1, ValueRecord? value2) { this.value1 = value1; this.value2 = value2; @@ -506,10 +505,8 @@ static LookupSubTable ReadLookupType2(BinaryReader reader, long subTableStartAt) pairSetTable.ReadFrom(reader, value1Format, value2Format); pairSetTables[n] = pairSetTable; } - var subTable = new LkSubTableType2Fmt1(pairSetTables); - //coverage - subTable.CoverageTable = CoverageTable.CreateFrom(reader, subTableStartAt + coverage); - return subTable; + return new LkSubTableType2Fmt1(pairSetTables, + CoverageTable.CreateFrom(reader, subTableStartAt + coverage)); } case 2: { @@ -536,13 +533,10 @@ static LookupSubTable ReadLookupType2(BinaryReader reader, long subTableStartAt) class1Records[c1] = new Lk2Class1Record(class2Records); } - var subTable = new LkSubTableType2Fmt2(class1Records, - ClassDefTable.CreateFrom(reader, subTableStartAt + classDef1_offset), - ClassDefTable.CreateFrom(reader, subTableStartAt + classDef2_offset)); - - - subTable.CoverageTable = CoverageTable.CreateFrom(reader, subTableStartAt + coverage); - return subTable; + return new LkSubTableType2Fmt2(class1Records, + ClassDefTable.CreateFrom(reader, subTableStartAt + classDef1_offset), + ClassDefTable.CreateFrom(reader, subTableStartAt + classDef2_offset), + CoverageTable.CreateFrom(reader, subTableStartAt + coverage)); } } } @@ -563,13 +557,18 @@ static LookupSubTable ReadLookupType3(BinaryReader reader, long subTableStartAt) /// class LkSubTableType4 : LookupSubTable { - public LkSubTableType4() + public LkSubTableType4(CoverageTable markCoverageTable, CoverageTable baseCoverageTable, MarkArrayTable markArrayTable, BaseArrayTable baseArrayTable) { + MarkCoverageTable = markCoverageTable; + BaseCoverageTable = baseCoverageTable; + MarkArrayTable = markArrayTable; + BaseArrayTable = baseArrayTable; } + public CoverageTable MarkCoverageTable { get; set; } public CoverageTable BaseCoverageTable { get; set; } - public BaseArrayTable BaseArrayTable { get; set; } public MarkArrayTable MarkArrayTable { get; set; } + public BaseArrayTable BaseArrayTable { get; set; } public override void DoGlyphPosition(IGlyphPositions inputGlyphs, int startAt, int len) { @@ -700,11 +699,11 @@ static LookupSubTable ReadLookupType4(BinaryReader reader, long subTableStartAt) ushort baseArrayOffset = reader.ReadUInt16(); //read mark array table - var lookupType4 = new LkSubTableType4(); - lookupType4.MarkCoverageTable = CoverageTable.CreateFrom(reader, subTableStartAt + markCoverageOffset); - lookupType4.BaseCoverageTable = CoverageTable.CreateFrom(reader, subTableStartAt + baseCoverageOffset); - lookupType4.MarkArrayTable = MarkArrayTable.CreateFrom(reader, subTableStartAt + markArrayOffset); - lookupType4.BaseArrayTable = BaseArrayTable.CreateFrom(reader, subTableStartAt + baseArrayOffset, markClassCount); + var lookupType4 = new LkSubTableType4( + CoverageTable.CreateFrom(reader, subTableStartAt + markCoverageOffset), + CoverageTable.CreateFrom(reader, subTableStartAt + baseCoverageOffset), + MarkArrayTable.CreateFrom(reader, subTableStartAt + markArrayOffset), + BaseArrayTable.CreateFrom(reader, subTableStartAt + baseArrayOffset, markClassCount)); #if DEBUG lookupType4.dbugTest(); #endif @@ -713,6 +712,14 @@ static LookupSubTable ReadLookupType4(BinaryReader reader, long subTableStartAt) class LkSubTableType5 : LookupSubTable { + public LkSubTableType5(CoverageTable markCoverage, CoverageTable ligatureCoverage, MarkArrayTable markArrayTable, LigatureArrayTable ligatureArrayTable) + { + MarkCoverage = markCoverage; + LigatureCoverage = ligatureCoverage; + MarkArrayTable = markArrayTable; + LigatureArrayTable = ligatureArrayTable; + } + public CoverageTable MarkCoverage { get; set; } public CoverageTable LigatureCoverage { get; set; } public MarkArrayTable MarkArrayTable { get; set; } @@ -749,17 +756,14 @@ static LookupSubTable ReadLookupType5(BinaryReader reader, long subTableStartAt) ushort markArrayOffset = reader.ReadUInt16(); ushort ligatureArrayOffset = reader.ReadUInt16(); //----------------------- - var subTable = new LkSubTableType5(); - subTable.MarkCoverage = CoverageTable.CreateFrom(reader, subTableStartAt + markCoverageOffset); - subTable.LigatureCoverage = CoverageTable.CreateFrom(reader, subTableStartAt + ligatureCoverageOffset); - subTable.MarkArrayTable = MarkArrayTable.CreateFrom(reader, subTableStartAt + markArrayOffset); + var markCoverage = CoverageTable.CreateFrom(reader, subTableStartAt + markCoverageOffset); + var ligatureCoverage = CoverageTable.CreateFrom(reader, subTableStartAt + ligatureCoverageOffset); + var markArrayTable = MarkArrayTable.CreateFrom(reader, subTableStartAt + markArrayOffset); reader.BaseStream.Seek(subTableStartAt + ligatureArrayOffset, SeekOrigin.Begin); var ligatureArrayTable = new LigatureArrayTable(); ligatureArrayTable.ReadFrom(reader, classCount); - subTable.LigatureArrayTable = ligatureArrayTable; - - return subTable; + return new LkSubTableType5(markCoverage, ligatureCoverage, markArrayTable, ligatureArrayTable); } //----------------------------------------------------------------- @@ -770,6 +774,13 @@ static LookupSubTable ReadLookupType5(BinaryReader reader, long subTableStartAt) /// class LkSubTableType6 : LookupSubTable { + public LkSubTableType6(CoverageTable markCoverage1, CoverageTable markCoverage2, MarkArrayTable mark1ArrayTable, Mark2ArrayTable mark2ArrayTable) + { + MarkCoverage1 = markCoverage1; + MarkCoverage2 = markCoverage2; + Mark1ArrayTable = mark1ArrayTable; + Mark2ArrayTable = mark2ArrayTable; + } public CoverageTable MarkCoverage1 { get; set; } public CoverageTable MarkCoverage2 { get; set; } @@ -882,13 +893,11 @@ static LookupSubTable ReadLookupType6(BinaryReader reader, long subTableStartAt) ushort mark1ArrayOffset = reader.ReadUInt16(); ushort mark2ArrayOffset = reader.ReadUInt16(); // - var subTable = new LkSubTableType6(); - subTable.MarkCoverage1 = CoverageTable.CreateFrom(reader, subTableStartAt + mark1CoverageOffset); - subTable.MarkCoverage2 = CoverageTable.CreateFrom(reader, subTableStartAt + mark2CoverageOffset); - subTable.Mark1ArrayTable = MarkArrayTable.CreateFrom(reader, subTableStartAt + mark1ArrayOffset); - subTable.Mark2ArrayTable = Mark2ArrayTable.CreateFrom(reader, subTableStartAt + mark2ArrayOffset, classCount); - - return subTable; + return new LkSubTableType6( + CoverageTable.CreateFrom(reader, subTableStartAt + mark1CoverageOffset), + CoverageTable.CreateFrom(reader, subTableStartAt + mark2CoverageOffset), + MarkArrayTable.CreateFrom(reader, subTableStartAt + mark1ArrayOffset), + Mark2ArrayTable.CreateFrom(reader, subTableStartAt + mark2ArrayOffset, classCount)); } /// @@ -918,10 +927,9 @@ static LookupSubTable ReadLookupType7(BinaryReader reader, long subTableStartAt) ushort posRuleSetCount = reader.ReadUInt16(); ushort[] posRuleSetOffsets = Utils.ReadUInt16Array(reader, posRuleSetCount); - LkSubTableType7Fmt1 subTable = new LkSubTableType7Fmt1(); - subTable.PosRuleSetTables = CreateMultiplePosRuleSetTables(subTableStartAt, posRuleSetOffsets, reader); - subTable.CoverageTable = CoverageTable.CreateFrom(reader, subTableStartAt + coverageOffset); - return subTable; + var posRuleSetTables = CreateMultiplePosRuleSetTables(subTableStartAt, posRuleSetOffsets, reader); + var coverageTable = CoverageTable.CreateFrom(reader, subTableStartAt + coverageOffset); + return new LkSubTableType7Fmt1(posRuleSetTables, coverageTable); } case 2: { @@ -937,17 +945,13 @@ static LookupSubTable ReadLookupType7(BinaryReader reader, long subTableStartAt) ushort posClassSetCount = reader.ReadUInt16(); ushort[] posClassSetOffsets = Utils.ReadUInt16Array(reader, posClassSetCount); - var subTable = new LkSubTableType7Fmt2(); - subTable.ClassDefOffset = classDefOffset; - PosClassSetTable[] posClassSetTables = new PosClassSetTable[posClassSetCount]; - subTable.PosClassSetTables = posClassSetTables; for (int n = 0; n < posClassSetCount; ++n) { posClassSetTables[n] = PosClassSetTable.CreateFrom(reader, subTableStartAt + posClassSetOffsets[n]); } - subTable.CoverageTable = CoverageTable.CreateFrom(reader, subTableStartAt + coverageOffset); - return subTable; + var coverageTable = CoverageTable.CreateFrom(reader, subTableStartAt + coverageOffset); + return new LkSubTableType7Fmt2(classDefOffset, posClassSetTables, coverageTable); } case 3: { @@ -958,23 +962,27 @@ static LookupSubTable ReadLookupType7(BinaryReader reader, long subTableStartAt) //uint16 PosCount Number of PosLookupRecords //Offset16 Coverage[GlyphCount] Array of offsets to Coverage tables-from beginning of ContextPos subtable //struct PosLookupRecord[PosCount] Array of positioning lookups-in design order - var subTable = new LkSubTableType7Fmt3(); ushort glyphCount = reader.ReadUInt16(); ushort posCount = reader.ReadUInt16(); //read each lookahead record ushort[] coverageOffsets = Utils.ReadUInt16Array(reader, glyphCount); - subTable.PosLookupRecords = CreateMultiplePosLookupRecords(reader, posCount); - subTable.CoverageTables = CoverageTable.CreateMultipleCoverageTables(subTableStartAt, coverageOffsets, reader); - - return subTable; + var posLookupRecords = CreateMultiplePosLookupRecords(reader, posCount); + var coverageTables = CoverageTable.CreateMultipleCoverageTables(subTableStartAt, coverageOffsets, reader); + return new LkSubTableType7Fmt3(posLookupRecords, coverageTables); } } } class LkSubTableType7Fmt1 : LookupSubTable { - public CoverageTable CoverageTable { get; set; } + public LkSubTableType7Fmt1(PosRuleSetTable[] posRuleSetTables , CoverageTable coverageTable) + { + PosRuleSetTables = posRuleSetTables; + CoverageTable = coverageTable; + } + public PosRuleSetTable[] PosRuleSetTables { get; set; } + public CoverageTable CoverageTable { get; set; } public override void DoGlyphPosition(IGlyphPositions inputGlyphs, int startAt, int len) { Utils.WarnUnimplemented("GPOS Lookup Sub Table Type 7 Format 1"); @@ -983,9 +991,16 @@ public override void DoGlyphPosition(IGlyphPositions inputGlyphs, int startAt, i class LkSubTableType7Fmt2 : LookupSubTable { + public LkSubTableType7Fmt2(ushort classDefOffset, PosClassSetTable[] posClassSetTables, CoverageTable coverageTable) + { + ClassDefOffset = classDefOffset; + PosClassSetTables = posClassSetTables; + CoverageTable = coverageTable; + } + public ushort ClassDefOffset { get; set; } - public CoverageTable CoverageTable { get; set; } public PosClassSetTable[] PosClassSetTables { get; set; } + public CoverageTable CoverageTable { get; set; } public override void DoGlyphPosition(IGlyphPositions inputGlyphs, int startAt, int len) { Utils.WarnUnimplemented("GPOS Lookup Sub Table Type 7 Format 2"); @@ -994,8 +1009,14 @@ public override void DoGlyphPosition(IGlyphPositions inputGlyphs, int startAt, i } class LkSubTableType7Fmt3 : LookupSubTable { - public CoverageTable[] CoverageTables { get; set; } + public LkSubTableType7Fmt3(PosLookupRecord[] posLookupRecords, CoverageTable[] coverageTables) + { + PosLookupRecords = posLookupRecords; + CoverageTables = coverageTables; + } + public PosLookupRecord[] PosLookupRecords { get; set; } + public CoverageTable[] CoverageTables { get; set; } public override void DoGlyphPosition(IGlyphPositions inputGlyphs, int startAt, int len) { Utils.WarnUnimplemented("GPOS Lookup Sub Table Type 7 Format 3"); @@ -1004,9 +1025,14 @@ public override void DoGlyphPosition(IGlyphPositions inputGlyphs, int startAt, i //---------------------------------------------------------------- class LkSubTableType8Fmt1 : LookupSubTable { + public LkSubTableType8Fmt1(PosRuleSetTable[] posRuleSetTables, CoverageTable coverageTable) + { + PosRuleSetTables = posRuleSetTables; + CoverageTable = coverageTable; + } - public CoverageTable CoverageTable { get; set; } public PosRuleSetTable[] PosRuleSetTables { get; set; } + public CoverageTable CoverageTable { get; set; } public override void DoGlyphPosition(IGlyphPositions inputGlyphs, int startAt, int len) { Utils.WarnUnimplemented("GPOS Lookup Sub Table Type 8 Format 1"); @@ -1016,17 +1042,22 @@ public override void DoGlyphPosition(IGlyphPositions inputGlyphs, int startAt, i class LkSubTableType8Fmt2 : LookupSubTable { ushort[] chainPosClassSetOffsetArray; - public LkSubTableType8Fmt2(ushort[] chainPosClassSetOffsetArray) + + public LkSubTableType8Fmt2(ushort[] chainPosClassSetOffsetArray, ushort backtrackClassDefOffset, ushort inputClassDefOffset, ushort lookaheadClassDefOffset, PosClassSetTable[] posClassSetTables, CoverageTable coverageTable) { this.chainPosClassSetOffsetArray = chainPosClassSetOffsetArray; + BacktrackClassDefOffset = backtrackClassDefOffset; + InputClassDefOffset = inputClassDefOffset; + LookaheadClassDefOffset = lookaheadClassDefOffset; + PosClassSetTables = posClassSetTables; + CoverageTable = coverageTable; } - public CoverageTable CoverageTable { get; set; } - public PosClassSetTable[] PosClassSetTables { get; set; } public ushort BacktrackClassDefOffset { get; set; } public ushort InputClassDefOffset { get; set; } public ushort LookaheadClassDefOffset { get; set; } - + public PosClassSetTable[] PosClassSetTables { get; set; } + public CoverageTable CoverageTable { get; set; } public override void DoGlyphPosition(IGlyphPositions inputGlyphs, int startAt, int len) { @@ -1035,10 +1066,18 @@ public override void DoGlyphPosition(IGlyphPositions inputGlyphs, int startAt, i } class LkSubTableType8Fmt3 : LookupSubTable { + public LkSubTableType8Fmt3(PosLookupRecord[] posLookupRecords, CoverageTable[] backtrackCoverages, CoverageTable[] inputGlyphCoverages, CoverageTable[] lookaheadCoverages) + { + PosLookupRecords = posLookupRecords; + BacktrackCoverages = backtrackCoverages; + InputGlyphCoverages = inputGlyphCoverages; + LookaheadCoverages = lookaheadCoverages; + } + + public PosLookupRecord[] PosLookupRecords { get; set; } public CoverageTable[] BacktrackCoverages { get; set; } public CoverageTable[] InputGlyphCoverages { get; set; } public CoverageTable[] LookaheadCoverages { get; set; } - public PosLookupRecord[] PosLookupRecords { get; set; } //Chaining Context Positioning Format 3: Coverage-based Chaining Context Glyph Positioning //USHORT PosFormat Format identifier-format = 3 @@ -1083,10 +1122,9 @@ LookupSubTable ReadLookupType8(BinaryReader reader, long subTableStartAt) ushort chainPosRuleSetCount = reader.ReadUInt16(); ushort[] chainPosRuleSetOffsetList = Utils.ReadUInt16Array(reader, chainPosRuleSetCount); - LkSubTableType8Fmt1 subTable = new LkSubTableType8Fmt1(); - subTable.PosRuleSetTables = CreateMultiplePosRuleSetTables(subTableStartAt, chainPosRuleSetOffsetList, reader); - subTable.CoverageTable = CoverageTable.CreateFrom(reader, subTableStartAt + coverageOffset); - return subTable; + var posRuleSetTables = CreateMultiplePosRuleSetTables(subTableStartAt, chainPosRuleSetOffsetList, reader); + var coverageTable = CoverageTable.CreateFrom(reader, subTableStartAt + coverageOffset); + return new LkSubTableType8Fmt1(posRuleSetTables, coverageTable); } case 2: { @@ -1101,25 +1139,19 @@ LookupSubTable ReadLookupType8(BinaryReader reader, long subTableStartAt) ushort coverageOffset = reader.ReadUInt16(); ushort backTrackClassDefOffset = reader.ReadUInt16(); - ushort inpuClassDefOffset = reader.ReadUInt16(); - ushort lookadheadClassDefOffset = reader.ReadUInt16(); - ushort chainPosClassSetCnt = reader.ReadUInt16(); - ushort[] chainPosClassSetOffsetArray = Utils.ReadUInt16Array(reader, chainPosClassSetCnt); - - LkSubTableType8Fmt2 subTable = new LkSubTableType8Fmt2(chainPosClassSetOffsetArray); - subTable.BacktrackClassDefOffset = backTrackClassDefOffset; - subTable.InputClassDefOffset = inpuClassDefOffset; - subTable.LookaheadClassDefOffset = lookadheadClassDefOffset; + ushort inputClassDefOffset = reader.ReadUInt16(); + ushort lookaheadClassDefOffset = reader.ReadUInt16(); + ushort chainPosClassSetCount = reader.ReadUInt16(); + ushort[] chainPosClassSetOffsetArray = Utils.ReadUInt16Array(reader, chainPosClassSetCount); + //---------- - PosClassSetTable[] posClassSetTables = new PosClassSetTable[chainPosClassSetCnt]; - for (int n = 0; n < chainPosClassSetCnt; ++n) + PosClassSetTable[] posClassSetTables = new PosClassSetTable[chainPosClassSetCount]; + for (int n = 0; n < chainPosClassSetCount; ++n) { posClassSetTables[n] = PosClassSetTable.CreateFrom(reader, subTableStartAt + chainPosClassSetOffsetArray[n]); } - subTable.PosClassSetTables = posClassSetTables; - - subTable.CoverageTable = CoverageTable.CreateFrom(reader, subTableStartAt + coverageOffset); - return subTable; + var coverageTable = CoverageTable.CreateFrom(reader, subTableStartAt + coverageOffset); + return new LkSubTableType8Fmt2(chainPosClassSetOffsetArray, backTrackClassDefOffset, inputClassDefOffset, lookaheadClassDefOffset, posClassSetTables, coverageTable); } case 3: { @@ -1134,8 +1166,6 @@ LookupSubTable ReadLookupType8(BinaryReader reader, long subTableStartAt) //uint16 PosCount Number of PosLookupRecords //struct PosLookupRecord[PosCount] Array of PosLookupRecords,in design order - var subTable = new LkSubTableType8Fmt3(); - ushort backtrackGlyphCount = reader.ReadUInt16(); ushort[] backtrackCoverageOffsets = Utils.ReadUInt16Array(reader, backtrackGlyphCount); ushort inputGlyphCount = reader.ReadUInt16(); @@ -1145,13 +1175,13 @@ LookupSubTable ReadLookupType8(BinaryReader reader, long subTableStartAt) ushort[] lookaheadCoverageOffsets = Utils.ReadUInt16Array(reader, lookaheadGlyphCount); ushort posCount = reader.ReadUInt16(); - subTable.PosLookupRecords = CreateMultiplePosLookupRecords(reader, posCount); + var posLookupRecords = CreateMultiplePosLookupRecords(reader, posCount); - subTable.BacktrackCoverages = CoverageTable.CreateMultipleCoverageTables(subTableStartAt, backtrackCoverageOffsets, reader); - subTable.InputGlyphCoverages = CoverageTable.CreateMultipleCoverageTables(subTableStartAt, inputGlyphCoverageOffsets, reader); - subTable.LookaheadCoverages = CoverageTable.CreateMultipleCoverageTables(subTableStartAt, lookaheadCoverageOffsets, reader); + var backtrackCoverages = CoverageTable.CreateMultipleCoverageTables(subTableStartAt, backtrackCoverageOffsets, reader); + var inputGlyphCoverages = CoverageTable.CreateMultipleCoverageTables(subTableStartAt, inputGlyphCoverageOffsets, reader); + var lookaheadCoverages = CoverageTable.CreateMultipleCoverageTables(subTableStartAt, lookaheadCoverageOffsets, reader); - return subTable; + return new LkSubTableType8Fmt3(posLookupRecords, backtrackCoverages, inputGlyphCoverages, lookaheadCoverages); } } } diff --git a/Typography.OpenFont/Tables.AdvancedLayout/GSUB.cs b/Typography.OpenFont/Tables.AdvancedLayout/GSUB.cs index 58573515..47b17d29 100644 --- a/Typography.OpenFont/Tables.AdvancedLayout/GSUB.cs +++ b/Typography.OpenFont/Tables.AdvancedLayout/GSUB.cs @@ -33,9 +33,9 @@ namespace Typography.OpenFont.Tables public partial class GSUB : GlyphShapingTableEntry { - public const string _N = "GSUB"; - public override string Name => _N; + public const string Name = "GSUB"; // + internal GSUB(TableHeader header, BinaryReader input) : base(header, input) { } protected override void ReadLookupTable(BinaryReader reader, long lookupTablePos, ushort lookupType, ushort lookupFlags, ushort[] subTableOffsets, ushort markFilteringSet) @@ -43,8 +43,7 @@ protected override void ReadLookupTable(BinaryReader reader, long lookupTablePos LookupTable lookupTable = new LookupTable(lookupType, lookupFlags, markFilteringSet); foreach (long subTableOffset in subTableOffsets) { - LookupSubTable subTable = lookupTable.ReadSubTable(reader, lookupTablePos + subTableOffset); - subTable.OwnerGSub = this; + LookupSubTable subTable = lookupTable.ReadSubTable(reader, lookupTablePos + subTableOffset, this); lookupTable.SubTables.Add(subTable); } @@ -70,8 +69,6 @@ protected override void ReadFeatureVariations(BinaryReader reader, long featureV /// public abstract class LookupSubTable { - public GSUB OwnerGSub; - public abstract bool DoSubstitutionAt(IGlyphIndexList glyphIndices, int pos, int len); //collect all substitution glyphs @@ -171,7 +168,7 @@ public override string ToString() } #endif - public LookupSubTable ReadSubTable(BinaryReader reader, long subTableStartAt) + public LookupSubTable ReadSubTable(BinaryReader reader, long subTableStartAt, GSUB ownerGSub) { switch (lookupType) { @@ -180,8 +177,8 @@ public LookupSubTable ReadSubTable(BinaryReader reader, long subTableStartAt) case 3: return ReadLookupType3(reader, subTableStartAt); case 4: return ReadLookupType4(reader, subTableStartAt); case 5: return ReadLookupType5(reader, subTableStartAt); - case 6: return ReadLookupType6(reader, subTableStartAt); - case 7: return ReadLookupType7(reader, subTableStartAt); + case 6: return ReadLookupType6(reader, subTableStartAt, ownerGSub); + case 7: return ReadLookupType7(reader, subTableStartAt, ownerGSub); case 8: return ReadLookupType8(reader, subTableStartAt); } @@ -344,9 +341,10 @@ LookupSubTable ReadLookupType1(BinaryReader reader, long subTableStartAt) class LkSubTableT2 : LookupSubTable { - - public CoverageTable CoverageTable { get; set; } + public LkSubTableT2(SequenceTable[] seqTables, CoverageTable coverageTable) => + (SeqTables, CoverageTable) = (seqTables, coverageTable); public SequenceTable[] SeqTables { get; set; } + public CoverageTable CoverageTable { get; set; } public override bool DoSubstitutionAt(IGlyphIndexList glyphIndices, int pos, int len) { int foundPos = CoverageTable.FindPosition(glyphIndices[pos]); @@ -437,18 +435,17 @@ LookupSubTable ReadLookupType2(BinaryReader reader, long subTableStartAt) ushort seqCount = reader.ReadUInt16(); ushort[] seqOffsets = Utils.ReadUInt16Array(reader, seqCount); - var subTable = new LkSubTableT2(); - subTable.SeqTables = new SequenceTable[seqCount]; + var seqTables = new SequenceTable[seqCount]; for (int n = 0; n < seqCount; ++n) { reader.BaseStream.Seek(subTableStartAt + seqOffsets[n], SeekOrigin.Begin); ushort glyphCount = reader.ReadUInt16(); - subTable.SeqTables[n] = new SequenceTable( + seqTables[n] = new SequenceTable( Utils.ReadUInt16Array(reader, glyphCount)); } - subTable.CoverageTable = CoverageTable.CreateFrom(reader, subTableStartAt + coverageOffset); + var coverageTable = CoverageTable.CreateFrom(reader, subTableStartAt + coverageOffset); - return subTable; + return new LkSubTableT2(seqTables, coverageTable); } } } @@ -458,8 +455,14 @@ LookupSubTable ReadLookupType2(BinaryReader reader, long subTableStartAt) /// class LkSubTableT3 : LookupSubTable { - public CoverageTable CoverageTable { get; set; } + public LkSubTableT3(AlternativeSetTable[] alternativeSetTables, CoverageTable coverageTable) + { + AlternativeSetTables = alternativeSetTables; + CoverageTable = coverageTable; + } + public AlternativeSetTable[] AlternativeSetTables { get; set; } + public CoverageTable CoverageTable { get; set; } public override bool DoSubstitutionAt(IGlyphIndexList glyphIndices, int pos, int len) { //Coverage table containing the indices of glyphs with alternative forms(Coverage), @@ -528,16 +531,14 @@ LookupSubTable ReadLookupType3(BinaryReader reader, long subTableStartAt) ushort alternativeSetCount = reader.ReadUInt16(); ushort[] alternativeTableOffsets = Utils.ReadUInt16Array(reader, alternativeSetCount); - LkSubTableT3 subTable = new LkSubTableT3(); - AlternativeSetTable[] alternativeSetTables = new AlternativeSetTable[alternativeSetCount]; - subTable.AlternativeSetTables = alternativeSetTables; + var alternativeSetTables = new AlternativeSetTable[alternativeSetCount]; for (int n = 0; n < alternativeSetCount; ++n) { alternativeSetTables[n] = AlternativeSetTable.CreateFrom(reader, subTableStartAt + alternativeTableOffsets[n]); } - subTable.CoverageTable = CoverageTable.CreateFrom(reader, subTableStartAt + coverageOffset); + var coverageTable = CoverageTable.CreateFrom(reader, subTableStartAt + coverageOffset); - return subTable; + return new LkSubTableT3(alternativeSetTables, coverageTable); } } } @@ -545,19 +546,29 @@ LookupSubTable ReadLookupType3(BinaryReader reader, long subTableStartAt) class AlternativeSetTable { public ushort[] alternativeGlyphIds; + + public AlternativeSetTable(ushort[] alternativeGlyphIds) + { + this.alternativeGlyphIds = alternativeGlyphIds; + } + public static AlternativeSetTable CreateFrom(BinaryReader reader, long beginAt) { reader.BaseStream.Seek(beginAt, SeekOrigin.Begin); // - AlternativeSetTable altTable = new AlternativeSetTable(); ushort glyphCount = reader.ReadUInt16(); - altTable.alternativeGlyphIds = Utils.ReadUInt16Array(reader, glyphCount); - return altTable; + return new AlternativeSetTable(Utils.ReadUInt16Array(reader, glyphCount)); } } class LkSubTableT4 : LookupSubTable { + public LkSubTableT4(LigatureSetTable[] ligatureSetTables, CoverageTable coverageTable) + { + LigatureSetTables = ligatureSetTables; + CoverageTable = coverageTable; + } + public CoverageTable CoverageTable { get; set; } public LigatureSetTable[] LigatureSetTables { get; set; } @@ -612,6 +623,11 @@ public override void CollectAssociatedSubtitutionGlyphs(List outputAssoc } class LigatureSetTable { + LigatureSetTable(LigatureTable[] ligatures) + { + Ligatures = ligatures; + } + //LigatureSet table: All ligatures beginning with the same glyph //Type Name Description //uint16 LigatureCount Number of Ligature tables @@ -620,18 +636,17 @@ class LigatureSetTable public LigatureTable[] Ligatures { get; set; } public static LigatureSetTable CreateFrom(BinaryReader reader, long beginAt) { - LigatureSetTable ligSetTable = new LigatureSetTable(); reader.BaseStream.Seek(beginAt, SeekOrigin.Begin); // ushort ligCount = reader.ReadUInt16(); //Number of Ligature tables ushort[] ligOffsets = Utils.ReadUInt16Array(reader, ligCount); // - LigatureTable[] ligTables = ligSetTable.Ligatures = new LigatureTable[ligCount]; + LigatureTable[] ligTables = new LigatureTable[ligCount]; for (int i = 0; i < ligCount; ++i) { ligTables[i] = LigatureTable.CreateFrom(reader, beginAt + ligOffsets[i]); } - return ligSetTable; + return new LigatureSetTable(ligTables); } } @@ -755,14 +770,13 @@ LookupSubTable ReadLookupType4(BinaryReader reader, long subTableStartAt) ushort coverageOffset = reader.ReadUInt16(); ushort ligSetCount = reader.ReadUInt16(); ushort[] ligSetOffsets = Utils.ReadUInt16Array(reader, ligSetCount); - LkSubTableT4 subTable = new LkSubTableT4(); - LigatureSetTable[] ligSetTables = subTable.LigatureSetTables = new LigatureSetTable[ligSetCount]; + LigatureSetTable[] ligSetTables = new LigatureSetTable[ligSetCount]; for (int n = 0; n < ligSetCount; ++n) { ligSetTables[n] = LigatureSetTable.CreateFrom(reader, subTableStartAt + ligSetOffsets[n]); } - subTable.CoverageTable = CoverageTable.CreateFrom(reader, subTableStartAt + coverageOffset); - return subTable; + var coverageTable = CoverageTable.CreateFrom(reader, subTableStartAt + coverageOffset); + return new LkSubTableT4(ligSetTables, coverageTable); } } } @@ -797,20 +811,25 @@ class ChainSubRuleSetTable //for text written from left to right, the left-most glyph will be first. ChainSubRuleSubTable[] chainSubRuleSubTables; + + ChainSubRuleSetTable(ChainSubRuleSubTable[] chainSubRuleSubTables) + { + this.chainSubRuleSubTables = chainSubRuleSubTables; + } + public static ChainSubRuleSetTable CreateFrom(BinaryReader reader, long beginAt) { reader.BaseStream.Seek(beginAt, SeekOrigin.Begin); //--- - ChainSubRuleSetTable table = new ChainSubRuleSetTable(); ushort subRuleCount = reader.ReadUInt16(); ushort[] subRuleOffsets = Utils.ReadUInt16Array(reader, subRuleCount); - ChainSubRuleSubTable[] chainSubRuleSubTables = table.chainSubRuleSubTables = new ChainSubRuleSubTable[subRuleCount]; + ChainSubRuleSubTable[] chainSubRuleSubTables = new ChainSubRuleSubTable[subRuleCount]; for (int i = 0; i < subRuleCount; ++i) { chainSubRuleSubTables[i] = ChainSubRuleSubTable.CreateFrom(reader, beginAt + subRuleOffsets[i]); } - return table; + return new ChainSubRuleSetTable(chainSubRuleSubTables); } } //--------------------- @@ -881,25 +900,33 @@ class ChainSubRuleSubTable ushort[] inputGlyphs; ushort[] lookaheadGlyphs; SubstLookupRecord[] substLookupRecords; + + public ChainSubRuleSubTable(ushort[] backTrackingGlyphs, ushort[] inputGlyphs, ushort[] lookaheadGlyphs, SubstLookupRecord[] substLookupRecords) + { + this.backTrackingGlyphs = backTrackingGlyphs; + this.inputGlyphs = inputGlyphs; + this.lookaheadGlyphs = lookaheadGlyphs; + this.substLookupRecords = substLookupRecords; + } + public static ChainSubRuleSubTable CreateFrom(BinaryReader reader, long beginAt) { reader.BaseStream.Seek(beginAt, SeekOrigin.Begin); // //------------ - ChainSubRuleSubTable subRuleTable = new ChainSubRuleSubTable(); ushort backtrackGlyphCount = reader.ReadUInt16(); - subRuleTable.backTrackingGlyphs = Utils.ReadUInt16Array(reader, backtrackGlyphCount); + var backTrackingGlyphs = Utils.ReadUInt16Array(reader, backtrackGlyphCount); //-------- ushort inputGlyphCount = reader.ReadUInt16(); - subRuleTable.inputGlyphs = Utils.ReadUInt16Array(reader, inputGlyphCount - 1);//*** start with second glyph, so -1 + var inputGlyphs = Utils.ReadUInt16Array(reader, inputGlyphCount - 1);//*** start with second glyph, so -1 //---------- ushort lookaheadGlyphCount = reader.ReadUInt16(); - subRuleTable.lookaheadGlyphs = Utils.ReadUInt16Array(reader, lookaheadGlyphCount); + var lookaheadGlyphs = Utils.ReadUInt16Array(reader, lookaheadGlyphCount); //------------ ushort substCount = reader.ReadUInt16(); - subRuleTable.substLookupRecords = SubstLookupRecord.CreateSubstLookupRecords(reader, substCount); + var substLookupRecords = SubstLookupRecord.CreateSubstLookupRecords(reader, substCount); - return subRuleTable; + return new ChainSubRuleSubTable(backTrackingGlyphs, inputGlyphs, lookaheadGlyphs, substLookupRecords); } } @@ -929,20 +956,25 @@ class ChainSubClassSet ChainSubClassRuleTable[] subClassRuleTables; + + public ChainSubClassSet(ChainSubClassRuleTable[] subClassRuleTables) + { + this.subClassRuleTables = subClassRuleTables; + } + public static ChainSubClassSet CreateFrom(BinaryReader reader, long beginAt) { reader.BaseStream.Seek(beginAt, SeekOrigin.Begin); // - ChainSubClassSet chainSubClassSet = new ChainSubClassSet(); ushort count = reader.ReadUInt16(); ushort[] subClassRuleOffsets = Utils.ReadUInt16Array(reader, count); - ChainSubClassRuleTable[] subClassRuleTables = chainSubClassSet.subClassRuleTables = new ChainSubClassRuleTable[count]; + ChainSubClassRuleTable[] subClassRuleTables = new ChainSubClassRuleTable[count]; for (int i = 0; i < count; ++i) { subClassRuleTables[i] = ChainSubClassRuleTable.CreateFrom(reader, beginAt + subClassRuleOffsets[i]); } - return chainSubClassSet; + return new ChainSubClassSet(subClassRuleTables); } } class ChainSubClassRuleTable @@ -962,29 +994,43 @@ class ChainSubClassRuleTable ushort[] inputClassDefs; ushort[] lookaheadClassDefs; SubstLookupRecord[] subsLookupRecords; + + public ChainSubClassRuleTable(ushort[] backtrakcingClassDefs, ushort[] inputClassDefs, ushort[] lookaheadClassDefs, SubstLookupRecord[] subsLookupRecords) + { + this.backtrakcingClassDefs = backtrakcingClassDefs; + this.inputClassDefs = inputClassDefs; + this.lookaheadClassDefs = lookaheadClassDefs; + this.subsLookupRecords = subsLookupRecords; + } + public static ChainSubClassRuleTable CreateFrom(BinaryReader reader, long beginAt) { reader.BaseStream.Seek(beginAt, SeekOrigin.Begin); - ChainSubClassRuleTable subClassRuleTable = new ChainSubClassRuleTable(); ushort backtrackingCount = reader.ReadUInt16(); - subClassRuleTable.backtrakcingClassDefs = Utils.ReadUInt16Array(reader, backtrackingCount); + var backtrakcingClassDefs = Utils.ReadUInt16Array(reader, backtrackingCount); ushort inputGlyphCount = reader.ReadUInt16(); - subClassRuleTable.inputClassDefs = Utils.ReadUInt16Array(reader, inputGlyphCount - 1);//** -1 + var inputClassDefs = Utils.ReadUInt16Array(reader, inputGlyphCount - 1);//** -1 ushort lookaheadGlyphCount = reader.ReadUInt16(); - subClassRuleTable.lookaheadClassDefs = Utils.ReadUInt16Array(reader, lookaheadGlyphCount); + var lookaheadClassDefs = Utils.ReadUInt16Array(reader, lookaheadGlyphCount); ushort substCount = reader.ReadUInt16(); - subClassRuleTable.subsLookupRecords = SubstLookupRecord.CreateSubstLookupRecords(reader, substCount); + var subsLookupRecords = SubstLookupRecord.CreateSubstLookupRecords(reader, substCount); - return subClassRuleTable; + return new ChainSubClassRuleTable(backtrakcingClassDefs, inputClassDefs, lookaheadClassDefs, subsLookupRecords); } } //------------------------------------------------------------- class LkSubTableT6Fmt1 : LookupSubTable { - public CoverageTable CoverageTable { get; set; } + public LkSubTableT6Fmt1(ChainSubRuleSetTable[] subRuleSets, CoverageTable coverageTable) + { + SubRuleSets = subRuleSets; + CoverageTable = coverageTable; + } + public ChainSubRuleSetTable[] SubRuleSets { get; set; } + public CoverageTable CoverageTable { get; set; } public override bool DoSubstitutionAt(IGlyphIndexList glyphIndices, int pos, int len) { Utils.WarnUnimplemented("Lookup Subtable Type 6 Format 1"); @@ -998,11 +1044,20 @@ public override void CollectAssociatedSubtitutionGlyphs(List outputAssoc class LkSubTableT6Fmt2 : LookupSubTable { - public CoverageTable CoverageTable { get; set; } + public LkSubTableT6Fmt2(ClassDefTable backtrackClassDef, ClassDefTable inputClassDef, ClassDefTable lookaheadClassDef, ChainSubClassSet[] chainSubClassSets, CoverageTable coverageTable) + { + BacktrackClassDef = backtrackClassDef; + InputClassDef = inputClassDef; + LookaheadClassDef = lookaheadClassDef; + ChainSubClassSets = chainSubClassSets; + CoverageTable = coverageTable; + } + public ClassDefTable BacktrackClassDef { get; set; } public ClassDefTable InputClassDef { get; set; } public ClassDefTable LookaheadClassDef { get; set; } public ChainSubClassSet[] ChainSubClassSets { get; set; } + public CoverageTable CoverageTable { get; set; } public override bool DoSubstitutionAt(IGlyphIndexList glyphIndices, int pos, int len) { Utils.WarnUnimplemented("Lookup Subtable Type 6 Format 2"); @@ -1016,10 +1071,19 @@ public override void CollectAssociatedSubtitutionGlyphs(List outputAssoc class LkSubTableT6Fmt3 : LookupSubTable { + public LkSubTableT6Fmt3(GSUB ownerGSub, SubstLookupRecord[] substLookupRecords, CoverageTable[] backtrackingCoverages, CoverageTable[] inputCoverages, CoverageTable[] lookaheadCoverages) + { + _ownerGSub = ownerGSub; + SubstLookupRecords = substLookupRecords; + BacktrackingCoverages = backtrackingCoverages; + InputCoverages = inputCoverages; + LookaheadCoverages = lookaheadCoverages; + } + private readonly GSUB _ownerGSub; + public SubstLookupRecord[] SubstLookupRecords { get; set; } public CoverageTable[] BacktrackingCoverages { get; set; } public CoverageTable[] InputCoverages { get; set; } public CoverageTable[] LookaheadCoverages { get; set; } - public SubstLookupRecord[] SubstLookupRecords { get; set; } public override bool DoSubstitutionAt(IGlyphIndexList glyphIndices, int pos, int len) { @@ -1064,7 +1128,7 @@ public override bool DoSubstitutionAt(IGlyphIndexList glyphIndices, int pos, int ushort replaceAt = lookupRecord.sequenceIndex; ushort lookupIndex = lookupRecord.lookupListIndex; - LookupTable anotherLookup = OwnerGSub.LookupList[lookupIndex]; + LookupTable anotherLookup = _ownerGSub.LookupList[lookupIndex]; if (anotherLookup.DoSubstitutionAt(glyphIndices, pos + replaceAt, len - replaceAt)) { hasChanged = true; @@ -1080,7 +1144,7 @@ public override void CollectAssociatedSubtitutionGlyphs(List outputAssoc ushort replaceAt = lookupRecord.sequenceIndex; ushort lookupIndex = lookupRecord.lookupListIndex; - LookupTable anotherLookup = OwnerGSub.LookupList[lookupIndex]; + LookupTable anotherLookup = _ownerGSub.LookupList[lookupIndex]; anotherLookup.CollectAssociatedSubstitutionGlyph(outputAssocGlyphs); } } @@ -1090,7 +1154,7 @@ public override void CollectAssociatedSubtitutionGlyphs(List outputAssoc /// LookupType 6: Chaining Contextual Substitution Subtable /// /// - LookupSubTable ReadLookupType6(BinaryReader reader, long subTableStartAt) + LookupSubTable ReadLookupType6(BinaryReader reader, long subTableStartAt, GSUB ownerGSub) { //LookupType 6: Chaining Contextual Substitution Subtable //A Chaining Contextual Substitution subtable (ChainContextSubst) describes glyph substitutions in context with an ability to look back and/or look ahead @@ -1120,18 +1184,17 @@ LookupSubTable ReadLookupType6(BinaryReader reader, long subTableStartAt) //Offset16 ChainSubRuleSet[ChainSubRuleSetCount] Array of offsets to ChainSubRuleSet tables-from beginning of Substitution table-ordered by Coverage Index //------------------------------- - var subTable = new LkSubTableT6Fmt1(); ushort coverage = reader.ReadUInt16(); ushort chainSubRulesetCount = reader.ReadUInt16(); ushort[] chainSubRulesetOffsets = Utils.ReadUInt16Array(reader, chainSubRulesetCount); - ChainSubRuleSetTable[] subRuleSets = subTable.SubRuleSets = new ChainSubRuleSetTable[chainSubRulesetCount]; + ChainSubRuleSetTable[] subRuleSets = new ChainSubRuleSetTable[chainSubRulesetCount]; for (int n = 0; n < chainSubRulesetCount; ++n) { subRuleSets[n] = ChainSubRuleSetTable.CreateFrom(reader, subTableStartAt + chainSubRulesetOffsets[n]); } //---------------------------- - subTable.CoverageTable = CoverageTable.CreateFrom(reader, subTableStartAt + coverage); - return subTable; + var coverageTable = CoverageTable.CreateFrom(reader, subTableStartAt + coverage); + return new LkSubTableT6Fmt1(subRuleSets, coverageTable); } case 2: { @@ -1147,7 +1210,6 @@ LookupSubTable ReadLookupType6(BinaryReader reader, long subTableStartAt) //uint16 ChainSubClassSetCnt Number of ChainSubClassSet tables //Offset16 ChainSubClassSet[ChainSubClassSetCnt] Array of offsets to ChainSubClassSet tables-from beginning of Substitution table-ordered by input class-may be NULL //------------------- - var subTable = new LkSubTableT6Fmt2(); ushort coverage = reader.ReadUInt16(); ushort backtrackClassDefOffset = reader.ReadUInt16(); ushort inputClassDefOffset = reader.ReadUInt16(); @@ -1155,20 +1217,18 @@ LookupSubTable ReadLookupType6(BinaryReader reader, long subTableStartAt) ushort chainSubClassSetCount = reader.ReadUInt16(); ushort[] chainSubClassSetOffsets = Utils.ReadUInt16Array(reader, chainSubClassSetCount); // - subTable.BacktrackClassDef = ClassDefTable.CreateFrom(reader, subTableStartAt + backtrackClassDefOffset); - subTable.InputClassDef = ClassDefTable.CreateFrom(reader, subTableStartAt + inputClassDefOffset); - subTable.LookaheadClassDef = ClassDefTable.CreateFrom(reader, subTableStartAt + lookaheadClassDefOffset); - if (chainSubClassSetCount != 0) + var backtrackClassDef = ClassDefTable.CreateFrom(reader, subTableStartAt + backtrackClassDefOffset); + var inputClassDef = ClassDefTable.CreateFrom(reader, subTableStartAt + inputClassDefOffset); + var lookaheadClassDef = ClassDefTable.CreateFrom(reader, subTableStartAt + lookaheadClassDefOffset); + + ChainSubClassSet[] chainSubClassSets = new ChainSubClassSet[chainSubClassSetCount]; + for (int n = 0; n < chainSubClassSetCount; ++n) { - ChainSubClassSet[] chainSubClassSets = subTable.ChainSubClassSets = new ChainSubClassSet[chainSubClassSetCount]; - for (int n = 0; n < chainSubClassSetCount; ++n) - { - chainSubClassSets[n] = ChainSubClassSet.CreateFrom(reader, subTableStartAt + chainSubClassSetOffsets[n]); - } + chainSubClassSets[n] = ChainSubClassSet.CreateFrom(reader, subTableStartAt + chainSubClassSetOffsets[n]); } - subTable.CoverageTable = CoverageTable.CreateFrom(reader, subTableStartAt + coverage); - return subTable; + var coverageTable = CoverageTable.CreateFrom(reader, subTableStartAt + coverage); + return new LkSubTableT6Fmt2(backtrackClassDef, inputClassDef, lookaheadClassDef, chainSubClassSets, coverageTable); } case 3: { @@ -1184,7 +1244,6 @@ LookupSubTable ReadLookupType6(BinaryReader reader, long subTableStartAt) //uint16 SubstCount Number of SubstLookupRecords //struct SubstLookupRecord[SubstCount] Array of SubstLookupRecords, in design order //------------------- - LkSubTableT6Fmt3 subTable = new LkSubTableT6Fmt3(); ushort backtrackingGlyphCount = reader.ReadUInt16(); ushort[] backtrackingCoverageOffsets = Utils.ReadUInt16Array(reader, backtrackingGlyphCount); ushort inputGlyphCount = reader.ReadUInt16(); @@ -1192,13 +1251,13 @@ LookupSubTable ReadLookupType6(BinaryReader reader, long subTableStartAt) ushort lookAheadGlyphCount = reader.ReadUInt16(); ushort[] lookAheadCoverageOffsets = Utils.ReadUInt16Array(reader, lookAheadGlyphCount); ushort substCount = reader.ReadUInt16(); - subTable.SubstLookupRecords = SubstLookupRecord.CreateSubstLookupRecords(reader, substCount); + var substLookupRecords = SubstLookupRecord.CreateSubstLookupRecords(reader, substCount); - subTable.BacktrackingCoverages = CoverageTable.CreateMultipleCoverageTables(subTableStartAt, backtrackingCoverageOffsets, reader); - subTable.InputCoverages = CoverageTable.CreateMultipleCoverageTables(subTableStartAt, inputGlyphCoverageOffsets, reader); - subTable.LookaheadCoverages = CoverageTable.CreateMultipleCoverageTables(subTableStartAt, lookAheadCoverageOffsets, reader); + var backtrackingCoverages = CoverageTable.CreateMultipleCoverageTables(subTableStartAt, backtrackingCoverageOffsets, reader); + var inputCoverages = CoverageTable.CreateMultipleCoverageTables(subTableStartAt, inputGlyphCoverageOffsets, reader); + var lookaheadCoverages = CoverageTable.CreateMultipleCoverageTables(subTableStartAt, lookAheadCoverageOffsets, reader); - return subTable; + return new LkSubTableT6Fmt3(ownerGSub, substLookupRecords, backtrackingCoverages, inputCoverages, lookaheadCoverages); } } } @@ -1207,7 +1266,7 @@ LookupSubTable ReadLookupType6(BinaryReader reader, long subTableStartAt) /// LookupType 7: Extension Substitution /// /// - LookupSubTable ReadLookupType7(BinaryReader reader, long subTableStartAt) + LookupSubTable ReadLookupType7(BinaryReader reader, long subTableStartAt, GSUB ownerGSub) { //LookupType 7: Extension Substitution //https://www.microsoft.com/typography/otspec/gsub.htm#ES @@ -1251,7 +1310,7 @@ LookupSubTable ReadLookupType7(BinaryReader reader, long subTableStartAt) } // Simply read the lookup table again with updated offsets lookupType = extensionLookupType; - LookupSubTable subTable = ReadSubTable(reader, subTableStartAt + extensionOffset); + LookupSubTable subTable = ReadSubTable(reader, subTableStartAt + extensionOffset, ownerGSub); // FIXME: this is a bit hackish, try to find a better construct lookupType = 7; return subTable; diff --git a/Typography.OpenFont/Tables.AdvancedLayout/GlyphShapingTableEntry.cs b/Typography.OpenFont/Tables.AdvancedLayout/GlyphShapingTableEntry.cs index 615895d7..93a93b31 100644 --- a/Typography.OpenFont/Tables.AdvancedLayout/GlyphShapingTableEntry.cs +++ b/Typography.OpenFont/Tables.AdvancedLayout/GlyphShapingTableEntry.cs @@ -37,8 +37,7 @@ public abstract class GlyphShapingTableEntry : TableEntry public ScriptList ScriptList { get; private set; } public FeatureList FeatureList { get; private set; } - - protected override void ReadContentFrom(BinaryReader reader) + internal GlyphShapingTableEntry(TableHeader header, BinaryReader reader) : base(header, reader) { //------------------------------------------- // GPOS/GSUB Header diff --git a/Typography.OpenFont/Tables.AdvancedLayout/JustificationTable.cs b/Typography.OpenFont/Tables.AdvancedLayout/JustificationTable.cs index 466a370d..6b9f98ab 100644 --- a/Typography.OpenFont/Tables.AdvancedLayout/JustificationTable.cs +++ b/Typography.OpenFont/Tables.AdvancedLayout/JustificationTable.cs @@ -13,9 +13,8 @@ public partial class JSTF : TableEntry { //https://docs.microsoft.com/en-us/typography/opentype/spec/jstf - public const string _N = "JSTF"; - public override string Name => _N; - JstfScriptTable[] _jsftScriptTables; + public const string Name = "JSTF"; + JstfScriptTable[]? _jsftScriptTables; //The Justification table(JSTF) provides font developers with additional control over glyph substitution and //positioning in justified text. @@ -23,7 +22,7 @@ public partial class JSTF : TableEntry //Text-processing clients now have more options to expand or //shrink word and glyph spacing so text fills the specified line length. - protected override void ReadContentFrom(BinaryReader reader) + internal JSTF(TableHeader header, BinaryReader reader) : base(header, reader) { //test this with Arial font @@ -61,8 +60,7 @@ protected override void ReadContentFrom(BinaryReader reader) JstfScriptRecord rec = recs[i]; reader.BaseStream.Position = tableStartAt + rec.jstfScriptOffset; - JstfScriptTable jstfScriptTable = ReadJstfScriptTable(reader); - jstfScriptTable.ScriptTag = rec.jstfScriptTag; + JstfScriptTable jstfScriptTable = ReadJstfScriptTable(reader, rec.jstfScriptTag); _jsftScriptTables[i] = jstfScriptTable; } } @@ -79,14 +77,16 @@ public JstfScriptRecord(string jstfScriptTag, ushort jstfScriptOffset) public class JstfScriptTable { - public ushort[] extenderGlyphs; + public ushort[]? extenderGlyphs; public JstfLangSysRecord defaultLangSys; - public JstfLangSysRecord[] other; + public JstfLangSysRecord[]? other; - public JstfScriptTable() + public JstfScriptTable(string scriptTag) { + ScriptTag = scriptTag; } + public string ScriptTag { get; set; } #if DEBUG public override string ToString() @@ -96,7 +96,7 @@ public override string ToString() #endif } - static JstfScriptTable ReadJstfScriptTable(BinaryReader reader) + static JstfScriptTable ReadJstfScriptTable(BinaryReader reader, string scriptTag) { //A Justification Script(JstfScript) table describes the justification information for a single script. //It consists of an offset to a table that defines extender glyphs(extenderGlyphOffset), @@ -122,7 +122,7 @@ static JstfScriptTable ReadJstfScriptTable(BinaryReader reader) //uint16 jstfLangSysCount Number of JstfLangSysRecords in this table - may be zero(0) //JstfLangSysRecord jstfLangSysRecords[jstfLangSysCount] Array of JstfLangSysRecords, in alphabetical order by JstfLangSysTag - JstfScriptTable jstfScriptTable = new JstfScriptTable(); + JstfScriptTable jstfScriptTable = new JstfScriptTable(scriptTag); long tableStartAt = reader.BaseStream.Position; @@ -178,6 +178,10 @@ public struct JstfLangSysRecord { public JstfPriority[] jstfPriority; + public JstfLangSysRecord(JstfPriority[] jstfPriority) + { + this.jstfPriority = jstfPriority; + } } static JstfLangSysRecord ReadJstfLangSysRecord(BinaryReader reader) { @@ -213,7 +217,7 @@ static JstfLangSysRecord ReadJstfLangSysRecord(BinaryReader reader) jstPriorities[i] = ReadJstfPriority(reader); } - return new JstfLangSysRecord() { jstfPriority = jstPriorities }; + return new JstfLangSysRecord(jstPriorities); } diff --git a/Typography.OpenFont/Tables.AdvancedLayout/LigatureCaretListTable.cs b/Typography.OpenFont/Tables.AdvancedLayout/LigatureCaretListTable.cs index 3b28b4a4..44f60f89 100644 --- a/Typography.OpenFont/Tables.AdvancedLayout/LigatureCaretListTable.cs +++ b/Typography.OpenFont/Tables.AdvancedLayout/LigatureCaretListTable.cs @@ -29,11 +29,16 @@ class LigCaretList LigGlyph[] _ligGlyphs; CoverageTable _coverageTable; + public LigCaretList(LigGlyph[] ligGlyphs, CoverageTable coverageTable) + { + _ligGlyphs = ligGlyphs; + _coverageTable = coverageTable; + } + public static LigCaretList CreateFrom(BinaryReader reader, long beginAt) { reader.BaseStream.Seek(beginAt, SeekOrigin.Begin); //---- - LigCaretList ligcaretList = new LigCaretList(); ushort coverageOffset = reader.ReadUInt16(); ushort ligGlyphCount = reader.ReadUInt16(); ushort[] ligGlyphOffsets = Utils.ReadUInt16Array(reader, ligGlyphCount); @@ -42,9 +47,7 @@ public static LigCaretList CreateFrom(BinaryReader reader, long beginAt) { ligGlyphs[i] = LigGlyph.CreateFrom(reader, beginAt + ligGlyphOffsets[i]); } - ligcaretList._ligGlyphs = ligGlyphs; - ligcaretList._coverageTable = CoverageTable.CreateFrom(reader, beginAt + coverageOffset); - return ligcaretList; + return new LigCaretList(ligGlyphs, CoverageTable.CreateFrom(reader, beginAt + coverageOffset)); } } @@ -68,14 +71,17 @@ class LigGlyph { ushort[] _caretValueOffsets; + public LigGlyph(ushort[] caretValueOffsets) + { + _caretValueOffsets = caretValueOffsets; + } + public static LigGlyph CreateFrom(BinaryReader reader, long beginAt) { reader.BaseStream.Seek(beginAt, SeekOrigin.Begin); //---------- - LigGlyph ligGlyph = new LigGlyph(); ushort caretCount = reader.ReadUInt16(); - ligGlyph._caretValueOffsets = Utils.ReadUInt16Array(reader, caretCount); - return ligGlyph; + return new LigGlyph(Utils.ReadUInt16Array(reader, caretCount)); } } @@ -195,21 +201,26 @@ class MarkGlyphSetsTable ushort _format; uint[] _coverageOffset; + public MarkGlyphSetsTable(ushort format, uint[] coverageOffset) + { + _format = format; + _coverageOffset = coverageOffset; + } + public static MarkGlyphSetsTable CreateFrom(BinaryReader reader, long beginAt) { reader.BaseStream.Seek(beginAt, SeekOrigin.Begin); // - MarkGlyphSetsTable markGlyphSetsTable = new MarkGlyphSetsTable(); - markGlyphSetsTable._format = reader.ReadUInt16(); + var format = reader.ReadUInt16(); ushort markSetCount = reader.ReadUInt16(); - uint[] coverageOffset = markGlyphSetsTable._coverageOffset = new uint[markSetCount]; + uint[] coverageOffset = new uint[markSetCount]; for (int i = 0; i < markSetCount; ++i) { //Note that the array of offsets for the Coverage tables uses ULONG coverageOffset[i] = reader.ReadUInt32();// } - return markGlyphSetsTable; + return new MarkGlyphSetsTable(format, coverageOffset); } } } \ No newline at end of file diff --git a/Typography.OpenFont/Tables.AdvancedLayout/MathTable.cs b/Typography.OpenFont/Tables.AdvancedLayout/MathTable.cs index 9285391c..9327c842 100644 --- a/Typography.OpenFont/Tables.AdvancedLayout/MathTable.cs +++ b/Typography.OpenFont/Tables.AdvancedLayout/MathTable.cs @@ -369,10 +369,10 @@ public MathGlyphInfo(ushort glyphIndex) public bool IsShapeExtensible { get; internal set; } //optional - public MathKern TopLeftMathKern => _mathKernRec.TopLeft; - public MathKern TopRightMathKern => _mathKernRec.TopRight; - public MathKern BottomLeftMathKern => _mathKernRec.BottomLeft; - public MathKern BottomRightMathKern => _mathKernRec.BottomRight; + public MathKern? TopLeftMathKern => _mathKernRec.TopLeft; + public MathKern? TopRightMathKern => _mathKernRec.TopRight; + public MathKern? BottomLeftMathKern => _mathKernRec.BottomLeft; + public MathKern? BottomRightMathKern => _mathKernRec.BottomRight; public bool HasSomeMathKern { get; private set; } // @@ -386,18 +386,23 @@ internal void SetMathKerns(MathKernInfoRecord mathKernRec) /// /// vertical glyph construction /// - public MathGlyphConstruction VertGlyphConstruction; + public MathGlyphConstruction? VertGlyphConstruction; /// /// horizontal glyph construction /// - public MathGlyphConstruction HoriGlyphConstruction; + public MathGlyphConstruction? HoriGlyphConstruction; } public class MathGlyphConstruction { - public MathValueRecord GlyphAsm_ItalicCorrection; - public GlyphPartRecord[] GlyphAsm_GlyphPartRecords; - public MathGlyphVariantRecord[] glyphVariantRecords; + public MathGlyphVariantRecord[] GlyphVariantRecords; + public (MathValueRecord ItalicCorrection, GlyphPartRecord[] GlyphPartRecords)? GlyphAsm; + + public MathGlyphConstruction(MathGlyphVariantRecord[] glyphVariantRecords, (MathValueRecord ItalicCorrection, GlyphPartRecord[] GlyphPartRecords)? glyphAsm) + { + GlyphVariantRecords = glyphVariantRecords; + GlyphAsm = glyphAsm; + } } @@ -513,16 +518,16 @@ public override string ToString() struct MathKernInfoRecord { //resolved value - public readonly MathKern TopRight; - public readonly MathKern TopLeft; - public readonly MathKern BottomRight; - public readonly MathKern BottomLeft; - public MathKernInfoRecord(MathKern topRight, - MathKern topLeft, - MathKern bottomRight, - MathKern bottomLeft) + public readonly MathKern? TopRight; + public readonly MathKern? TopLeft; + public readonly MathKern? BottomRight; + public readonly MathKern? BottomLeft; + public MathKernInfoRecord(MathKern? topRight, + MathKern? topLeft, + MathKern? bottomRight, + MathKern? bottomLeft) { - TopRight = topLeft; + TopRight = topRight; TopLeft = topLeft; BottomRight = bottomRight; BottomLeft = bottomLeft; @@ -560,14 +565,14 @@ struct MathGlyphLoader static MathGlyphInfo GetMathGlyphOrCreateNew(MathGlyphInfo[] mathGlyphInfos, ushort glyphIndex) { - return mathGlyphInfos[glyphIndex] ?? (mathGlyphInfos[glyphIndex] = new MathGlyphInfo(glyphIndex)); + return mathGlyphInfos[glyphIndex] ??= new MathGlyphInfo(glyphIndex); } public void LoadMathGlyph(Typeface typeface, MathTable mathTable) { //expand math info to each glyph in typeface typeface._mathTable = mathTable; - Glyph[] allGlyphs = typeface.GetRawGlyphList(); + Glyph[] allGlyphs = typeface.Glyphs; //expand all information to the glyph int glyphCount = allGlyphs.Length; @@ -621,10 +626,10 @@ public void LoadMathGlyph(Typeface typeface, MathTable mathTable) { //2.4 math kern index = 0; //reset - if (mathTable._mathKernInfoCoverage != null) + if (mathTable._mathKernInfo is var (mathKernInfoRecords, mathKernInfoCoverage)) { - MathKernInfoRecord[] kernRecs = mathTable._mathKernInfoRecords; - foreach (ushort glyphIndex in mathTable._mathKernInfoCoverage.GetExpandedValueIter()) + MathKernInfoRecord[] kernRecs = mathKernInfoRecords; + foreach (ushort glyphIndex in mathKernInfoCoverage.GetExpandedValueIter()) { GetMathGlyphOrCreateNew(mathGlyphInfos, glyphIndex).SetMathKerns(kernRecs[index]); index++; @@ -672,12 +677,10 @@ public void LoadMathGlyph(Typeface typeface, MathTable mathTable) class MathTable : TableEntry { - public const string _N = "MATH"; - public override string Name => _N; + public const string Name = "MATH"; // internal MathConstants _mathConstTable; - - protected override void ReadContentFrom(BinaryReader reader) + internal MathTable(TableHeader header, BinaryReader reader) : base(header, reader) { //eg. latin-modern-math-regular.otf, asana-math.otf @@ -699,15 +702,16 @@ protected override void ReadContentFrom(BinaryReader reader) //(1) reader.BaseStream.Position = beginAt + mathConstants_offset; - ReadMathConstantsTable(reader); + _mathConstTable = ReadMathConstantsTable(reader); // //(2) reader.BaseStream.Position = beginAt + mathGlyphInfo_offset; - ReadMathGlyphInfoTable(reader); + (_mathItalicCorrectionInfo, _mathTopAccentAttachmentTable, _extendedShapeCoverageTable, _mathKernInfo) = + ReadMathGlyphInfoTable(reader); // //(3) reader.BaseStream.Position = beginAt + mathVariants_offset; - ReadMathVariantsTable(reader); + _mathVariantsTable = ReadMathVariantsTable(reader); //NOTE: expose MinConnectorOverlap via _mathConstTable _mathConstTable.MinConnectorOverlap = _mathVariantsTable.MinConnectorOverlap; @@ -716,7 +720,7 @@ protected override void ReadContentFrom(BinaryReader reader) /// (1) MathConstants /// /// - void ReadMathConstantsTable(BinaryReader reader) + MathConstants ReadMathConstantsTable(BinaryReader reader) { //MathConstants Table @@ -808,8 +812,7 @@ void ReadMathConstantsTable(BinaryReader reader) mc.RadicalKernAfterDegree = reader.ReadMathValueRecord(); mc.RadicalDegreeBottomRaisePercent = reader.ReadInt16(); - - _mathConstTable = mc; + return mc; } @@ -819,7 +822,8 @@ void ReadMathConstantsTable(BinaryReader reader) /// (2) MathGlyphInfo /// /// - void ReadMathGlyphInfoTable(BinaryReader reader) + (MathItalicsCorrectonInfoTable, MathTopAccentAttachmentTable, CoverageTable? extendedShapeCoverageTable, + (MathKernInfoRecord[], CoverageTable)? mathKernInfo) ReadMathGlyphInfoTable(BinaryReader reader) { //MathGlyphInfo Table @@ -842,11 +846,11 @@ void ReadMathGlyphInfoTable(BinaryReader reader) //(2.1) reader.BaseStream.Position = startAt + offsetTo_MathItalicsCorrectionInfo_Table; - ReadMathItalicCorrectionInfoTable(reader); + var italicCorrectionInfo = ReadMathItalicCorrectionInfoTable(reader); //(2.2) reader.BaseStream.Position = startAt + offsetTo_MathTopAccentAttachment_Table; - ReadMathTopAccentAttachment(reader); + var topAccentAttachment = ReadMathTopAccentAttachment(reader); // @@ -861,6 +865,7 @@ void ReadMathGlyphInfoTable(BinaryReader reader) //.... + CoverageTable? extendedShapeCoverageTable = null; //(2.3) if (offsetTo_Extended_Shape_coverage_Table > 0) { @@ -868,14 +873,16 @@ void ReadMathGlyphInfoTable(BinaryReader reader) _extendedShapeCoverageTable = CoverageTable.CreateFrom(reader, startAt + offsetTo_Extended_Shape_coverage_Table); } + (MathKernInfoRecord[], CoverageTable)? mathKernInfo = null; //(2.4) if (offsetTo_MathKernInfo_Table > 0) { //may be null, eg. latin-modern-math.otf => not found //we found this in Asana-math-regular reader.BaseStream.Position = startAt + offsetTo_MathKernInfo_Table; - ReadMathKernInfoTable(reader); + mathKernInfo = ReadMathKernInfoTable(reader); } + return (italicCorrectionInfo, topAccentAttachment, extendedShapeCoverageTable, mathKernInfo); } @@ -886,11 +893,9 @@ void ReadMathGlyphInfoTable(BinaryReader reader) /// /// (2.1) /// - /// - void ReadMathItalicCorrectionInfoTable(BinaryReader reader) + MathItalicsCorrectonInfoTable ReadMathItalicCorrectionInfoTable(BinaryReader reader) { long beginAt = reader.BaseStream.Position; - _mathItalicCorrectionInfo = new MathItalicsCorrectonInfoTable(); //MathItalicsCorrectionInfo Table //Type Name Description //Offset16 Coverage Offset to Coverage table - from the beginning of MathItalicsCorrectionInfo table. @@ -898,13 +903,15 @@ void ReadMathItalicCorrectionInfoTable(BinaryReader reader) //MathValueRecord ItalicsCorrection[ItalicsCorrectionCount] Array of MathValueRecords defining italics correction values for each covered glyph. ushort coverageOffset = reader.ReadUInt16(); ushort italicCorrectionCount = reader.ReadUInt16(); - _mathItalicCorrectionInfo.ItalicCorrections = reader.ReadMathValueRecords(italicCorrectionCount); + var italicCorrections = reader.ReadMathValueRecords(italicCorrectionCount); + CoverageTable? coverageTable = null; //read coverage ... if (coverageOffset > 0) { //may be null?, eg. found in font Linux Libertine Regular (https://sourceforge.net/projects/linuxlibertine/) - _mathItalicCorrectionInfo.CoverageTable = CoverageTable.CreateFrom(reader, beginAt + coverageOffset); + coverageTable = CoverageTable.CreateFrom(reader, beginAt + coverageOffset); } + return new MathItalicsCorrectonInfoTable(italicCorrections, coverageTable); } @@ -916,7 +923,7 @@ void ReadMathItalicCorrectionInfoTable(BinaryReader reader) /// (2.2) /// /// - void ReadMathTopAccentAttachment(BinaryReader reader) + MathTopAccentAttachmentTable ReadMathTopAccentAttachment(BinaryReader reader) { //MathTopAccentAttachment Table @@ -942,38 +949,34 @@ void ReadMathTopAccentAttachment(BinaryReader reader) long beginAt = reader.BaseStream.Position; - _mathTopAccentAttachmentTable = new MathTopAccentAttachmentTable(); ushort coverageOffset = reader.ReadUInt16(); ushort topAccentAttachmentCount = reader.ReadUInt16(); - _mathTopAccentAttachmentTable.TopAccentAttachment = reader.ReadMathValueRecords(topAccentAttachmentCount); + var topAccentAttachment = reader.ReadMathValueRecords(topAccentAttachmentCount); + CoverageTable? coverageTable = null; if (coverageOffset > 0) { //may be null?, eg. found in font Linux Libertine Regular (https://sourceforge.net/projects/linuxlibertine/) - _mathTopAccentAttachmentTable.CoverageTable = CoverageTable.CreateFrom(reader, beginAt + coverageOffset); + coverageTable = CoverageTable.CreateFrom(reader, beginAt + coverageOffset); } - + return new MathTopAccentAttachmentTable(topAccentAttachment, coverageTable); } /// /// (2.3) /// - internal CoverageTable _extendedShapeCoverageTable; + internal CoverageTable? _extendedShapeCoverageTable; /// /// (2.4) /// - internal CoverageTable _mathKernInfoCoverage; - /// - /// (2.4) - /// - internal MathKernInfoRecord[] _mathKernInfoRecords; + internal (MathKernInfoRecord[], CoverageTable)? _mathKernInfo; /// /// (2.4) /// /// - void ReadMathKernInfoTable(BinaryReader reader) + (MathKernInfoRecord[] mathKernInfoRecords, CoverageTable mathKernInfoCoverage) ReadMathKernInfoTable(BinaryReader reader) { // MathKernInfo Table @@ -1012,7 +1015,7 @@ void ReadMathKernInfoTable(BinaryReader reader) ushort[] allKernRecOffset = Utils.ReadUInt16Array(reader, 4 * mathKernCount);//*** //read each kern table - _mathKernInfoRecords = new MathKernInfoRecord[mathKernCount]; + var mathKernInfoRecords = new MathKernInfoRecord[mathKernCount]; int index = 0; ushort m_kern_offset = 0; @@ -1022,7 +1025,7 @@ void ReadMathKernInfoTable(BinaryReader reader) //top-right m_kern_offset = allKernRecOffset[index]; - MathKern topRight = null, topLeft = null, bottomRight = null, bottomLeft = null; + MathKern? topRight = null, topLeft = null, bottomRight = null, bottomLeft = null; if (m_kern_offset > 0) { @@ -1051,14 +1054,14 @@ void ReadMathKernInfoTable(BinaryReader reader) bottomLeft = ReadMathKernTable(reader); } - _mathKernInfoRecords[i] = new MathKernInfoRecord(topRight, topLeft, bottomRight, bottomLeft); + mathKernInfoRecords[i] = new MathKernInfoRecord(topRight, topLeft, bottomRight, bottomLeft); index += 4;//*** } //----- - _mathKernInfoCoverage = CoverageTable.CreateFrom(reader, beginAt + mathKernCoverage_offset); - + var mathKernInfoCoverage = CoverageTable.CreateFrom(reader, beginAt + mathKernCoverage_offset); + return (mathKernInfoRecords, mathKernInfoCoverage); } /// /// (2.4) @@ -1101,11 +1104,12 @@ static MathKern ReadMathKernTable(BinaryReader reader) /// (3) /// internal MathVariantsTable _mathVariantsTable; + /// /// (3) MathVariants /// /// - void ReadMathVariantsTable(BinaryReader reader) + MathVariantsTable ReadMathVariantsTable(BinaryReader reader) { //MathVariants Table @@ -1145,11 +1149,9 @@ void ReadMathVariantsTable(BinaryReader reader) //Offset16 VertGlyphConstruction[VertGlyphCount] Array of offsets to MathGlyphConstruction tables - from the beginning of the MathVariants table, for shapes growing in vertical direction. //Offset16 HorizGlyphConstruction[HorizGlyphCount] Array of offsets to MathGlyphConstruction tables - from the beginning of the MathVariants table, for shapes growing in horizontal direction. - _mathVariantsTable = new MathVariantsTable(); - long beginAt = reader.BaseStream.Position; // - _mathVariantsTable.MinConnectorOverlap = reader.ReadUInt16(); + var minConnectorOverlap = reader.ReadUInt16(); // ushort vertGlyphCoverageOffset = reader.ReadUInt16(); ushort horizGlyphCoverageOffset = reader.ReadUInt16(); @@ -1159,18 +1161,19 @@ void ReadMathVariantsTable(BinaryReader reader) ushort[] horizonGlyphConstructions = Utils.ReadUInt16Array(reader, horizGlyphCount); // - _mathVariantsTable.vertCoverage = CoverageTable.CreateFrom(reader, beginAt + vertGlyphCoverageOffset); + var vertCoverage = CoverageTable.CreateFrom(reader, beginAt + vertGlyphCoverageOffset); + CoverageTable? horizCoverage = null; if (horizGlyphCoverageOffset > 0) { //may be null?, eg. found in font Linux Libertine Regular (https://sourceforge.net/projects/linuxlibertine/) - _mathVariantsTable.horizCoverage = CoverageTable.CreateFrom(reader, beginAt + horizGlyphCoverageOffset); + horizCoverage = CoverageTable.CreateFrom(reader, beginAt + horizGlyphCoverageOffset); } //read math construction table //(3.1) //vertical - var vertGlyphConstructionTables = _mathVariantsTable.vertConstructionTables = new MathGlyphConstruction[vertGlyphCount]; + var vertGlyphConstructionTables = new MathGlyphConstruction[vertGlyphCount]; for (int i = 0; i < vertGlyphCount; ++i) { reader.BaseStream.Position = beginAt + vertGlyphConstructions[i]; @@ -1179,12 +1182,14 @@ void ReadMathVariantsTable(BinaryReader reader) //(3.2) //horizon - var horizGlyphConstructionTables = _mathVariantsTable.horizConstructionTables = new MathGlyphConstruction[horizGlyphCount]; + var horizGlyphConstructionTables = new MathGlyphConstruction[horizGlyphCount]; for (int i = 0; i < horizGlyphCount; ++i) { reader.BaseStream.Position = beginAt + horizonGlyphConstructions[i]; horizGlyphConstructionTables[i] = ReadMathGlyphConstructionTable(reader); } + + return new MathVariantsTable(minConnectorOverlap, vertCoverage, horizCoverage, vertGlyphConstructionTables, horizGlyphConstructionTables); } @@ -1224,12 +1229,10 @@ MathGlyphConstruction ReadMathGlyphConstructionTable(BinaryReader reader) long beginAt = reader.BaseStream.Position; - var glyphConstructionTable = new MathGlyphConstruction(); - ushort glyphAsmOffset = reader.ReadUInt16(); ushort variantCount = reader.ReadUInt16(); - var variantRecords = glyphConstructionTable.glyphVariantRecords = new MathGlyphVariantRecord[variantCount]; + var variantRecords = new MathGlyphVariantRecord[variantCount]; for (int i = 0; i < variantCount; ++i) { @@ -1239,21 +1242,21 @@ MathGlyphConstruction ReadMathGlyphConstructionTable(BinaryReader reader) ); } - + (MathValueRecord, GlyphPartRecord[])? glyphAsm = null; //read glyph asm table if (glyphAsmOffset > 0)//may be NULL { reader.BaseStream.Position = beginAt + glyphAsmOffset; - FillGlyphAssemblyInfo(reader, glyphConstructionTable); + glyphAsm = ReadGlyphAssemblyInfo(reader); } - return glyphConstructionTable; + return new MathGlyphConstruction(variantRecords, glyphAsm); } /// /// (3.1, 3.2,) /// /// /// - static void FillGlyphAssemblyInfo(BinaryReader reader, MathGlyphConstruction glyphConstruction) + static (MathValueRecord italicCorrection, GlyphPartRecord[] partRecords) ReadGlyphAssemblyInfo(BinaryReader reader) { //since MathGlyphConstructionTable: GlyphAssembly is 1:1 //--------- @@ -1278,9 +1281,9 @@ static void FillGlyphAssemblyInfo(BinaryReader reader, MathGlyphConstruction gly //Note that the glyphs comprising the assembly should be designed so that they align properly in the direction that is orthogonal to the direction of growth. - glyphConstruction.GlyphAsm_ItalicCorrection = reader.ReadMathValueRecord(); + var italicCorrection = reader.ReadMathValueRecord(); ushort partCount = reader.ReadUInt16(); - var partRecords = glyphConstruction.GlyphAsm_GlyphPartRecords = new GlyphPartRecord[partCount]; + var partRecords = new GlyphPartRecord[partCount]; for (int i = 0; i < partCount; ++i) { partRecords[i] = new GlyphPartRecord( @@ -1291,6 +1294,7 @@ static void FillGlyphAssemblyInfo(BinaryReader reader, MathGlyphConstruction gly reader.ReadUInt16() ); } + return (italicCorrection, partRecords); } @@ -1318,14 +1322,24 @@ class MathItalicsCorrectonInfoTable // When positioning superscripts and subscripts, their default horizontal positions are also different by the amount of the italics correction of the preceding glyph. public MathValueRecord[] ItalicCorrections; - public CoverageTable CoverageTable; - + public CoverageTable? CoverageTable; + public MathItalicsCorrectonInfoTable(MathValueRecord[] italicCorrections, CoverageTable? coverageTable) + { + ItalicCorrections = italicCorrections; + CoverageTable = coverageTable; + } } class MathTopAccentAttachmentTable { public MathValueRecord[] TopAccentAttachment; - public CoverageTable CoverageTable; + public CoverageTable? CoverageTable; + + public MathTopAccentAttachmentTable(MathValueRecord[] topAccentAttachment, CoverageTable? coverageTable) + { + TopAccentAttachment = topAccentAttachment; + CoverageTable = coverageTable; + } } @@ -1333,9 +1347,18 @@ class MathVariantsTable { public ushort MinConnectorOverlap; public CoverageTable vertCoverage; - public CoverageTable horizCoverage; + public CoverageTable? horizCoverage; public MathGlyphConstruction[] vertConstructionTables; public MathGlyphConstruction[] horizConstructionTables; + + public MathVariantsTable(ushort minConnectorOverlap, CoverageTable vertCoverage, CoverageTable? horizCoverage, MathGlyphConstruction[] vertConstructionTables, MathGlyphConstruction[] horizConstructionTables) + { + MinConnectorOverlap = minConnectorOverlap; + this.vertCoverage = vertCoverage; + this.horizCoverage = horizCoverage; + this.vertConstructionTables = vertConstructionTables; + this.horizConstructionTables = horizConstructionTables; + } } diff --git a/Typography.OpenFont/Tables.AdvancedLayout/ScriptLang.cs b/Typography.OpenFont/Tables.AdvancedLayout/ScriptLang.cs index 8a9ce5c5..4a41baa1 100644 --- a/Typography.OpenFont/Tables.AdvancedLayout/ScriptLang.cs +++ b/Typography.OpenFont/Tables.AdvancedLayout/ScriptLang.cs @@ -689,11 +689,11 @@ static ScriptLang _(string fullname, string shortname, params UnicodeLangBits[] return scriptLang; } } - public static bool TryGetUnicodeLangBitsArray(string langShortName, out UnicodeLangBits[] unicodeLangBits) + public static bool TryGetUnicodeLangBitsArray(string langShortName, [System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out UnicodeLangBits[]? unicodeLangBits) { return s_registeredScriptTagsToUnicodeLangBits.TryGetValue(langShortName, out unicodeLangBits); } - public static bool TryGetScriptLang(char c, out ScriptLang scLang) + public static bool TryGetScriptLang(char c, [System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out ScriptLang? scLang) { foreach (var kp in s_unicodeLangToScriptLang) { @@ -717,14 +717,14 @@ public static bool TryGetScriptLang(char c, out ScriptLang scLang) return false; } - public static ScriptLang GetRegisteredScriptLang(string shortname) + public static ScriptLang? GetRegisteredScriptLang(string shortname) { - s_registeredScriptTags.TryGetValue(shortname, out ScriptLang found); + s_registeredScriptTags.TryGetValue(shortname, out ScriptLang? found); return found; } - public static ScriptLang GetRegisteredScriptLangFromLanguageName(string languageName) + public static ScriptLang? GetRegisteredScriptLangFromLanguageName(string languageName) { - s_registerScriptFromFullNames.TryGetValue(languageName, out ScriptLang found); + s_registerScriptFromFullNames.TryGetValue(languageName, out ScriptLang? found); return found; } public static IEnumerable GetRegiteredScriptLangIter() diff --git a/Typography.OpenFont/Tables.AdvancedLayout/ScriptList.cs b/Typography.OpenFont/Tables.AdvancedLayout/ScriptList.cs index c78461e8..e324ba2c 100644 --- a/Typography.OpenFont/Tables.AdvancedLayout/ScriptList.cs +++ b/Typography.OpenFont/Tables.AdvancedLayout/ScriptList.cs @@ -13,9 +13,9 @@ public class ScriptList : Dictionary // Language system tables reference features, which are defined in the FeatureList. // Each feature table references the lookup data defined in the LookupList that describes how, when, and where to implement the feature. private ScriptList() { } - public new ScriptTable this[string tagName] + public new ScriptTable? this[string tagName] { - get { return TryGetValue(tagName, out ScriptTable ret) ? ret : null; } + get { return TryGetValue(tagName, out ScriptTable? ret) ? ret : null; } } public static ScriptList CreateFrom(BinaryReader reader, long beginAt) @@ -49,8 +49,7 @@ public static ScriptList CreateFrom(BinaryReader reader, long beginAt) // Read each table and add it to the dictionary for (int i = 0; i < scriptCount; ++i) { - ScriptTable scriptTable = ScriptTable.CreateFrom(reader, beginAt + scriptOffsets[i]); - scriptTable.scriptTag = scriptTags[i]; + ScriptTable scriptTable = ScriptTable.CreateFrom(reader, beginAt + scriptOffsets[i], scriptTags[i]); scriptList.Add(Utils.TagToString(scriptTags[i]), scriptTable); } diff --git a/Typography.OpenFont/Tables.AdvancedLayout/ScriptTable.cs b/Typography.OpenFont/Tables.AdvancedLayout/ScriptTable.cs index 6d2494c2..203f439b 100644 --- a/Typography.OpenFont/Tables.AdvancedLayout/ScriptTable.cs +++ b/Typography.OpenFont/Tables.AdvancedLayout/ScriptTable.cs @@ -65,12 +65,20 @@ namespace Typography.OpenFont.Tables //--------------------- public class ScriptTable { - public LangSysTable defaultLang; public LangSysTable[] langSysTables; + public LangSysTable? defaultLang; public uint scriptTag; + + public ScriptTable(LangSysTable[] langSysTables, LangSysTable? defaultLang, uint scriptTag) + { + this.langSysTables = langSysTables; + this.defaultLang = defaultLang; + this.scriptTag = scriptTag; + } + public string ScriptTagName => Utils.TagToString(this.scriptTag); - public static ScriptTable CreateFrom(BinaryReader reader, long beginAt) + public static ScriptTable CreateFrom(BinaryReader reader, long beginAt, uint scriptTag) { reader.BaseStream.Seek(beginAt, SeekOrigin.Begin); //--------------- @@ -80,10 +88,9 @@ public static ScriptTable CreateFrom(BinaryReader reader, long beginAt) //uint16 LangSysCount Number of LangSysRecords for this script-excluding the DefaultLangSys //struct LangSysRecord[LangSysCount] Array of LangSysRecords-listed alphabetically by LangSysTag //--------------- - ScriptTable scriptTable = new ScriptTable(); ushort defaultLangSysOffset = reader.ReadUInt16(); ushort langSysCount = reader.ReadUInt16(); - LangSysTable[] langSysTables = scriptTable.langSysTables = new LangSysTable[langSysCount]; + LangSysTable[] langSysTables = new LangSysTable[langSysCount]; for (int i = 0; i < langSysCount; ++i) { //----------------------- @@ -98,12 +105,13 @@ public static ScriptTable CreateFrom(BinaryReader reader, long beginAt) reader.ReadUInt16()); //offset } + LangSysTable? defaultLang = null; //----------- if (defaultLangSysOffset > 0) { - scriptTable.defaultLang = new LangSysTable(0, defaultLangSysOffset); + defaultLang = new LangSysTable(0, defaultLangSysOffset); reader.BaseStream.Seek(beginAt + defaultLangSysOffset, SeekOrigin.Begin); - scriptTable.defaultLang.ReadFrom(reader); + defaultLang.ReadFrom(reader); } @@ -116,7 +124,7 @@ public static ScriptTable CreateFrom(BinaryReader reader, long beginAt) langSysTable.ReadFrom(reader); } - return scriptTable; + return new ScriptTable(langSysTables, defaultLang, scriptTag); } @@ -137,7 +145,7 @@ public class LangSysTable public readonly ushort offset; // - public ushort[] featureIndexList { get; private set; } + public ushort[]? featureIndexList { get; private set; } public ushort RequireFeatureIndex { get; private set; } public LangSysTable(uint langSysTagIden, ushort offset) diff --git a/Typography.OpenFont/Tables.BitmapAndSvgFonts/BitmapFontsCommon.cs b/Typography.OpenFont/Tables.BitmapAndSvgFonts/BitmapFontsCommon.cs index 3797ec26..9b6d7b79 100644 --- a/Typography.OpenFont/Tables.BitmapAndSvgFonts/BitmapFontsCommon.cs +++ b/Typography.OpenFont/Tables.BitmapAndSvgFonts/BitmapFontsCommon.cs @@ -59,8 +59,8 @@ class BitmapSizeTable public sbyte flags; //----- - //reconstructed - public IndexSubTableBase[] indexSubTables; + // to be reconstructed in CBLC constructor + public IndexSubTableBase[] indexSubTables = new IndexSubTableBase[0]; // static void ReadSbitLineMetrics(BinaryReader reader, ref SbitLineMetrics lineMetric) { @@ -206,6 +206,11 @@ abstract class IndexSubTableBase public ushort firstGlyphIndex; public ushort lastGlyphIndex; + protected IndexSubTableBase(IndexSubHeader header) + { + this.header = header; + } + public static IndexSubTableBase CreateFrom(BitmapSizeTable bmpSizeTable, BinaryReader reader) { //read IndexSubHeader @@ -251,10 +256,7 @@ public static IndexSubTableBase CreateFrom(BitmapSizeTable bmpSizeTable, BinaryR int nElem = (bmpSizeTable.endGlyphIndex - bmpSizeTable.startGlyphIndex + 1); uint[] offsetArray = Utils.ReadUInt32Array(reader, nElem); //check 16 bit align padd - IndexSubTable1 subTable = new IndexSubTable1(); - subTable.header = header; - subTable.offsetArray = offsetArray; - return subTable; + return new IndexSubTable1(header, offsetArray); } case 2: //IndexSubTable2: all glyphs have identical metrics @@ -263,11 +265,9 @@ public static IndexSubTableBase CreateFrom(BitmapSizeTable bmpSizeTable, BinaryR //uint32 imageSize All the glyphs are of the same size. //BigGlyphMetrics bigMetrics All glyphs have the same metrics; glyph data may be compressed, byte-aligned, or bit-aligned. { - IndexSubTable2 subtable = new IndexSubTable2(); - subtable.header = header; - subtable.imageSize = reader.ReadUInt32(); - BigGlyphMetrics.ReadBigGlyphMetric(reader, ref subtable.BigGlyphMetrics); - return subtable; + var imageSize = reader.ReadUInt32(); + var bigGlyphMetrics = BigGlyphMetrics.ReadBigGlyphMetric(reader); + return new IndexSubTable2(header, imageSize, bigGlyphMetrics); } case 3: @@ -279,10 +279,7 @@ public static IndexSubTableBase CreateFrom(BitmapSizeTable bmpSizeTable, BinaryR int nElem = (bmpSizeTable.endGlyphIndex - bmpSizeTable.startGlyphIndex + 1); ushort[] offsetArray = Utils.ReadUInt16Array(reader, nElem); //check 16 bit align padd - IndexSubTable3 subTable = new IndexSubTable3(); - subTable.header = header; - subTable.offsetArray = offsetArray; - return subTable; + return new IndexSubTable3(header, offsetArray); } case 4: //IndexSubTable4: variable - metrics glyphs with sparse glyph codes @@ -291,16 +288,13 @@ public static IndexSubTableBase CreateFrom(BitmapSizeTable bmpSizeTable, BinaryR //uint32 numGlyphs Array length. //GlyphIdOffsetPair glyphArray[numGlyphs + 1] One per glyph. { - IndexSubTable4 subTable = new IndexSubTable4(); - subTable.header = header; - uint numGlyphs = reader.ReadUInt32(); - GlyphIdOffsetPair[] glyphArray = subTable.glyphArray = new GlyphIdOffsetPair[numGlyphs + 1]; + GlyphIdOffsetPair[] glyphArray = new GlyphIdOffsetPair[numGlyphs + 1]; for (int i = 0; i <= numGlyphs; ++i) //*** { glyphArray[i] = new GlyphIdOffsetPair(reader.ReadUInt16(), reader.ReadUInt16()); } - return subTable; + return new IndexSubTable4(header, glyphArray); } case 5: //IndexSubTable5: constant - metrics glyphs with sparse glyph codes @@ -311,13 +305,10 @@ public static IndexSubTableBase CreateFrom(BitmapSizeTable bmpSizeTable, BinaryR //uint32 numGlyphs Array length. //uint16 glyphIdArray[numGlyphs] One per glyph, sorted by glyph ID. { - IndexSubTable5 subTable = new IndexSubTable5(); - subTable.header = header; - - subTable.imageSize = reader.ReadUInt32(); - BigGlyphMetrics.ReadBigGlyphMetric(reader, ref subTable.BigGlyphMetrics); - subTable.glyphIdArray = Utils.ReadUInt16Array(reader, (int)reader.ReadUInt32()); - return subTable; + var imageSize = reader.ReadUInt32(); + var bigGlyphMetrics = BigGlyphMetrics.ReadBigGlyphMetric(reader); + var glyphIdArray = Utils.ReadUInt16Array(reader, (int)reader.ReadUInt32()); + return new IndexSubTable5(header, imageSize, bigGlyphMetrics, glyphIdArray); } } @@ -358,8 +349,7 @@ public static IndexSubTableBase CreateFrom(BitmapSizeTable bmpSizeTable, BinaryR //When there is an odd number of elements in these arrays //**it is necessary to add an extra padding element to maintain proper alignment. - - return null; + throw new NotSupportedException(); } public abstract void BuildGlyphList(List glyphList); @@ -372,6 +362,11 @@ class IndexSubTable1 : IndexSubTableBase public override int SubTypeNo => 1; public uint[] offsetArray; + public IndexSubTable1(IndexSubHeader header, uint[] offsetArray) : base(header) + { + this.offsetArray = offsetArray; + } + public override void BuildGlyphList(List glyphList) { int n = 0; @@ -389,7 +384,13 @@ class IndexSubTable2 : IndexSubTableBase { public override int SubTypeNo => 2; public uint imageSize; - public BigGlyphMetrics BigGlyphMetrics = new BigGlyphMetrics(); + + public BigGlyphMetrics BigGlyphMetrics; + public IndexSubTable2(IndexSubHeader header, uint imageSize, BigGlyphMetrics bigGlyphMetrics) : base(header) + { + this.imageSize = imageSize; + this.BigGlyphMetrics = bigGlyphMetrics; + } public override void BuildGlyphList(List glyphList) { uint incrementalOffset = 0;//TODO: review this @@ -407,6 +408,11 @@ class IndexSubTable3 : IndexSubTableBase { public override int SubTypeNo => 3; public ushort[] offsetArray; + + public IndexSubTable3(IndexSubHeader header, ushort[] offsetArray) : base(header) + { + this.offsetArray = offsetArray; + } public override void BuildGlyphList(List glyphList) { int n = 0; @@ -423,6 +429,11 @@ class IndexSubTable4 : IndexSubTableBase { public override int SubTypeNo => 4; public GlyphIdOffsetPair[] glyphArray; + + public IndexSubTable4(IndexSubHeader header, GlyphIdOffsetPair[] glyphArray) : base(header) + { + this.glyphArray = glyphArray; + } public override void BuildGlyphList(List glyphList) { for (int i = 0; i < glyphArray.Length; ++i) @@ -439,9 +450,16 @@ class IndexSubTable5 : IndexSubTableBase { public override int SubTypeNo => 5; public uint imageSize; - public BigGlyphMetrics BigGlyphMetrics = new BigGlyphMetrics(); + public BigGlyphMetrics BigGlyphMetrics; public ushort[] glyphIdArray; + + public IndexSubTable5(IndexSubHeader header, uint imageSize, BigGlyphMetrics bigGlyphMetrics, ushort[] glyphIdArray) : base(header) + { + this.imageSize = imageSize; + this.BigGlyphMetrics = bigGlyphMetrics; + this.glyphIdArray = glyphIdArray; + } public override void BuildGlyphList(List glyphList) { uint incrementalOffset = 0;//TODO: review this @@ -494,10 +512,12 @@ struct BigGlyphMetrics public sbyte vertBearingY; public byte vertAdvance; - public const int SIZE = 8; //size of BigGlyphMetrics - - public static void ReadBigGlyphMetric(BinaryReader reader, ref BigGlyphMetrics output) + public const int SIZE = 8; //size of BigGlyphMetrics = 8 bytes = pointer size on 64-bit systems + // NOTE! Microsoft recommendation: all structs less than 16 bytes in size can be passed by value, no need for "ref" + // https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/choosing-between-class-and-struct + public static BigGlyphMetrics ReadBigGlyphMetric(BinaryReader reader) { + var output = new BigGlyphMetrics(); output.height = reader.ReadByte(); output.width = reader.ReadByte(); @@ -508,6 +528,7 @@ public static void ReadBigGlyphMetric(BinaryReader reader, ref BigGlyphMetrics o output.vertBearingX = (sbyte)reader.ReadByte(); output.vertBearingY = (sbyte)reader.ReadByte(); output.vertAdvance = reader.ReadByte(); + return output; } } @@ -526,15 +547,17 @@ struct SmallGlyphMetrics public sbyte bearingY; public byte advance; - public const int SIZE = 5; //size of SmallGlyphMetrics - public static void ReadSmallGlyphMetric(BinaryReader reader, ref SmallGlyphMetrics output) + public const int SIZE = 5; //size of SmallGlyphMetrics = 5 bytes + public static SmallGlyphMetrics ReadSmallGlyphMetric(BinaryReader reader) { + var output = new SmallGlyphMetrics(); output.height = reader.ReadByte(); output.width = reader.ReadByte(); output.bearingX = (sbyte)reader.ReadByte(); output.bearingY = (sbyte)reader.ReadByte(); output.advance = reader.ReadByte(); + return output; } } @@ -709,7 +732,7 @@ class GlyphBitmapDataFmt8 : GlyphBitmapDataFormatBase public SmallGlyphMetrics smallMetrics; public byte pad; - public EbdtComponent[] components; + public EbdtComponent[]? components; //Format 8: small metrics, component data //Type Name Description //SmallGlyphMetrics smallMetrics Metrics information for the glyph @@ -734,7 +757,7 @@ class GlyphBitmapDataFmt9 : GlyphBitmapDataFormatBase { public override int FormatNumber => 9; public BigGlyphMetrics bigMetrics; - public EbdtComponent[] components; + public EbdtComponent[]? components; //Format 9: big metrics, component data //Type Name Description @@ -780,8 +803,7 @@ class GlyphBitmapDataFmt17 : GlyphBitmapDataFormatBase public override void FillGlyphInfo(BinaryReader reader, Glyph bitmapGlyph) { - SmallGlyphMetrics smallGlyphMetric = new SmallGlyphMetrics(); - SmallGlyphMetrics.ReadSmallGlyphMetric(reader, ref smallGlyphMetric); + var smallGlyphMetric = SmallGlyphMetrics.ReadSmallGlyphMetric(reader); uint dataLen = reader.ReadUInt32(); bitmapGlyph.OriginalAdvanceWidth = smallGlyphMetric.advance; bitmapGlyph.Bounds = new Bounds(0, 0, smallGlyphMetric.width, smallGlyphMetric.height); @@ -813,8 +835,7 @@ class GlyphBitmapDataFmt18 : GlyphBitmapDataFormatBase public override void FillGlyphInfo(BinaryReader reader, Glyph bitmapGlyph) { - BigGlyphMetrics bigGlyphMetric = new BigGlyphMetrics(); - BigGlyphMetrics.ReadBigGlyphMetric(reader, ref bigGlyphMetric); + BigGlyphMetrics bigGlyphMetric = BigGlyphMetrics.ReadBigGlyphMetric(reader); uint dataLen = reader.ReadUInt32(); bitmapGlyph.OriginalAdvanceWidth = bigGlyphMetric.horiAdvance; diff --git a/Typography.OpenFont/Tables.BitmapAndSvgFonts/CBDT.cs b/Typography.OpenFont/Tables.BitmapAndSvgFonts/CBDT.cs index 149bfae2..843f5c32 100644 --- a/Typography.OpenFont/Tables.BitmapAndSvgFonts/CBDT.cs +++ b/Typography.OpenFont/Tables.BitmapAndSvgFonts/CBDT.cs @@ -31,36 +31,28 @@ namespace Typography.OpenFont.Tables //byte alignment is sufficient. class CBDT : TableEntry, IDisposable { - public const string _N = "CBDT"; - public override string Name => _N; + public const string Name = "CBDT"; GlyphBitmapDataFmt17 _format17 = new GlyphBitmapDataFmt17(); GlyphBitmapDataFmt18 _format18 = new GlyphBitmapDataFmt18(); GlyphBitmapDataFmt19 _format19 = new GlyphBitmapDataFmt19(); - - System.IO.MemoryStream _ms; //sub-stream contains image data - Typography.OpenFont.IO.ByteOrderSwappingBinaryReader _binReader; + // BinaryReaders also dispose their underlying streams + IO.ByteOrderSwappingBinaryReader? _binReader; // underlying stream contains image data public void Dispose() { if (_binReader != null) { - ((System.IDisposable)_binReader).Dispose(); + ((IDisposable)_binReader).Dispose(); _binReader = null; } - if (_ms != null) - { - _ms.Dispose(); - _ms = null; - } } - protected override void ReadContentFrom(BinaryReader reader) + internal CBDT(TableHeader header, BinaryReader reader) : base(header, reader) { //we will read this later byte[] data = reader.ReadBytes((int)this.Header.Length);//*** - _ms = new MemoryStream(data); - _binReader = new IO.ByteOrderSwappingBinaryReader(_ms); + _binReader = new IO.ByteOrderSwappingBinaryReader(new MemoryStream(data)); //ushort majorVersion = reader.ReadUInt16(); //ushort minorVersion = reader.ReadUInt16(); @@ -69,9 +61,12 @@ protected override void ReadContentFrom(BinaryReader reader) } public void FillGlyphInfo(Glyph glyph) { + if (_binReader is null) throw new ObjectDisposedException(nameof(_binReader)); //int srcOffset, int srcLen, int srcFormat, - _binReader.BaseStream.Position = glyph.BitmapStreamOffset; - switch (glyph.BitmapFormat) + if (!(glyph.BitmapSVGInfo is { } bitmapSvg)) + throw new NotSupportedException("Only Bitmap/SVG glyphs are supported"); + _binReader.BaseStream.Position = bitmapSvg.streamOffset; + switch (bitmapSvg.imgFormat) { case 17: _format17.FillGlyphInfo(_binReader, glyph); break; case 18: _format18.FillGlyphInfo(_binReader, glyph); break; @@ -80,11 +75,14 @@ public void FillGlyphInfo(Glyph glyph) throw new NotSupportedException(); } } - public void CopyBitmapContent(Glyph glyph, System.IO.Stream outputStream) + public void CopyBitmapContent(Glyph glyph, Stream outputStream) { + if (_binReader is null) throw new ObjectDisposedException(nameof(_binReader)); //1 - _binReader.BaseStream.Position = glyph.BitmapStreamOffset; - switch (glyph.BitmapFormat) + if (!(glyph.BitmapSVGInfo is { } bitmapSvg)) + throw new NotSupportedException("Only Bitmap/SVG glyphs are supported"); + _binReader.BaseStream.Position = bitmapSvg.streamOffset; + switch (bitmapSvg.imgFormat) { case 17: _format17.ReadRawBitmap(_binReader, glyph, outputStream); break; case 18: _format18.ReadRawBitmap(_binReader, glyph, outputStream); break; diff --git a/Typography.OpenFont/Tables.BitmapAndSvgFonts/CBLC.cs b/Typography.OpenFont/Tables.BitmapAndSvgFonts/CBLC.cs index 26547ee5..be0264e5 100644 --- a/Typography.OpenFont/Tables.BitmapAndSvgFonts/CBLC.cs +++ b/Typography.OpenFont/Tables.BitmapAndSvgFonts/CBLC.cs @@ -36,10 +36,9 @@ class CBLC : TableEntry { BitmapSizeTable[] _bmpSizeTables; - public const string _N = "CBLC"; - public override string Name => _N; + public const string Name = "CBLC"; - protected override void ReadContentFrom(BinaryReader reader) + internal CBLC(TableHeader header, BinaryReader reader) : base(header, reader) { long cblcBeginPos = reader.BaseStream.Position; ushort majorVersion = reader.ReadUInt16(); //3 diff --git a/Typography.OpenFont/Tables.BitmapAndSvgFonts/EBDT.cs b/Typography.OpenFont/Tables.BitmapAndSvgFonts/EBDT.cs index 34857b61..dba7cd82 100644 --- a/Typography.OpenFont/Tables.BitmapAndSvgFonts/EBDT.cs +++ b/Typography.OpenFont/Tables.BitmapAndSvgFonts/EBDT.cs @@ -35,10 +35,9 @@ namespace Typography.OpenFont.Tables /// class EBDT : TableEntry { - public const string _N = "EBDT"; - public override string Name => _N; + public const string Name = "EBDT"; - protected override void ReadContentFrom(BinaryReader reader) + internal EBDT(TableHeader header, BinaryReader reader) : base(header, reader) { ushort majorVersion = reader.ReadUInt16(); ushort minorVersion = reader.ReadUInt16(); diff --git a/Typography.OpenFont/Tables.BitmapAndSvgFonts/EBLC.cs b/Typography.OpenFont/Tables.BitmapAndSvgFonts/EBLC.cs index 79e1edfc..976d8647 100644 --- a/Typography.OpenFont/Tables.BitmapAndSvgFonts/EBLC.cs +++ b/Typography.OpenFont/Tables.BitmapAndSvgFonts/EBLC.cs @@ -12,8 +12,7 @@ namespace Typography.OpenFont.Tables /// class EBLC : TableEntry { - public const string _N = "EBLC"; - public override string Name => _N; + public const string Name = "EBLC"; // //from https://docs.microsoft.com/en-us/typography/opentype/spec/eblc //EBLC - Embedded Bitmap Location Table @@ -37,7 +36,7 @@ class EBLC : TableEntry //Each strike is defined by one bitmapSizeTable. BitmapSizeTable[] _bmpSizeTables; - protected override void ReadContentFrom(BinaryReader reader) + internal EBLC(TableHeader header, BinaryReader reader) : base(header, reader) { // load each strike table long eblcBeginPos = reader.BaseStream.Position; diff --git a/Typography.OpenFont/Tables.BitmapAndSvgFonts/EBSC.cs b/Typography.OpenFont/Tables.BitmapAndSvgFonts/EBSC.cs index 4287973c..33705477 100644 --- a/Typography.OpenFont/Tables.BitmapAndSvgFonts/EBSC.cs +++ b/Typography.OpenFont/Tables.BitmapAndSvgFonts/EBSC.cs @@ -30,10 +30,9 @@ namespace Typography.OpenFont.Tables /// class EBSC : TableEntry { - public const string _N = "EBSC"; - public override string Name => _N; + public const string Name = "EBSC"; - protected override void ReadContentFrom(BinaryReader reader) + public EBSC(TableHeader header, BinaryReader reader) : base(header, reader) { } diff --git a/Typography.OpenFont/Tables.BitmapAndSvgFonts/SvgTable.cs b/Typography.OpenFont/Tables.BitmapAndSvgFonts/SvgTable.cs index 9f4a184b..46281af9 100644 --- a/Typography.OpenFont/Tables.BitmapAndSvgFonts/SvgTable.cs +++ b/Typography.OpenFont/Tables.BitmapAndSvgFonts/SvgTable.cs @@ -8,17 +8,16 @@ class SvgTable : TableEntry { - public const string _N = "SVG "; //with 1 whitespace *** - public override string Name => _N; + public const string Name = "SVG "; //with 1 whitespace *** // // https://www.microsoft.com/typography/otspec/svg.htm //OpenType fonts with either TrueType or CFF outlines may also contain an optional 'SVG ' table, //which allows some or all glyphs in the font to be defined with color, gradients, or animation. - Dictionary _dicSvgEntries; + Dictionary? _dicSvgEntries; SvgDocumentEntry[] _entries; //TODO: review again - protected override void ReadContentFrom(BinaryReader reader) + internal SvgTable(TableHeader header, BinaryReader reader) : base(header, reader) { long svgTableStartAt = reader.BaseStream.Position; //SVG Main Header @@ -123,7 +122,7 @@ public bool ReadSvgContent(ushort glyphIndex, System.Text.StringBuilder outputSt _dicSvgEntries.Add(en.startGlyphID, en.svgBuffer); } } - if (_dicSvgEntries.TryGetValue(glyphIndex, out byte[] svgData)) + if (_dicSvgEntries.TryGetValue(glyphIndex, out byte[]? svgData)) { outputStBuilder.Append(System.Text.Encoding.UTF8.GetString(svgData)); return true; diff --git a/Typography.OpenFont/Tables.CFF/CFF.cs b/Typography.OpenFont/Tables.CFF/CFF.cs index dd42aed5..2ba32c37 100644 --- a/Typography.OpenFont/Tables.CFF/CFF.cs +++ b/Typography.OpenFont/Tables.CFF/CFF.cs @@ -1,4 +1,4 @@ -//Apache2, 2018, apache/pdfbox Authors ( https://github.com/apache/pdfbox) +//Apache2, 2018, apache/pdfbox Authors ( https://github.com/apache/pdfbox) // //Apache PDFBox //Copyright 2014 The Apache Software Foundation @@ -64,6 +64,11 @@ namespace Typography.OpenFont.CFF class Cff1FontSet { + public Cff1FontSet(List fontNames, string[] uniqueStringTable) + { + _fontNames = fontNames; + _uniqueStringTable = uniqueStringTable; + } internal List _fontNames; internal List _fonts = new List(); internal string[] _uniqueStringTable; @@ -462,7 +467,6 @@ class Cff1FontSet "Regular", "Roman", "Semibold" };//390 - } public class Cff1Font { @@ -470,8 +474,8 @@ public class Cff1Font internal Glyph[] _glyphs; internal List _privateDict; - internal List _localSubrRawBufferList; - internal List _globalSubrRawBufferList; + internal List? _localSubrRawBufferList; + internal List? _globalSubrRawBufferList; //internal List _localSubrs; @@ -480,8 +484,20 @@ public class Cff1Font internal int _defaultWidthX; internal int _nominalWidthX; - Dictionary _cachedGlyphDicByName; - public Glyph GetGlyphByName(string name) + Dictionary? _cachedGlyphDicByName; + + internal Cff1Font(string fontName, Glyph[] glyphs, List privateDict, List? localSubrRawBufferList, List? globalSubrRawBufferList, int defaultWidthX, int nominalWidthX) + { + FontName = fontName; + _glyphs = glyphs; + _privateDict = privateDict; + _localSubrRawBufferList = localSubrRawBufferList; + _globalSubrRawBufferList = globalSubrRawBufferList; + _defaultWidthX = defaultWidthX; + _nominalWidthX = nominalWidthX; + } + + public Glyph? GetGlyphByName(string name) { if (_cachedGlyphDicByName == null) { @@ -490,11 +506,13 @@ public Glyph GetGlyphByName(string name) for (int i = 1; i < j; ++i) { Glyph cff1Glyph = _glyphs[i]; - _cachedGlyphDicByName.Add(cff1Glyph._cff1GlyphData.Name, cff1Glyph); + if (cff1Glyph.CffInfo is { } cff) + _cachedGlyphDicByName.Add(cff.Name, cff1Glyph); + else throw new NotSupportedException("Non-CFF glyph in CFF font"); } } - _cachedGlyphDicByName.TryGetValue(name, out Glyph found); + _cachedGlyphDicByName.TryGetValue(name, out Glyph? found); return found; } @@ -507,16 +525,20 @@ internal IEnumerable GetGlyphNameIter() for (int i = 1; i < j; ++i) { Glyph cff1Glyph = _glyphs[i]; - yield return new GlyphNameMap((ushort)i, cff1Glyph._cff1GlyphData.Name); + if (cff1Glyph.CffInfo is { } cff) + yield return new GlyphNameMap((ushort)i, cff.Name); + else throw new NotSupportedException("Non-CFF glyph in CFF font"); } } } public class Cff1GlyphData { - - public Cff1GlyphData() + internal Cff1GlyphData(string name, ushort glyphIndex, Type2Instruction[] glyphInstructions) { + Name = name; + GlyphIndex = glyphIndex; + GlyphInstructions = glyphInstructions; } public string Name { get; set; } @@ -574,46 +596,38 @@ class Cff1Parser //from Apache's PDF box/FontBox //@author Villu Ruusmann - BinaryReader _reader; - - Cff1FontSet _cff1FontSet; - Cff1Font _currentCff1Font; + readonly BinaryReader _reader; - List _topDic; - - uint _cffStartAt; - - int _charStringsOffset; - int _charsetOffset; - int _encodingOffset; - int _privateDICTSize; - int _privateDICTOffset; - public void ParseAfterHeader(uint cffStartAt, BinaryReader reader) + public Cff1Parser(uint cffStartAt, BinaryReader reader) { - _cffStartAt = cffStartAt; - _cff1FontSet = new Cff1FontSet(); _reader = reader; // - ReadNameIndex(); - ReadTopDICTIndex(); - ReadStringIndex(); - ReadGlobalSubrIndex(); + if (!(ReadNameIndex() is { } fontNames)) return; + if (!(ReadTopDICTIndex() is var (charStringsOffset, charsetOffset, encodingOffset, privateDICTSize, privateDICTOffset))) + return; + if(!(ReadStringIndex() is { } uniqueStringTable)) return; + ResultCff1FontSet = new Cff1FontSet(fontNames, uniqueStringTable); + var globalSubrRawBufferList = ReadGlobalSubrIndex(); //---------------------- - ReadPrivateDict(); - ReadCharStringsIndex(); - ReadCharsets(); - ReadEncodings(); + var (privateDict, localSubrRawBufferList, defaultWidthX, nominalWidthX) + = ReadPrivateDict(cffStartAt, privateDICTOffset, privateDICTSize); + if(!(ReadCharStringsIndex(cffStartAt, charStringsOffset, globalSubrRawBufferList, localSubrRawBufferList) is { } glyphInstructions)) + return; + var glyphs = ReadCharsets(cffStartAt, charsetOffset, glyphInstructions, uniqueStringTable); + ReadEncodings(cffStartAt, encodingOffset); ReadFDSelect(); + var currentCff1Font = new Cff1Font(fontNames[0], glyphs, privateDict, localSubrRawBufferList, globalSubrRawBufferList, defaultWidthX, nominalWidthX); + ResultCff1FontSet._fonts.Add(currentCff1Font); //... } - public Cff1FontSet ResultCff1FontSet => _cff1FontSet; + public Cff1FontSet? ResultCff1FontSet { get; } // - void ReadNameIndex() + List? ReadNameIndex() { //7. Name INDEX //This contains the PostScript language names(FontName or @@ -648,8 +662,8 @@ void ReadNameIndex() //previous or next name in the INDEX to ensure that all //appropriate names are matched. - CffIndexOffset[] nameIndexElems = ReadIndexDataOffsets(); - if (nameIndexElems == null) return; + CffIndexOffset[]? nameIndexElems = ReadIndexDataOffsets(); + if (nameIndexElems == null) return null; // int count = nameIndexElems.Length; @@ -663,10 +677,6 @@ void ReadNameIndex() fontNames.Add(Encoding.UTF8.GetString(_reader.ReadBytes(indexElem.len), 0, indexElem.len)); } - // - _cff1FontSet._fontNames = fontNames; - - //TODO: review here //in this version //count ==1 @@ -674,12 +684,11 @@ void ReadNameIndex() { throw new NotSupportedException(); } - _currentCff1Font = new Cff1Font(); - _currentCff1Font.FontName = fontNames[0]; - _cff1FontSet._fonts.Add(_currentCff1Font); + return fontNames; } - void ReadTopDICTIndex() + (int charStringsOffset, int charsetOffset, int encodingOffset, + int privateDICTSize, int privateDICTOffset)? ReadTopDICTIndex() { //8. Top DICT INDEX //This contains the top - level DICTs of all the fonts in the FontSet @@ -689,7 +698,8 @@ void ReadTopDICTIndex() //the top-level dictionary of a PostScript font. //A font is identified by an entry in the Name INDEX and its data //is accessed via the corresponding Top DICT - CffIndexOffset[] offsets = ReadIndexDataOffsets(); + CffIndexOffset[]? offsets = ReadIndexDataOffsets(); + if (offsets is null) return null; //9. Top DICT Data //The names of the Top DICT operators shown in //Table 9 are, where possible, the same as the corresponding Type 1 dict key. @@ -707,49 +717,41 @@ void ReadTopDICTIndex() throw new NotSupportedException(); } + List topDic = new List(); // for (int i = 0; i < count; ++i) { //read DICT data CffIndexOffset offset = offsets[i]; - List dicData = ReadDICTData(offset.len); - _topDic = dicData; + topDic.AddRange(ReadDICTData(offset.len)); } - + int charStringsOffset = 0, charsetOffset = 0, encodingOffset = 0, + privateDICTSize = 0, privateDICTOffset = 0; //translate top-dic - foreach (CffDataDicEntry entry in _topDic) + foreach (CffDataDicEntry entry in topDic) { switch (entry._operator.Name) { case "CharStrings": - _charStringsOffset = (int)entry.operands[0]._realNumValue; + charStringsOffset = (int)entry.operands[0]._realNumValue; break; case "charset": - _charsetOffset = (int)entry.operands[0]._realNumValue; + charsetOffset = (int)entry.operands[0]._realNumValue; break; case "Encoding": - _encodingOffset = (int)entry.operands[0]._realNumValue; + encodingOffset = (int)entry.operands[0]._realNumValue; break; case "Private": //private DICT size and offset - _privateDICTSize = (int)entry.operands[0]._realNumValue; - _privateDICTOffset = (int)entry.operands[1]._realNumValue; + privateDICTSize = (int)entry.operands[0]._realNumValue; + privateDICTOffset = (int)entry.operands[1]._realNumValue; break; } - - - } - - + return (charStringsOffset, charsetOffset, encodingOffset, privateDICTSize, privateDICTOffset); } - - string[] _uniqueStringTable; - - - - void ReadStringIndex() + string[]? ReadStringIndex() { //10 String INDEX @@ -790,25 +792,25 @@ void ReadStringIndex() //INDEX using a value of(SID – nStdStrings) as the index. - CffIndexOffset[] offsets = ReadIndexDataOffsets(); - if (offsets == null) return; + CffIndexOffset[]? offsets = ReadIndexDataOffsets(); + if (offsets == null) return null; // int count = offsets.Length; - _uniqueStringTable = new string[count]; + var uniqueStringTable = new string[count]; for (int i = 0; i < count; ++i) { CffIndexOffset offset = offsets[i]; //TODO: review here again, //check if we need to set _reader.BaseStream.Position or not //TODO: Is Charsets.ISO_8859_1 Encoding supported in .netcore - _uniqueStringTable[i] = Encoding.UTF8.GetString(_reader.ReadBytes(offset.len), 0, offset.len); + uniqueStringTable[i] = Encoding.UTF8.GetString(_reader.ReadBytes(offset.len), 0, offset.len); } - _cff1FontSet._uniqueStringTable = _uniqueStringTable; + return uniqueStringTable; } - void ReadGlobalSubrIndex() + List? ReadGlobalSubrIndex() { //16. Local / Global Subrs INDEXes //Both Type 1 and Type 2 charstrings support the notion of @@ -837,15 +839,15 @@ void ReadGlobalSubrIndex() //Global subrs are stored in an INDEX structure which follows the //String INDEX. A FontSet without any global subrs is represented //by an empty Global Subrs INDEX. - _currentCff1Font._globalSubrRawBufferList = ReadSubrBuffer(); + return ReadSubrBuffer(); } - void ReadLocalSubrs() + List? ReadLocalSubrs() { - _currentCff1Font._localSubrRawBufferList = ReadSubrBuffer(); + return ReadSubrBuffer(); } - void ReadEncodings() + void ReadEncodings(uint cffStartAt, int encodingOffset) { //Encoding data is located via the offset operand to the //Encoding operator in the Top DICT. @@ -877,7 +879,7 @@ void ReadEncodings() } //TODO: ... } - void ReadCharsets() + Glyph[] ReadCharsets(uint cffStartAt, int charsetOffset, Type2Instruction[][] glyphInstructions, string[] uniqueStringTable) { //Charset data is located via the offset operand to the //charset operator in the Top DICT. @@ -887,7 +889,7 @@ void ReadCharsets() //Three formats are currently defined as shown in Tables //17, 18, and 20. - _reader.BaseStream.Position = _cffStartAt + _charsetOffset; + _reader.BaseStream.Position = cffStartAt + charsetOffset; //TODO: ... byte format = _reader.ReadByte(); switch (format) @@ -895,17 +897,14 @@ void ReadCharsets() default: throw new NotSupportedException(); case 0: - ReadCharsetsFormat0(); - break; + return ReadCharsetsFormat0(glyphInstructions, uniqueStringTable); case 1: - ReadCharsetsFormat1(); - break; + return ReadCharsetsFormat1(glyphInstructions, uniqueStringTable); case 2: - ReadCharsetsFormat2(); - break; + return ReadCharsetsFormat2(glyphInstructions, uniqueStringTable); } } - void ReadCharsetsFormat0() + Glyph[] ReadCharsetsFormat0(Type2Instruction[][] glyphInstructions, string[] uniqueStringTable) { //Table 17: Format 0 //Type Name Description @@ -920,25 +919,29 @@ void ReadCharsetsFormat0() //one less element in the glyph name array than nGlyphs because //the .notdef glyph name is omitted.) - Glyph[] cff1Glyphs = _currentCff1Font._glyphs; - int nGlyphs = cff1Glyphs.Length; + int nGlyphs = glyphInstructions.Length; + var glyphs = new Glyph[nGlyphs]; + glyphs[0] = new Glyph(new Cff1GlyphData(".notdef", 0, glyphInstructions[0])); for (int i = 1; i < nGlyphs; ++i) { ushort sid = _reader.ReadUInt16(); + string name; if (sid <= Cff1FontSet.N_STD_STRINGS) { //use standard name //TODO: review here - cff1Glyphs[i]._cff1GlyphData.Name = Cff1FontSet.s_StdStrings[sid]; + name = Cff1FontSet.s_StdStrings[sid]; } else { - cff1Glyphs[i]._cff1GlyphData.Name = _uniqueStringTable[sid - Cff1FontSet.N_STD_STRINGS - 1]; + name = uniqueStringTable[sid - Cff1FontSet.N_STD_STRINGS - 1]; } + glyphs[i] = new Glyph(new Cff1GlyphData(name, (ushort)i, glyphInstructions[i])); } + return glyphs; } - void ReadCharsetsFormat1() + Glyph[] ReadCharsetsFormat1(Type2Instruction[][] glyphInstructions, string[] uniqueStringTable) { //Table 18 Format 1 //Type Name Description @@ -958,32 +961,36 @@ void ReadCharsetsFormat1() //that are well ordered // throw new NotSupportedException(); - Glyph[] cff1Glyphs = _currentCff1Font._glyphs; - int nGlyphs = cff1Glyphs.Length; + int nGlyphs = glyphInstructions.Length; + var glyphs = new Glyph[nGlyphs]; + glyphs[0] = new Glyph(new Cff1GlyphData(".notdef", 0, glyphInstructions[0])); for (int i = 1; i < nGlyphs;) { int sid = _reader.ReadUInt16();// First glyph in range int count = _reader.ReadByte() + 1;//since it not include first elem do { + string name; if (sid <= Cff1FontSet.N_STD_STRINGS) { //use standard name //TODO: review here - cff1Glyphs[i]._cff1GlyphData.Name = Cff1FontSet.s_StdStrings[sid]; + name = Cff1FontSet.s_StdStrings[sid]; } else { - cff1Glyphs[i]._cff1GlyphData.Name = _uniqueStringTable[sid - Cff1FontSet.N_STD_STRINGS - 1]; + name = uniqueStringTable[sid - Cff1FontSet.N_STD_STRINGS - 1]; } + glyphs[i] = new Glyph(new Cff1GlyphData(name, (ushort)i, glyphInstructions[i])); count--; i++; sid++; } while (count > 0); } + return glyphs; } - void ReadCharsetsFormat2() + Glyph[] ReadCharsetsFormat2(Type2Instruction[][] glyphInstructions, string[] uniqueStringTable) { //note:eg, Adobe's source-code-pro font @@ -1004,30 +1011,34 @@ void ReadCharsetsFormat2() //Format 2 differs from format 1 only in the size of the nLeft field in each range. //This format is most suitable for fonts with a large well - ordered charset — for example, for Asian CIDFonts. - Glyph[] cff1Glyphs = _currentCff1Font._glyphs; - int nGlyphs = cff1Glyphs.Length; + int nGlyphs = glyphInstructions.Length; + var glyphs = new Glyph[nGlyphs]; + glyphs[0] = new Glyph(new Cff1GlyphData(".notdef", 0, glyphInstructions[0])); for (int i = 1; i < nGlyphs;) { int sid = _reader.ReadUInt16();// First glyph in range int count = _reader.ReadUInt16() + 1;//since it not include first elem do { + string name; if (sid <= Cff1FontSet.N_STD_STRINGS) { //use standard name //TODO: review here - cff1Glyphs[i]._cff1GlyphData.Name = Cff1FontSet.s_StdStrings[sid]; + name = Cff1FontSet.s_StdStrings[sid]; } else { - cff1Glyphs[i]._cff1GlyphData.Name = _uniqueStringTable[sid - Cff1FontSet.N_STD_STRINGS - 1]; + name = uniqueStringTable[sid - Cff1FontSet.N_STD_STRINGS - 1]; } + glyphs[i] = new Glyph(new Cff1GlyphData(name, (ushort)i, glyphInstructions[i])); count--; i++; sid++; } while (count > 0); } + return glyphs; } void ReadFDSelect() { @@ -1043,7 +1054,8 @@ void ReadFDSelect() //are currently defined, as shown in Tables 27 and 28. //TODO: ... } - void ReadCharStringsIndex() + Type2Instruction[][]? + ReadCharStringsIndex(uint cffStartAt, int charStringsOffset, List? globalSubrRawBufferList, List? localSubrRawBufferList) { //14. CharStrings INDEX @@ -1076,18 +1088,17 @@ void ReadCharStringsIndex() //“Type 2 Charstring Format.” Other charstring types may also be //supported by this method. - _reader.BaseStream.Position = _cffStartAt + _charStringsOffset; - CffIndexOffset[] offsets = ReadIndexDataOffsets(); + _reader.BaseStream.Position = cffStartAt + charStringsOffset; + CffIndexOffset[]? offsets = ReadIndexDataOffsets(); + if (offsets is null) return null; int glyphCount = offsets.Length; //assume Type2 //TODO: review here - Glyph[] glyphs = new Glyph[glyphCount]; + var glyphs = new Type2Instruction[glyphCount][]; - _currentCff1Font._glyphs = glyphs; - Type2CharStringParser type2Parser = new Type2CharStringParser(); - type2Parser.SetCurrentCff1Font(_currentCff1Font); + Type2CharStringParser type2Parser = new Type2CharStringParser(globalSubrRawBufferList, localSubrRawBufferList); #if DEBUG double total = 0; @@ -1111,16 +1122,12 @@ void ReadCharStringsIndex() } #endif //now we can parse the raw glyph instructions - - Cff1GlyphData glyphData = new Cff1GlyphData(); - glyphData.GlyphIndex = (ushort)i; #if DEBUG - type2Parser.dbugCurrentGlyphIndex = glyphData.GlyphIndex; + type2Parser.dbugCurrentGlyphIndex = (ushort)i; #endif + Type2Instruction[] instructions; Type2GlyphInstructionList instList = type2Parser.ParseType2CharString(buffer); - if (instList != null) - { - //use compact form or not + //use compact form or not if (_useCompactInstruction) { @@ -1128,20 +1135,20 @@ void ReadCharStringsIndex() //if you don't want compact version //just use original - glyphData.GlyphInstructions = _instCompacter.Compact(instList.InnerInsts); + instructions = _instCompacter.Compact(instList.InnerInsts); #if DEBUG - total += glyphData.GlyphInstructions.Length / (float)instList.InnerInsts.Count; + total += instructions.Length / (float)instList.InnerInsts.Count; #endif - } - else - { - glyphData.GlyphInstructions = instList.InnerInsts.ToArray(); + } + else + { + instructions = instList.InnerInsts.ToArray(); - } } - glyphs[i] = new Glyph(_currentCff1Font, glyphData); + + glyphs[i] = instructions; } #if DEBUG @@ -1151,11 +1158,11 @@ void ReadCharStringsIndex() System.Diagnostics.Debug.WriteLine("cff instruction compact avg:" + avg + "%"); } #endif - + return glyphs; } //--------------- - bool _useCompactInstruction = true; - Type2InstructionCompacter _instCompacter = new Type2InstructionCompacter(); + readonly bool _useCompactInstruction = true; + readonly Type2InstructionCompacter _instCompacter = new Type2InstructionCompacter(); void ReadFormat0Encoding() @@ -1222,31 +1229,32 @@ void ReadFormat1Encoding() //Card8 code Encoding //SID glyph Name } - void ReadPrivateDict() + (List privateDict, List? localSubrRawBufferList, int defaultWidthX, int nominalWidthX) + ReadPrivateDict(uint cffStartAt, int privateDICTOffset, int privateDICTSize) { //per-font - _reader.BaseStream.Position = _cffStartAt + _privateDICTOffset; - _currentCff1Font._privateDict = ReadDICTData(_privateDICTSize); + _reader.BaseStream.Position = cffStartAt + privateDICTOffset; + var privateDict = ReadDICTData(privateDICTSize); //interpret the values of private dict // - foreach (CffDataDicEntry dicEntry in _currentCff1Font._privateDict) + List? localSubrRawBufferList = null; + int defaultWidthX = 0, nominalWidthX = 0; + foreach (CffDataDicEntry dicEntry in privateDict) { switch (dicEntry._operator.Name) { case "Subrs": - { - int localSubrsOffset = (int)dicEntry.operands[0]._realNumValue; - _reader.BaseStream.Position = _cffStartAt + _privateDICTOffset + localSubrsOffset; - ReadLocalSubrs(); - } + int localSubrsOffset = (int)dicEntry.operands[0]._realNumValue; + _reader.BaseStream.Position = cffStartAt + privateDICTOffset + localSubrsOffset; + localSubrRawBufferList = ReadLocalSubrs(); break; case "defaultWidthX": - _currentCff1Font._defaultWidthX = (int)dicEntry.operands[0]._realNumValue; + defaultWidthX = (int)dicEntry.operands[0]._realNumValue; break; case "nominalWidthX": - _currentCff1Font._nominalWidthX = (int)dicEntry.operands[0]._realNumValue; + nominalWidthX = (int)dicEntry.operands[0]._realNumValue; break; default: { @@ -1255,11 +1263,12 @@ void ReadPrivateDict() break; } } + return (privateDict, localSubrRawBufferList, defaultWidthX, nominalWidthX); } - List ReadSubrBuffer() + List? ReadSubrBuffer() { - CffIndexOffset[] offsets = ReadIndexDataOffsets(); + CffIndexOffset[]? offsets = ReadIndexDataOffsets(); if (offsets == null) return null; // int nsubrs = offsets.Length; @@ -1323,7 +1332,7 @@ CffDataDicEntry ReadEntry() //An operator may be preceded by up to a maximum of 48 operands - CffDataDicEntry dicEntry = new CffDataDicEntry(); + CFFOperator dicEntryOperator; List operands = new List(); while (true) @@ -1333,7 +1342,7 @@ CffDataDicEntry ReadEntry() if (b0 >= 0 && b0 <= 21) { //operators - dicEntry._operator = ReadOperator(b0); + dicEntryOperator = ReadOperator(b0); break; //**break after found operator } else if (b0 == 28 || b0 == 29) @@ -1357,8 +1366,7 @@ CffDataDicEntry ReadEntry() } } - dicEntry.operands = operands.ToArray(); - return dicEntry; + return new CffDataDicEntry(dicEntryOperator, operands.ToArray()); } CFFOperator ReadOperator(byte b0) @@ -1498,7 +1506,7 @@ int ReadIntegerNumber(byte b0) - CffIndexOffset[] ReadIndexDataOffsets() + CffIndexOffset[]? ReadIndexDataOffsets() { //INDEX Data @@ -1603,8 +1611,14 @@ public static int ReadOffset(this BinaryReader reader, int offsetSize) class CffDataDicEntry { - public CffOperand[] operands; public CFFOperator _operator; + public CffOperand[] operands; + + public CffDataDicEntry(CFFOperator @operator, CffOperand[] operands) + { + _operator = @operator; + this.operands = operands; + } #if DEBUG @@ -1695,8 +1709,7 @@ private CFFOperator(string name, byte b0, byte b1, OperatorOperandKind operatorO public static CFFOperator GetOperatorByKey(byte b0, byte b1) { - s_registered_Operators.TryGetValue((b1 << 8) | b0, out CFFOperator found); - return found; + return s_registered_Operators[(b1 << 8) | b0]; } diff --git a/Typography.OpenFont/Tables.CFF/CFFTable.cs b/Typography.OpenFont/Tables.CFF/CFFTable.cs index 9e1205ae..2c090ad8 100644 --- a/Typography.OpenFont/Tables.CFF/CFFTable.cs +++ b/Typography.OpenFont/Tables.CFF/CFFTable.cs @@ -54,16 +54,15 @@ namespace Typography.OpenFont.Tables class CFFTable : TableEntry { - public const string _N = "CFF ";//4 chars, left 1 blank whitespace - public override string Name => _N; + public const string Name = "CFF ";//4 chars, left 1 blank whitespace // - Cff1FontSet _cff1FontSet; + Cff1FontSet? _cff1FontSet; // - internal Cff1FontSet Cff1FontSet => _cff1FontSet; - protected override void ReadContentFrom(BinaryReader reader) + internal Cff1FontSet? Cff1FontSet => _cff1FontSet; + public CFFTable(TableHeader h, BinaryReader reader) : base(h, reader) { - uint tableOffset = this.Header.Offset; + uint tableOffset = h.Offset; // // //Table 8 Header Format @@ -85,8 +84,7 @@ protected override void ReadContentFrom(BinaryReader reader) default: throw new NotSupportedException(); case 1: { - Cff1Parser cff1 = new Cff1Parser(); - cff1.ParseAfterHeader(tableOffset, reader); + Cff1Parser cff1 = new Cff1Parser(tableOffset, reader); _cff1FontSet = cff1.ResultCff1FontSet; } break; diff --git a/Typography.OpenFont/Tables.CFF/CffEvaluationEngine.cs b/Typography.OpenFont/Tables.CFF/CffEvaluationEngine.cs index 2fba9ba7..ca1603d3 100644 --- a/Typography.OpenFont/Tables.CFF/CffEvaluationEngine.cs +++ b/Typography.OpenFont/Tables.CFF/CffEvaluationEngine.cs @@ -12,8 +12,6 @@ namespace Typography.OpenFont.CFF public class CffEvaluationEngine { - CFF.Cff1Font _cff1Font; - float _scale = 1;//default Stack _evalStackPool = new Stack(); @@ -77,16 +75,15 @@ public CffEvaluationEngine() { } - public void Run(IGlyphTranslator tx, Cff1Font cff1Font, Cff1GlyphData glyphData, float scale = 1) + public void Run(IGlyphTranslator tx, Cff1GlyphData glyphData, float scale = 1) { - Run(tx, cff1Font, glyphData.GlyphInstructions, scale); + Run(tx, glyphData.GlyphInstructions, scale); } - internal void Run(IGlyphTranslator tx, Cff1Font cff1Font, Type2Instruction[] instructionList, float scale = 1) + internal void Run(IGlyphTranslator tx, Type2Instruction[] instructionList, float scale = 1) { //all fields are set to new values*** - _cff1Font = cff1Font; _scale = scale; double currentX = 0, currentY = 0; @@ -292,14 +289,12 @@ class Type2EvaluationStack double[] _argStack = new double[50]; int _currentIndex = 0; //current stack index - IGlyphTranslator _glyphTranslator; + IGlyphTranslator? _glyphTranslator; #if DEBUG public int dbugGlyphIndex; #endif - public Type2EvaluationStack() - { - } + public Type2EvaluationStack() { } public void Reset() { @@ -307,11 +302,13 @@ public void Reset() _currentX = _currentY = 0; _glyphTranslator = null; } - public IGlyphTranslator GlyphTranslator + public IGlyphTranslator? GlyphTranslator { get => _glyphTranslator; set => _glyphTranslator = value; } + [System.Diagnostics.CodeAnalysis.DoesNotReturn] + private void ThrowNullGlyphTranslator() => throw new InvalidOperationException(nameof(GlyphTranslator) + " not set"); public void Push(double value) { _argStack[_currentIndex] = value; @@ -348,6 +345,7 @@ public void Push(int value) /// public void R_MoveTo() { + if (_glyphTranslator is null) ThrowNullGlyphTranslator(); //|- dx1 dy1 rmoveto(21) |- //moves the current point to @@ -372,6 +370,7 @@ public void R_MoveTo() /// public void H_MoveTo() { + if (_glyphTranslator is null) ThrowNullGlyphTranslator(); //|- dx1 hmoveto(22) |- //moves the current point @@ -383,6 +382,7 @@ public void H_MoveTo() } public void V_MoveTo() { + if (_glyphTranslator is null) ThrowNullGlyphTranslator(); //|- dy1 vmoveto (4) |- //moves the current point //dy1 units in the vertical direction. @@ -398,6 +398,7 @@ public void V_MoveTo() } public void R_LineTo() { + if (_glyphTranslator is null) ThrowNullGlyphTranslator(); //|- {dxa dya}+ rlineto (5) |- //appends a line from the current point to @@ -423,7 +424,7 @@ public void R_LineTo() } public void H_LineTo() { - + if (_glyphTranslator is null) ThrowNullGlyphTranslator(); //|- dx1 {dya dxb}* hlineto (6) |- //|- {dxa dyb}+ hlineto (6) |- @@ -473,6 +474,7 @@ public void H_LineTo() } public void V_LineTo() { + if (_glyphTranslator is null) ThrowNullGlyphTranslator(); //|- dy1 {dxa dyb}* vlineto (7) |- //|- {dya dxb}+ vlineto (7) |- @@ -524,7 +526,7 @@ public void V_LineTo() public void RR_CurveTo() { - + if (_glyphTranslator is null) ThrowNullGlyphTranslator(); //|- {dxa dya dxb dyb dxc dyc}+ rrcurveto (8) |- //appends a Bézier curve, defined by dxa...dyc, to the current point. @@ -571,7 +573,7 @@ public void RR_CurveTo() } public void HH_CurveTo() { - + if (_glyphTranslator is null) ThrowNullGlyphTranslator(); //|- dy1? {dxa dxb dyb dxc}+ hhcurveto (27) |- //appends one or more Bézier curves, as described by the @@ -618,6 +620,7 @@ public void HH_CurveTo() } public void HV_CurveTo() { + if (_glyphTranslator is null) ThrowNullGlyphTranslator(); //|- dx1 dx2 dy2 dy3 {dya dxb dyb dxc dxd dxe dye dyf}* dxf? hvcurveto (31) |- //|- {dxa dxb dyb dyc dyd dxe dye dxf}+ dyf? hvcurveto (31) |- @@ -776,6 +779,7 @@ public void HV_CurveTo() } public void R_CurveLine() { + if (_glyphTranslator is null) ThrowNullGlyphTranslator(); #if DEBUG @@ -819,6 +823,7 @@ public void R_CurveLine() } public void R_LineCurve() { + if (_glyphTranslator is null) ThrowNullGlyphTranslator(); #if DEBUG #endif @@ -860,7 +865,7 @@ public void R_LineCurve() } public void VH_CurveTo() { - + if (_glyphTranslator is null) ThrowNullGlyphTranslator(); #if DEBUG @@ -1002,6 +1007,7 @@ public void VH_CurveTo() } public void VV_CurveTo() { + if (_glyphTranslator is null) ThrowNullGlyphTranslator(); // |- dx1? {dya dxb dyb dyc}+ vvcurveto (26) |- //appends one or more curves to the current point. //If the argument count is a multiple of four, the curve starts and ends vertical. diff --git a/Typography.OpenFont/Tables.CFF/Type2CharStringParser.cs b/Typography.OpenFont/Tables.CFF/Type2CharStringParser.cs index f6be5cce..bd3239e1 100644 --- a/Typography.OpenFont/Tables.CFF/Type2CharStringParser.cs +++ b/Typography.OpenFont/Tables.CFF/Type2CharStringParser.cs @@ -67,7 +67,7 @@ public float ReadValueAsFixed1616() bool _dbug_OnlyOp; [System.ThreadStatic] - static System.Text.StringBuilder s_dbugSb; + static System.Text.StringBuilder? s_dbugSb; public override string ToString() { @@ -411,7 +411,7 @@ internal void ChangeFirstInstToGlyphWidthValue() _insts[0] = new Type2Instruction(OperatorName.GlyphWidth, firstInst.Value); } - + public void ClearAll() => _insts.Clear(); internal List InnerInsts => _insts; @@ -504,8 +504,18 @@ class Type2CharStringParser //and encoded as the difference from nominalWidthX - public Type2CharStringParser() + public Type2CharStringParser(List? globalSubrRawBufferList, List? localSubrRawBufferList) { + _globalSubrRawBufferList = globalSubrRawBufferList; + _localSubrRawBufferList = localSubrRawBufferList; + if (globalSubrRawBufferList != null) + { + _globalSubrBias = CalculateBias(globalSubrRawBufferList.Count); + } + if (localSubrRawBufferList != null) + { + _localSubrBias = CalculateBias(localSubrRawBufferList.Count); + } } #if DEBUG @@ -516,27 +526,11 @@ public Type2CharStringParser() bool _foundSomeStem = false; bool _enterPathConstructionSeq = false; - Type2GlyphInstructionList _insts; + Type2GlyphInstructionList _insts = new Type2GlyphInstructionList(); int _current_integer_count = 0; bool _doStemCount = true; - Cff1Font _currentCff1Font; - int _globalSubrBias; - int _localSubrBias; - - public void SetCurrentCff1Font(Cff1Font currentCff1Font) - { - //this will provide subr buffer for callsubr callgsubr - _currentCff1Font = currentCff1Font; - - if (_currentCff1Font._globalSubrRawBufferList != null) - { - _globalSubrBias = CalculateBias(currentCff1Font._globalSubrRawBufferList.Count); - } - if (_currentCff1Font._localSubrRawBufferList != null) - { - _localSubrBias = CalculateBias(currentCff1Font._localSubrRawBufferList.Count); - } - } + List? _globalSubrRawBufferList, _localSubrRawBufferList; + int _globalSubrBias, _localSubrBias; static int CalculateBias(int nsubr) @@ -770,7 +764,7 @@ void ParseType2CharStringBuffer(byte[] buffer) case (byte)Type2Operator1.callsubr: { //get local subr proc - if (_currentCff1Font != null) + if (_localSubrRawBufferList is { } localSubrBuffers) { Type2Instruction inst = _insts.RemoveLast(); if (!inst.IsLoadInt) @@ -782,13 +776,13 @@ void ParseType2CharStringBuffer(byte[] buffer) _current_integer_count--; } //subr_no must be adjusted with proper bias value - ParseType2CharStringBuffer(_currentCff1Font._localSubrRawBufferList[inst.Value + _localSubrBias]); + ParseType2CharStringBuffer(localSubrBuffers[inst.Value + _localSubrBias]); } } break; case (byte)Type2Operator1.callgsubr: { - if (_currentCff1Font != null) + if (_globalSubrRawBufferList is { } globalSubrBuffers) { Type2Instruction inst = _insts.RemoveLast(); if (!inst.IsLoadInt) @@ -801,7 +795,7 @@ void ParseType2CharStringBuffer(byte[] buffer) } //subr_no must be adjusted with proper bias value //load global subr - ParseType2CharStringBuffer(_currentCff1Font._globalSubrRawBufferList[inst.Value + _globalSubrBias]); + ParseType2CharStringBuffer(globalSubrBuffers[inst.Value + _globalSubrBias]); } } break; @@ -820,14 +814,10 @@ public Type2GlyphInstructionList ParseType2CharString(byte[] buffer) _enterPathConstructionSeq = false; _doStemCount = true; - _insts = new Type2GlyphInstructionList(); + _insts.ClearAll(); //-------------------- #if DEBUG _dbugInstructionListMark++; - if (_currentCff1Font == null) - { - throw new NotSupportedException(); - } // _insts.dbugGlyphIndex = dbugCurrentGlyphIndex; diff --git a/Typography.OpenFont/Tables.CFF/Type2InstructionCompacter.cs b/Typography.OpenFont/Tables.CFF/Type2InstructionCompacter.cs index 8ed54bda..47d5df6d 100644 --- a/Typography.OpenFont/Tables.CFF/Type2InstructionCompacter.cs +++ b/Typography.OpenFont/Tables.CFF/Type2InstructionCompacter.cs @@ -1,4 +1,4 @@ -//MIT, 2020-present, WinterDev +//MIT, 2020-present, WinterDev using System; using System.Collections.Generic; @@ -14,10 +14,10 @@ class Type2InstructionCompacter #if DEBUG public static bool s_dbugBreakMe; #endif - List _step1List; - List _step2List; + List? _step1List; + List? _step2List; - void CompactStep1OnlyLoadInt(List insts) + void CompactStep1OnlyLoadInt(List step1List, List insts) { int j = insts.Count; CompactRange _latestCompactRange = CompactRange.None; @@ -34,7 +34,7 @@ void FlushWaitingNumbers() default: throw new NotSupportedException(); case 0: break; //nothing case 2: - _step1List.Add(new Type2Instruction(OperatorName.LoadShort2, + step1List.Add(new Type2Instruction(OperatorName.LoadShort2, (((ushort)insts[startCollectAt].Value) << 16) | (((ushort)insts[startCollectAt + 1].Value)) )); @@ -42,7 +42,7 @@ void FlushWaitingNumbers() collecting_count -= 2; break; case 1: - _step1List.Add(insts[startCollectAt]); + step1List.Add(insts[startCollectAt]); startCollectAt += 1; collecting_count -= 1; break; @@ -57,7 +57,7 @@ void FlushWaitingNumbers() case 0: break;//nothing case 4: { - _step1List.Add(new Type2Instruction(OperatorName.LoadSbyte4, + step1List.Add(new Type2Instruction(OperatorName.LoadSbyte4, (((byte)insts[startCollectAt].Value) << 24) | (((byte)insts[startCollectAt + 1].Value) << 16) | (((byte)insts[startCollectAt + 2].Value) << 8) | @@ -68,7 +68,7 @@ void FlushWaitingNumbers() } break; case 3: - _step1List.Add(new Type2Instruction(OperatorName.LoadSbyte3, + step1List.Add(new Type2Instruction(OperatorName.LoadSbyte3, (((byte)insts[startCollectAt].Value) << 24) | (((byte)insts[startCollectAt + 1].Value) << 16) | (((byte)insts[startCollectAt + 2].Value) << 8) @@ -77,7 +77,7 @@ void FlushWaitingNumbers() collecting_count -= 3; break; case 2: - _step1List.Add(new Type2Instruction(OperatorName.LoadShort2, + step1List.Add(new Type2Instruction(OperatorName.LoadShort2, (((ushort)insts[startCollectAt].Value) << 16) | ((ushort)insts[startCollectAt + 1].Value) )); @@ -85,7 +85,7 @@ void FlushWaitingNumbers() collecting_count -= 2; break; case 1: - _step1List.Add(insts[startCollectAt]); + step1List.Add(insts[startCollectAt]); startCollectAt += 1; collecting_count -= 1; break; @@ -114,7 +114,7 @@ void FlushWaitingNumbers() { FlushWaitingNumbers(); } - _step1List.Add(inst); + step1List.Add(inst); _latestCompactRange = CompactRange.None; } break; @@ -183,7 +183,7 @@ void FlushWaitingNumbers() FlushWaitingNumbers(); } - _step1List.Add(inst); + step1List.Add(inst); _latestCompactRange = CompactRange.None; } } @@ -204,15 +204,15 @@ static byte IsLoadIntOrMergeableLoadIntExtension(OperatorName opName) } return 0; } - void CompactStep2MergeLoadIntWithNextCommand() + void CompactStep2MergeLoadIntWithNextCommand(List step1List, List step2List) { //a second pass //check if we can merge some load int( LoadInt, LoadSByte4, LoadShort2) except LoadSByte3 //to next instruction command or not - int j = _step1List.Count; + int j = step1List.Count; for (int i = 0; i < j; ++i) { - Type2Instruction i0 = _step1List[i]; + Type2Instruction i0 = step1List[i]; if (i + 1 < j) { @@ -220,7 +220,7 @@ void CompactStep2MergeLoadIntWithNextCommand() byte merge_flags = IsLoadIntOrMergeableLoadIntExtension((OperatorName)i0.Op); if (merge_flags > 0) { - Type2Instruction i1 = _step1List[i + 1]; + Type2Instruction i1 = step1List[i + 1]; //check i1 has empty space for i0 or not bool canbe_merged = false; switch ((OperatorName)i1.Op) @@ -253,25 +253,25 @@ void CompactStep2MergeLoadIntWithNextCommand() if (merge_flags > 3) { throw new NotSupportedException(); } #endif - _step2List.Add(new Type2Instruction((byte)((merge_flags << 6) | i1.Op), i0.Value)); + step2List.Add(new Type2Instruction((byte)((merge_flags << 6) | i1.Op), i0.Value)); i += 1; } else { - _step2List.Add(i0); + step2List.Add(i0); } } else { //this is the last one - _step2List.Add(i0); + step2List.Add(i0); } } else { //this is the last one - _step2List.Add(i0); + step2List.Add(i0); } } } @@ -286,16 +286,14 @@ public Type2Instruction[] Compact(List insts) if (_step1List == null) { _step1List = new List(); - } + } else _step1List.Clear(); if (_step2List == null) { _step2List = new List(); - } - _step1List.Clear(); - _step2List.Clear(); + } else _step2List.Clear(); // - CompactStep1OnlyLoadInt(insts); - CompactStep2MergeLoadIntWithNextCommand(); + CompactStep1OnlyLoadInt(_step1List, insts); + CompactStep2MergeLoadIntWithNextCommand(_step1List, _step2List); #if DEBUG //you can check/compare the compact form and the original form diff --git a/Typography.OpenFont/Tables.Others/HorizontalDeviceMetrics.cs b/Typography.OpenFont/Tables.Others/HorizontalDeviceMetrics.cs index c92c302f..c9b3cd5d 100644 --- a/Typography.OpenFont/Tables.Others/HorizontalDeviceMetrics.cs +++ b/Typography.OpenFont/Tables.Others/HorizontalDeviceMetrics.cs @@ -7,8 +7,7 @@ namespace Typography.OpenFont.Tables class HorizontalDeviceMetrics : TableEntry { - public const string _N = "hdmx"; - public override string Name => _N; + public const string Name = "hdmx"; // //https://www.microsoft.com/typography/otspec/hdmx.htm //The hdmx table relates to OpenType™ fonts with TrueType outlines. @@ -51,7 +50,7 @@ class HorizontalDeviceMetrics : TableEntry //The ppem sizes are measured along the y axis. - protected override void ReadContentFrom(BinaryReader reader) + internal HorizontalDeviceMetrics(TableHeader header, BinaryReader reader) : base(header, reader) { } diff --git a/Typography.OpenFont/Tables.Others/Kern.cs b/Typography.OpenFont/Tables.Others/Kern.cs index f14fa5cb..d1cb0d3b 100644 --- a/Typography.OpenFont/Tables.Others/Kern.cs +++ b/Typography.OpenFont/Tables.Others/Kern.cs @@ -7,8 +7,7 @@ namespace Typography.OpenFont.Tables { class Kern : TableEntry { - public const string _N = "kern"; - public override string Name => _N; + public const string Name = "kern"; // //https://www.microsoft.com/typography/otspec/kern.htm @@ -19,7 +18,7 @@ public short GetKerningDistance(ushort left, ushort right) //TODO: review if have more than 1 table return _kernSubTables[0].GetKernDistance(left, right); } - protected override void ReadContentFrom(BinaryReader reader) + public Kern(TableHeader header, BinaryReader reader) : base(header, reader) { ushort verion = reader.ReadUInt16(); ushort nTables = reader.ReadUInt16();//subtable count diff --git a/Typography.OpenFont/Tables.Others/STAT.cs b/Typography.OpenFont/Tables.Others/STAT.cs index 38365882..75d1eade 100644 --- a/Typography.OpenFont/Tables.Others/STAT.cs +++ b/Typography.OpenFont/Tables.Others/STAT.cs @@ -23,10 +23,9 @@ namespace Typography.OpenFont.Tables class STAT : TableEntry { - public const string _N = "STAT"; - public override string Name => _N; + public const string Name = "STAT"; // - protected override void ReadContentFrom(BinaryReader reader) + internal STAT(TableHeader header, BinaryReader reader) : base(header, reader) { //Style Attributes Header //The style attributes table, version 1.2, is organized as follows: @@ -86,11 +85,10 @@ protected override void ReadContentFrom(BinaryReader reader) AxisRecord[] axisRecords = new AxisRecord[designAxisCount]; for (int i = 0; i < designAxisCount; ++i) { - var axisRecord = new AxisRecord(); - axisRecords[i] = axisRecord; - axisRecord.axisTagName = Utils.TagToString(reader.ReadUInt32()); //4 - axisRecord.axisNameId = reader.ReadUInt16(); //2 - axisRecord.axisOrdering = reader.ReadUInt16(); //2 + axisRecords[i] = new AxisRecord( + Utils.TagToString(reader.ReadUInt32()), //4 + reader.ReadUInt16(), //2 + reader.ReadUInt16()); //2 //*** @@ -130,17 +128,14 @@ protected override void ReadContentFrom(BinaryReader reader) reader.BaseStream.Position = axisValueOffsets_beginPos + offset; ushort format = reader.ReadUInt16();//common field of all axis value table - AxisValueTableBase axisValueTbl = null; switch (format) { default: throw new NotSupportedException(); - case 1: axisValueTbl = new AxisValueTableFmt1(); break; - case 2: axisValueTbl = new AxisValueTableFmt2(); break; - case 3: axisValueTbl = new AxisValueTableFmt3(); break; - case 4: axisValueTbl = new AxisValueTableFmt4(); break; + case 1: axisValueTables[i] = new AxisValueTableFmt1(reader); break; + case 2: axisValueTables[i] = new AxisValueTableFmt2(reader); break; + case 3: axisValueTables[i] = new AxisValueTableFmt3(reader); break; + case 4: axisValueTables[i] = new AxisValueTableFmt4(reader); break; } - axisValueTbl.ReadContent(reader); - axisValueTables[i] = axisValueTbl; } @@ -195,6 +190,13 @@ public class AxisRecord public string axisTagName; public ushort axisNameId; public ushort axisOrdering; + + public AxisRecord(string axisTagName, ushort axisNameId, ushort axisOrdering) + { + this.axisTagName = axisTagName; + this.axisNameId = axisNameId; + this.axisOrdering = axisOrdering; + } #if DEBUG public override string ToString() { @@ -206,13 +208,6 @@ public override string ToString() public abstract class AxisValueTableBase { public abstract int Format { get; } - - - /// - /// assume we have read format - /// - /// - public abstract void ReadContent(BinaryReader reader); } @@ -238,7 +233,7 @@ public class AxisValueTableFmt1 : AxisValueTableBase public ushort flags; public ushort valueNameId; public float value; - public override void ReadContent(BinaryReader reader) + public AxisValueTableFmt1(BinaryReader reader) { //at here, assume we have read format, //Fixed => 32-bit signed fixed-point number (16.16) @@ -298,7 +293,7 @@ public class AxisValueTableFmt2 : AxisValueTableBase public float nominalValue; public float rangeMinValue; public float rangeMaxValue; - public override void ReadContent(BinaryReader reader) + public AxisValueTableFmt2(BinaryReader reader) { axisIndex = reader.ReadUInt16(); flags = reader.ReadUInt16(); @@ -343,7 +338,7 @@ public class AxisValueTableFmt3 : AxisValueTableBase public float value; public float linkedValue; - public override void ReadContent(BinaryReader reader) + public AxisValueTableFmt3(BinaryReader reader) { axisIndex = reader.ReadUInt16(); flags = reader.ReadUInt16(); @@ -372,7 +367,7 @@ public class AxisValueTableFmt4 : AxisValueTableBase public AxisValueRecord[] _axisValueRecords; public ushort flags; public ushort valueNameId; - public override void ReadContent(BinaryReader reader) + public AxisValueTableFmt4(BinaryReader reader) { ushort axisCount = reader.ReadUInt16(); flags = reader.ReadUInt16(); diff --git a/Typography.OpenFont/Tables.Others/VerticalDeviceMetrics.cs b/Typography.OpenFont/Tables.Others/VerticalDeviceMetrics.cs index ebcbf177..10e45cbc 100644 --- a/Typography.OpenFont/Tables.Others/VerticalDeviceMetrics.cs +++ b/Typography.OpenFont/Tables.Others/VerticalDeviceMetrics.cs @@ -6,8 +6,7 @@ namespace Typography.OpenFont.Tables { class VerticalDeviceMetrics : TableEntry { - public const string _N = "VDMX"; - public override string Name => _N; + public const string Name = "VDMX"; // //https://www.microsoft.com/typography/otspec/vdmx.htm //VDMX - Vertical Device Metrics @@ -22,7 +21,7 @@ class VerticalDeviceMetrics : TableEntry //The VDMX table consists of a header followed by groupings of VDMX records: Ratio[] _ratios; - protected override void ReadContentFrom(BinaryReader reader) + public VerticalDeviceMetrics(TableHeader header, BinaryReader reader) : base(header, reader) { //uint16 version Version number (0 or 1). //uint16 numRecs Number of VDMX groups present diff --git a/Typography.OpenFont/Tables.Others/VerticalMetrics.cs b/Typography.OpenFont/Tables.Others/VerticalMetrics.cs index f82cf328..401d9c9e 100644 --- a/Typography.OpenFont/Tables.Others/VerticalMetrics.cs +++ b/Typography.OpenFont/Tables.Others/VerticalMetrics.cs @@ -9,8 +9,7 @@ namespace Typography.OpenFont.Tables /// class VerticalMetrics : TableEntry { - public const string _N = "vmtx"; - public override string Name => _N; + public const string Name = "vmtx"; // https://www.microsoft.com/typography/otspec/vmtx.htm // vmtx - Vertical Metrics Table @@ -58,17 +57,12 @@ class VerticalMetrics : TableEntry //Type Name Description // int16 topSideBearing[] The top sidebearing of the glyph. Signed integer in FUnits. - ushort _numOfLongVerMetrics; AdvanceHeightAndTopSideBearing[] _advHeightAndTopSideBearings; - public VerticalMetrics(ushort numOfLongVerMetrics) + internal VerticalMetrics(ushort numOfLongVerMetrics, TableHeader header, BinaryReader reader) : base(header, reader) { - _numOfLongVerMetrics = numOfLongVerMetrics; - } - protected override void ReadContentFrom(BinaryReader reader) - { - _advHeightAndTopSideBearings = new AdvanceHeightAndTopSideBearing[_numOfLongVerMetrics]; + _advHeightAndTopSideBearings = new AdvanceHeightAndTopSideBearing[numOfLongVerMetrics]; int m = 0; - for (int i = _numOfLongVerMetrics - 1; i >= 0; --i) + for (int i = numOfLongVerMetrics - 1; i >= 0; --i) { _advHeightAndTopSideBearings[m] = new AdvanceHeightAndTopSideBearing( reader.ReadUInt16(), diff --git a/Typography.OpenFont/Tables.Others/VerticalMetricsHeader.cs b/Typography.OpenFont/Tables.Others/VerticalMetricsHeader.cs index 244235ba..c51bdd4d 100644 --- a/Typography.OpenFont/Tables.Others/VerticalMetricsHeader.cs +++ b/Typography.OpenFont/Tables.Others/VerticalMetricsHeader.cs @@ -7,8 +7,7 @@ namespace Typography.OpenFont.Tables { class VerticalHeader : TableEntry { - public const string _N = "vhea"; - public override string Name => _N; + public const string Name = "vhea"; //vhea — Vertical Header Tables //The vertical header table(tag name: 'vhea') contains information needed for vertical fonts.The glyphs of vertical fonts are written either top to bottom or bottom to top. This table contains information that is general to the font as a whole. Information that pertains to specific glyphs is given in the vertical metrics table (tag name: 'vmtx') described separately.The formats of these tables are similar to those for horizontal metrics (hhea and hmtx). @@ -87,7 +86,7 @@ class VerticalHeader : TableEntry public short CaretSlopeRun { get; set; } public short CaretOffset { get; set; } public ushort NumOfLongVerMetrics { get; set; } - protected override void ReadContentFrom(BinaryReader reader) + internal VerticalHeader(TableHeader header, BinaryReader reader) : base(header, reader) { uint version = reader.ReadUInt32(); VersionMajor = (byte)(version >> 16); diff --git a/Typography.OpenFont/Tables.TrueType/Cvt_Programs.cs b/Typography.OpenFont/Tables.TrueType/Cvt_Programs.cs index 7087ceab..d70bc094 100644 --- a/Typography.OpenFont/Tables.TrueType/Cvt_Programs.cs +++ b/Typography.OpenFont/Tables.TrueType/Cvt_Programs.cs @@ -6,8 +6,7 @@ namespace Typography.OpenFont.Tables class CvtTable : TableEntry { - public const string _N = "cvt ";//need 4 chars//*** - public override string Name => _N; + public const string Name = "cvt ";//need 4 chars//*** // @@ -15,7 +14,7 @@ class CvtTable : TableEntry /// control value in font unit /// internal int[] _controlValues; - protected override void ReadContentFrom(BinaryReader reader) + internal CvtTable(TableHeader header, BinaryReader reader) : base(header, reader) { int nelems = (int)(this.TableLength / sizeof(short)); var results = new int[nelems]; @@ -28,25 +27,23 @@ protected override void ReadContentFrom(BinaryReader reader) } class PrepTable : TableEntry { - public const string _N = "prep"; - public override string Name => _N; + public const string Name = "prep"; // internal byte[] _programBuffer; // - protected override void ReadContentFrom(BinaryReader reader) + internal PrepTable(TableHeader header, BinaryReader reader) : base(header, reader) { _programBuffer = reader.ReadBytes((int)this.TableLength); } } class FpgmTable : TableEntry { - public const string _N = "fpgm"; - public override string Name => _N; + public const string Name = "fpgm"; // internal byte[] _programBuffer; - protected override void ReadContentFrom(BinaryReader reader) + internal FpgmTable(TableHeader header, BinaryReader reader) : base(header, reader) { _programBuffer = reader.ReadBytes((int)this.TableLength); } diff --git a/Typography.OpenFont/Tables.TrueType/Gasp.cs b/Typography.OpenFont/Tables.TrueType/Gasp.cs index 515ff6ce..88b29d3c 100644 --- a/Typography.OpenFont/Tables.TrueType/Gasp.cs +++ b/Typography.OpenFont/Tables.TrueType/Gasp.cs @@ -8,8 +8,7 @@ namespace Typography.OpenFont.Tables /// class Gasp : TableEntry { - public const string _N = "gasp"; - public override string Name => _N; + public const string Name = "gasp"; // //https://www.microsoft.com/typography/otspec/gasp.htm @@ -33,7 +32,7 @@ class Gasp : TableEntry //The 'gasp' table consists of a header followed by groupings of 'gasp' records: GaspRangeRecord[] _rangeRecords; - protected override void ReadContentFrom(BinaryReader reader) + public Gasp(TableHeader header, BinaryReader reader) : base(header, reader) { //Type Name Description diff --git a/Typography.OpenFont/Tables.TrueType/Glyf.cs b/Typography.OpenFont/Tables.TrueType/Glyf.cs index b225dc14..019f98ad 100644 --- a/Typography.OpenFont/Tables.TrueType/Glyf.cs +++ b/Typography.OpenFont/Tables.TrueType/Glyf.cs @@ -6,31 +6,33 @@ namespace Typography.OpenFont.Tables { class Glyf : TableEntry { - public const string _N = "glyf"; - public override string Name => _N; + public const string Name = "glyf"; // Glyph[] _glyphs; - GlyphLocations _glyphLocations; //-------------------- //both ttf and cff //we don't share EmptyGlyph between typefaces - internal readonly Glyph _emptyGlyph = new Glyph(new GlyphPointF[0], new ushort[0], Bounds.Zero, null, 0); + public static Glyph GenerateTypefaceSpecificEmptyGlyph() => + new Glyph(new GlyphPointF[0], new ushort[0], Bounds.Zero, null, 0); + internal readonly Glyph _emptyGlyph; - public Glyf(GlyphLocations glyphLocations) - { - _glyphLocations = glyphLocations; - } public Glyph[] Glyphs { get => _glyphs; internal set => _glyphs = value; } - protected override void ReadContentFrom(BinaryReader reader) - { + /// WOFF2 constructor + internal Glyf(TableHeader header, Glyph[] glyphs, Glyph emptyGlyph) : base(header, null) { + _emptyGlyph = emptyGlyph; + _glyphs = glyphs; + } + /// TTF/OTF constructor + internal Glyf(GlyphLocations locations, TableHeader header, BinaryReader reader) : base(header, reader) + { + _emptyGlyph = GenerateTypefaceSpecificEmptyGlyph(); uint tableOffset = this.Header.Offset; - GlyphLocations locations = _glyphLocations; int glyphCount = locations.GlyphCount; _glyphs = new Glyph[glyphCount]; @@ -82,7 +84,7 @@ protected override void ReadContentFrom(BinaryReader reader) } #endif - _glyphs[glyphIndex] = ReadCompositeGlyph(_glyphs, reader, tableOffset, glyphIndex); + _glyphs[glyphIndex] = ReadCompositeGlyph(locations, _glyphs, reader, tableOffset, glyphIndex); } @@ -264,7 +266,7 @@ internal enum CompositeGlyphFlags : ushort UNSCALED_COMPONENT_OFFSET = 1 << 12 } - Glyph ReadCompositeGlyph(Glyph[] createdGlyphs, BinaryReader reader, uint tableOffset, ushort compositeGlyphIndex) + Glyph ReadCompositeGlyph(GlyphLocations locations, Glyph[] createdGlyphs, BinaryReader reader, uint tableOffset, ushort compositeGlyphIndex) { //------------------------------------------------------ //https://www.microsoft.com/typography/OTSPEC/glyf.htm @@ -284,12 +286,12 @@ Glyph ReadCompositeGlyph(Glyph[] createdGlyphs, BinaryReader reader, uint tableO //--------- //move to composite glyph position - reader.BaseStream.Seek(tableOffset + _glyphLocations.Offsets[compositeGlyphIndex], SeekOrigin.Begin);//reset + reader.BaseStream.Seek(tableOffset + locations.Offsets[compositeGlyphIndex], SeekOrigin.Begin);//reset //------------------------ short contoursCount = reader.ReadInt16(); // ignored Bounds bounds = Utils.ReadBounds(reader); - Glyph finalGlyph = null; + Glyph? finalGlyph = null; CompositeGlyphFlags flags; #if DEBUG @@ -303,7 +305,7 @@ Glyph ReadCompositeGlyph(Glyph[] createdGlyphs, BinaryReader reader, uint tableO { // This glyph is not read yet, resolve it first! long storedOffset = reader.BaseStream.Position; - Glyph missingGlyph = ReadCompositeGlyph(createdGlyphs, reader, tableOffset, glyphIndex); + Glyph missingGlyph = ReadCompositeGlyph(locations, createdGlyphs, reader, tableOffset, glyphIndex); createdGlyphs[glyphIndex] = missingGlyph; reader.BaseStream.Position = storedOffset; } diff --git a/Typography.OpenFont/Tables.TrueType/GlyphLocations.cs b/Typography.OpenFont/Tables.TrueType/GlyphLocations.cs index 3ad0b3be..b4b02567 100644 --- a/Typography.OpenFont/Tables.TrueType/GlyphLocations.cs +++ b/Typography.OpenFont/Tables.TrueType/GlyphLocations.cs @@ -7,9 +7,7 @@ namespace Typography.OpenFont.Tables { class GlyphLocations : TableEntry { - public const string _N = "loca"; - public override string Name => _N; - + public const string Name = "loca"; // loca - Index to Location @@ -34,17 +32,15 @@ class GlyphLocations : TableEntry //There are two versions of this table, the short and the long. The version is specified in the indexToLocFormat entry in the 'head' table. uint[] _offsets; - public GlyphLocations(int glyphCount, bool isLongVersion) - { - _offsets = new uint[glyphCount + 1]; - this.IsLongVersion = isLongVersion; - } public bool IsLongVersion { get; private set; } public uint[] Offsets => _offsets; public int GlyphCount => _offsets.Length - 1; - protected override void ReadContentFrom(BinaryReader reader) + public GlyphLocations(int glyphCount, bool isLongVersion, TableHeader header, BinaryReader reader) : base(header, reader) { + _offsets = new uint[glyphCount + 1]; + this.IsLongVersion = isLongVersion; + //Short version //Type Name Description //USHORT offsets[n] The actual local offset divided by 2 is stored. @@ -58,7 +54,6 @@ protected override void ReadContentFrom(BinaryReader reader) //Note that the local offsets should be long-aligned, i.e., multiples of 4. Offsets which are not long-aligned may seriously degrade performance of some processors. - int glyphCount = GlyphCount; int lim = glyphCount + 1; _offsets = new uint[lim]; if (IsLongVersion) diff --git a/Typography.OpenFont/Tables.Variations/AVar.cs b/Typography.OpenFont/Tables.Variations/AVar.cs index c158f79b..f1833fe6 100644 --- a/Typography.OpenFont/Tables.Variations/AVar.cs +++ b/Typography.OpenFont/Tables.Variations/AVar.cs @@ -11,8 +11,7 @@ namespace Typography.OpenFont.Tables /// class AVar : TableEntry { - public const string _N = "avar"; - public override string Name => _N; + public const string Name = "avar"; //The axis variations table('avar') is an optional table //used in variable fonts that use OpenType Font Variations mechanisms. @@ -25,7 +24,7 @@ class AVar : TableEntry //other required or optional tables used in variable fonts. SegmentMapRecord[] _axisSegmentMaps; - protected override void ReadContentFrom(BinaryReader reader) + internal AVar(TableHeader header, BinaryReader reader) : base(header, reader) { //The 'avar' table is comprised of a small header plus segment maps for each axis. @@ -54,8 +53,7 @@ protected override void ReadContentFrom(BinaryReader reader) _axisSegmentMaps = new SegmentMapRecord[axisCount]; for (int i = 0; i < axisCount; ++i) { - SegmentMapRecord segmentMap = new SegmentMapRecord(); - segmentMap.ReadContent(reader); + SegmentMapRecord segmentMap = new SegmentMapRecord(reader); _axisSegmentMaps[i] = segmentMap; } @@ -69,7 +67,7 @@ public class SegmentMapRecord //uint16 positionMapCount The number of correspondence pairs for this axis. //AxisValueMap axisValueMaps[positionMapCount] The array of axis value map records for this axis. public AxisValueMap[] axisValueMaps; - public void ReadContent(BinaryReader reader) + public SegmentMapRecord(BinaryReader reader) { ushort positionMapCount = reader.ReadUInt16(); axisValueMaps = new AxisValueMap[positionMapCount]; diff --git a/Typography.OpenFont/Tables.Variations/CVar.cs b/Typography.OpenFont/Tables.Variations/CVar.cs index 55bc4abd..e7e14dcf 100644 --- a/Typography.OpenFont/Tables.Variations/CVar.cs +++ b/Typography.OpenFont/Tables.Variations/CVar.cs @@ -11,13 +11,8 @@ namespace Typography.OpenFont.Tables /// class CVar : TableEntry { - public const string _N = "cvar"; - public override string Name => _N; - public CVar() - { - - } - protected override void ReadContentFrom(BinaryReader reader) + public const string Name = "cvar"; + internal CVar(TableHeader header, BinaryReader reader) : base(header, reader) { } diff --git a/Typography.OpenFont/Tables.Variations/Common.ItemVariationStore.cs b/Typography.OpenFont/Tables.Variations/Common.ItemVariationStore.cs index bac45631..0b105efe 100644 --- a/Typography.OpenFont/Tables.Variations/Common.ItemVariationStore.cs +++ b/Typography.OpenFont/Tables.Variations/Common.ItemVariationStore.cs @@ -22,7 +22,7 @@ class ItemVariationStoreTable { public VariationRegion[] variationRegions; - public void ReadContentFrom(BinaryReader reader) + public ItemVariationStoreTable(BinaryReader reader) { @@ -40,8 +40,7 @@ public void ReadContentFrom(BinaryReader reader) variationRegions = new VariationRegion[regionCount]; for (int i = 0; i < regionCount; ++i) { - var variationRegion = new VariationRegion(); - variationRegion.ReadContent(reader, axisCount); + var variationRegion = new VariationRegion(reader, axisCount); variationRegions[i] = variationRegion; } } @@ -54,7 +53,7 @@ class VariationRegion //Each RegionAxisCoordinates record provides coordinate values for a region along a single axis: public RegionAxisCoordinate[] regionAxes; - public void ReadContent(BinaryReader reader, int axisCount) + public VariationRegion(BinaryReader reader, int axisCount) { regionAxes = new RegionAxisCoordinate[axisCount]; for (int i = 0; i < axisCount; ++i) diff --git a/Typography.OpenFont/Tables.Variations/FVar.cs b/Typography.OpenFont/Tables.Variations/FVar.cs index 3c7e8e3d..d5ec031a 100644 --- a/Typography.OpenFont/Tables.Variations/FVar.cs +++ b/Typography.OpenFont/Tables.Variations/FVar.cs @@ -17,15 +17,14 @@ namespace Typography.OpenFont.Tables /// class FVar : TableEntry { - public const string _N = "fvar"; - public override string Name => _N; + public const string Name = "fvar"; public VariableAxisRecord[] variableAxisRecords; public InstanceRecord[] instanceRecords; // - protected override void ReadContentFrom(BinaryReader reader) + internal FVar(TableHeader header, BinaryReader reader) : base(header, reader) { //Font variations header: @@ -83,8 +82,7 @@ protected override void ReadContentFrom(BinaryReader reader) for (int i = 0; i < axisCount; ++i) { long pos = reader.BaseStream.Position; - VariableAxisRecord varAxisRecord = new VariableAxisRecord(); - varAxisRecord.ReadContent(reader); + VariableAxisRecord varAxisRecord = new VariableAxisRecord(reader); variableAxisRecords[i] = varAxisRecord; if (reader.BaseStream.Position != pos + axisSize) { @@ -99,8 +97,7 @@ protected override void ReadContentFrom(BinaryReader reader) { long pos = reader.BaseStream.Position; - InstanceRecord instanecRec = new InstanceRecord(); - instanecRec.ReadContent(reader, axisCount, instanceSize); + InstanceRecord instanecRec = new InstanceRecord(reader, axisCount, instanceSize); if (reader.BaseStream.Position != pos + instanceSize) { @@ -133,7 +130,7 @@ public class VariableAxisRecord public float maxValue; public ushort flags; public ushort axisNameID; - public void ReadContent(BinaryReader reader) + public VariableAxisRecord(BinaryReader reader) { axisTag = Utils.TagToString(reader.ReadUInt32());//4 minValue = reader.ReadFixed();//4 @@ -170,7 +167,7 @@ public class InstanceRecord public ushort flags; public float[] coordinates; //tuple record public ushort postScriptNameID; - public void ReadContent(BinaryReader reader, int axisCount, int instanceRecordSize) + public InstanceRecord(BinaryReader reader, int axisCount, int instanceRecordSize) { long expectedEndPos = reader.BaseStream.Position + instanceRecordSize; subfamilyNameID = reader.ReadUInt16(); diff --git a/Typography.OpenFont/Tables.Variations/GVar.cs b/Typography.OpenFont/Tables.Variations/GVar.cs index c4414654..99af4079 100644 --- a/Typography.OpenFont/Tables.Variations/GVar.cs +++ b/Typography.OpenFont/Tables.Variations/GVar.cs @@ -8,16 +8,11 @@ namespace Typography.OpenFont.Tables class GVar : TableEntry { - public const string _N = "gvar"; - public override string Name => _N; + public const string Name = "gvar"; public ushort axisCount; - public GVar() - { - - } // - protected override void ReadContentFrom(BinaryReader reader) + internal GVar(TableHeader header, BinaryReader reader) : base(header, reader) { //'gvar' header @@ -56,7 +51,7 @@ protected override void ReadContentFrom(BinaryReader reader) ushort flags = reader.ReadUInt16(); uint glyphVariationDataArrayOffset = reader.ReadUInt32(); - uint[] glyphVariationDataOffsets = null; + uint[]? glyphVariationDataOffsets = null; if ((flags & 0x1) == 0) { //bit 0 is clear-> use Offset16 diff --git a/Typography.OpenFont/Tables.Variations/HVar.cs b/Typography.OpenFont/Tables.Variations/HVar.cs index ada5f918..267b4540 100644 --- a/Typography.OpenFont/Tables.Variations/HVar.cs +++ b/Typography.OpenFont/Tables.Variations/HVar.cs @@ -12,20 +12,16 @@ namespace Typography.OpenFont.Tables /// class HVar : TableEntry { - public const string _N = "HVAR"; - public override string Name => _N; + public const string Name = "HVAR"; ItemVariationStoreTable _itemVartionStore; - public HVar() + public HVar(TableHeader header, BinaryReader reader) : base(header, reader) { //The HVAR table is used in variable fonts to provide variations for horizontal glyph metrics values. //This can be used to provide variation data for advance widths in the 'hmtx' table. //In fonts with TrueType outlines, it can also be used to provide variation data for left and right side //bearings obtained from the 'hmtx' table and glyph bounding box. - } - protected override void ReadContentFrom(BinaryReader reader) - { long beginAt = reader.BaseStream.Position; //Horizontal metrics variations table: @@ -48,8 +44,7 @@ protected override void ReadContentFrom(BinaryReader reader) //itemVariationStore reader.BaseStream.Position = beginAt + itemVariationStoreOffset; - _itemVartionStore = new ItemVariationStoreTable(); - _itemVartionStore.ReadContentFrom(reader); + _itemVartionStore = new ItemVariationStoreTable(reader); } } } \ No newline at end of file diff --git a/Typography.OpenFont/Tables.Variations/MVar.cs b/Typography.OpenFont/Tables.Variations/MVar.cs index a517f44b..3867e575 100644 --- a/Typography.OpenFont/Tables.Variations/MVar.cs +++ b/Typography.OpenFont/Tables.Variations/MVar.cs @@ -13,8 +13,7 @@ namespace Typography.OpenFont.Tables /// class MVar : TableEntry { - public const string _N = "MVAR"; - public override string Name => _N; + public const string Name = "MVAR"; //The metrics variations table is used in variable fonts //to provide variations for font-wide metric values @@ -47,13 +46,9 @@ class MVar : TableEntry public ValueRecord[] valueRecords; - public ItemVariationStoreTable itemVariationStore; + public ItemVariationStoreTable? itemVariationStore; - public MVar() - { - - } - protected override void ReadContentFrom(BinaryReader reader) + internal MVar(TableHeader header, BinaryReader reader) : base(header, reader) { long startAt = reader.BaseStream.Position; @@ -107,8 +102,7 @@ protected override void ReadContentFrom(BinaryReader reader) if (valueRecordCount > 0) { reader.BaseStream.Position = startAt + itemVariationStoreOffset; - itemVariationStore = new ItemVariationStoreTable(); - itemVariationStore.ReadContentFrom(reader); + itemVariationStore = new ItemVariationStoreTable(reader); } } @@ -178,7 +172,7 @@ static class ValueTags { static Dictionary s_registerTags = new Dictionary(); - public static bool TryGetValueTagInfo(string tag, out ValueTagInfo valueTagInfo) + public static bool TryGetValueTagInfo(string tag, [System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out ValueTagInfo? valueTagInfo) { return s_registerTags.TryGetValue(tag, out valueTagInfo); } diff --git a/Typography.OpenFont/Tables/CharacterMap.cs b/Typography.OpenFont/Tables/CharacterMap.cs index 52fa9b48..fad57ac2 100644 --- a/Typography.OpenFont/Tables/CharacterMap.cs +++ b/Typography.OpenFont/Tables/CharacterMap.cs @@ -184,7 +184,7 @@ public ushort CharacterPairToGlyphIndex(int codepoint, ushort defaultGlyphIndex, { // Only check codepoint if nextCodepoint is a variation selector - if (_variationSelectors.TryGetValue(nextCodepoint, out VariationSelector sel)) + if (_variationSelectors.TryGetValue(nextCodepoint, out VariationSelector? sel)) { // If the sequence is a non-default UVS, return the mapped glyph @@ -353,7 +353,7 @@ public static CharMapFormat14 Create(BinaryReader reader) variationSelectors.Add(varSelectors[i], sel); } - return new CharMapFormat14 { _variationSelectors = variationSelectors }; + return new CharMapFormat14(variationSelectors); } class VariationSelector @@ -364,6 +364,11 @@ class VariationSelector } private Dictionary _variationSelectors; + + CharMapFormat14(Dictionary variationSelectors) + { + _variationSelectors = variationSelectors; + } } /// diff --git a/Typography.OpenFont/Tables/Cmap.cs b/Typography.OpenFont/Tables/Cmap.cs index fc954b76..3c43e381 100644 --- a/Typography.OpenFont/Tables/Cmap.cs +++ b/Typography.OpenFont/Tables/Cmap.cs @@ -73,11 +73,10 @@ namespace Typography.OpenFont.Tables partial class Cmap : TableEntry { - public const string _N = "cmap"; - public override string Name => _N; + public const string Name = "cmap"; - CharacterMap[] _charMaps = null; - List _charMap14List; + CharacterMap[] _charMaps; + List? _charMap14List; Dictionary _codepointToGlyphs = new Dictionary(); @@ -139,7 +138,7 @@ public ushort GetGlyphIndex(int codepoint, int nextCodepoint, out bool skipNextC return found; } - protected override void ReadContentFrom(BinaryReader input) + public Cmap(TableHeader header, BinaryReader input) : base(header, input) { //https://www.microsoft.com/typography/otspec/cmap.htm long beginAt = input.BaseStream.Position; diff --git a/Typography.OpenFont/Tables/Head.cs b/Typography.OpenFont/Tables/Head.cs index 08df81f0..2e4f5d8e 100644 --- a/Typography.OpenFont/Tables/Head.cs +++ b/Typography.OpenFont/Tables/Head.cs @@ -7,21 +7,17 @@ namespace Typography.OpenFont.Tables { class Head : TableEntry { - public const string _N = "head"; - public override string Name => _N; + public const string Name = "head"; // short _indexToLocFormat; Bounds _bounds; - public Head() - { - } - protected override void ReadContentFrom(BinaryReader input) + public Head(TableHeader header, BinaryReader input) : base(header, input) { Version = input.ReadUInt32(); // 0x00010000 for version 1.0. FontRevision = input.ReadUInt32(); CheckSumAdjustment = input.ReadUInt32(); MagicNumber = input.ReadUInt32(); - if (MagicNumber != 0x5F0F3CF5) throw new Exception("Invalid magic number!" + MagicNumber.ToString("x")); + if (MagicNumber != 0x5F0F3CF5) throw new Exception("Invalid magic number! " + MagicNumber.ToString("x")); Flags = input.ReadUInt16(); UnitsPerEm = input.ReadUInt16(); // valid is 16 to 16384 Created = input.ReadUInt64(); // International date (8-byte field). (?) diff --git a/Typography.OpenFont/Tables/HorizontalHeader.cs b/Typography.OpenFont/Tables/HorizontalHeader.cs index 7299137f..6bca29e6 100644 --- a/Typography.OpenFont/Tables/HorizontalHeader.cs +++ b/Typography.OpenFont/Tables/HorizontalHeader.cs @@ -10,8 +10,7 @@ namespace Typography.OpenFont.Tables /// class HorizontalHeader : TableEntry { - public const string _N = "hhea"; - public override string Name => _N; + public const string Name = "hhea"; //----- // Type Name Description @@ -35,10 +34,7 @@ class HorizontalHeader : TableEntry //int16 metricDataFormat 0 for current format. //uint16 numberOfHMetrics Number of hMetric entries in 'hmtx' table - public HorizontalHeader() - { - } - protected override void ReadContentFrom(BinaryReader input) + public HorizontalHeader(TableHeader header, BinaryReader input) : base(header, input) { Version = input.ReadUInt32(); //major + minor Ascent = input.ReadInt16(); diff --git a/Typography.OpenFont/Tables/HorizontalMetrics.cs b/Typography.OpenFont/Tables/HorizontalMetrics.cs index 99435c39..6f3c73cc 100644 --- a/Typography.OpenFont/Tables/HorizontalMetrics.cs +++ b/Typography.OpenFont/Tables/HorizontalMetrics.cs @@ -11,8 +11,7 @@ namespace Typography.OpenFont.Tables /// class HorizontalMetrics : TableEntry { - public const string _N = "hmtx"; - public override string Name => _N; + public const string Name = "hmtx"; // //https://www.microsoft.com/typography/otspec/hmtx.htm // A font rendering engine must use the advanceWidths in the hmtx table for the advances of a CFF OFF font, @@ -26,16 +25,6 @@ class HorizontalMetrics : TableEntry List _advanceWidths; //in font design unit List _leftSideBearings;//lsb, in font design unit - int _numOfHMetrics; - int _numGlyphs; - public HorizontalMetrics(UInt16 numOfHMetrics, UInt16 numGlyphs) - { - //The value numOfHMetrics comes from the 'hhea' table** - _advanceWidths = new List(numGlyphs); - _leftSideBearings = new List(numGlyphs); - _numOfHMetrics = numOfHMetrics; - _numGlyphs = numGlyphs; - } public ushort GetAdvanceWidth(ushort index) { return _advanceWidths[index]; @@ -49,8 +38,12 @@ public void GetHMatric(ushort index, out ushort advWidth, out short lsb) advWidth = _advanceWidths[index]; lsb = _leftSideBearings[index]; } - protected override void ReadContentFrom(BinaryReader input) + public HorizontalMetrics(UInt16 numOfHMetrics, UInt16 numGlyphs, TableHeader header, BinaryReader input) : base(header, input) { + //The value numOfHMetrics comes from the 'hhea' table** + _advanceWidths = new List(numGlyphs); + _leftSideBearings = new List(numGlyphs); + //=============================================================================== //1. hMetrics : have both advance width and leftSideBearing(lsb) //Paired advance width and left side bearing values for each glyph. @@ -58,7 +51,6 @@ protected override void ReadContentFrom(BinaryReader input) //If the font is monospaced, only one entry need be in the array, //but that entry is required. The last entry applies to all subsequent glyphs - int numOfHMetrics = _numOfHMetrics; for (int i = 0; i < numOfHMetrics; i++) { _advanceWidths.Add(input.ReadUInt16()); @@ -69,7 +61,6 @@ protected override void ReadContentFrom(BinaryReader input) //2. (only) LeftSideBearing: (same advanced width (eg. monospace font), vary only left side bearing) //Here the advanceWidth is assumed to be the same as the advanceWidth for the last entry above. //The number of entries in this array is derived from numGlyphs (from 'maxp' table) minus numberOfHMetrics. - int numGlyphs = _numGlyphs; int nEntries = numGlyphs - numOfHMetrics; ushort advanceWidth = _advanceWidths[numOfHMetrics - 1]; diff --git a/Typography.OpenFont/Tables/MaxProfile.cs b/Typography.OpenFont/Tables/MaxProfile.cs index a44f3773..502d4367 100644 --- a/Typography.OpenFont/Tables/MaxProfile.cs +++ b/Typography.OpenFont/Tables/MaxProfile.cs @@ -8,8 +8,7 @@ namespace Typography.OpenFont.Tables //https://docs.microsoft.com/en-us/typography/opentype/spec/maxp class MaxProfile : TableEntry { - public const string _N = "maxp"; - public override string Name => _N; + public const string Name = "maxp"; //This table establishes the memory requirements for this font. //Fonts with CFF data must use Version 0.5 of this table, @@ -57,7 +56,7 @@ class MaxProfile : TableEntry public ushort MaxComponentElements { get; private set; } public ushort MaxComponentDepth { get; private set; } - protected override void ReadContentFrom(BinaryReader input) + public MaxProfile(TableHeader header, BinaryReader input) : base(header, input) { Version = input.ReadUInt32(); // 0x00010000 == 1.0 GlyphCount = input.ReadUInt16(); diff --git a/Typography.OpenFont/Tables/NameEntry.cs b/Typography.OpenFont/Tables/NameEntry.cs index 43db3f92..ffc0324d 100644 --- a/Typography.OpenFont/Tables/NameEntry.cs +++ b/Typography.OpenFont/Tables/NameEntry.cs @@ -9,10 +9,9 @@ namespace Typography.OpenFont.Tables class NameEntry : TableEntry { - public const string _N = "name"; - public override string Name => _N; + public const string Name = "name"; // - protected override void ReadContentFrom(BinaryReader reader) + public NameEntry(TableHeader header, BinaryReader reader) : base(header, reader) { ushort uFSelector = reader.ReadUInt16(); @@ -98,7 +97,7 @@ protected override void ReadContentFrom(BinaryReader reader) /// /// Font Family name is used in combination with Font Subfamily name (name ID 2)... /// - public string FontName { get; private set; } + public string? FontName { get; private set; } /// /// Font Subfamily name. The Font Subfamily name distinguishes the fonts in a group with the /// same Font Family name (name ID 1). @@ -107,16 +106,16 @@ protected override void ReadContentFrom(BinaryReader reader) /// A font with no distinctive weight or style (e.g. medium weight, not italic, and OS/2.fsSelection bit 6 set) /// should use the string “Regular” as the Font Subfamily name (for English language). /// - public string FontSubFamily { get; private set; } - public string UniqueFontIden { get; private set; } + public string? FontSubFamily { get; private set; } + public string? UniqueFontIden { get; private set; } /// /// Full font name that reflects all family and relevant subfamily descriptors. /// The full font name is generally a combination of name IDs 1 and 2, or /// of name IDs 16 and 17, or a similar human-readable variant. /// - public string FullFontName { get; set; } + public string? FullFontName { get; set; } - public string VersionString { get; set; } + public string? VersionString { get; set; } /// /// PostScript name for the font; Name ID 6 specifies a string which is used to invoke a PostScript language font that corresponds to this OpenType font. @@ -127,11 +126,11 @@ protected override void ReadContentFrom(BinaryReader reader) ///the same CFF may be shared among multiple font components in a Font Collection. ///... /// - public string PostScriptName { get; set; } - public string PostScriptCID_FindfontName { get; set; } + public string? PostScriptName { get; set; } + public string? PostScriptCID_FindfontName { get; set; } // - public string TypographicFamilyName { get; set; } - public string TypographyicSubfamilyName { get; set; } + public string? TypographicFamilyName { get; set; } + public string? TypographyicSubfamilyName { get; set; } struct TT_NAME_RECORD diff --git a/Typography.OpenFont/Tables/OS2.cs b/Typography.OpenFont/Tables/OS2.cs index e4dd772f..22bad40c 100644 --- a/Typography.OpenFont/Tables/OS2.cs +++ b/Typography.OpenFont/Tables/OS2.cs @@ -12,8 +12,7 @@ namespace Typography.OpenFont.Tables /// class OS2Table : TableEntry { - public const string _N = "OS/2"; - public override string Name => _N; + public const string Name = "OS/2"; // // Type Name of Entry Comments @@ -106,8 +105,8 @@ public override string ToString() { return version + "," + Utils.TagToString(this.achVendID); } -#endif - protected override void ReadContentFrom(BinaryReader reader) +# endif + public OS2Table(TableHeader header, BinaryReader reader) : base(header, reader) { //Six versions of the OS/2 table have been defined: versions 0 to 5 //Versions 0 to 4 were defined in earlier versions of the OpenType or @@ -135,6 +134,8 @@ protected override void ReadContentFrom(BinaryReader reader) ReadVersion5(reader); break; } + if (panose is { } x) panose = x; // https://github.com/dotnet/roslyn/issues/39740 + else throw new System.NotImplementedException($"{nameof(panose)} is null."); } void ReadVersion0(BinaryReader reader) { diff --git a/Typography.OpenFont/Tables/Post.cs b/Typography.OpenFont/Tables/Post.cs index 02251ac7..03ec847b 100644 --- a/Typography.OpenFont/Tables/Post.cs +++ b/Typography.OpenFont/Tables/Post.cs @@ -48,8 +48,7 @@ namespace Typography.OpenFont.Tables class PostTable : TableEntry { - public const string _N = "post"; - public override string Name => _N; + public const string Name = "post"; // uint _italicAngle; short _underlinePosition; @@ -57,13 +56,13 @@ class PostTable : TableEntry //--------------- - Dictionary _glyphNames; - Dictionary _glyphIndiceByName; + Dictionary? _glyphNames; + Dictionary? _glyphIndiceByName; public int Version { get; private set; } - protected override void ReadContentFrom(BinaryReader reader) + public PostTable(TableHeader header, BinaryReader reader) : base(header, reader) { //header uint version = reader.ReadUInt32(); //16.16 @@ -149,7 +148,7 @@ protected override void ReadContentFrom(BinaryReader reader) } - internal Dictionary GlyphNames => _glyphNames; + internal Dictionary? GlyphNames => _glyphNames; // internal ushort GetGlyphIndex(string glyphName) { diff --git a/Typography.OpenFont/Tables/TableEntry.cs b/Typography.OpenFont/Tables/TableEntry.cs index eb889bc7..e8c2aac2 100644 --- a/Typography.OpenFont/Tables/TableEntry.cs +++ b/Typography.OpenFont/Tables/TableEntry.cs @@ -10,36 +10,23 @@ namespace Typography.OpenFont.Tables /// public abstract class TableEntry { - public TableEntry() + internal TableEntry(TableHeader header, BinaryReader? reader) { + Header = header; + reader?.BaseStream.Seek(this.Header.Offset, SeekOrigin.Begin); } - internal TableHeader Header { get; set; } - protected abstract void ReadContentFrom(BinaryReader reader); - public abstract string Name { get; } - internal void LoadDataFrom(BinaryReader reader) - { - reader.BaseStream.Seek(this.Header.Offset, SeekOrigin.Begin); - ReadContentFrom(reader); - } + internal TableHeader Header { get; } public uint TableLength => this.Header.Length; - } class UnreadTableEntry : TableEntry { - public UnreadTableEntry(TableHeader header) + public UnreadTableEntry(TableHeader header) : base(header, null) { - this.Header = header; - } - public override string Name => this.Header.Tag; - // - protected sealed override void ReadContentFrom(BinaryReader reader) - { - //intend *** - throw new NotImplementedException(); } + public string Name => this.Header.Tag; public bool HasCustomContentReader { get; protected set; } - public virtual T CreateTableEntry(BinaryReader reader, T expectedResult) + public virtual T CreateTableEntry(BinaryReader reader, OpenFontReader.TableReader tableReader) where T : TableEntry { throw new NotImplementedException(); diff --git a/Typography.OpenFont/Tables/TableEntryCollection.cs b/Typography.OpenFont/Tables/TableEntryCollection.cs index b275b097..3f544ee4 100644 --- a/Typography.OpenFont/Tables/TableEntryCollection.cs +++ b/Typography.OpenFont/Tables/TableEntryCollection.cs @@ -8,19 +8,19 @@ class TableEntryCollection { Dictionary _tables = new Dictionary(); public TableEntryCollection() { } - public void AddEntry(TableEntry en) + public void AddEntry(string tableName, TableEntry en) { - _tables.Add(en.Name, en); + _tables.Add(tableName, en); } - public bool TryGetTable(string tableName, out TableEntry entry) + public bool TryGetTable(string tableName, [System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out TableEntry? entry) { return _tables.TryGetValue(tableName, out entry); } - public void ReplaceTable(TableEntry table) + public void ReplaceTable(string tableName, TableEntry table) { - _tables[table.Name] = table; + _tables[tableName] = table; } } } diff --git a/Typography.OpenFont/Tables/Utils.cs b/Typography.OpenFont/Tables/Utils.cs index 8821aee3..44a17900 100644 --- a/Typography.OpenFont/Tables/Utils.cs +++ b/Typography.OpenFont/Tables/Utils.cs @@ -95,14 +95,14 @@ public static T[] ConcatArray(T[] arr1, T[] arr2) return newArr; } - public static void WarnUnimplemented(string format, params object[] args) + public static void WarnUnimplemented(string format, params object?[] args) { #if DEBUG System.Diagnostics.Debug.WriteLine("!STUB! " + string.Format(format, args)); #endif } - internal static void WarnUnimplementedCollectAssocGlyphs(string msg) + internal static void WarnUnimplementedCollectAssocGlyphs(string? msg) { #if DEBUG System.Diagnostics.Debug.WriteLine("!STUB! UnimplementedCollectAssocGlyph :" + msg); diff --git a/Typography.OpenFont/TrueTypeInterperter/TrueTypeInterpreter.cs b/Typography.OpenFont/TrueTypeInterperter/TrueTypeInterpreter.cs index feb0ff20..eb39e545 100644 --- a/Typography.OpenFont/TrueTypeInterperter/TrueTypeInterpreter.cs +++ b/Typography.OpenFont/TrueTypeInterperter/TrueTypeInterpreter.cs @@ -36,6 +36,12 @@ public void SetTypeFace(Typeface typeface) } } + public TrueTypeInterpreter(Typeface typeface) { + SetTypeFace(typeface); + // https://github.com/dotnet/roslyn/issues/39740 + if (_currentTypeFace is { } t) _currentTypeFace = t; else throw new NotImplementedException(); + if (_interpreter is { } i) _interpreter = i; else throw new NotImplementedException(); + } public GlyphPointF[] HintGlyph(ushort glyphIndex, float glyphSizeInPixel) { @@ -45,13 +51,14 @@ public GlyphPointF[] HintGlyph(ushort glyphIndex, float glyphSizeInPixel) //1. start with original points/contours from glyph int horizontalAdv = _currentTypeFace.GetHAdvanceWidthFromGlyphIndex(glyphIndex); int hFrontSideBearing = _currentTypeFace.GetHFrontSideBearingFromGlyphIndex(glyphIndex); - + if (!(glyph.TtfWoffInfo is var (endPoints, glyphPoints))) + throw new NotSupportedException("Only TTF glyphs are supported"); return HintGlyph(horizontalAdv, hFrontSideBearing, glyph.MinX, glyph.MaxY, - glyph.GlyphPoints, - glyph.EndPoints, + glyphPoints, + endPoints, glyph.GlyphInstructions, glyphSizeInPixel); @@ -63,7 +70,7 @@ public GlyphPointF[] HintGlyph( int maxY, GlyphPointF[] glyphPoints, ushort[] contourEndPoints, - byte[] instructions, + byte[]? instructions, float glyphSizeInPixel) { @@ -150,9 +157,9 @@ class SharpFontInterpreter ExecutionStack _stack; InstructionStream[] _functions; InstructionStream[] _instructionDefs; - float[] _controlValueTable; + float[]? _controlValueTable; int[] _storage; - ushort[] _contours; + ushort[]? _contours; float _scale; int _ppem; int _callStackSize; @@ -179,7 +186,7 @@ public void InitializeFunctionDefs(byte[] instructions) Execute(new InstructionStream(instructions), false, true); } - public void SetControlValueTable(int[] cvt, float scale, float ppem, byte[] cvProgram) + public void SetControlValueTable(int[]? cvt, float scale, float ppem, byte[]? cvProgram) { if (_scale == scale || cvt == null) return; @@ -216,7 +223,7 @@ public void SetControlValueTable(int[] cvt, float scale, float ppem, byte[] cvPr } } - public void HintGlyph(GlyphPointF[] glyphPoints, ushort[] contours, byte[] instructions) + public void HintGlyph(GlyphPointF[] glyphPoints, ushort[] contours, byte[]? instructions) { if (instructions == null || instructions.Length == 0) return; @@ -325,6 +332,8 @@ void Execute(InstructionStream stream, bool inFunction, bool allowFunctionDefs) // ==== CONTROL VALUE TABLE ==== case OpCode.WCVTP: { + if (_controlValueTable is null) + throw new NotSupportedException(); var value = _stack.PopFloat(); var loc = CheckIndex(_stack.Pop(), _controlValueTable.Length); _controlValueTable[loc] = value; @@ -332,6 +341,8 @@ void Execute(InstructionStream stream, bool inFunction, bool allowFunctionDefs) break; case OpCode.WCVTF: { + if (_controlValueTable is null) + throw new NotSupportedException(); var value = _stack.Pop(); var loc = CheckIndex(_stack.Pop(), _controlValueTable.Length); _controlValueTable[loc] = value * _scale; @@ -505,6 +516,7 @@ void Execute(InstructionStream stream, bool inFunction, bool allowFunctionDefs) case OpCode.SHC0: case OpCode.SHC1: { + if (_contours is null) throw new NotSupportedException(); Zone zone; int point; var displacement = ComputeDisplacement((int)opcode, out zone, out point); @@ -527,6 +539,7 @@ void Execute(InstructionStream stream, bool inFunction, bool allowFunctionDefs) case OpCode.SHZ0: case OpCode.SHZ1: { + if (_contours is null) throw new NotSupportedException(); Zone zone; int point; var displacement = ComputeDisplacement((int)opcode, out zone, out point); @@ -666,6 +679,7 @@ void Execute(InstructionStream stream, bool inFunction, bool allowFunctionDefs) case OpCode.UTP: _zp0.TouchState[_stack.Pop()] &= ~GetTouchState(); break; case OpCode.IUP0: case OpCode.IUP1: + if (_contours is null) throw new NotSupportedException(); // bail if no contours (empty outline) if (_contours.Length == 0) { @@ -1172,6 +1186,7 @@ void Execute(InstructionStream stream, bool inFunction, bool allowFunctionDefs) case OpCode.DELTAC2: case OpCode.DELTAC3: { + if (_controlValueTable is null) throw new NotSupportedException(); var last = _stack.Pop(); for (int i = 1; i <= last; i++) { @@ -1291,7 +1306,11 @@ int CheckIndex(int index, int length) return index; } - float ReadCvt() { return _controlValueTable[CheckIndex(_stack.Pop(), _controlValueTable.Length)]; } + float ReadCvt() + { + if (_controlValueTable is null) throw new NotSupportedException(); + return _controlValueTable[CheckIndex(_stack.Pop(), _controlValueTable.Length)]; + } void OnVectorsUpdated() { diff --git a/Typography.OpenFont/Typeface.cs b/Typography.OpenFont/Typeface.cs index e96a334e..f25802cc 100644 --- a/Typography.OpenFont/Typeface.cs +++ b/Typography.OpenFont/Typeface.cs @@ -8,90 +8,54 @@ namespace Typography.OpenFont public class Typeface { - readonly Bounds _bounds; - readonly ushort _unitsPerEm; - readonly Glyph[] _glyphs; - //TODO: implement vertical metrics - readonly HorizontalMetrics _horizontalMetrics; - readonly NameEntry _nameEntry; - // - CFFTable _cffTable; - BitmapFontGlyphSource _bitmapFontGlyphSource; - internal Typeface( + OS2Table os2Table, NameEntry nameEntry, - Bounds bounds, - ushort unitsPerEm, - Glyph[] glyphs, + Head header, + MaxProfile maxProfile, + HorizontalHeader horizontalHeader, HorizontalMetrics horizontalMetrics, - OS2Table os2Table) + Cmap cmaps, + Glyph[] glyphs + ) { - _nameEntry = nameEntry; - _bounds = bounds; - _unitsPerEm = unitsPerEm; - _glyphs = glyphs; - _horizontalMetrics = horizontalMetrics; OS2Table = os2Table; - } - internal Typeface( - NameEntry nameEntry, - Bounds bounds, - ushort unitsPerEm, - CFFTable cffTable, - HorizontalMetrics horizontalMetrics, - OS2Table os2Table) - { - _nameEntry = nameEntry; - _bounds = bounds; - _unitsPerEm = unitsPerEm; - _cffTable = cffTable; + Bounds = header.Bounds; + UnitsPerEm = header.UnitsPerEm; + MaxProfile = maxProfile; + CmapTable = cmaps; + HheaTable = horizontalHeader; _horizontalMetrics = horizontalMetrics; - OS2Table = os2Table; - - - //------ - _glyphs = _cffTable.Cff1FontSet._fonts[0]._glyphs; + Glyphs = glyphs; } - internal Typeface( - NameEntry nameEntry, - Bounds bounds, - ushort unitsPerEm, - BitmapFontGlyphSource bitmapFontGlyphSource, - Glyph[] glyphs, - HorizontalMetrics horizontalMetrics, - OS2Table os2Table) - { - - _nameEntry = nameEntry; - _bounds = bounds; - _unitsPerEm = unitsPerEm; - _bitmapFontGlyphSource = bitmapFontGlyphSource; - _horizontalMetrics = horizontalMetrics; - OS2Table = os2Table; + internal OS2Table OS2Table { get; } + readonly NameEntry _nameEntry; + public Bounds Bounds { get; } + public ushort UnitsPerEm { get; } + internal MaxProfile MaxProfile { get; } + internal Cmap CmapTable { get; } + internal HorizontalHeader HheaTable { get; } + //TODO: implement vertical metrics + readonly HorizontalMetrics _horizontalMetrics; + public Glyph[] Glyphs { get; } - _glyphs = glyphs; - } /// /// control values in Font unit /// - internal int[] ControlValues { get; set; } - internal byte[] PrepProgramBuffer { get; set; } - internal byte[] FpgmProgramBuffer { get; set; } - internal MaxProfile MaxProfile { get; set; } - internal Cmap CmapTable { get; set; } - internal Kern KernTable { get; set; } - internal Gasp GaspTable { get; set; } - internal HorizontalHeader HheaTable { get; set; } - internal OS2Table OS2Table { get; set; } + internal int[]? ControlValues { get; set; } + internal byte[]? PrepProgramBuffer { get; set; } + internal byte[]? FpgmProgramBuffer { get; set; } + internal Kern? KernTable { get; set; } + internal Gasp? GaspTable { get; set; } // public bool HasPrepProgramBuffer => PrepProgramBuffer != null; - internal CFFTable CffTable => _cffTable; + internal CFFTable? CffTable { get; set; } /// - /// actual font filename + /// actual font filename, NOT set by default, must be set by user! /// - public string Filename { get; set; } + public string? Filename { get; set; } /// /// OS2 sTypoAscender, in font designed unit /// @@ -132,10 +96,10 @@ internal Typeface( //(unless Apple exposes the 'OS/2' table through a new API) //--------------- - public string Name => _nameEntry.FontName; - public string FontSubFamily => _nameEntry.FontSubFamily; + public string? Name => _nameEntry.FontName; + public string? FontSubFamily => _nameEntry.FontSubFamily; - public int GlyphCount => _glyphs.Length; + public int GlyphCount => Glyphs.Length; // /// @@ -158,15 +122,14 @@ public void CollectUnicode(List unicodes) CmapTable.CollectUnicode(unicodes); } - public Glyph GetGlyphByName(string glyphName) + public Glyph? GetGlyphByName(string glyphName) { - if (_cffTable != null) + if (CffTable is { Cff1FontSet:{ _fonts:var fonts } }) { //early preview ... - List cff1Fonts = _cffTable.Cff1FontSet._fonts; - for (int i = 0; i < cff1Fonts.Count; i++) + foreach (var font in fonts) { - Glyph glyph = cff1Fonts[i].GetGlyphByName(glyphName); + Glyph? glyph = font.GetGlyphByName(glyphName); if (glyph != null) return glyph; } return null; @@ -179,7 +142,7 @@ public Glyph GetGlyphByName(string glyphName) } public ushort GetGlyphIndexByName(string glyphName) { - if (_cffTable != null) + if (CffTable != null) { return GetGlyphByName(glyphName)?.GlyphIndex ?? 0; } @@ -208,7 +171,7 @@ public ushort GetGlyphIndexByName(string glyphName) public Glyph GetGlyph(ushort glyphIndex) { - return _glyphs[glyphIndex]; + return Glyphs[glyphIndex]; } @@ -228,14 +191,8 @@ public short GetHFrontSideBearingFromGlyphIndex(ushort glyphIndex) public short GetKernDistance(ushort leftGlyphIndex, ushort rightGlyphIndex) { //DEPRECATED -> use OpenFont layout instead - return this.KernTable.GetKerningDistance(leftGlyphIndex, rightGlyphIndex); + return this.KernTable?.GetKerningDistance(leftGlyphIndex, rightGlyphIndex) ?? 0; } - // - public Bounds Bounds => _bounds; - public ushort UnitsPerEm => _unitsPerEm; - public Glyph[] Glyphs => _glyphs; - // - const int pointsPerInch = 72; //TODO: should be configurable /// /// convert from point-unit value to pixel value @@ -275,20 +232,20 @@ public float CalculateScaleToPixelFromPointSize(float targetPointSize, int resol return (targetPointSize * resolution / pointsPerInch) / this.UnitsPerEm; } - internal BASE BaseTable { get; set; } - internal GDEF GDEFTable { get; set; } + internal BASE? BaseTable { get; set; } + internal GDEF? GDEFTable { get; set; } - public COLR COLRTable { get; set; } - public CPAL CPALTable { get; set; } - public GPOS GPOSTable { get; set; } - public GSUB GSUBTable { get; set; } + public COLR? COLRTable { get; set; } + public CPAL? CPALTable { get; set; } + public GPOS? GPOSTable { get; set; } + public GSUB? GSUBTable { get; set; } //------------------------------------------------------- //experiment - internal void LoadOpenFontLayoutInfo(GDEF gdefTable, GSUB gsubTable, GPOS gposTable, BASE baseTable, COLR colrTable, CPAL cpalTable) + internal void LoadOpenFontLayoutInfo(GDEF? gdefTable, GSUB? gsubTable, GPOS? gposTable, BASE? baseTable, COLR? colrTable, CPAL? cpalTable) { //*** @@ -319,21 +276,20 @@ internal void LoadOpenFontLayoutInfo(GDEF gdefTable, GSUB gsubTable, GPOS gposTa //--------- - internal PostTable PostTable { get; set; } + internal PostTable? PostTable { get; set; } internal bool _evalCffGlyphBounds; - public bool IsCffFont => _cffTable != null; + public bool IsCffFont => CffTable != null; //--------- - internal MathTable _mathTable; - internal MathGlyphs.MathGlyphInfo[] _mathGlyphInfos; - internal Glyph[] GetRawGlyphList() => _glyphs; + internal MathTable? _mathTable; + internal MathGlyphs.MathGlyphInfo[]? _mathGlyphInfos; // - public MathGlyphs.MathConstants MathConsts => (_mathTable != null) ? _mathTable._mathConstTable : null; + public MathGlyphs.MathConstants? MathConsts => _mathTable?._mathConstTable; //--------- //svg and bitmap font - internal SvgTable _svgTable; + internal SvgTable? _svgTable; public void ReadSvgContent(Glyph glyph, System.Text.StringBuilder output) { if (_svgTable != null) @@ -342,10 +298,14 @@ public void ReadSvgContent(Glyph glyph, System.Text.StringBuilder output) } } - public bool IsBitmapFont => _bitmapFontGlyphSource != null; + + public bool IsBitmapFont => BitmapFontGlyphSource != null; + + internal BitmapFontGlyphSource? BitmapFontGlyphSource { get; set; } + public void ReadBitmapContent(Glyph glyph, System.IO.Stream output) { - _bitmapFontGlyphSource.CopyBitmapContent(glyph, output); + BitmapFontGlyphSource?.CopyBitmapContent(glyph, output); } } @@ -831,19 +791,21 @@ public static class TypefaceExtension2 public static IEnumerable GetGlyphNameIter(this Typeface typeface) { - if (typeface.IsCffFont) + if (typeface.IsCffFont && typeface is { CffTable: { Cff1FontSet:{ _fonts:var fonts } } }) { - CFF.Cff1Font cff1Font = typeface.CffTable.Cff1FontSet._fonts[0]; - foreach (var kp in cff1Font.GetGlyphNameIter()) + foreach(var font in fonts) { - yield return kp; + foreach (var kp in font.GetGlyphNameIter()) + { + yield return kp; + } } } - else if (typeface.PostTable.Version == 2) + else if (typeface.PostTable?.Version == 2 && typeface.PostTable.GlyphNames is { } names) { //version 1 and 3 => no glyph names - foreach (var kp in typeface.PostTable.GlyphNames) + foreach (var kp in names) { yield return new GlyphNameMap(kp.Key, kp.Value); } @@ -1049,9 +1011,9 @@ public static void UpdateAllCffGlyphBounds(this Typeface typeface) Glyph g = typeface.GetGlyph(i); boundFinder.Reset(); - evalEngine.Run(boundFinder, - g._ownerCffFont, - g._cff1GlyphData.GlyphInstructions); + if (g.CffInfo is { } cff) + evalEngine.Run(boundFinder, cff.GlyphInstructions); + else throw new System.NotSupportedException("Non-CFF glyph in CFF font"); g.Bounds = boundFinder.GetResultBounds(); } diff --git a/Typography.OpenFont/WebFont/Woff2Reader.cs b/Typography.OpenFont/WebFont/Woff2Reader.cs index a0e3545a..dc6f83fe 100644 --- a/Typography.OpenFont/WebFont/Woff2Reader.cs +++ b/Typography.OpenFont/WebFont/Woff2Reader.cs @@ -52,8 +52,14 @@ class Woff2TableDirectory public uint origLength; public uint transformLength; + + public Woff2TableDirectory(string name) + { + Name = name; + } + //translated values - public string Name { get; set; } //translate from tag + public string Name { get; } //translate from tag public byte PreprocessingTransformation { get; set; } public long ExpectedStartAt { get; set; } #if DEBUG @@ -69,7 +75,7 @@ public override string ToString() public static class Woff2DefaultBrotliDecompressFunc { - public static BrotliDecompressStreamFunc DecompressHandler; + public static BrotliDecompressStreamFunc? DecompressHandler; } class TransformedGlyf : UnreadTableEntry @@ -84,15 +90,9 @@ public TransformedGlyf(TableHeader header, Woff2TableDirectory tableDir) : base( } public Woff2TableDirectory TableDir { get; } - public override T CreateTableEntry(BinaryReader reader, T expectedResult) + public override T CreateTableEntry(BinaryReader reader, OpenFontReader.TableReader expectedResult) { - Glyf glyfTable = expectedResult as Glyf; - - if (glyfTable == null) throw new System.NotSupportedException(); - - ReconstructGlyfTable(reader, TableDir, glyfTable); - - return expectedResult; + return ReconstructGlyfTable(Header, reader, TableDir) is T t ? t : throw new System.NotSupportedException(); } @@ -120,7 +120,7 @@ public override string ToString() } - static void ReconstructGlyfTable(BinaryReader reader, Woff2TableDirectory woff2TableDir, Glyf glyfTable) + static Glyf ReconstructGlyfTable(TableHeader header, BinaryReader reader, Woff2TableDirectory woff2TableDir) { //fill the information to glyfTable //reader.BaseStream.Position += woff2TableDir.transformLength; @@ -158,7 +158,7 @@ static void ReconstructGlyfTable(BinaryReader reader, Woff2TableDirectory woff2T //UInt8 bboxBitmap[] Bitmap(a numGlyphs-long bit array) indicating explicit bounding boxes //Int16 bboxStream[] Stream of Int16 values representing glyph bounding box data //UInt8 instructionStream[] Stream of UInt8 values representing a set of instructions for each corresponding glyph - + reader.BaseStream.Position = woff2TableDir.ExpectedStartAt; long start = reader.BaseStream.Position; @@ -187,7 +187,7 @@ static void ReconstructGlyfTable(BinaryReader reader, Woff2TableDirectory woff2T long expected_EndAt = expected_InstructionStreamStartAt + instructionStreamSize; //--------------------------------------------- - Glyph[] glyphs = new Glyph[numGlyphs]; + Glyph?[] readingGlyphs = new Glyph?[numGlyphs]; TempGlyph[] allGlyphs = new TempGlyph[numGlyphs]; List compositeGlyphs = new List(); int contourCount = 0; @@ -262,6 +262,7 @@ static void ReconstructGlyfTable(BinaryReader reader, Woff2TableDirectory woff2T System.Diagnostics.Debug.WriteLine("ERR!!"); } #endif + var emptyGlyph = Glyf.GenerateTypefaceSpecificEmptyGlyph(); // //1) nPoints stream, npoint for each contour @@ -313,9 +314,9 @@ static void ReconstructGlyfTable(BinaryReader reader, Woff2TableDirectory woff2T int pntContourIndex = 0; for (int i = 0; i < allGlyphs.Length; ++i) { - glyphs[i] = BuildSimpleGlyphStructure(reader, + readingGlyphs[i] = BuildSimpleGlyphStructure(reader, ref allGlyphs[i], - glyfTable._emptyGlyph, + emptyGlyph, pntPerContours, ref pntContourIndex, flagStream, ref curFlagsIndex); } @@ -348,7 +349,7 @@ static void ReconstructGlyfTable(BinaryReader reader, Woff2TableDirectory woff2T for (ushort i = 0; i < j; ++i) { int compositeGlyphIndex = compositeGlyphs[i]; - glyphs[compositeGlyphIndex] = ReadCompositeGlyph(glyphs, reader, i, glyfTable._emptyGlyph); + readingGlyphs[compositeGlyphIndex] = ReadCompositeGlyph(readingGlyphs, reader, i, emptyGlyph); } } @@ -379,11 +380,13 @@ static void ReconstructGlyfTable(BinaryReader reader, Woff2TableDirectory woff2T #endif int bitmapCount = (numGlyphs + 7) / 8; byte[] bboxBitmap = ExpandBitmap(reader.ReadBytes(bitmapCount)); + var glyphs = new Glyph[numGlyphs]; for (ushort i = 0; i < numGlyphs; ++i) { TempGlyph tempGlyph = allGlyphs[i]; - Glyph glyph = glyphs[i]; - + var glyph = readingGlyphs[i] ?? throw new System.NotSupportedException + ($"Both {nameof(BuildSimpleGlyphStructure)} and {nameof(ReadCompositeGlyph)} failed to read the glyph at {i}"); + glyphs[i] = glyph; byte hasBbox = bboxBitmap[i]; if (hasBbox == 1) { @@ -449,13 +452,13 @@ static void ReconstructGlyfTable(BinaryReader reader, Woff2TableDirectory woff2T } #endif - - glyfTable.Glyphs = glyphs; + return new Glyf(header, glyphs, emptyGlyph); } static Bounds FindSimpleGlyphBounds(Glyph glyph) { - GlyphPointF[] glyphPoints = glyph.GlyphPoints; + if (!(glyph.TtfWoffInfo is var (_, glyphPoints))) + throw new System.NotImplementedException("Built glyph is not WOFF glyph"); int j = glyphPoints.Length; float xmin = float.MaxValue; @@ -499,7 +502,7 @@ static byte[] ExpandBitmap(byte[] orgBBoxBitmap) return expandArr; } - static Glyph BuildSimpleGlyphStructure(BinaryReader glyphStreamReader, + static Glyph? BuildSimpleGlyphStructure(BinaryReader glyphStreamReader, ref TempGlyph tmpGlyph, Glyph emptyGlyph, ushort[] pntPerContours, ref int pntContourIndex, @@ -729,7 +732,7 @@ static bool CompositeHasInstructions(BinaryReader reader, ushort compositeGlyphI return Glyf.HasFlag(flags, Glyf.CompositeGlyphFlags.WE_HAVE_INSTRUCTIONS); } - static Glyph ReadCompositeGlyph(Glyph[] createdGlyphs, BinaryReader reader, ushort compositeGlyphIndex, Glyph emptyGlyph) + static Glyph ReadCompositeGlyph(Glyph?[] createdGlyphs, BinaryReader reader, ushort compositeGlyphIndex, Glyph emptyGlyph) { //Decoding of Composite Glyphs @@ -750,22 +753,23 @@ static Glyph ReadCompositeGlyph(Glyph[] createdGlyphs, BinaryReader reader, usho - Glyph finalGlyph = null; + Glyph? finalGlyph = null; Glyf.CompositeGlyphFlags flags; do { flags = (Glyf.CompositeGlyphFlags)reader.ReadUInt16(); ushort glyphIndex = reader.ReadUInt16(); - if (createdGlyphs[glyphIndex] == null) + var existingGlyph = createdGlyphs[glyphIndex]; + if (existingGlyph == null) { // This glyph is not read yet, resolve it first! long storedOffset = reader.BaseStream.Position; Glyph missingGlyph = ReadCompositeGlyph(createdGlyphs, reader, glyphIndex, emptyGlyph); - createdGlyphs[glyphIndex] = missingGlyph; + createdGlyphs[glyphIndex] = existingGlyph = missingGlyph; reader.BaseStream.Position = storedOffset; } - Glyph newGlyph = Glyph.Clone(createdGlyphs[glyphIndex], compositeGlyphIndex); + Glyph newGlyph = Glyph.Clone(existingGlyph, compositeGlyphIndex); short arg1 = 0; short arg2 = 0; @@ -973,17 +977,10 @@ public override string ToString() class TripleEncodingTable { - static TripleEncodingTable s_encTable; + static TripleEncodingTable? s_encTable; List _records = new List(); - public static TripleEncodingTable GetEncTable() - { - if (s_encTable == null) - { - s_encTable = new TripleEncodingTable(); - } - return s_encTable; - } + public static TripleEncodingTable GetEncTable() => s_encTable ??= new TripleEncodingTable(); private TripleEncodingTable() { @@ -1252,10 +1249,12 @@ void AddRecord(byte byteCount, byte xbits, byte ybits, ushort deltaX, ushort del #endif _records.Add(rec); } - void BuildRecords(byte byteCount, byte xbits, byte ybits, ushort[] deltaXs, ushort[] deltaYs) + void BuildRecords(byte byteCount, byte xbits, byte ybits, ushort[]? deltaXs, ushort[]? deltaYs) { if (deltaXs == null) { + if (deltaYs == null) + throw new System.ArgumentException($"{nameof(deltaXs)} and {nameof(deltaYs)} cannot both be null"); //(set 1.1) for (int y = 0; y < deltaYs.Length; ++y) { @@ -1302,13 +1301,12 @@ public TransformedLoca(TableHeader header, Woff2TableDirectory tableDir) : base( TableDir = tableDir; } public Woff2TableDirectory TableDir { get; } - public override T CreateTableEntry(BinaryReader reader, T expectedResult) + public override T CreateTableEntry(BinaryReader reader, OpenFontReader.TableReader expectedResult) { - GlyphLocations loca = expectedResult as GlyphLocations; - if (loca == null) throw new System.NotSupportedException(); - - //nothing todo here :) - return expectedResult; + //nothing todo here, read nothing :) + return + new GlyphLocations(-1, true, Header, new BinaryReader(Stream.Null)) is T t + ? t : throw new System.NotSupportedException(); } } @@ -1316,9 +1314,7 @@ public override T CreateTableEntry(BinaryReader reader, T expectedResult) class Woff2Reader { - Woff2Header _header; - - public BrotliDecompressStreamFunc DecompressHandler; + public BrotliDecompressStreamFunc? DecompressHandler; public Woff2Reader() { @@ -1351,12 +1347,11 @@ static void dbugVerifyKnownTables() } #endif - public PreviewFontInfo ReadPreview(BinaryReader reader) + public PreviewFontInfo? ReadPreview(BinaryReader reader) { - - _header = ReadHeader(reader); - if (_header == null) return null; //=> return here and notify user too. - Woff2TableDirectory[] woff2TablDirs = ReadTableDirectories(reader); + var header = ReadHeader(reader); + if (header == null) return null; //=> return here and notify user too. + Woff2TableDirectory[] woff2TablDirs = ReadTableDirectories(header, reader); if (DecompressHandler == null) { //if no Brotli decoder=> return here and notify user too. @@ -1372,8 +1367,8 @@ public PreviewFontInfo ReadPreview(BinaryReader reader) } //try read each compressed tables - byte[] compressedBuffer = reader.ReadBytes((int)_header.totalCompressSize); - if (compressedBuffer.Length != _header.totalCompressSize) + byte[] compressedBuffer = reader.ReadBytes((int)header.totalCompressSize); + if (compressedBuffer.Length != header.totalCompressSize) { //error! return null; //can't read this, notify user too. @@ -1400,11 +1395,11 @@ public PreviewFontInfo ReadPreview(BinaryReader reader) } } } - internal Typeface Read(BinaryReader reader) + internal Typeface? Read(BinaryReader reader) { - _header = ReadHeader(reader); - if (_header == null) return null; //=> return here and notify user too. - Woff2TableDirectory[] woff2TablDirs = ReadTableDirectories(reader); + var header = ReadHeader(reader); + if (header == null) return null; //=> return here and notify user too. + Woff2TableDirectory[] woff2TablDirs = ReadTableDirectories(header, reader); if (DecompressHandler == null) { //if no Brotli decoder=> return here and notify user too. @@ -1420,8 +1415,8 @@ internal Typeface Read(BinaryReader reader) } //try read each compressed tables - byte[] compressedBuffer = reader.ReadBytes((int)_header.totalCompressSize); - if (compressedBuffer.Length != _header.totalCompressSize) + byte[] compressedBuffer = reader.ReadBytes((int)header.totalCompressSize); + if (compressedBuffer.Length != header.totalCompressSize) { //error! return null; //can't read this, notify user too. @@ -1449,7 +1444,7 @@ internal Typeface Read(BinaryReader reader) } } } - public Typeface Read(Stream inputstream) + public Typeface? Read(Stream inputstream) { using (ByteOrderSwappingBinaryReader reader = new ByteOrderSwappingBinaryReader(inputstream)) { @@ -1459,7 +1454,7 @@ public Typeface Read(Stream inputstream) - Woff2Header ReadHeader(BinaryReader reader) + Woff2Header? ReadHeader(BinaryReader reader) { //WOFF2 Header //UInt32 signature 0x774F4632 'wOF2' @@ -1509,10 +1504,10 @@ Woff2Header ReadHeader(BinaryReader reader) return header; } - Woff2TableDirectory[] ReadTableDirectories(BinaryReader reader) + Woff2TableDirectory[] ReadTableDirectories(Woff2Header header, BinaryReader reader) { - uint tableCount = (uint)_header.numTables; //? + uint tableCount = (uint)header.numTables; //? var tableDirs = new Woff2TableDirectory[tableCount]; long expectedTableStartAt = 0; @@ -1525,7 +1520,6 @@ Woff2TableDirectory[] ReadTableDirectories(BinaryReader reader) //UIntBase128 origLength length of original table //UIntBase128 transformLength transformed length(if applicable) - Woff2TableDirectory table = new Woff2TableDirectory(); byte flags = reader.ReadByte(); //The interpretation of the flags field is as follows. @@ -1535,7 +1529,7 @@ Woff2TableDirectory[] ReadTableDirectories(BinaryReader reader) //interprete flags int knowTable = flags & 0x1F; //5 bits => known table or not - string tableName = null; + string tableName; if (knowTable < 63) { //this is known table @@ -1545,8 +1539,7 @@ Woff2TableDirectory[] ReadTableDirectories(BinaryReader reader) { tableName = Utils.TagToString(reader.ReadUInt32()); //other tag } - - table.Name = tableName; + Woff2TableDirectory table = new Woff2TableDirectory(tableName); //Bits 6 and 7 indicate the preprocessing transformation version number(0 - 3) that was applied to each table. @@ -1578,7 +1571,7 @@ Woff2TableDirectory[] ReadTableDirectories(BinaryReader reader) break; case 0: { - if (table.Name == Glyf._N) + if (table.Name == Glyf.Name) { if (!ReadUIntBase128(reader, out table.transformLength)) { @@ -1586,7 +1579,7 @@ Woff2TableDirectory[] ReadTableDirectories(BinaryReader reader) } expectedTableStartAt += table.transformLength;//*** } - else if (table.Name == GlyphLocations._N) + else if (table.Name == GlyphLocations.Name) { //BUT by spec, transform 'loca' MUST has transformLength=0 if (!ReadUIntBase128(reader, out table.transformLength)) @@ -1629,12 +1622,9 @@ static TableEntryCollection CreateTableEntryCollection(Woff2TableDirectory[] wof for (int i = 0; i < woffTableDirs.Length; ++i) { Woff2TableDirectory woffTableDir = woffTableDirs[i]; - UnreadTableEntry unreadTableEntry = null; - - - + UnreadTableEntry unreadTableEntry; - if (woffTableDir.Name == Glyf._N && woffTableDir.PreprocessingTransformation == 0) + if (woffTableDir.Name == Glyf.Name && woffTableDir.PreprocessingTransformation == 0) { //this is transformed glyf table, //we need another techqniue @@ -1644,7 +1634,7 @@ static TableEntryCollection CreateTableEntryCollection(Woff2TableDirectory[] wof unreadTableEntry = new TransformedGlyf(tableHeader, woffTableDir); } - else if (woffTableDir.Name == GlyphLocations._N && woffTableDir.PreprocessingTransformation == 0) + else if (woffTableDir.Name == GlyphLocations.Name && woffTableDir.PreprocessingTransformation == 0) { //this is transformed glyf table, //we need another techqniue @@ -1660,7 +1650,7 @@ static TableEntryCollection CreateTableEntryCollection(Woff2TableDirectory[] wof woffTableDir.origLength); unreadTableEntry = new UnreadTableEntry(tableHeader); } - tableEntryCollection.AddEntry(unreadTableEntry); + tableEntryCollection.AddEntry(unreadTableEntry.Name, unreadTableEntry); } return tableEntryCollection; @@ -1690,41 +1680,41 @@ static TableEntryCollection CreateTableEntryCollection(Woff2TableDirectory[] wof //------------------------------------------------------------------- //-- TODO:implement missing table too! - Cmap._N, //0 - Head._N, //1 - HorizontalHeader._N,//2 - HorizontalMetrics._N,//3 - MaxProfile._N,//4 - NameEntry._N,//5 - OS2Table._N, //6 - PostTable._N,//7 - CvtTable._N,//8 - FpgmTable._N,//9 - Glyf._N,//10 - GlyphLocations._N,//11 - PrepTable._N,//12 - CFFTable._N,//13 + Cmap.Name, //0 + Head.Name, //1 + HorizontalHeader.Name,//2 + HorizontalMetrics.Name,//3 + MaxProfile.Name,//4 + NameEntry.Name,//5 + OS2Table.Name, //6 + PostTable.Name,//7 + CvtTable.Name,//8 + FpgmTable.Name,//9 + Glyf.Name,//10 + GlyphLocations.Name,//11 + PrepTable.Name,//12 + CFFTable.Name,//13 "VORG",//14 - EBDT._N,//15, + EBDT.Name,//15, //--------------- - EBLC._N,//16 - Gasp._N,//17 - HorizontalDeviceMetrics._N,//18 - Kern._N,//19 + EBLC.Name,//16 + Gasp.Name,//17 + HorizontalDeviceMetrics.Name,//18 + Kern.Name,//19 "LTSH",//20 "PCLT",//21 - VerticalDeviceMetrics._N,//22 - VerticalHeader._N,//23 - VerticalMetrics._N,//24 - BASE._N,//25 - GDEF._N,//26 - GPOS._N,//27 - GSUB._N,//28 - EBSC._N, //29 + VerticalDeviceMetrics.Name,//22 + VerticalHeader.Name,//23 + VerticalMetrics.Name,//24 + BASE.Name,//25 + GDEF.Name,//26 + GPOS.Name,//27 + GSUB.Name,//28 + EBSC.Name, //29 "JSTF", //30 - MathTable._N,//31 + MathTable.Name,//31 //--------------- @@ -1748,11 +1738,11 @@ static TableEntryCollection CreateTableEntryCollection(Woff2TableDirectory[] wof //15 => EBDT, 31 =>MATH, 47 =>fvar, 63 =>arbitrary tag follows,... //------------------------------------------------------------------- - CBDT._N, //32 - CBLC._N,//33 - COLR._N,//34 - CPAL._N,//35, - SvgTable._N,//36 + CBDT.Name, //32 + CBLC.Name,//33 + COLR.Name,//34 + CPAL.Name,//35, + SvgTable.Name,//36 "sbix",//37 "acnt",//38 "avar",//39 diff --git a/Typography.OpenFont/WebFont/WoffReader.cs b/Typography.OpenFont/WebFont/WoffReader.cs index 748d0bf9..d81ca873 100644 --- a/Typography.OpenFont/WebFont/WoffReader.cs +++ b/Typography.OpenFont/WebFont/WoffReader.cs @@ -53,12 +53,22 @@ class WoffTableDirectory public uint origLength; public uint origChecksum; + public WoffTableDirectory(uint tag, uint offset, uint compLength, uint origLength, uint origChecksum, long expectedStartAt, string name) + { + this.tag = tag; + this.offset = offset; + this.compLength = compLength; + this.origLength = origLength; + this.origChecksum = origChecksum; + ExpectedStartAt = expectedStartAt; + Name = name; + } + + public long ExpectedStartAt { get; set; } + public string Name { get; set; } //translated values //public UnreadTableEntry unreadTableEntry; //simulate - public string Name { get; set; } - public long ExpectedStartAt { get; set; } #if DEBUG - public WoffTableDirectory() { } public override string ToString() { return Name; @@ -69,15 +79,14 @@ public override string ToString() public delegate bool ZlibDecompressStreamFunc(byte[] compressedInput, byte[] decompressOutput); public static class WoffDefaultZlibDecompressFunc { - public static ZlibDecompressStreamFunc DecompressHandler; + public static ZlibDecompressStreamFunc? DecompressHandler; } class WoffReader { - WoffHeader _header; - public ZlibDecompressStreamFunc DecompressHandler; + public ZlibDecompressStreamFunc? DecompressHandler; - public PreviewFontInfo ReadPreview(BinaryReader reader) + public PreviewFontInfo? ReadPreview(BinaryReader reader) { //read preview only //WOFF File @@ -87,9 +96,8 @@ public PreviewFontInfo ReadPreview(BinaryReader reader) //ExtendedMetadata An optional block of extended metadata, represented in XML format and compressed for storage in the WOFF file. //PrivateData An optional block of private data for the font designer, foundry, or vendor to use. - PreviewFontInfo fontPreviewInfo = null; - _header = ReadWOFFHeader(reader); - if (_header == null) + var header = ReadWOFFHeader(reader); + if (header == null) { #if DEBUG System.Diagnostics.Debug.WriteLine("can't read "); @@ -98,7 +106,7 @@ public PreviewFontInfo ReadPreview(BinaryReader reader) } // - WoffTableDirectory[] woffTableDirs = ReadTableDirectories(reader); + WoffTableDirectory[] woffTableDirs = ReadTableDirectories(header, reader); if (woffTableDirs == null) { return null; @@ -124,7 +132,7 @@ public PreviewFontInfo ReadPreview(BinaryReader reader) //for font preview, we may not need to extract using (MemoryStream decompressStream = new MemoryStream()) { - if (Extract(reader, woffTableDirs, decompressStream)) + if (Extract(DecompressHandler, reader, woffTableDirs, decompressStream)) { using (ByteOrderSwappingBinaryReader reader2 = new ByteOrderSwappingBinaryReader(decompressStream)) { @@ -141,10 +149,10 @@ public PreviewFontInfo ReadPreview(BinaryReader reader) } } - return fontPreviewInfo; + return null; } - internal Typeface Read(BinaryReader reader) + internal Typeface? Read(BinaryReader reader) { //WOFF File //WOFFHeader File header with basic font type and version, along with offsets to metadata and private data blocks. @@ -152,8 +160,8 @@ internal Typeface Read(BinaryReader reader) //FontTables The font data tables from the input sfnt font, compressed to reduce bandwidth requirements. //ExtendedMetadata An optional block of extended metadata, represented in XML format and compressed for storage in the WOFF file. //PrivateData An optional block of private data for the font designer, foundry, or vendor to use. - _header = ReadWOFFHeader(reader); - if (_header == null) + var header = ReadWOFFHeader(reader); + if (header == null) { #if DEBUG System.Diagnostics.Debug.WriteLine("can't read "); @@ -162,7 +170,7 @@ internal Typeface Read(BinaryReader reader) } // - WoffTableDirectory[] woffTableDirs = ReadTableDirectories(reader); + WoffTableDirectory[] woffTableDirs = ReadTableDirectories(header, reader); if (woffTableDirs == null) { return null; @@ -188,7 +196,7 @@ internal Typeface Read(BinaryReader reader) using (MemoryStream decompressStream = new MemoryStream()) { - if (Extract(reader, woffTableDirs, decompressStream)) + if (Extract(DecompressHandler, reader, woffTableDirs, decompressStream)) { using (ByteOrderSwappingBinaryReader reader2 = new ByteOrderSwappingBinaryReader(decompressStream)) { @@ -200,7 +208,7 @@ internal Typeface Read(BinaryReader reader) } return null; } - public Typeface Read(Stream inputStream) + public Typeface? Read(Stream inputStream) { using (ByteOrderSwappingBinaryReader reader = new ByteOrderSwappingBinaryReader(inputStream)) { @@ -214,17 +222,18 @@ static TableEntryCollection CreateTableEntryCollection(WoffTableDirectory[] woff for (int i = 0; i < woffTableDirs.Length; ++i) { WoffTableDirectory woffTableDir = woffTableDirs[i]; - tableEntryCollection.AddEntry( + var unreadTableEntry = new UnreadTableEntry( new TableHeader(woffTableDir.tag, woffTableDir.origChecksum, (uint)woffTableDir.ExpectedStartAt, - woffTableDir.origLength))); + woffTableDir.origLength)); + tableEntryCollection.AddEntry(unreadTableEntry.Name, unreadTableEntry); } return tableEntryCollection; } - static WoffHeader ReadWOFFHeader(BinaryReader reader) + static WoffHeader? ReadWOFFHeader(BinaryReader reader) { //WOFFHeader //UInt32 signature 0x774F4646 'wOFF' @@ -271,7 +280,7 @@ static WoffHeader ReadWOFFHeader(BinaryReader reader) return header; } - WoffTableDirectory[] ReadTableDirectories(BinaryReader reader) + WoffTableDirectory[] ReadTableDirectories(WoffHeader header, BinaryReader reader) { //The table directory is an array of WOFF table directory entries, as defined below. @@ -280,7 +289,7 @@ WoffTableDirectory[] ReadTableDirectories(BinaryReader reader) //Its size is calculated by multiplying the numTables value in the WOFF header times the size of a single WOFF table directory. //Each table directory entry specifies the size and location of a single font data table. - uint tableCount = (uint)_header.numTables; //? + uint tableCount = (uint)header.numTables; //? //tableDirs = new WoffTableDirectory[tableCount]; long expectedStartAt = 0; @@ -296,19 +305,18 @@ WoffTableDirectory[] ReadTableDirectories(BinaryReader reader) //UInt32 origLength Length of the uncompressed table, excluding padding. //UInt32 origChecksum Checksum of the uncompressed table. - WoffTableDirectory table = new WoffTableDirectory(); - table.tag = reader.ReadUInt32(); - table.offset = reader.ReadUInt32(); - table.compLength = reader.ReadUInt32(); - table.origLength = reader.ReadUInt32(); - table.origChecksum = reader.ReadUInt32(); + var tag = reader.ReadUInt32(); + var offset = reader.ReadUInt32(); + var compLength = reader.ReadUInt32(); + var origLength = reader.ReadUInt32(); + var origChecksum = reader.ReadUInt32(); - table.ExpectedStartAt = expectedStartAt; - table.Name = Utils.TagToString(table.tag); + var name = Utils.TagToString(tag); //var tableHeader = new TableHeader(tag, origChecksum, (uint)expectedStartAt, origLength); //var unreadTable = new UnreadTableEntry(tableHeader); //tableEntryCollection.AddEntry(unreadTable); //table.unreadTableEntry = unreadTable; + WoffTableDirectory table = new WoffTableDirectory(tag, offset, compLength, origLength, origChecksum, expectedStartAt, name); tableDirs[i] = table; expectedStartAt += table.origLength; @@ -317,7 +325,7 @@ WoffTableDirectory[] ReadTableDirectories(BinaryReader reader) return tableDirs; } - bool Extract(BinaryReader reader, WoffTableDirectory[] tables, Stream newDecompressedStream) + bool Extract(ZlibDecompressStreamFunc decompressHandler, BinaryReader reader, WoffTableDirectory[] tables, Stream newDecompressedStream) { for (int i = 0; i < tables.Length; ++i) { @@ -340,8 +348,8 @@ bool Extract(BinaryReader reader, WoffTableDirectory[] tables, Stream newDecompr } else { - var decompressedBuffer = new byte[table.origLength]; - if (!DecompressHandler(compressedBuffer, decompressedBuffer)) + byte[]? decompressedBuffer = new byte[table.origLength]; + if (!decompressHandler(compressedBuffer, decompressedBuffer)) { //if not pass set to null decompressedBuffer = null; diff --git a/Typography.TextBreak/Reference_TextBreak.Icu/Reference_TextBreak.Icu.csproj b/Typography.TextBreak/Reference_TextBreak.Icu/Reference_TextBreak.Icu.csproj index 17fd606b..58bcfe78 100644 --- a/Typography.TextBreak/Reference_TextBreak.Icu/Reference_TextBreak.Icu.csproj +++ b/Typography.TextBreak/Reference_TextBreak.Icu/Reference_TextBreak.Icu.csproj @@ -12,6 +12,8 @@ Reference_TextBreak.Icu v2.0 512 + 8.0 + CS8632 true diff --git a/Typography.TextBreak/TextBreakerTest/Form1.cs b/Typography.TextBreak/TextBreakerTest/Form1.cs index 243380c9..eb2592a5 100644 --- a/Typography.TextBreak/TextBreakerTest/Form1.cs +++ b/Typography.TextBreak/TextBreakerTest/Form1.cs @@ -89,18 +89,18 @@ private void cmdManaged_Click(object sender, EventArgs e) //TODO: dic should be read once var dicProvider = new IcuSimpleTextFileDictionaryProvider() { DataDir = "../../../icu62/brkitr" }; CustomBreakerBuilder.Setup(dicProvider); - CustomBreaker breaker1 = CustomBreakerBuilder.NewCustomBreaker(); - breaker1.BreakNumberAfterText = true; char[] test = this.textBox1.Text.ToCharArray(); this.listBox1.Items.Clear(); - - breaker1.SetNewBreakHandler(vis => + var breaker1 = CustomBreakerBuilder.NewCustomBreaker(vis => { BreakSpan span = vis.GetBreakSpan(); string s = new string(test, span.startAt, span.len); this.listBox1.Items.Add(span.startAt + " " + s); }); + if (breaker1 == null) throw new InvalidOperationException("Invalid dicProvider"); + breaker1.BreakNumberAfterText = true; + breaker1.BreakWords(test, 0, test.Length); //foreach (BreakSpan span in breaker1.GetBreakSpanIter()) @@ -169,8 +169,9 @@ void ParseWithManaged(int ntimes) //------------------- var dicProvider = new IcuSimpleTextFileDictionaryProvider() { DataDir = "../../../icu58/brkitr_src" }; CustomBreakerBuilder.Setup(dicProvider); - CustomBreaker breaker1 = CustomBreakerBuilder.NewCustomBreaker(); - breaker1.SetNewBreakHandler(vis => { }); //just break, do nothing about result + var breaker1 = CustomBreakerBuilder.NewCustomBreaker(vis => { }); //just break, do nothing about result + + if (breaker1 == null) throw new InvalidOperationException("Invalid dicProvider"); char[] test = this.textBox1.Text.ToCharArray(); //------------- for (int i = ntimes - 1; i >= 0; --i) diff --git a/Typography.TextBreak/TextBreakerTest/Tests.csproj b/Typography.TextBreak/TextBreakerTest/Tests.csproj index e7edc314..58ca988d 100644 --- a/Typography.TextBreak/TextBreakerTest/Tests.csproj +++ b/Typography.TextBreak/TextBreakerTest/Tests.csproj @@ -73,8 +73,8 @@ - - {bc10cc51-a795-40d0-96f0-f87585d59d02} + + {dc8ee8cc-8882-4de5-8405-b7452f83b30a} Typography.TextBreak diff --git a/Typography.TextBreak/Typography.TextBreak.UnitTests/BasicTests.cs b/Typography.TextBreak/Typography.TextBreak.UnitTests/BasicTests.cs index fc92e549..f3663c28 100644 --- a/Typography.TextBreak/Typography.TextBreak.UnitTests/BasicTests.cs +++ b/Typography.TextBreak/Typography.TextBreak.UnitTests/BasicTests.cs @@ -1,16 +1,14 @@ -using System.Collections.Generic; -using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Collections.Generic; +using Xunit; using Typography.TextBreak; -[TestClass] public class BasicTests { - public void BasicTest(string input, string[] output, bool breakNumberAfterText = false) + void BasicTest(string input, string[] output, bool breakNumberAfterText = false) { var outputList = new List { 0 }; - var customBreaker = new CustomBreaker(); - customBreaker.SetNewBreakHandler(vis => outputList.Add(vis.LatestBreakAt)); + var customBreaker = new CustomBreaker(vis => outputList.Add(vis.LatestBreakAt)); customBreaker.BreakNumberAfterText = breakNumberAfterText; // @@ -20,7 +18,7 @@ public void BasicTest(string input, string[] output, bool breakNumberAfterText = //customBreaker.CopyBreakResults(outputList); for (int i = 0; i < outputList.Count - 1; i++) { - Assert.AreEqual + Assert.Equal ( output[i], input.Substring(outputList[i], outputList[i + 1] - outputList[i]) @@ -28,57 +26,58 @@ public void BasicTest(string input, string[] output, bool breakNumberAfterText = } } - [DataTestMethod] - [DataRow("Hi!", 0, new[] { "Hi", "!" })] - [DataRow("We are #1", 0, new[] { "We", " ", "are", " ", "#", "1" })] - [DataRow("1337 5P34K", 0, new[] { "1337", " ", "5", "P34K" })] - [DataRow("!@#$%^&*()", 0, new[] { "!", "@", "#", "$", "%", "^", "&", "*", "(", ")" })] - [DataRow("1st line\r2nd line\n3rd line\r\n4th line\u00855th line", 0, + [Theory] + [InlineData("Hi!", new[] { "Hi", "!" })] + [InlineData("We are #1", new[] { "We", " ", "are", " ", "#", "1" })] + [InlineData("1337 5P34K", new[] { "1337", " ", "5", "P34K" })] + [InlineData("!@#$%^&*()", new[] { "!", "@", "#", "$", "%", "^", "&", "*", "(", ")" })] + [InlineData("1st line\r2nd line\n3rd line\r\n4th line\u00855th line", new[] { "1", "st", " ", "line", "\r", "2", "nd", " ", "line", "\n", "3", "rd", " ", "line", "\r\n", "4", "th", " ", "line", "\u0085", "5", "th", " ", "line" })] - [DataRow("6+23-456*78/9", 0, new[] { "6", "+", "23", "-456", "*", "78", "/", "9" })] - [DataRow("<>_____DisplayClass", 0, new[] { "<", ">", "_", "_", "_", "_", "_", "DisplayClass" })] - [DataRow("In\u000Bbetween\u000Care\u0020spaces", 0, + [InlineData("6+23-456*78/9", new[] { "6", "+", "23", "-456", "*", "78", "/", "9" })] + [InlineData("<>_____DisplayClass", new[] { "<", ">", "_", "_", "_", "_", "_", "DisplayClass" })] + [InlineData("In\u000Bbetween\u000Care\u0020spaces", new[] { "In", "\u000B", "between", "\u000C", "are", "\u0020", "spaces" })] - public void Basic(string input, int _, string[] output) => BasicTest(input, output); + public void Basic(string input, string[] output) => BasicTest(input, output); - [DataTestMethod] - [DataRow("\0\x1\x2\x3\x4\x5\x6\x7\x8\x9", 0, + [Theory] + [InlineData("\0\x1\x2\x3\x4\x5\x6\x7\x8\x9", new[] { "\0", "\x1", "\x2", "\x3", "\x4", "\x5", "\x6", "\x7", "\x8", "\x9" })] - public void Control(string input, int _, string[] output) => BasicTest(input, output); + public void Control(string input, string[] output) => BasicTest(input, output); - [DataTestMethod] - [DataRow("\u0100", 0, new[] { "\u0100" })] - [DataRow("\u3DB4", 0, new[] { "\u3DB4" })] - [DataRow("\uFFFF", 0, new[] { "\uFFFF" })] - [DataRow("\r\n‸", 0, new[] { "\r\n", "‸" })] - [DataRow("\r\n‸\r\n", 0, new[] { "\r\n", "‸", "\r\n" })] - [DataRow("\r\n‸12a\r\n", 0, new[] { "\r\n", "‸", "12", "a", "\r\n" })] - public void OutOfRange(string input, int _, string[] output) => BasicTest(input, output); + [Theory] + [InlineData("\u0100", new[] { "\u0100" })] + [InlineData("\u3DB4", new[] { "\u3DB4" })] + [InlineData("\uFFFF", new[] { "\uFFFF" })] + [InlineData("\r\n‸", new[] { "\r\n", "‸" })] + [InlineData("\r\n‸\r\n", new[] { "\r\n", "‸", "\r\n" })] + [InlineData("\r\n‸12a\r\n", new[] { "\r\n", "‸", "12", "a", "\r\n" })] + public void OutOfRange(string input, string[] output) => BasicTest(input, output); - [DataTestMethod] - [DataRow("😀", 0, new[] { "😀" })] - [DataRow("😂", 0, new[] { "😂" })] - [DataRow("😂😂", 0, new[] { "😂", "😂" })] - [DataRow("😂A😂", 0, new[] { "😂", "A", "😂" })] - [DataRow("😂A123😂", 0, new[] { "😂", "A123", "😂" })] - public void Surrogates(string input, int _, string[] output) => BasicTest(input, output); + [Theory] + [InlineData("😀", new[] { "😀" })] + [InlineData("😂", new[] { "😂" })] + [InlineData("😂😂", new[] { "😂", "😂" })] + [InlineData("😂A😂", new[] { "😂", "A", "😂" })] + [InlineData("😂A123😂", new[] { "😂", "A123", "😂" })] + public void Surrogates(string input, string[] output) => BasicTest(input, output); - [DataTestMethod] - [DataRow("A123", 0, new[] { "A", "123" })] - public void BreakNumAfterText(string input, int _, string[] output) + [Theory] + [InlineData("A123", new[] { "A", "123" })] + public void BreakNumAfterText(string input, string[] output) { BasicTest(input, output, true); } - [DataTestMethod] - [DataRow("a.m", 0, new[] { "a.m" })] - [DataRow("a.m.", 0, new[] { "a.m." })] - [DataRow("a.m", 0, new[] { "a.m" })] - [DataRow("9 a.m.", 0, new[] { "9", " ", "a.m." })] - public void DontBreakPerioidInTextSpan(string input, int _, string[] output) + [Theory] + [InlineData("a.m", new[] { "a.m" })] + [InlineData("a.m.", new[] { "a.m." })] + [InlineData(".a.m", new[] { ".", "a.m" })] + [InlineData(".a.m.", new[] { ".", "a.m." })] + [InlineData("9 a.m.", new[] { "9", " ", "a.m." })] + public void DontBreakPerioidInTextSpan(string input, string[] output) { BasicTest(input, output, true); } diff --git a/Typography.TextBreak/Typography.TextBreak.UnitTests/FrenchTests.cs b/Typography.TextBreak/Typography.TextBreak.UnitTests/FrenchTests.cs index 07d80a82..fd89a8ea 100644 --- a/Typography.TextBreak/Typography.TextBreak.UnitTests/FrenchTests.cs +++ b/Typography.TextBreak/Typography.TextBreak.UnitTests/FrenchTests.cs @@ -1,4 +1,4 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Xunit; using System; using System.Collections.Generic; using System.Linq; @@ -6,10 +6,9 @@ using System.Threading.Tasks; using Typography.TextBreak; -[TestClass] public class FrenchTests { - [TestMethod] + [Fact] public void EngEngine() { //Text source: https://en.wikibooks.org/wiki/French/Texts/Simple/Le_Corbeau_et_le_Renard @@ -53,9 +52,8 @@ Apprenez que tout flatteur |Jura|,| |mais| |un| |peu| |tard|,| |qu|’|on| |ne| |l|’|y| |prendrait| |plus.|"; string BreakText(string text, string seperator = "|") { - var breaker = new CustomBreaker { ThrowIfCharOutOfRange = true }; var breakList = new List(); - breaker.SetNewBreakHandler(vis => breakList.Add(new BreakAtInfo(vis.LatestBreakAt, vis.LatestWordKind))); + var breaker = new CustomBreaker(vis => breakList.Add(new BreakAtInfo(vis.LatestBreakAt, vis.LatestWordKind))) { ThrowIfCharOutOfRange = true }; #warning Use `breaker.BreakWords(text, breakList);` once #156 is merged @@ -71,33 +69,32 @@ string BreakText(string text, string seperator = "|") return sb.ToString(); } var brokenString = BreakText(Le_Corbeau_et_le_Renard); - Assert.AreEqual(Le_Corbeau_et_le_Renard__Broken, brokenString); + Assert.Equal(Le_Corbeau_et_le_Renard__Broken, brokenString); } - [TestMethod] + [Fact] public void WordKindTest() { - var breaker = new CustomBreaker { ThrowIfCharOutOfRange = true }; var breakList = new List(); + var breaker = new CustomBreaker(vis => breakList.Add(vis.GetBreakSpan())) { ThrowIfCharOutOfRange = true }; char[] test = "«Maître leçon»".ToCharArray(); - breaker.SetNewBreakHandler(vis => breakList.Add(vis.GetBreakSpan())); - #warning Use `breaker.BreakWords("«Maître leçon»", breakList);` once #156 is merged breaker.BreakWords(test, 0, test.Length); - Assert.AreEqual(breakList.Count, 5); - void BreakSpanEqual(BreakSpan actual, BreakSpan expected) + Action BreakSpanEqual(BreakSpan expected) => actual => { - Assert.AreEqual(expected.startAt, actual.startAt); - Assert.AreEqual(expected.len, actual.len); - Assert.AreEqual(expected.wordKind, actual.wordKind); - } - BreakSpanEqual(breakList[0], new BreakSpan { startAt = 0, len = 1, wordKind = WordKind.Punc }); - BreakSpanEqual(breakList[1], new BreakSpan { startAt = 1, len = 6, wordKind = WordKind.Text }); - BreakSpanEqual(breakList[2], new BreakSpan { startAt = 7, len = 1, wordKind = WordKind.Whitespace }); - BreakSpanEqual(breakList[3], new BreakSpan { startAt = 8, len = 5, wordKind = WordKind.Text }); - BreakSpanEqual(breakList[4], new BreakSpan { startAt = 13, len = 1, wordKind = WordKind.Punc }); + Assert.Equal(expected.startAt, actual.startAt); + Assert.Equal(expected.len, actual.len); + Assert.Equal(expected.wordKind, actual.wordKind); + }; + Assert.Collection(breakList, + BreakSpanEqual(new BreakSpan { startAt = 0, len = 1, wordKind = WordKind.Punc }), + BreakSpanEqual(new BreakSpan { startAt = 1, len = 6, wordKind = WordKind.Text }), + BreakSpanEqual(new BreakSpan { startAt = 7, len = 1, wordKind = WordKind.Whitespace }), + BreakSpanEqual(new BreakSpan { startAt = 8, len = 5, wordKind = WordKind.Text }), + BreakSpanEqual(new BreakSpan { startAt = 13, len = 1, wordKind = WordKind.Punc }) + ); } } \ No newline at end of file diff --git a/Typography.TextBreak/Typography.TextBreak.UnitTests/Properties/AssemblyInfo.cs b/Typography.TextBreak/Typography.TextBreak.UnitTests/Properties/AssemblyInfo.cs deleted file mode 100644 index 7e6ba283..00000000 --- a/Typography.TextBreak/Typography.TextBreak.UnitTests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -[assembly: AssemblyTitle("Typography.TextBreak.UnitTests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Typography.TextBreak.UnitTests")] -[assembly: AssemblyCopyright("Copyright © 2018")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -[assembly: ComVisible(false)] - -[assembly: Guid("2e593fca-b809-4270-9eb2-93f380af2d6c")] - -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Typography.TextBreak/Typography.TextBreak.UnitTests/TextBreakTests.csproj b/Typography.TextBreak/Typography.TextBreak.UnitTests/TextBreakTests.csproj index 0b1619a3..6fc1a1ca 100644 --- a/Typography.TextBreak/Typography.TextBreak.UnitTests/TextBreakTests.csproj +++ b/Typography.TextBreak/Typography.TextBreak.UnitTests/TextBreakTests.csproj @@ -1,75 +1,14 @@  - + - Debug - AnyCPU - {2E593FCA-B809-4270-9EB2-93F380AF2D6C} - Library - Properties - Typography.TextBreak.UnitTests - Typography.TextBreak.UnitTests - v4.5 - 512 - {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 15.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - ../.. - $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages - False - UnitTest - - + netcoreapp3.1 + 8.0 + enable + nullable - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - $(SolutionDir)\packages\MSTest.TestFramework.1.3.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll - - - $(SolutionDir)\packages\MSTest.TestFramework.1.3.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll - - - - - $(SolutionDir)\packages\System.ValueTuple.4.5.0\lib\netstandard1.0\System.ValueTuple.dll - - - - - - - - - + + - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - \ No newline at end of file diff --git a/Typography.TextBreak/Typography.TextBreak.UnitTests/WordKindTests.cs b/Typography.TextBreak/Typography.TextBreak.UnitTests/WordKindTests.cs index c1e72314..4a19d92c 100644 --- a/Typography.TextBreak/Typography.TextBreak.UnitTests/WordKindTests.cs +++ b/Typography.TextBreak/Typography.TextBreak.UnitTests/WordKindTests.cs @@ -1,60 +1,57 @@ using System.Collections.Generic; -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Xunit; using Typography.TextBreak; using static Typography.TextBreak.WordKind; -using o = System.Object; -[TestClass] public class WordKindTests { + static object[] Row(string input, params (string section, WordKind wordKind)[] output) => + new object[] { input, output }; + public static IEnumerable WordKindData => + new[] { + Row("Hi!", ("Hi", Text), ("!", Punc)), + Row("We are #1", + ("We", Text), (" ", Whitespace), ("are", Text), (" ", Whitespace), ("#", Punc), ("1", Number) + ), + Row("1337 5P34K", + ("1337", Number), (" ", Whitespace), ("5", Number), ("P34K", Text) + ), + Row("In\u000Bbetween\u000Care\u0020spaces", + ("In", Text), ("\u000B", Whitespace), ("between", Text), + ("\u000C", Whitespace), ("are", Text), ("\u0020", Whitespace), ("spaces", Text) + ), + Row("!@#$%^&*()", + ("!", Punc), ("@", Punc), ("#", Punc), ("$", Punc), ("%", Punc), + ("^", Punc), ("&", Punc), ("*", Punc), ("(", Punc), (")", Punc) + ), + Row("1st line\r2nd line\n3rd line\r\n4th line\u00855th line", + ("1", Number), ("st", Text), (" ", Whitespace), ("line", Text), + ("\r", NewLine), ("2", Number), ("nd", Text), (" ", Whitespace), + ("line", Text), ("\n", NewLine), + ("3", Number), ("rd", Text), (" ", Whitespace), ("line", Text), + ("\r\n", NewLine), ("4", Number), ("th", Text), (" ", Whitespace), + ("line", Text), ("\u0085", NewLine), + ("5", Number), ("th", Text), (" ", Whitespace), ("line", Text) + ) + }; + [Theory] + [MemberData(nameof(WordKindData))] public void WordKindTest(string input, (string section, WordKind wordKind)[] output) { - var customBreaker = new CustomBreaker(); var outputList = new List { new BreakAtInfo(0, Unknown) }; - customBreaker.SetNewBreakHandler(vis => outputList.Add(new BreakAtInfo(vis.LatestBreakAt, vis.LatestWordKind))); + var customBreaker = new CustomBreaker(vis => outputList.Add(new BreakAtInfo(vis.LatestBreakAt, vis.LatestWordKind))); customBreaker.BreakWords(input); for (int i = 0; i < outputList.Count - 1; i++) { - Assert.AreEqual + Assert.Equal ( output[i].section, input.Substring(outputList[i].breakAt, outputList[i + 1].breakAt - outputList[i].breakAt) ); - Assert.AreEqual(output[i].wordKind, outputList[i + 1].wordKind); - } - } - - [TestMethod] - public void WordKind() - { - foreach (var testCase in new[] { - ("Hi!", new [] { ("Hi", Text), ("!", Punc) }), - ("We are #1", new[] { ("We", Text), (" ", Whitespace), - ("are", Text), (" ", Whitespace), ("#", Punc), - ("1", Number) }), - ("1337 5P34K", new[] { ("1337", Number), (" ", Whitespace), - ("5", Number), ("P34K", Text) }), - ("In\u000Bbetween\u000Care\u0020spaces", new[] { - ("In", Text), ("\u000B", Whitespace), ("between", Text), - ("\u000C", Whitespace), ("are", Text), ("\u0020", Whitespace), - ("spaces", Text) }), - ("!@#$%^&*()", new[] { ("!", Punc), ("@", Punc), ("#", Punc), - ("$", Punc), ("%", Punc), ("^", Punc), ("&", Punc), ("*", Punc), - ("(", Punc), (")", Punc) }), - ("1st line\r2nd line\n3rd line\r\n4th line\u00855th line", - new[] { ("1", Number), ("st", Text), (" ", Whitespace), ("line", Text), - ("\r", NewLine), ("2", Number), ("nd", Text), (" ", Whitespace), - ("line", Text), ("\n", NewLine), - ("3", Number), ("rd", Text), (" ", Whitespace), ("line", Text), - ("\r\n", NewLine), ("4", Number), ("th", Text), (" ", Whitespace), - ("line", Text), ("\u0085", NewLine), - ("5", Number), ("th", Text), (" ", Whitespace), ("line", Text) }) - }) - { - WordKindTest(testCase.Item1, testCase.Item2); + Assert.Equal(output[i].wordKind, outputList[i + 1].wordKind); } } } \ No newline at end of file diff --git a/Typography.TextBreak/Typography.TextBreak.UnitTests/packages.config b/Typography.TextBreak/Typography.TextBreak.UnitTests/packages.config deleted file mode 100644 index 67c9800c..00000000 --- a/Typography.TextBreak/Typography.TextBreak.UnitTests/packages.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Typography.TextBreak/Typography.TextBreak/BreakingEngine.cs b/Typography.TextBreak/Typography.TextBreak/BreakingEngine.cs index 61e0a3a5..47e4def1 100644 --- a/Typography.TextBreak/Typography.TextBreak/BreakingEngine.cs +++ b/Typography.TextBreak/Typography.TextBreak/BreakingEngine.cs @@ -24,7 +24,7 @@ public override bool CanHandle(char c) return c >= this.FirstUnicodeChar && c <= this.LastUnicodeChar; } protected abstract CustomDic CurrentCustomDic { get; } - protected abstract WordGroup GetWordGroupForFirstChar(char c); + protected abstract WordGroup? GetWordGroupForFirstChar(char c); public bool BreakPeroidInTextSpan { get; set; } @@ -78,7 +78,7 @@ internal override void BreakWord(WordVisitor visitor, char[] charBuff, int start } //---------------------- - WordGroup wordgroup = GetWordGroupForFirstChar(c); + WordGroup? wordgroup = GetWordGroupForFirstChar(c); if (wordgroup == null) { //continue next char @@ -118,7 +118,7 @@ internal override void BreakWord(WordVisitor visitor, char[] charBuff, int start //end *** visitor.State = VisitorState.End; //---------------------------------------- - WordGroup next1 = GetSubGroup(visitor, c_wordgroup); + WordGroup? next1 = GetSubGroup(visitor, c_wordgroup); bool latest_candidate_isNotWord = false; if (next1 != null) @@ -203,7 +203,7 @@ internal override void BreakWord(WordVisitor visitor, char[] charBuff, int start goto ENTER_LOOP; } //---------------------------------------- - WordGroup next = GetSubGroup(visitor, c_wordgroup); + WordGroup? next = GetSubGroup(visitor, c_wordgroup); //for debug //string prefix = (next == null) ? "" : next.GetPrefix(CurrentCustomDic.TextBuffer); if (next != null) @@ -457,7 +457,7 @@ internal override void BreakWord(WordVisitor visitor, char[] charBuff, int start } } } - internal WordGroup GetSubGroup(WordVisitor visitor, WordGroup wordGroup) + internal WordGroup? GetSubGroup(WordVisitor visitor, WordGroup wordGroup) { char c = visitor.Char; @@ -470,7 +470,7 @@ internal WordGroup GetSubGroup(WordVisitor visitor, WordGroup wordGroup) } //----------------- //can handle - WordGroup[] subGroups = wordGroup.GetSubGroups(); + WordGroup[]? subGroups = wordGroup.GetSubGroups(); if (subGroups != null) { return subGroups[c - this.FirstUnicodeChar]; @@ -480,7 +480,7 @@ internal WordGroup GetSubGroup(WordVisitor visitor, WordGroup wordGroup) int FindInWordSpans(WordVisitor visitor, WordGroup wordGroup) { - WordSpan[] wordSpans = wordGroup.GetWordSpans(); + WordSpan[]? wordSpans = wordGroup.GetWordSpans(); if (wordSpans == null) { throw new NotSupportedException(); diff --git a/Typography.TextBreak/Typography.TextBreak/CustomBreaker.cs b/Typography.TextBreak/Typography.TextBreak/CustomBreaker.cs index 8031898b..e7b382c7 100644 --- a/Typography.TextBreak/Typography.TextBreak/CustomBreaker.cs +++ b/Typography.TextBreak/Typography.TextBreak/CustomBreaker.cs @@ -21,10 +21,11 @@ public class CustomBreaker bool _breakNumberAfterText; - public CustomBreaker() + public CustomBreaker(NewWordBreakHandlerDelegate newWordBreakHandler) { ThrowIfCharOutOfRange = false; _breakingEngine = _engBreakingEngine; //default eng-breaking engine + _visitor = new WordVisitor(newWordBreakHandler); } public void SetNewBreakHandler(NewWordBreakHandlerDelegate newWordBreakHandler) { diff --git a/Typography.TextBreak/Typography.TextBreak/CustomBreakerBuilder.cs b/Typography.TextBreak/Typography.TextBreak/CustomBreakerBuilder.cs index 5bec1c3d..c5ccef47 100644 --- a/Typography.TextBreak/Typography.TextBreak/CustomBreakerBuilder.cs +++ b/Typography.TextBreak/Typography.TextBreak/CustomBreakerBuilder.cs @@ -17,21 +17,21 @@ public static class CustomBreakerBuilder //custom dic may be shared among breaking engine [System.ThreadStatic] - static CustomDic s_thaiDic; + static CustomDic? s_thaiDic; [System.ThreadStatic] - static CustomDic s_laoDic; + static CustomDic? s_laoDic; [System.ThreadStatic] - static CustomAbbrvDic s_enAbbrvDic; + static CustomAbbrvDic? s_enAbbrvDic; [System.ThreadStatic] - static DictionaryProvider s_dicProvider; + static DictionaryProvider? s_dicProvider; static void InitAllDics() { // - + if (s_dicProvider == null) return; if (s_thaiDic == null) { var customDic = new CustomDic(); @@ -67,7 +67,7 @@ public static void Setup(DictionaryProvider dicProvider) InitAllDics(); } - public static CustomBreaker NewCustomBreaker() + public static CustomBreaker? NewCustomBreaker(NewWordBreakHandlerDelegate newWordBreakHandler) { if (s_thaiDic == null) { @@ -78,19 +78,23 @@ public static CustomBreaker NewCustomBreaker() } InitAllDics(); } - var breaker = new CustomBreaker(); + var breaker = new CustomBreaker(newWordBreakHandler); breaker.EngBreakingEngine.EngCustomAbbrvDic = s_enAbbrvDic;//optional breaker.EngBreakingEngine.EnableCustomAbbrv = true;//optional // - var thBreaker = new ThaiDictionaryBreakingEngine(); - //thBreaker.DontMergeLastIncompleteWord = true; - thBreaker.SetDictionaryData(s_thaiDic); - breaker.AddBreakingEngine(thBreaker); + if (s_thaiDic != null) + { + var thBreaker = new ThaiDictionaryBreakingEngine(s_thaiDic); + //thBreaker.DontMergeLastIncompleteWord = true; + breaker.AddBreakingEngine(thBreaker); + } // - var laoBreak = new LaoDictionaryBreakingEngine(); - laoBreak.SetDictionaryData(s_laoDic); - breaker.AddBreakingEngine(laoBreak); + if (s_laoDic != null) + { + var laoBreak = new LaoDictionaryBreakingEngine(s_laoDic); + breaker.AddBreakingEngine(laoBreak); + } return breaker; } } diff --git a/Typography.TextBreak/Typography.TextBreak/CustomDict.cs b/Typography.TextBreak/Typography.TextBreak/CustomDict.cs index 00e651bf..45217171 100644 --- a/Typography.TextBreak/Typography.TextBreak/CustomDict.cs +++ b/Typography.TextBreak/Typography.TextBreak/CustomDict.cs @@ -14,8 +14,8 @@ namespace Typography.TextBreak /// public class CustomDic { - CustomDicTextBuffer _textBuffer; - WordGroup[] _wordGroups; + CustomDicTextBuffer? _textBuffer; + WordGroup[]? _wordGroups; char _firstChar, _lastChar; @@ -26,7 +26,8 @@ public void SetCharRange(char firstChar, char lastChar) } public char FirstChar => _firstChar; public char LastChar => _lastChar; - internal CustomDicTextBuffer TextBuffer => _textBuffer; + internal CustomDicTextBuffer TextBuffer => + _textBuffer ?? throw new InvalidOperationException(nameof(LoadSortedUniqueWordList) + " not called"); public void LoadSortedUniqueWordList(IEnumerable sortedWordList) @@ -64,7 +65,7 @@ public void LoadSortedUniqueWordList(IEnumerable sortedWordList) WordSpan wordspan = new WordSpan(startAt, (byte)lineLen); //each wordgroup contains text span - DevelopingWordGroup found; + DevelopingWordGroup? found; if (!wordGroups.TryGetValue(c0, out found)) { found = new DevelopingWordGroup(new WordSpan(startAt, 1)); @@ -89,6 +90,7 @@ public void LoadSortedUniqueWordList(IEnumerable sortedWordList) // void DoIndex(Dictionary wordGroups) { + if (_textBuffer == null) throw new InvalidOperationException(nameof(LoadSortedUniqueWordList) + " not called"); //1. expand word group WordGroup[] newWordGroups = new WordGroup[_lastChar - _firstChar + 1]; @@ -104,6 +106,8 @@ void DoIndex(Dictionary wordGroups) } public void GetWordList(char startWithChar, List output) { + if (_textBuffer == null) throw new InvalidOperationException(nameof(LoadSortedUniqueWordList) + " not called"); + if (_wordGroups == null) throw new InvalidOperationException(nameof(DoIndex) + " not called"); if (startWithChar >= _firstChar && startWithChar <= _lastChar) { //in range @@ -115,8 +119,10 @@ public void GetWordList(char startWithChar, List output) } } } - internal WordGroup GetWordGroupForFirstChar(char c) + internal WordGroup? GetWordGroupForFirstChar(char c) { + if (_wordGroups == null) throw new InvalidOperationException(nameof(DoIndex) + " not called"); + if (c >= _firstChar && c <= _lastChar) { //in range @@ -176,8 +182,8 @@ public struct BreakSpan class DevelopingWordGroup { - List _wordSpanList = new List(); - DevelopingWordGroup[] _subGroups; + List? _wordSpanList = new List(); + DevelopingWordGroup[]? _subGroups; WordSpan _prefixSpan; internal DevelopingWordGroup(WordSpan prefixSpan) { @@ -237,7 +243,7 @@ internal void CollectAllWords(CustomDicTextBuffer textBuffer, List outpu // internal void AddWordSpan(WordSpan span) { - _wordSpanList.Add(span); + _wordSpanList?.Add(span); #if DEBUG dbugDataState = debugDataState.UnIndex; #endif @@ -250,9 +256,10 @@ public int WordSpanListCount return _wordSpanList.Count; } } - WordGroup _resultWordGroup;//after call DoIndex() + WordGroup? _resultWordGroup;//after call DoIndex() internal void DoIndex(CustomDicTextBuffer textBuffer, CustomDic owner) { + if (_wordSpanList == null) throw new InvalidOperationException(nameof(DoIndex) + " already called"); //recursive if (this.PrefixLen > 7) @@ -351,7 +358,7 @@ internal void DoIndex(CustomDicTextBuffer textBuffer, CustomDic owner) } //-------------------------------- - WordGroup[] newsubGroups = null; + WordGroup[]? newsubGroups = null; if (_subGroups != null) { newsubGroups = new WordGroup[_subGroups.Length]; @@ -373,11 +380,11 @@ internal void DoIndex(CustomDicTextBuffer textBuffer, CustomDic owner) } // - public WordGroup ResultWordGroup => _resultWordGroup; + public WordGroup ResultWordGroup => _resultWordGroup ?? throw new InvalidOperationException(nameof(DoIndex) + " not called"); // void DoIndexOfSmallAmount(CustomDicTextBuffer textBuffer) { - + if (_wordSpanList == null) throw new InvalidOperationException(nameof(DoIndex) + " already called"); //convention... //data must me sorted (ascending) before use with the wordSpanList @@ -424,15 +431,16 @@ public override string ToString() class CustomDicTextBuffer { - List _tmpCharList; + List? _tmpCharList; int _position; - char[] _charBuffer; + char[]? _charBuffer; public CustomDicTextBuffer(int initCapacity) { _tmpCharList = new List(initCapacity); } public void AddWord(char[] wordBuffer) { + if (_tmpCharList == null) return; _tmpCharList.AddRange(wordBuffer); //append with ' ' _tmpCharList.Add(' '); @@ -440,7 +448,7 @@ public void AddWord(char[] wordBuffer) } public void Freeze() { - _charBuffer = _tmpCharList.ToArray(); + _charBuffer ??= _tmpCharList?.ToArray(); _tmpCharList = null; } // @@ -450,22 +458,23 @@ public char GetChar(int index) { //refactor note: //remain in this style -> easy to debug - + if (_charBuffer == null) throw new InvalidOperationException("Buffer not frozen yet"); return _charBuffer[index]; } public string GetString(int index, int len) { + if (_charBuffer == null) throw new InvalidOperationException("Buffer not frozen yet"); return new string(_charBuffer, index, len); } } public class WordGroup { - readonly WordGroup[] _subGroups; - readonly WordSpan[] _wordSpans; + readonly WordGroup[]? _subGroups; + readonly WordSpan[]? _wordSpans; readonly WordSpan _prefixSpan; readonly bool _prefixIsWord; - internal WordGroup(WordSpan prefixSpan, WordGroup[] subGroups, WordSpan[] wordSpanList, bool isPrefixIsWord) + internal WordGroup(WordSpan prefixSpan, WordGroup[]? subGroups, WordSpan[]? wordSpanList, bool isPrefixIsWord) { _prefixSpan = prefixSpan; _subGroups = subGroups; @@ -514,8 +523,8 @@ public int WordSpanListCount return _wordSpans.Length; } } - internal WordSpan[] GetWordSpans() => _wordSpans; - internal WordGroup[] GetSubGroups() => _subGroups; + internal WordSpan[]? GetWordSpans() => _wordSpans; + internal WordGroup[]? GetSubGroups() => _subGroups; #if DEBUG public override string ToString() diff --git a/Typography.TextBreak/Typography.TextBreak/DictionaryBasedBreakingEngine/LaoDictionaryBreakingEngine.cs b/Typography.TextBreak/Typography.TextBreak/DictionaryBasedBreakingEngine/LaoDictionaryBreakingEngine.cs index bb08d740..8da48216 100644 --- a/Typography.TextBreak/Typography.TextBreak/DictionaryBasedBreakingEngine/LaoDictionaryBreakingEngine.cs +++ b/Typography.TextBreak/Typography.TextBreak/DictionaryBasedBreakingEngine/LaoDictionaryBreakingEngine.cs @@ -11,7 +11,7 @@ namespace Typography.TextBreak public class LaoDictionaryBreakingEngine : DictionaryBreakingEngine { CustomDic _customDic; - public void SetDictionaryData(CustomDic customDic) + public LaoDictionaryBreakingEngine(CustomDic customDic) { _customDic = customDic; } @@ -22,7 +22,7 @@ public override bool CanBeStartChar(char c) { return s_canbeStartChars[c - _customDic.FirstChar]; } - protected override WordGroup GetWordGroupForFirstChar(char c) + protected override WordGroup? GetWordGroupForFirstChar(char c) { return _customDic.GetWordGroupForFirstChar(c); } diff --git a/Typography.TextBreak/Typography.TextBreak/DictionaryBasedBreakingEngine/ThaiDictionaryBreakingEngine.cs b/Typography.TextBreak/Typography.TextBreak/DictionaryBasedBreakingEngine/ThaiDictionaryBreakingEngine.cs index 21999537..0d2455e5 100644 --- a/Typography.TextBreak/Typography.TextBreak/DictionaryBasedBreakingEngine/ThaiDictionaryBreakingEngine.cs +++ b/Typography.TextBreak/Typography.TextBreak/DictionaryBasedBreakingEngine/ThaiDictionaryBreakingEngine.cs @@ -12,7 +12,7 @@ namespace Typography.TextBreak public class ThaiDictionaryBreakingEngine : DictionaryBreakingEngine { CustomDic _customDic; - public void SetDictionaryData(CustomDic customDic) + public ThaiDictionaryBreakingEngine(CustomDic customDic) { _customDic = customDic; @@ -25,7 +25,7 @@ public override bool CanBeStartChar(char c) //refactor note, ease of debug return s_canbeStartChars[c - this.FirstUnicodeChar]; } - protected override WordGroup GetWordGroupForFirstChar(char c) + protected override WordGroup? GetWordGroupForFirstChar(char c) { return _customDic.GetWordGroupForFirstChar(c); } diff --git a/Typography.TextBreak/Typography.TextBreak/EngBreakingEngine.cs b/Typography.TextBreak/Typography.TextBreak/EngBreakingEngine.cs index 18e390c6..2638efb3 100644 --- a/Typography.TextBreak/Typography.TextBreak/EngBreakingEngine.cs +++ b/Typography.TextBreak/Typography.TextBreak/EngBreakingEngine.cs @@ -21,7 +21,7 @@ enum LexState public bool BreakPeroidInTextSpan { get; set; } public bool EnableCustomAbbrv { get; set; } - public CustomAbbrvDic EngCustomAbbrvDic { get; set; } + public CustomAbbrvDic? EngCustomAbbrvDic { get; set; } BreakBounds _breakBounds = new BreakBounds(); diff --git a/Typography.TextBreak/Typography.TextBreak/WordVisitor.cs b/Typography.TextBreak/Typography.TextBreak/WordVisitor.cs index 7815a44c..6bfc6bbc 100644 --- a/Typography.TextBreak/Typography.TextBreak/WordVisitor.cs +++ b/Typography.TextBreak/Typography.TextBreak/WordVisitor.cs @@ -26,7 +26,7 @@ public class WordVisitor #if DEBUG List dbugBreakAtList = new List(); #endif - char[] _buffer; + char[]? _buffer; int _startIndex; int _endIndex; @@ -82,6 +82,7 @@ internal void LoadText(char[] buffer, int index, int len) public string CopyCurrentSpanString() { + if (_buffer == null) throw new InvalidOperationException(nameof(LoadText) + " not called"); return new string(_buffer, LatestSpanStartAt, LatestSpanLen); } @@ -127,6 +128,7 @@ internal void AddWordBreakAtCurrentIndex(WordKind wordKind = WordKind.Text) // internal void SetCurrentIndex(int index) { + if (_buffer == null) throw new InvalidOperationException(nameof(LoadText) + " not called"); _currentIndex = index; if (index < _endIndex) { diff --git a/Typography.TextFlow/Dom/EditableTextBlockLayoutEngine.cs b/Typography.TextFlow/Dom/EditableTextBlockLayoutEngine.cs index 2b74de26..4ec69a06 100644 --- a/Typography.TextFlow/Dom/EditableTextBlockLayoutEngine.cs +++ b/Typography.TextFlow/Dom/EditableTextBlockLayoutEngine.cs @@ -19,11 +19,12 @@ public class EditableTextBlockLayoutEngine GlyphLayout _glyphLayout; UnscaledGlyphPlanList _outputGlyphPlan = new UnscaledGlyphPlanList(); - public EditableTextBlockLayoutEngine() + public EditableTextBlockLayoutEngine(Typeface defaultTypeface, float fontSizeInPts = 10) { _textBlockLexer = new TextBlockLexer(); - _glyphLayout = new GlyphLayout(); - FontSizeInPts = 10; + _glyphLayout = new GlyphLayout(defaultTypeface); + FontSizeInPts = fontSizeInPts; + DefaultTypeface = defaultTypeface; } public Typeface DefaultTypeface { get; set; } /// @@ -46,9 +47,7 @@ public void LoadText(string text) //TODO: extend with custom lexer*** //test only ... - TextRunFontStyle fontStyle = new TextRunFontStyle(); - fontStyle.Name = "tahoma"; - fontStyle.SizeInPoints = FontSizeInPts;//10 pts; + TextRunFontStyle fontStyle = new TextRunFontStyle("tahoma", FontSizeInPts);//10 pts; TextBuffer buffer = new TextBuffer(text.ToCharArray()); _textBlockLexer.Lex(buffer); @@ -75,9 +74,7 @@ public void LoadText(string text) else { //create a 'Run' for this span - TextRun textRun = new TextRun(buffer, sp.start, sp.len, sp.kind); - //add property font style to text run - textRun.FontStyle = fontStyle; + TextRun textRun = new TextRun(buffer, sp.start, sp.len, sp.kind, fontStyle); line.AppendLast(textRun); } } @@ -125,7 +122,7 @@ public void DoLayout() for (int r = 0; r < runCount; ++r) { - TextRun tt = runList[r] as TextRun; + var tt = runList[r] as TextRun; if (tt == null) continue; //this is text run if (tt.IsMeasured) continue; diff --git a/Typography.TextFlow/Dom/TextBuffer.cs b/Typography.TextFlow/Dom/TextBuffer.cs index 34d3c2a1..b2bdae68 100644 --- a/Typography.TextFlow/Dom/TextBuffer.cs +++ b/Typography.TextFlow/Dom/TextBuffer.cs @@ -19,18 +19,14 @@ public string CopyString(int start, int len) return new string(_buffer, start, len); } //-------- - internal char[] UnsafeGetInternalBuffer() => _buffer; - internal TextBuffer() - { - - } + public char[] UnsafeGetInternalBuffer() => _buffer; } public class ReusableTextBuffer : TextBuffer { - public ReusableTextBuffer() + public ReusableTextBuffer(char[] buffer) : base(buffer) { - //for reusable textbuffer + _buffer = buffer; } public void SetRawCharBuffer(char[] buffer) { diff --git a/Typography.TextFlow/Dom/TextRun.cs b/Typography.TextFlow/Dom/TextRun.cs index d1870ff8..06cb363d 100644 --- a/Typography.TextFlow/Dom/TextRun.cs +++ b/Typography.TextFlow/Dom/TextRun.cs @@ -6,6 +6,12 @@ namespace Typography.TextLayout public class TextRunFontStyle { + public TextRunFontStyle(string name, float sizeInPoints) + { + Name = name; + SizeInPoints = sizeInPoints; + } + //font spec //resolve later public string Name { get; set; } @@ -31,12 +37,13 @@ public class TextRun : IRun GlyphPlanSequence _glyphPlanSeq; //1 text run 1 glyph plan sequence float _runWidth; - public TextRun(TextBuffer srcTextBuffer, int startAt, int len, WordSpanKind kind) + public TextRun(TextBuffer srcTextBuffer, int startAt, int len, WordSpanKind kind, TextRunFontStyle fontStyle) { _srcText = srcTextBuffer; _startAt = startAt; _len = len; _kind = kind; + FontStyle = fontStyle; } internal void SetGlyphPlanSeq(GlyphPlanSequence seq) diff --git a/Typography.TextFlow/Simple/SmallLine.cs b/Typography.TextFlow/Simple/SmallLine.cs index 4d9fbab2..50fb82f3 100644 --- a/Typography.TextFlow/Simple/SmallLine.cs +++ b/Typography.TextFlow/Simple/SmallLine.cs @@ -1,4 +1,5 @@ //MIT, 2014-present, WinterDev +using System; using System.Collections.Generic; namespace Typography.TextLayout @@ -10,7 +11,7 @@ public class SmallLine int _caretCharIndex = 0;//default //TODO: temp public, review accessibility here again public List _charBuffer = new List(); - public PxScaledGlyphPlan[] _glyphPlans; + public PxScaledGlyphPlan[] _glyphPlans = new PxScaledGlyphPlan[100]; // no writes to this just yet public List _userCodePointToGlyphIndexMap = new List(); bool _contentChanged = true; diff --git a/Typography.TextServices/FontStoreAndManagment/FontManagement.cs b/Typography.TextServices/FontStoreAndManagment/FontManagement.cs index 762582ba..bdc7515c 100644 --- a/Typography.TextServices/FontStoreAndManagment/FontManagement.cs +++ b/Typography.TextServices/FontStoreAndManagment/FontManagement.cs @@ -4,16 +4,15 @@ using System.IO; using Typography.OpenFont; - namespace Typography.FontManagement { public class InstalledTypeface { - internal InstalledTypeface(string fontName, - string fontSubFamily, - string tFamilyName, - string tSubFamilyName, + internal InstalledTypeface(string? fontName, + string? fontSubFamily, + string? tFamilyName, + string? tSubFamilyName, string fontPath, TypefaceStyle typefaceStyle, ushort weight) @@ -29,10 +28,10 @@ internal InstalledTypeface(string fontName, Weight = weight; } - public string FontName { get; internal set; } - public string FontSubFamily { get; internal set; } - public string TypographicFamilyName { get; internal set; } - public string TypographicFontSubFamily { get; internal set; } + public string? FontName { get; internal set; } + public string? FontSubFamily { get; internal set; } + public string? TypographicFamilyName { get; internal set; } + public string? TypographicFontSubFamily { get; internal set; } public TypefaceStyle TypefaceStyle { get; internal set; } public ushort Weight { get; internal set; } @@ -91,7 +90,7 @@ public enum FontNameDuplicatedDecision public interface IInstalledTypefaceProvider { - InstalledTypeface GetInstalledTypeface(string fontName, TypefaceStyle style); + InstalledTypeface? GetInstalledTypeface(string fontName, TypefaceStyle style); } public class InstalledTypefaceCollection : IInstalledTypefaceProvider @@ -104,7 +103,7 @@ public void AddFont(string registerName, InstalledTypeface installedFont) { _members.Add(registerName, installedFont); } - public bool TryGetValue(string registerName, out InstalledTypeface found) + public bool TryGetValue(string registerName, [System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out InstalledTypeface? found) { return _members.TryGetValue(registerName, out found); } @@ -114,10 +113,10 @@ public void Replace(string registerName, InstalledTypeface newone) } #if DEBUG - public string dbugGroupName; + public string? dbugGroupName; public override string ToString() { - return dbugGroupName; + return dbugGroupName ?? ""; } #endif @@ -132,8 +131,8 @@ public override string ToString() InstalledTypefaceGroup _regular, _bold, _italic, _bold_italic; List _allGroups = new List(); - FontNameDuplicatedHandler _fontNameDuplicatedHandler; - FontNotFoundHandler _fontNotFoundHandler; + FontNameDuplicatedHandler? _fontNameDuplicatedHandler; + FontNotFoundHandler? _fontNotFoundHandler; Dictionary _otherFontNames = new Dictionary(); @@ -160,7 +159,7 @@ public void SetFontNotFoundHandler(FontNotFoundHandler fontNotFoundHandler) _fontNotFoundHandler = fontNotFoundHandler; } - static InstalledTypefaceCollection s_intalledTypefaces; + static InstalledTypefaceCollection? s_intalledTypefaces; public static InstalledTypefaceCollection GetSharedTypefaceCollection(FirstInitFontCollectionDelegate initdel) { if (s_intalledTypefaces == null) @@ -175,7 +174,7 @@ public static void SetAsSharedTypefaceCollection(InstalledTypefaceCollection ins { s_intalledTypefaces = installedTypefaceCollection; } - public static InstalledTypefaceCollection GetSharedTypefaceCollection() + public static InstalledTypefaceCollection? GetSharedTypefaceCollection() { return s_intalledTypefaces; } @@ -197,7 +196,7 @@ InstalledTypefaceGroup CreateCreateNewGroup(TypefaceStyle installedFontStyle, pa bool AddFontPreview(PreviewFontInfo previewFont, string srcPath) { - _onlyFontNames[previewFont.Name] = true; + _onlyFontNames[previewFont.Name ?? ""] = true; TypefaceStyle typefaceStyle = TypefaceStyle.Regular; switch (previewFont.OS2TranslatedStyle) @@ -219,7 +218,7 @@ bool AddFontPreview(PreviewFontInfo previewFont, string srcPath) //--------------- //some font subfam="Bold Italic" but OS2TranslatedStyle is only Italic //so we should check the subfam name too! - string[] fontSubFamUpperCaseName_split = previewFont.SubFamilyName.ToUpper().Split(' '); + string[] fontSubFamUpperCaseName_split = (previewFont.SubFamilyName ?? "").ToUpper().Split(' '); if (fontSubFamUpperCaseName_split.Length > 1) { if (typefaceStyle != (TypefaceStyle.Bold | TypefaceStyle.Italic)) @@ -259,30 +258,30 @@ public bool AddFontStreamSource(IFontStreamSource src) using (Stream stream = src.ReadFontStream()) { var reader = new OpenFontReader(); - PreviewFontInfo previewFont = reader.ReadPreview(stream); - if (previewFont == null || string.IsNullOrEmpty(previewFont.Name)) + if (!(reader.ReadPreview(stream) is { } previewFont) || string.IsNullOrEmpty(previewFont.Name)) { //err! return false; } - if (previewFont.IsFontCollection) + if (previewFont is PreviewFontCollectionInfo collectionPreview) { - int mbCount = previewFont.MemberCount; + int mbCount = collectionPreview.Fonts.Length; bool totalResult = true; for (int i = 0; i < mbCount; ++i) { //extract and each members - if (!AddFontPreview(previewFont.GetMember(i), src.PathName)) + if (!AddFontPreview(collectionPreview.Fonts[i], src.PathName)) { totalResult = false; } } return totalResult; } - else + else if (previewFont is PreviewFontInfo fontPreview) { - return AddFontPreview(previewFont, src.PathName); + return AddFontPreview(fontPreview, src.PathName); } + else throw new NotImplementedException(); } } @@ -298,9 +297,9 @@ bool Register(InstalledTypeface newTypeface) - InstalledTypefaceGroup selectedFontGroup = null; + InstalledTypefaceGroup? selectedFontGroup = null; - string fontSubFamUpperCaseName = newTypeface.TypographicFontSubFamily; + string? fontSubFamUpperCaseName = newTypeface.TypographicFontSubFamily; bool use_typographicSubFam = true; if (fontSubFamUpperCaseName == null) { @@ -308,6 +307,7 @@ bool Register(InstalledTypeface newTypeface) fontSubFamUpperCaseName = newTypeface.FontSubFamily; use_typographicSubFam = false; } + if (fontSubFamUpperCaseName == null) throw new NotImplementedException(); fontSubFamUpperCaseName = fontSubFamUpperCaseName.ToUpper(); //-------------- @@ -363,7 +363,7 @@ bool Register(InstalledTypeface newTypeface) //------------------ //for font management //we use 'typographic family name' if avaliable, - string register_name = newTypeface.TypographicFamilyName; + string? register_name = newTypeface.TypographicFamilyName; bool use_typographicFontFam = true; if (register_name == null) { @@ -371,11 +371,12 @@ bool Register(InstalledTypeface newTypeface) register_name = newTypeface.FontName; use_typographicFontFam = false; } + if (register_name == null) throw new NotImplementedException(); register_name = register_name.ToUpper(); //*** bool register_result = false; - if (selectedFontGroup.TryGetValue(register_name, out InstalledTypeface found)) + if (selectedFontGroup.TryGetValue(register_name, out InstalledTypeface? found)) { //TODO: //we already have this font name @@ -403,26 +404,27 @@ bool Register(InstalledTypeface newTypeface) } if (use_typographicFontFam && + newTypeface.FontName != null && newTypeface.FontName != newTypeface.TypographicFamilyName && newTypeface.TypefaceStyle == TypefaceStyle.Regular) { //in this case, the code above register the typeface with TypographicFamilyName //so we register this typeface with original name too - _otherFontNames.Add(newTypeface.FontName.ToUpper(), newTypeface); + try { _otherFontNames.Add(newTypeface.FontName.ToUpper(), newTypeface); } catch { } } return register_result; } - public InstalledTypeface GetInstalledTypeface(string fontName, string subFamName) + public InstalledTypeface? GetInstalledTypeface(string fontName, string subFamName) { string upperCaseFontName = fontName.ToUpper(); string upperCaseSubFamName = subFamName.ToUpper(); - InstalledTypeface foundInstalledFont; + InstalledTypeface? foundInstalledFont; //find font group - if (_subFamToFontGroup.TryGetValue(upperCaseSubFamName, out InstalledTypefaceGroup foundFontGroup)) + if (_subFamToFontGroup.TryGetValue(upperCaseSubFamName, out InstalledTypefaceGroup? foundFontGroup)) { if (foundFontGroup.TryGetValue(upperCaseFontName, out foundInstalledFont)) { @@ -444,11 +446,11 @@ public InstalledTypeface GetInstalledTypeface(string fontName, string subFamName return null; //not found } - public InstalledTypeface GetInstalledTypeface(string fontName, TypefaceStyle wellknownSubFam) + public InstalledTypeface? GetInstalledTypeface(string fontName, TypefaceStyle wellknownSubFam) { //not auto resolve InstalledTypefaceGroup selectedFontGroup; - InstalledTypeface _found; + InstalledTypeface? _found; switch (wellknownSubFam) { default: return null; @@ -545,7 +547,7 @@ public IEnumerable GetInstalledTypefaceIter(string fontName) fontName = fontName.ToUpper(); foreach (InstalledTypefaceGroup typefaceGroup in _subFamToFontGroup.Values) { - if (typefaceGroup.TryGetValue(fontName, out InstalledTypeface found)) + if (typefaceGroup.TryGetValue(fontName, out InstalledTypeface? found)) { yield return found; } @@ -554,16 +556,90 @@ public IEnumerable GetInstalledTypefaceIter(string fontName) } + public class TypefaceStore + { + + FontNotFoundHandler? _fontNotFoundHandler; + Dictionary _loadedTypefaces = new Dictionary(); + + public TypefaceStore(InstalledTypefaceCollection fontCollection) + { + FontCollection = fontCollection; + } + /// + /// font collection of the store + /// + public InstalledTypefaceCollection FontCollection { get; set; } + public void SetFontNotFoundHandler(FontNotFoundHandler fontNotFoundHandler) + { + _fontNotFoundHandler = fontNotFoundHandler; + } + public Typeface? GetTypeface(InstalledTypeface installedFont) + { + return GetTypefaceOrCreateNew(installedFont); + } + public Typeface? GetTypeface(string fontname, string fontSubFam) + { + + var installedFont = FontCollection.GetInstalledTypeface(fontname, fontSubFam); + //convert from + if (installedFont == null && _fontNotFoundHandler != null) + { + installedFont = _fontNotFoundHandler(this.FontCollection, fontname, fontSubFam); + } + if (installedFont == null) + { + return null; + } + return GetTypefaceOrCreateNew(installedFont); + } + /// + /// get typeface from wellknown style + /// + /// + /// + /// + public Typeface? GetTypeface(string fontname, TypefaceStyle style) + { + var installedFont = FontCollection.GetInstalledTypeface(fontname, style); + if (installedFont == null && _fontNotFoundHandler != null) + { + installedFont = _fontNotFoundHandler(this.FontCollection, fontname, InstalledTypefaceCollection.GetSubFam(style)); + } + if (installedFont == null) + { + return null; + } + return GetTypefaceOrCreateNew(installedFont); + } + Typeface? GetTypefaceOrCreateNew(InstalledTypeface installedFont) + { + //load + //check if we have create this typeface or not + Typeface? typeface; + if (!_loadedTypefaces.TryGetValue(installedFont, out typeface)) + { + //TODO: review how to load font here + using (var fs = new FileStream(installedFont.FontPath, FileMode.Open, FileAccess.Read)) + { + var reader = new OpenFontReader(); + typeface = reader.Read(fs, installedFont.ActualStreamOffset); + } + return _loadedTypefaces[installedFont] = typeface; + } + return typeface; + } + } public static class InstalledTypefaceCollectionExtensions { public delegate R MyFunc(T1 t1, T2 t2); public delegate R MyFunc(T t); - public static Action CustomSystemFontListLoader; + public static Action? CustomSystemFontListLoader; - public static MyFunc CustomFontStreamLoader; + public static MyFunc? CustomFontStreamLoader; public static void LoadFontsFromFolder(this InstalledTypefaceCollection fontCollection, string folder, bool recursive = false) diff --git a/Typography.TextServices/IcuData/LangCodes.cs b/Typography.TextServices/IcuData/LangCodes.cs index ec409093..7f39847f 100644 --- a/Typography.TextServices/IcuData/LangCodes.cs +++ b/Typography.TextServices/IcuData/LangCodes.cs @@ -671,7 +671,7 @@ static void InitData() //parse using (StringReader reader = new StringReader(LangsCode)) { - string line = reader.ReadLine(); + string? line = reader.ReadLine(); while (line != null) { @@ -702,7 +702,9 @@ static void InitData() } } } - public static bool TryGetFullLanguageNameFromLangCode(string langCode1, string langCode2, out string fullLangName) + + public static bool TryGetFullLanguageNameFromLangCode + (string langCode1, string langCode2, [System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out string? fullLangName) { if (!_init_data) InitData(); // diff --git a/Typography.TextServices/TextServices.cs b/Typography.TextServices/TextServices.cs index bb8b3deb..e269a4fd 100644 --- a/Typography.TextServices/TextServices.cs +++ b/Typography.TextServices/TextServices.cs @@ -1,4 +1,4 @@ -//MIT, 2014-present, WinterDev +//MIT, 2014-present, WinterDev using System; using System.Collections.Generic; using Typography.OpenFont; @@ -40,11 +40,19 @@ public class TextServices ScriptLang _scLang; - public TextServices() + public TextServices(InstalledTypefaceCollection installedCollection, ScriptLang defaultScriptLang) { - + using var enumerator = installedCollection.GetInstalledFontIter().GetEnumerator(); + enumerator.MoveNext(); + var first = enumerator.Current ?? throw new ArgumentException("Empty collection!", nameof(installedCollection)); _typefaceStore = ActiveTypefaceCache.GetTypefaceStoreOrCreateNewIfNotExist(); - _glyphLayout = new GlyphLayout(); + SetCurrentFont(_typefaceStore.GetTypeface(first), 0); + _installedTypefaceCollection = installedCollection; + // https://github.com/dotnet/roslyn/issues/39740 + if (_currentTypeface is { } t) _currentTypeface = t; else throw new NotImplementedException(); + if (_glyphLayout is { } g) _glyphLayout = g; else throw new NotImplementedException(); + if (_currentGlyphPlanSeqCache is { } s) _currentGlyphPlanSeqCache = s; else throw new NotImplementedException(); + _scLang = _defaultScriptLang = _glyphLayout.ScriptLang = defaultScriptLang; } public void SetDefaultScriptLang(ScriptLang scLang) { @@ -64,26 +72,27 @@ public ScriptLang CurrentScriptLang public void SetCurrentFont(Typeface typeface, float fontSizeInPts) { + _glyphLayout ??= new GlyphLayout(typeface); //check if we have the cache-key or create a new one. var key = new TextShapingContextKey(typeface, _glyphLayout.ScriptLang); - if (!_registerShapingContexts.TryGetValue(key, out _currentGlyphPlanSeqCache)) + if (!_registerShapingContexts.TryGetValue(key, out var currentGlyphPlanSeqCache)) { //not found //the create the new one var shapingContext = new GlyphPlanCacheForTypefaceAndScriptLang(typeface, _glyphLayout.ScriptLang); //shaping context setup ... _registerShapingContexts.Add(key, shapingContext); - _currentGlyphPlanSeqCache = shapingContext; + currentGlyphPlanSeqCache = shapingContext; } - - _currentTypeface = _glyphLayout.Typeface = typeface; + _currentGlyphPlanSeqCache = currentGlyphPlanSeqCache; + _currentTypeface = typeface; _fontSizeInPts = fontSizeInPts; //_glyphLayout.FontSizeInPoints = _fontSizeInPts = fontSizeInPts; } - public Typeface GetTypeface(string name, TypefaceStyle installedFontStyle) + public Typeface? GetTypeface(string name, TypefaceStyle installedFontStyle) { - InstalledTypeface inst = _installedTypefaceCollection.GetInstalledTypeface(name, InstalledTypefaceCollection.GetSubFam(installedFontStyle)); + var inst = _installedTypefaceCollection.GetInstalledTypeface(name, InstalledTypefaceCollection.GetSubFam(installedFontStyle)); if (inst != null) { @@ -103,20 +112,19 @@ internal void ClearAllRegisteredShapingContext() _registerShapingContexts.Clear(); } - CustomBreaker _textBreaker; + CustomBreaker? _textBreaker; List _breakSpans = new List(); public IEnumerable BreakToLineSegments(char[] str, int startAt, int len) { //user must setup the CustomBreakerBuilder before use if (_textBreaker == null) { - _textBreaker = Typography.TextBreak.CustomBreakerBuilder.NewCustomBreaker(); - _textBreaker.SetNewBreakHandler(vis => _breakSpans.Add(vis.GetBreakSpan())); + _textBreaker = CustomBreakerBuilder.NewCustomBreaker(vis => _breakSpans.Add(vis.GetBreakSpan())); #if DEBUG if (_textBreaker == null) { - + throw new InvalidOperationException("Failed to load custom breakers"); } #endif } @@ -159,7 +167,7 @@ internal void ClearAllRegisteredShapingContext() else { // - Typography.OpenFont.ScriptLang scLang; + Typography.OpenFont.ScriptLang? scLang; if (Typography.OpenFont.ScriptLangs.TryGetScriptLang(sample, out scLang)) { //we should decide to use @@ -277,7 +285,7 @@ class GlyphPlanSeqSet /// GlyphPlanSeqCollection[] _cacheSeqCollection1; //other len - Dictionary _cacheSeqCollection2; //lazy init + Dictionary? _cacheSeqCollection2; //lazy init public GlyphPlanSeqSet() { _cacheSeqCollection1 = new GlyphPlanSeqCollection[PREDEFINE_LEN]; @@ -309,7 +317,7 @@ public GlyphPlanSeqCollection GetSeqCollectionOrCreateIfNotExist(int len) { _cacheSeqCollection2 = new Dictionary(); } - GlyphPlanSeqCollection seqCol; + GlyphPlanSeqCollection? seqCol; if (!_cacheSeqCollection2.TryGetValue(len, out seqCol)) { //new one if not exist @@ -448,7 +456,7 @@ public ActiveTypefaceCache() { } - static ActiveTypefaceCache s_typefaceStore; + static ActiveTypefaceCache? s_typefaceStore; public static ActiveTypefaceCache GetTypefaceStoreOrCreateNewIfNotExist() { if (s_typefaceStore == null) @@ -460,13 +468,13 @@ public static ActiveTypefaceCache GetTypefaceStoreOrCreateNewIfNotExist() public Typeface GetTypeface(InstalledTypeface installedFont) { return GetTypefaceOrCreateNew(installedFont); - } + } Typeface GetTypefaceOrCreateNew(InstalledTypeface installedFont) { //load //check if we have create this typeface or not - if (!_loadedTypefaces.TryGetValue(installedFont, out Typeface typeface)) + if (!_loadedTypefaces.TryGetValue(installedFont, out Typeface? typeface)) { //TODO: review how to load font here if (Typography.FontManagement.InstalledTypefaceCollectionExtensions.CustomFontStreamLoader != null) @@ -475,7 +483,7 @@ Typeface GetTypefaceOrCreateNew(InstalledTypeface installedFont) { var reader = new OpenFontReader(); - typeface = reader.Read(fontStream, installedFont.ActualStreamOffset); + typeface = reader.Read(fontStream, installedFont.ActualStreamOffset) ?? throw new InvalidOperationException("Invalid font!"); typeface.Filename = installedFont.FontPath; } @@ -487,7 +495,7 @@ Typeface GetTypefaceOrCreateNew(InstalledTypeface installedFont) using (var fs = new FileStream(installedFont.FontPath, FileMode.Open, FileAccess.Read)) { var reader = new OpenFontReader(); - typeface = reader.Read(fs, installedFont.ActualStreamOffset); + typeface = reader.Read(fs, installedFont.ActualStreamOffset) ?? throw new InvalidOperationException("Invalid font!"); typeface.Filename = installedFont.FontPath; } diff --git a/Typography.sln b/Typography.sln index a90dc014..b57d4d89 100644 --- a/Typography.sln +++ b/Typography.sln @@ -25,12 +25,6 @@ Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Typography.GlyphLayout", "T EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Typography_Build", "Typography_Build", "{CCC8D030-3F27-4560-B290-B95F4022DDB8}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NET20", "NET20", "{189B365C-127C-4377-88F3-C3D391B43993}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Typography.OpenFont", "Build\N20\Typography.OpenFont\Typography.OpenFont.csproj", "{F7D71E61-9342-4DD7-9AFD-69045F2EC98B}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Typography.GlyphLayout", "Build\N20\Typography.GlyphLayout\Typography.GlyphLayout.csproj", "{C6807D05-09BE-4313-9F8B-BD2D51C55819}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xamarin.IOS.GLES2", "Demo\iOS\Xamarin.iOS.GLES2\Xamarin.IOS.GLES2.csproj", "{A09B4BF0-2C5E-42E9-B23C-AFD0B5A8697D}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GlyphTess.WinForms", "Demo\Windows\GlyphTess.WinForms\GlyphTess.WinForms.csproj", "{56DCAE82-671D-409E-A3B3-BF4834756D3F}" @@ -39,8 +33,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TextBoxSample.WinForms", "D EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "DrawingGL.Common", "Demo\Shared\DrawingGL.Common.shproj", "{2E1E828F-6D2C-4B0E-A2E2-DDF24798CACF}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PixelFarm.MiniAgg.One", "x_autogen2\PixelFarm.MiniAgg.One\PixelFarm.MiniAgg.One.csproj", "{FB5F78F5-C921-405D-8F21-42F7C15C2AD9}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PixelFarm.Typography", "PixelFarm.Typography\PixelFarm.Typography.csproj", "{540A2EA6-DAE3-4625-8951-B2C3118603A4}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TypographyTest.WinForms", "Demo\Windows\TypographyTest.WinForms\TypographyTest.WinForms.csproj", "{9D2F3501-7705-4401-BE13-A7613CA0C4BD}" @@ -59,15 +51,7 @@ Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Typography.TextFlow", "Typo EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Typography.TextServices", "Typography.TextServices\Typography.TextServices.shproj", "{D07686EE-2618-4C20-8EB5-32AD4C4D3810}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Typography.MsdfGen", "Build\N20\Typography.MsdfGen\Typography.MsdfGen.csproj", "{9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Typography.TextFlow", "Build\N20\Typography.TextFlow\Typography.TextFlow.csproj", "{333F3209-8DA9-4D33-A560-299ED4C6DFA5}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Typography.TextServices", "Build\N20\Typography.TextServices\Typography.TextServices.csproj", "{6B0E034B-0EBD-4907-AD7F-437DE66D78D4}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Typography.TextBreak", "Build\N20\Typography.TextBreak\Typography.TextBreak.csproj", "{BC10CC51-A795-40D0-96F0-F87585D59D02}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TextBreakTests", "Typography.TextBreak\Typography.TextBreak.UnitTests\TextBreakTests.csproj", "{2E593FCA-B809-4270-9EB2-93F380AF2D6C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TextBreakTests", "Typography.TextBreak\Typography.TextBreak.UnitTests\TextBreakTests.csproj", "{2E593FCA-B809-4270-9EB2-93F380AF2D6C}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BackEnd.Triangulation", "PixelFarm\BackEnd.Triangulation\BackEnd.Triangulation.csproj", "{C5E5802D-6A45-4FE9-BAE7-5F0AE91D72C1}" EndProject @@ -75,69 +59,59 @@ Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Triangulation", "PixelFarm\ EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Unpack_SH", "Unpack_SH\Unpack_SH.shproj", "{CE0D5C56-C9DA-4F22-9AD8-3677D0E034A4}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unpack", "Build\N20\Unpack\Unpack.csproj", "{901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PaintLab.Svg", "PixelFarm\PaintLab.Svg\PaintLab.Svg.csproj", "{466DD2AE-EADC-4E20-82B3-DA6D018006C5}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Typography.OpenFont", "Build\NetStandard\Typography.OpenFont\Typography.OpenFont.csproj", "{55C6CCFF-6BF9-45FE-BF86-406100E8D170}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GdiPlusSample.WinForms_2", "Demo\Windows\GdiPlusSample.WinForms_2\GdiPlusSample.WinForms_2.csproj", "{91ACD6FC-E152-41EB-BACA-F0AA283FA201}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NETSTD", "NETSTD", "{8DD7A804-99D0-41EE-9546-21E5A89223A2}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xamarin.Android.OpenGL", "Demo\Android\Xamarin.OpenGL\Xamarin.Android.OpenGL.csproj", "{B824FFB2-D057-490A-8967-892C0E20C0B6}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Typography.GlyphLayout", "Build\NetStandard\Typography.GlyphLayout\Typography.GlyphLayout.csproj", "{7F481A1E-38F8-484C-960B-45EBB185A00E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PixelFarm.MiniAgg.One", "Build\PixelFarm.MiniAgg.One\PixelFarm.MiniAgg.One.csproj", "{D4037FB8-0349-41B9-A0BF-8E6052D34D75}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Typography.MsdfGen", "Build\NetStandard\Typography.MsdfGen\Typography.MsdfGen.csproj", "{23624298-2E7B-4E44-8FF9-1543CAAB238A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PixelFarm.One.HtmlRenderer", "Build\PixelFarm.One.HtmlRenderer\PixelFarm.One.HtmlRenderer.csproj", "{1E687C41-4086-44C1-9A64-8122925A48AF}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Typography.TextBreak", "Build\NetStandard\Typography.TextBreak\Typography.TextBreak.csproj", "{87A39D2B-A539-4077-8488-BB98D67AB660}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Typography.GlyphLayout", "Build\Typography.GlyphLayout\Typography.GlyphLayout.csproj", "{0E1CAB21-DA5B-4539-8BD6-3036CE29102D}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Typography.TextServices", "Build\NetStandard\Typography.TextServices\Typography.TextServices.csproj", "{6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Typography.One", "Build\Typography.One\Typography.One.csproj", "{25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Unpack", "Build\NetStandard\Unpack\Unpack.csproj", "{9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Typography.OpenFont", "Build\Typography.OpenFont\Typography.OpenFont.csproj", "{22A6EFD2-D92E-448F-8459-8EB66D1AF15C}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PixelFarm.MiniAgg.One", "x_autogen_netstandard2.0\PixelFarm.MiniAgg.One\PixelFarm.MiniAgg.One.csproj", "{40D0DBFA-6427-478F-83B0-DAA0F0A8014A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Typography.TextBreak", "Build\Typography.TextBreak\Typography.TextBreak.csproj", "{DC8EE8CC-8882-4DE5-8405-B7452F83B30A}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ONE", "ONE", "{46EDD385-59F7-4402-A023-9314C55471BB}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Typography.TextFlow", "Build\Typography.TextFlow\Typography.TextFlow.csproj", "{65B22280-ED4D-43A2-947C-BBFAB44AD8FD}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Typography.One", "Build\NetStandard\Typography.One\Typography.One.csproj", "{95E23DEE-0AAA-4F93-94DD-A18AB84625F9}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Typography.TextServices", "Build\Typography.TextServices\Typography.TextServices.csproj", "{6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GdiPlusSample.WinForms_2", "Demo\Windows\GdiPlusSample.WinForms_2\GdiPlusSample.WinForms_2.csproj", "{91ACD6FC-E152-41EB-BACA-F0AA283FA201}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Unpack", "Build\Unpack\Unpack.csproj", "{49F57B62-B937-4715-9CF5-E5431D049D56}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xamarin.Android.OpenGL", "Demo\Android\Xamarin.OpenGL\Xamarin.Android.OpenGL.csproj", "{B824FFB2-D057-490A-8967-892C0E20C0B6}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Typography.MsdfGen", "Build\Typography.MsdfGen\Typography.MsdfGen.csproj", "{9C359551-463A-4D62-A6AE-EA72F41A7AEB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PixelFarm.Drawing", "PixelFarm\PixelFarm.Drawing\PixelFarm.Drawing.csproj", "{51D63482-5697-4B16-8401-506965624657}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PaintLab.PaintFx.MiniAgg", "PixelFarm\PaintLab.PaintFx\PaintLab.PaintFx.MiniAgg.csproj", "{A533E1C7-AB74-4BCF-BC7A-12D4DBBFA918}" EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution + Typography.GlyphLayout\Typography.GlyphLayout.projitems*{0e1cab21-da5b-4539-8bd6-3036ce29102d}*SharedItemsImports = 5 + Typography.OpenFont\Typography.OpenFont.projitems*{22a6efd2-d92e-448f-8459-8eb66d1af15c}*SharedItemsImports = 5 Typography.OpenFont\Typography.OpenFont.projitems*{235a071b-8d06-40ae-a5c5-b1ce59715ee9}*SharedItemsImports = 13 + Typography.GlyphLayout\Typography.GlyphLayout.projitems*{25f0bd32-e312-4060-a6b5-9ef76ff1c4df}*SharedItemsImports = 5 + Typography.OpenFont\Typography.OpenFont.projitems*{25f0bd32-e312-4060-a6b5-9ef76ff1c4df}*SharedItemsImports = 5 Demo\Shared\DrawingGL.Common.projitems*{2e1e828f-6d2c-4b0e-a2e2-ddf24798cacf}*SharedItemsImports = 13 - Typography.TextBreak\Typography.TextBreak\Typography.TextBreak.projitems*{2e593fca-b809-4270-9eb2-93f380af2d6c}*SharedItemsImports = 4 - Typography.TextFlow\Typography.TextFlow.projitems*{333f3209-8da9-4d33-a560-299ed4c6dfa5}*SharedItemsImports = 4 + Typography.TextBreak\Typography.TextBreak\Typography.TextBreak.projitems*{2e593fca-b809-4270-9eb2-93f380af2d6c}*SharedItemsImports = 5 + Unpack_SH\Unpack_SH.projitems*{49f57b62-b937-4715-9cf5-e5431d049d56}*SharedItemsImports = 5 PixelFarm\BackEnd.Triangulation\Triangulation.projitems*{4f435da3-706a-4e6d-ae29-e1e95bd6f68a}*SharedItemsImports = 13 - Typography.OpenFont\Typography.OpenFont.projitems*{55c6ccff-6bf9-45fe-bf86-406100e8d170}*SharedItemsImports = 5 - Typography.TextBreak\Typography.TextBreak\Typography.TextBreak.projitems*{6b0e034b-0ebd-4907-ad7f-437de66d78d4}*SharedItemsImports = 4 - Typography.TextFlow\Typography.TextFlow.projitems*{6b0e034b-0ebd-4907-ad7f-437de66d78d4}*SharedItemsImports = 4 - Typography.TextServices\Typography.TextServices.projitems*{6b0e034b-0ebd-4907-ad7f-437de66d78d4}*SharedItemsImports = 4 - Typography.TextBreak\Typography.TextBreak\Typography.TextBreak.projitems*{6c5f8d13-5d4e-405b-9bf2-f4c9e5aa405c}*SharedItemsImports = 5 - Typography.TextFlow\Typography.TextFlow.projitems*{6c5f8d13-5d4e-405b-9bf2-f4c9e5aa405c}*SharedItemsImports = 5 - Typography.TextServices\Typography.TextServices.projitems*{6c5f8d13-5d4e-405b-9bf2-f4c9e5aa405c}*SharedItemsImports = 5 + Typography.TextFlow\Typography.TextFlow.projitems*{65b22280-ed4d-43a2-947c-bbfab44ad8fd}*SharedItemsImports = 5 + Typography.TextServices\Typography.TextServices.projitems*{6faf0ad2-22f1-46d9-ade4-ece3fa670bd0}*SharedItemsImports = 5 Typography.TextFlow\Typography.TextFlow.projitems*{7a8a63d2-2cb5-41f5-8e83-6f6e54398cf4}*SharedItemsImports = 13 - Typography.GlyphLayout\Typography.GlyphLayout.projitems*{7f481a1e-38f8-484c-960b-45ebb185a00e}*SharedItemsImports = 5 - Typography.TextBreak\Typography.TextBreak\Typography.TextBreak.projitems*{87a39d2b-a539-4077-8488-bb98d67ab660}*SharedItemsImports = 5 - Unpack_SH\Unpack_SH.projitems*{901a60ed-baef-45f6-8919-6e07ee6bad8d}*SharedItemsImports = 4 - Typography.GlyphLayout\Typography.GlyphLayout.projitems*{95e23dee-0aaa-4f93-94dd-a18ab84625f9}*SharedItemsImports = 5 - Typography.OpenFont\Typography.OpenFont.projitems*{95e23dee-0aaa-4f93-94dd-a18ab84625f9}*SharedItemsImports = 5 - Unpack_SH\Unpack_SH.projitems*{95e23dee-0aaa-4f93-94dd-a18ab84625f9}*SharedItemsImports = 5 Typography.TextBreak\Typography.TextBreak\Typography.TextBreak.projitems*{9a99f103-b119-4a4d-8093-6a03baa6d36b}*SharedItemsImports = 13 - Unpack_SH\Unpack_SH.projitems*{9b1d6d45-7a2f-4ed1-95a6-54b3b892bbd1}*SharedItemsImports = 5 Demo\Shared\DrawingGL.Common.projitems*{a09b4bf0-2c5e-42e9-b23c-afd0b5a8697d}*SharedItemsImports = 4 PixelFarm\BackEnd.PaintFx\PdnSharedProject\PdnSharedProject.projitems*{a533e1c7-ab74-4bcf-bc7a-12d4dbbfa918}*SharedItemsImports = 4 Demo\Shared\DrawingGL.Common.projitems*{b824ffb2-d057-490a-8967-892c0e20c0b6}*SharedItemsImports = 4 - Typography.TextBreak\Typography.TextBreak\Typography.TextBreak.projitems*{bc10cc51-a795-40d0-96f0-f87585d59d02}*SharedItemsImports = 4 PixelFarm\BackEnd.Triangulation\Triangulation.projitems*{c5e5802d-6a45-4fe9-bae7-5f0ae91d72c1}*SharedItemsImports = 4 - Typography.GlyphLayout\Typography.GlyphLayout.projitems*{c6807d05-09be-4313-9f8b-bd2d51c55819}*SharedItemsImports = 4 Unpack_SH\Unpack_SH.projitems*{ce0d5c56-c9da-4f22-9ad8-3677d0e034a4}*SharedItemsImports = 13 Typography.TextServices\Typography.TextServices.projitems*{d07686ee-2618-4c20-8eb5-32ad4c4d3810}*SharedItemsImports = 13 Typography.GlyphLayout\Typography.GlyphLayout.projitems*{d8861cf8-c506-472b-8a57-632bd6ca6496}*SharedItemsImports = 13 - Typography.OpenFont\Typography.OpenFont.projitems*{f7d71e61-9342-4dd7-9afd-69045f2ec98b}*SharedItemsImports = 4 + Typography.TextBreak\Typography.TextBreak\Typography.TextBreak.projitems*{dc8ee8cc-8882-4de5-8405-b7452f83b30a}*SharedItemsImports = 5 EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Ad-Hoc|Any CPU = Ad-Hoc|Any CPU @@ -282,118 +256,6 @@ Global {0DABB64B-3D8C-4447-A129-619390ED0E87}.Release64|iPhoneSimulator.Build.0 = Release|Any CPU {0DABB64B-3D8C-4447-A129-619390ED0E87}.Release64|x86.ActiveCfg = Release|Any CPU {0DABB64B-3D8C-4447-A129-619390ED0E87}.Release64|x86.Build.0 = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Ad-Hoc|x86.Build.0 = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.AppStore|Any CPU.ActiveCfg = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.AppStore|Any CPU.Build.0 = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.AppStore|iPhone.ActiveCfg = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.AppStore|iPhone.Build.0 = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.AppStore|x86.ActiveCfg = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.AppStore|x86.Build.0 = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Debug|iPhone.Build.0 = Debug|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Debug|x86.ActiveCfg = Debug|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Debug|x86.Build.0 = Debug|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Debug45|Any CPU.ActiveCfg = Debug|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Debug45|Any CPU.Build.0 = Debug|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Debug45|iPhone.ActiveCfg = Debug|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Debug45|iPhone.Build.0 = Debug|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Debug45|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Debug45|iPhoneSimulator.Build.0 = Debug|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Debug45|x86.ActiveCfg = Debug|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Debug45|x86.Build.0 = Debug|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Release|Any CPU.Build.0 = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Release|iPhone.ActiveCfg = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Release|iPhone.Build.0 = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Release|x86.ActiveCfg = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Release|x86.Build.0 = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Release45|Any CPU.ActiveCfg = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Release45|Any CPU.Build.0 = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Release45|iPhone.ActiveCfg = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Release45|iPhone.Build.0 = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Release45|iPhoneSimulator.ActiveCfg = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Release45|iPhoneSimulator.Build.0 = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Release45|x86.ActiveCfg = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Release45|x86.Build.0 = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Release64|Any CPU.ActiveCfg = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Release64|Any CPU.Build.0 = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Release64|iPhone.ActiveCfg = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Release64|iPhone.Build.0 = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Release64|iPhoneSimulator.ActiveCfg = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Release64|iPhoneSimulator.Build.0 = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Release64|x86.ActiveCfg = Release|Any CPU - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B}.Release64|x86.Build.0 = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Ad-Hoc|x86.Build.0 = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.AppStore|Any CPU.ActiveCfg = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.AppStore|Any CPU.Build.0 = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.AppStore|iPhone.ActiveCfg = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.AppStore|iPhone.Build.0 = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.AppStore|x86.ActiveCfg = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.AppStore|x86.Build.0 = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Debug|iPhone.Build.0 = Debug|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Debug|x86.ActiveCfg = Debug|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Debug|x86.Build.0 = Debug|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Debug45|Any CPU.ActiveCfg = Debug|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Debug45|Any CPU.Build.0 = Debug|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Debug45|iPhone.ActiveCfg = Debug|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Debug45|iPhone.Build.0 = Debug|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Debug45|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Debug45|iPhoneSimulator.Build.0 = Debug|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Debug45|x86.ActiveCfg = Debug|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Debug45|x86.Build.0 = Debug|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Release|Any CPU.Build.0 = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Release|iPhone.ActiveCfg = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Release|iPhone.Build.0 = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Release|x86.ActiveCfg = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Release|x86.Build.0 = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Release45|Any CPU.ActiveCfg = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Release45|Any CPU.Build.0 = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Release45|iPhone.ActiveCfg = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Release45|iPhone.Build.0 = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Release45|iPhoneSimulator.ActiveCfg = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Release45|iPhoneSimulator.Build.0 = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Release45|x86.ActiveCfg = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Release45|x86.Build.0 = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Release64|Any CPU.ActiveCfg = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Release64|Any CPU.Build.0 = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Release64|iPhone.ActiveCfg = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Release64|iPhone.Build.0 = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Release64|iPhoneSimulator.ActiveCfg = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Release64|iPhoneSimulator.Build.0 = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Release64|x86.ActiveCfg = Release|Any CPU - {C6807D05-09BE-4313-9F8B-BD2D51C55819}.Release64|x86.Build.0 = Release|Any CPU {A09B4BF0-2C5E-42E9-B23C-AFD0B5A8697D}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone {A09B4BF0-2C5E-42E9-B23C-AFD0B5A8697D}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone {A09B4BF0-2C5E-42E9-B23C-AFD0B5A8697D}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone @@ -547,62 +409,6 @@ Global {7E00196D-3E47-412A-8F1D-41DF082502F0}.Release64|iPhoneSimulator.Build.0 = Release|Any CPU {7E00196D-3E47-412A-8F1D-41DF082502F0}.Release64|x86.ActiveCfg = Release|Any CPU {7E00196D-3E47-412A-8F1D-41DF082502F0}.Release64|x86.Build.0 = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Ad-Hoc|x86.Build.0 = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.AppStore|Any CPU.ActiveCfg = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.AppStore|Any CPU.Build.0 = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.AppStore|iPhone.ActiveCfg = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.AppStore|iPhone.Build.0 = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.AppStore|x86.ActiveCfg = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.AppStore|x86.Build.0 = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Debug|iPhone.Build.0 = Debug|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Debug|x86.ActiveCfg = Debug|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Debug|x86.Build.0 = Debug|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Debug45|Any CPU.ActiveCfg = Debug|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Debug45|Any CPU.Build.0 = Debug|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Debug45|iPhone.ActiveCfg = Debug|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Debug45|iPhone.Build.0 = Debug|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Debug45|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Debug45|iPhoneSimulator.Build.0 = Debug|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Debug45|x86.ActiveCfg = Debug|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Debug45|x86.Build.0 = Debug|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Release|Any CPU.Build.0 = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Release|iPhone.ActiveCfg = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Release|iPhone.Build.0 = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Release|x86.ActiveCfg = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Release|x86.Build.0 = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Release45|Any CPU.ActiveCfg = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Release45|Any CPU.Build.0 = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Release45|iPhone.ActiveCfg = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Release45|iPhone.Build.0 = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Release45|iPhoneSimulator.ActiveCfg = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Release45|iPhoneSimulator.Build.0 = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Release45|x86.ActiveCfg = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Release45|x86.Build.0 = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Release64|Any CPU.ActiveCfg = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Release64|Any CPU.Build.0 = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Release64|iPhone.ActiveCfg = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Release64|iPhone.Build.0 = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Release64|iPhoneSimulator.ActiveCfg = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Release64|iPhoneSimulator.Build.0 = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Release64|x86.ActiveCfg = Release|Any CPU - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9}.Release64|x86.Build.0 = Release|Any CPU {540A2EA6-DAE3-4625-8951-B2C3118603A4}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU {540A2EA6-DAE3-4625-8951-B2C3118603A4}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU {540A2EA6-DAE3-4625-8951-B2C3118603A4}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU @@ -878,230 +684,6 @@ Global {949DBA60-3DB1-4F6C-8BFA-B0056D320DF0}.Release64|iPhoneSimulator.Build.0 = Release|x86 {949DBA60-3DB1-4F6C-8BFA-B0056D320DF0}.Release64|x86.ActiveCfg = Release|x86 {949DBA60-3DB1-4F6C-8BFA-B0056D320DF0}.Release64|x86.Build.0 = Release|x86 - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Ad-Hoc|x86.Build.0 = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.AppStore|Any CPU.ActiveCfg = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.AppStore|Any CPU.Build.0 = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.AppStore|iPhone.ActiveCfg = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.AppStore|iPhone.Build.0 = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.AppStore|x86.ActiveCfg = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.AppStore|x86.Build.0 = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Debug|iPhone.Build.0 = Debug|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Debug|x86.ActiveCfg = Debug|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Debug|x86.Build.0 = Debug|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Debug45|Any CPU.ActiveCfg = Debug|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Debug45|Any CPU.Build.0 = Debug|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Debug45|iPhone.ActiveCfg = Debug|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Debug45|iPhone.Build.0 = Debug|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Debug45|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Debug45|iPhoneSimulator.Build.0 = Debug|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Debug45|x86.ActiveCfg = Debug|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Debug45|x86.Build.0 = Debug|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Release|Any CPU.Build.0 = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Release|iPhone.ActiveCfg = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Release|iPhone.Build.0 = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Release|x86.ActiveCfg = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Release|x86.Build.0 = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Release45|Any CPU.ActiveCfg = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Release45|Any CPU.Build.0 = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Release45|iPhone.ActiveCfg = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Release45|iPhone.Build.0 = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Release45|iPhoneSimulator.ActiveCfg = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Release45|iPhoneSimulator.Build.0 = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Release45|x86.ActiveCfg = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Release45|x86.Build.0 = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Release64|Any CPU.ActiveCfg = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Release64|Any CPU.Build.0 = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Release64|iPhone.ActiveCfg = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Release64|iPhone.Build.0 = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Release64|iPhoneSimulator.ActiveCfg = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Release64|iPhoneSimulator.Build.0 = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Release64|x86.ActiveCfg = Release|Any CPU - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71}.Release64|x86.Build.0 = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Ad-Hoc|x86.Build.0 = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.AppStore|Any CPU.ActiveCfg = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.AppStore|Any CPU.Build.0 = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.AppStore|iPhone.ActiveCfg = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.AppStore|iPhone.Build.0 = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.AppStore|x86.ActiveCfg = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.AppStore|x86.Build.0 = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Debug|iPhone.Build.0 = Debug|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Debug|x86.ActiveCfg = Debug|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Debug|x86.Build.0 = Debug|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Debug45|Any CPU.ActiveCfg = Debug|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Debug45|Any CPU.Build.0 = Debug|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Debug45|iPhone.ActiveCfg = Debug|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Debug45|iPhone.Build.0 = Debug|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Debug45|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Debug45|iPhoneSimulator.Build.0 = Debug|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Debug45|x86.ActiveCfg = Debug|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Debug45|x86.Build.0 = Debug|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Release|Any CPU.Build.0 = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Release|iPhone.ActiveCfg = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Release|iPhone.Build.0 = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Release|x86.ActiveCfg = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Release|x86.Build.0 = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Release45|Any CPU.ActiveCfg = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Release45|Any CPU.Build.0 = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Release45|iPhone.ActiveCfg = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Release45|iPhone.Build.0 = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Release45|iPhoneSimulator.ActiveCfg = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Release45|iPhoneSimulator.Build.0 = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Release45|x86.ActiveCfg = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Release45|x86.Build.0 = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Release64|Any CPU.ActiveCfg = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Release64|Any CPU.Build.0 = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Release64|iPhone.ActiveCfg = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Release64|iPhone.Build.0 = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Release64|iPhoneSimulator.ActiveCfg = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Release64|iPhoneSimulator.Build.0 = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Release64|x86.ActiveCfg = Release|Any CPU - {333F3209-8DA9-4D33-A560-299ED4C6DFA5}.Release64|x86.Build.0 = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Ad-Hoc|x86.Build.0 = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.AppStore|Any CPU.ActiveCfg = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.AppStore|Any CPU.Build.0 = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.AppStore|iPhone.ActiveCfg = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.AppStore|iPhone.Build.0 = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.AppStore|x86.ActiveCfg = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.AppStore|x86.Build.0 = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Debug|iPhone.Build.0 = Debug|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Debug|x86.ActiveCfg = Debug|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Debug|x86.Build.0 = Debug|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Debug45|Any CPU.ActiveCfg = Debug|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Debug45|Any CPU.Build.0 = Debug|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Debug45|iPhone.ActiveCfg = Debug|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Debug45|iPhone.Build.0 = Debug|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Debug45|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Debug45|iPhoneSimulator.Build.0 = Debug|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Debug45|x86.ActiveCfg = Debug|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Debug45|x86.Build.0 = Debug|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Release|Any CPU.Build.0 = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Release|iPhone.ActiveCfg = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Release|iPhone.Build.0 = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Release|x86.ActiveCfg = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Release|x86.Build.0 = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Release45|Any CPU.ActiveCfg = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Release45|Any CPU.Build.0 = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Release45|iPhone.ActiveCfg = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Release45|iPhone.Build.0 = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Release45|iPhoneSimulator.ActiveCfg = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Release45|iPhoneSimulator.Build.0 = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Release45|x86.ActiveCfg = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Release45|x86.Build.0 = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Release64|Any CPU.ActiveCfg = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Release64|Any CPU.Build.0 = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Release64|iPhone.ActiveCfg = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Release64|iPhone.Build.0 = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Release64|iPhoneSimulator.ActiveCfg = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Release64|iPhoneSimulator.Build.0 = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Release64|x86.ActiveCfg = Release|Any CPU - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4}.Release64|x86.Build.0 = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Ad-Hoc|x86.Build.0 = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.AppStore|Any CPU.ActiveCfg = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.AppStore|Any CPU.Build.0 = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.AppStore|iPhone.ActiveCfg = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.AppStore|iPhone.Build.0 = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.AppStore|x86.ActiveCfg = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.AppStore|x86.Build.0 = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Debug|iPhone.Build.0 = Debug|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Debug|x86.ActiveCfg = Debug|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Debug|x86.Build.0 = Debug|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Debug45|Any CPU.ActiveCfg = Debug|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Debug45|Any CPU.Build.0 = Debug|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Debug45|iPhone.ActiveCfg = Debug|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Debug45|iPhone.Build.0 = Debug|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Debug45|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Debug45|iPhoneSimulator.Build.0 = Debug|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Debug45|x86.ActiveCfg = Debug|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Debug45|x86.Build.0 = Debug|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Release|Any CPU.Build.0 = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Release|iPhone.ActiveCfg = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Release|iPhone.Build.0 = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Release|x86.ActiveCfg = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Release|x86.Build.0 = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Release45|Any CPU.ActiveCfg = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Release45|Any CPU.Build.0 = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Release45|iPhone.ActiveCfg = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Release45|iPhone.Build.0 = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Release45|iPhoneSimulator.ActiveCfg = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Release45|iPhoneSimulator.Build.0 = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Release45|x86.ActiveCfg = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Release45|x86.Build.0 = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Release64|Any CPU.ActiveCfg = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Release64|Any CPU.Build.0 = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Release64|iPhone.ActiveCfg = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Release64|iPhone.Build.0 = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Release64|iPhoneSimulator.ActiveCfg = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Release64|iPhoneSimulator.Build.0 = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Release64|x86.ActiveCfg = Release|Any CPU - {BC10CC51-A795-40D0-96F0-F87585D59D02}.Release64|x86.Build.0 = Release|Any CPU {2E593FCA-B809-4270-9EB2-93F380AF2D6C}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU {2E593FCA-B809-4270-9EB2-93F380AF2D6C}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU {2E593FCA-B809-4270-9EB2-93F380AF2D6C}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU @@ -1214,62 +796,6 @@ Global {C5E5802D-6A45-4FE9-BAE7-5F0AE91D72C1}.Release64|iPhoneSimulator.Build.0 = Release|Any CPU {C5E5802D-6A45-4FE9-BAE7-5F0AE91D72C1}.Release64|x86.ActiveCfg = Release|x86 {C5E5802D-6A45-4FE9-BAE7-5F0AE91D72C1}.Release64|x86.Build.0 = Release|x86 - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Ad-Hoc|x86.Build.0 = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.AppStore|Any CPU.ActiveCfg = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.AppStore|Any CPU.Build.0 = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.AppStore|iPhone.ActiveCfg = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.AppStore|iPhone.Build.0 = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.AppStore|x86.ActiveCfg = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.AppStore|x86.Build.0 = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Debug|iPhone.Build.0 = Debug|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Debug|x86.ActiveCfg = Debug|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Debug|x86.Build.0 = Debug|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Debug45|Any CPU.ActiveCfg = Debug|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Debug45|Any CPU.Build.0 = Debug|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Debug45|iPhone.ActiveCfg = Debug|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Debug45|iPhone.Build.0 = Debug|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Debug45|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Debug45|iPhoneSimulator.Build.0 = Debug|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Debug45|x86.ActiveCfg = Debug|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Debug45|x86.Build.0 = Debug|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Release|Any CPU.Build.0 = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Release|iPhone.ActiveCfg = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Release|iPhone.Build.0 = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Release|x86.ActiveCfg = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Release|x86.Build.0 = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Release45|Any CPU.ActiveCfg = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Release45|Any CPU.Build.0 = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Release45|iPhone.ActiveCfg = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Release45|iPhone.Build.0 = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Release45|iPhoneSimulator.ActiveCfg = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Release45|iPhoneSimulator.Build.0 = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Release45|x86.ActiveCfg = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Release45|x86.Build.0 = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Release64|Any CPU.ActiveCfg = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Release64|Any CPU.Build.0 = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Release64|iPhone.ActiveCfg = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Release64|iPhone.Build.0 = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Release64|iPhoneSimulator.ActiveCfg = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Release64|iPhoneSimulator.Build.0 = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Release64|x86.ActiveCfg = Release|Any CPU - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D}.Release64|x86.Build.0 = Release|Any CPU {466DD2AE-EADC-4E20-82B3-DA6D018006C5}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU {466DD2AE-EADC-4E20-82B3-DA6D018006C5}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU {466DD2AE-EADC-4E20-82B3-DA6D018006C5}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU @@ -1326,454 +852,6 @@ Global {466DD2AE-EADC-4E20-82B3-DA6D018006C5}.Release64|iPhoneSimulator.Build.0 = Release|Any CPU {466DD2AE-EADC-4E20-82B3-DA6D018006C5}.Release64|x86.ActiveCfg = Release|Any CPU {466DD2AE-EADC-4E20-82B3-DA6D018006C5}.Release64|x86.Build.0 = Release|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.AppStore|iPhone.Build.0 = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.AppStore|x86.ActiveCfg = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.AppStore|x86.Build.0 = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Debug|Any CPU.Build.0 = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Debug|iPhone.Build.0 = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Debug|x86.ActiveCfg = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Debug|x86.Build.0 = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Debug45|Any CPU.ActiveCfg = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Debug45|Any CPU.Build.0 = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Debug45|iPhone.ActiveCfg = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Debug45|iPhone.Build.0 = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Debug45|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Debug45|iPhoneSimulator.Build.0 = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Debug45|x86.ActiveCfg = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Debug45|x86.Build.0 = Debug|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Release|Any CPU.ActiveCfg = Release|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Release|Any CPU.Build.0 = Release|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Release|iPhone.ActiveCfg = Release|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Release|iPhone.Build.0 = Release|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Release|x86.ActiveCfg = Release|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Release|x86.Build.0 = Release|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Release45|Any CPU.ActiveCfg = Release|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Release45|Any CPU.Build.0 = Release|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Release45|iPhone.ActiveCfg = Release|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Release45|iPhone.Build.0 = Release|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Release45|iPhoneSimulator.ActiveCfg = Release|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Release45|iPhoneSimulator.Build.0 = Release|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Release45|x86.ActiveCfg = Release|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Release45|x86.Build.0 = Release|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Release64|Any CPU.ActiveCfg = Release|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Release64|Any CPU.Build.0 = Release|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Release64|iPhone.ActiveCfg = Release|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Release64|iPhone.Build.0 = Release|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Release64|iPhoneSimulator.ActiveCfg = Release|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Release64|iPhoneSimulator.Build.0 = Release|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Release64|x86.ActiveCfg = Release|Any CPU - {55C6CCFF-6BF9-45FE-BF86-406100E8D170}.Release64|x86.Build.0 = Release|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.AppStore|iPhone.Build.0 = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.AppStore|x86.ActiveCfg = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.AppStore|x86.Build.0 = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Debug|iPhone.Build.0 = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Debug|x86.ActiveCfg = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Debug|x86.Build.0 = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Debug45|Any CPU.ActiveCfg = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Debug45|Any CPU.Build.0 = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Debug45|iPhone.ActiveCfg = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Debug45|iPhone.Build.0 = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Debug45|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Debug45|iPhoneSimulator.Build.0 = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Debug45|x86.ActiveCfg = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Debug45|x86.Build.0 = Debug|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Release|Any CPU.Build.0 = Release|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Release|iPhone.ActiveCfg = Release|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Release|iPhone.Build.0 = Release|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Release|x86.ActiveCfg = Release|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Release|x86.Build.0 = Release|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Release45|Any CPU.ActiveCfg = Release|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Release45|Any CPU.Build.0 = Release|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Release45|iPhone.ActiveCfg = Release|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Release45|iPhone.Build.0 = Release|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Release45|iPhoneSimulator.ActiveCfg = Release|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Release45|iPhoneSimulator.Build.0 = Release|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Release45|x86.ActiveCfg = Release|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Release45|x86.Build.0 = Release|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Release64|Any CPU.ActiveCfg = Release|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Release64|Any CPU.Build.0 = Release|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Release64|iPhone.ActiveCfg = Release|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Release64|iPhone.Build.0 = Release|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Release64|iPhoneSimulator.ActiveCfg = Release|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Release64|iPhoneSimulator.Build.0 = Release|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Release64|x86.ActiveCfg = Release|Any CPU - {7F481A1E-38F8-484C-960B-45EBB185A00E}.Release64|x86.Build.0 = Release|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.AppStore|iPhone.Build.0 = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.AppStore|x86.ActiveCfg = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.AppStore|x86.Build.0 = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Debug|iPhone.Build.0 = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Debug|x86.ActiveCfg = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Debug|x86.Build.0 = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Debug45|Any CPU.ActiveCfg = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Debug45|Any CPU.Build.0 = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Debug45|iPhone.ActiveCfg = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Debug45|iPhone.Build.0 = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Debug45|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Debug45|iPhoneSimulator.Build.0 = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Debug45|x86.ActiveCfg = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Debug45|x86.Build.0 = Debug|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Release|Any CPU.Build.0 = Release|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Release|iPhone.ActiveCfg = Release|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Release|iPhone.Build.0 = Release|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Release|x86.ActiveCfg = Release|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Release|x86.Build.0 = Release|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Release45|Any CPU.ActiveCfg = Release|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Release45|Any CPU.Build.0 = Release|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Release45|iPhone.ActiveCfg = Release|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Release45|iPhone.Build.0 = Release|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Release45|iPhoneSimulator.ActiveCfg = Release|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Release45|iPhoneSimulator.Build.0 = Release|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Release45|x86.ActiveCfg = Release|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Release45|x86.Build.0 = Release|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Release64|Any CPU.ActiveCfg = Release|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Release64|Any CPU.Build.0 = Release|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Release64|iPhone.ActiveCfg = Release|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Release64|iPhone.Build.0 = Release|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Release64|iPhoneSimulator.ActiveCfg = Release|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Release64|iPhoneSimulator.Build.0 = Release|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Release64|x86.ActiveCfg = Release|Any CPU - {23624298-2E7B-4E44-8FF9-1543CAAB238A}.Release64|x86.Build.0 = Release|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.AppStore|iPhone.Build.0 = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.AppStore|x86.ActiveCfg = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.AppStore|x86.Build.0 = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Debug|Any CPU.Build.0 = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Debug|iPhone.Build.0 = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Debug|x86.ActiveCfg = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Debug|x86.Build.0 = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Debug45|Any CPU.ActiveCfg = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Debug45|Any CPU.Build.0 = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Debug45|iPhone.ActiveCfg = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Debug45|iPhone.Build.0 = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Debug45|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Debug45|iPhoneSimulator.Build.0 = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Debug45|x86.ActiveCfg = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Debug45|x86.Build.0 = Debug|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Release|Any CPU.ActiveCfg = Release|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Release|Any CPU.Build.0 = Release|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Release|iPhone.ActiveCfg = Release|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Release|iPhone.Build.0 = Release|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Release|x86.ActiveCfg = Release|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Release|x86.Build.0 = Release|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Release45|Any CPU.ActiveCfg = Release|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Release45|Any CPU.Build.0 = Release|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Release45|iPhone.ActiveCfg = Release|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Release45|iPhone.Build.0 = Release|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Release45|iPhoneSimulator.ActiveCfg = Release|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Release45|iPhoneSimulator.Build.0 = Release|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Release45|x86.ActiveCfg = Release|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Release45|x86.Build.0 = Release|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Release64|Any CPU.ActiveCfg = Release|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Release64|Any CPU.Build.0 = Release|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Release64|iPhone.ActiveCfg = Release|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Release64|iPhone.Build.0 = Release|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Release64|iPhoneSimulator.ActiveCfg = Release|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Release64|iPhoneSimulator.Build.0 = Release|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Release64|x86.ActiveCfg = Release|Any CPU - {87A39D2B-A539-4077-8488-BB98D67AB660}.Release64|x86.Build.0 = Release|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.AppStore|iPhone.Build.0 = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.AppStore|x86.ActiveCfg = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.AppStore|x86.Build.0 = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Debug|iPhone.Build.0 = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Debug|x86.ActiveCfg = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Debug|x86.Build.0 = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Debug45|Any CPU.ActiveCfg = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Debug45|Any CPU.Build.0 = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Debug45|iPhone.ActiveCfg = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Debug45|iPhone.Build.0 = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Debug45|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Debug45|iPhoneSimulator.Build.0 = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Debug45|x86.ActiveCfg = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Debug45|x86.Build.0 = Debug|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Release|Any CPU.Build.0 = Release|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Release|iPhone.ActiveCfg = Release|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Release|iPhone.Build.0 = Release|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Release|x86.ActiveCfg = Release|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Release|x86.Build.0 = Release|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Release45|Any CPU.ActiveCfg = Release|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Release45|Any CPU.Build.0 = Release|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Release45|iPhone.ActiveCfg = Release|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Release45|iPhone.Build.0 = Release|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Release45|iPhoneSimulator.ActiveCfg = Release|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Release45|iPhoneSimulator.Build.0 = Release|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Release45|x86.ActiveCfg = Release|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Release45|x86.Build.0 = Release|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Release64|Any CPU.ActiveCfg = Release|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Release64|Any CPU.Build.0 = Release|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Release64|iPhone.ActiveCfg = Release|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Release64|iPhone.Build.0 = Release|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Release64|iPhoneSimulator.ActiveCfg = Release|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Release64|iPhoneSimulator.Build.0 = Release|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Release64|x86.ActiveCfg = Release|Any CPU - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C}.Release64|x86.Build.0 = Release|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.AppStore|iPhone.Build.0 = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.AppStore|x86.ActiveCfg = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.AppStore|x86.Build.0 = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Debug|iPhone.Build.0 = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Debug|x86.ActiveCfg = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Debug|x86.Build.0 = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Debug45|Any CPU.ActiveCfg = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Debug45|Any CPU.Build.0 = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Debug45|iPhone.ActiveCfg = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Debug45|iPhone.Build.0 = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Debug45|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Debug45|iPhoneSimulator.Build.0 = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Debug45|x86.ActiveCfg = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Debug45|x86.Build.0 = Debug|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Release|Any CPU.Build.0 = Release|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Release|iPhone.ActiveCfg = Release|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Release|iPhone.Build.0 = Release|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Release|x86.ActiveCfg = Release|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Release|x86.Build.0 = Release|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Release45|Any CPU.ActiveCfg = Release|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Release45|Any CPU.Build.0 = Release|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Release45|iPhone.ActiveCfg = Release|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Release45|iPhone.Build.0 = Release|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Release45|iPhoneSimulator.ActiveCfg = Release|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Release45|iPhoneSimulator.Build.0 = Release|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Release45|x86.ActiveCfg = Release|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Release45|x86.Build.0 = Release|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Release64|Any CPU.ActiveCfg = Release|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Release64|Any CPU.Build.0 = Release|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Release64|iPhone.ActiveCfg = Release|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Release64|iPhone.Build.0 = Release|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Release64|iPhoneSimulator.ActiveCfg = Release|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Release64|iPhoneSimulator.Build.0 = Release|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Release64|x86.ActiveCfg = Release|Any CPU - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1}.Release64|x86.Build.0 = Release|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.AppStore|iPhone.Build.0 = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.AppStore|x86.ActiveCfg = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.AppStore|x86.Build.0 = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Debug|iPhone.Build.0 = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Debug|x86.ActiveCfg = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Debug|x86.Build.0 = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Debug45|Any CPU.ActiveCfg = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Debug45|Any CPU.Build.0 = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Debug45|iPhone.ActiveCfg = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Debug45|iPhone.Build.0 = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Debug45|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Debug45|iPhoneSimulator.Build.0 = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Debug45|x86.ActiveCfg = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Debug45|x86.Build.0 = Debug|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Release|Any CPU.Build.0 = Release|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Release|iPhone.ActiveCfg = Release|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Release|iPhone.Build.0 = Release|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Release|x86.ActiveCfg = Release|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Release|x86.Build.0 = Release|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Release45|Any CPU.ActiveCfg = Release|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Release45|Any CPU.Build.0 = Release|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Release45|iPhone.ActiveCfg = Release|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Release45|iPhone.Build.0 = Release|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Release45|iPhoneSimulator.ActiveCfg = Release|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Release45|iPhoneSimulator.Build.0 = Release|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Release45|x86.ActiveCfg = Release|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Release45|x86.Build.0 = Release|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Release64|Any CPU.ActiveCfg = Release|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Release64|Any CPU.Build.0 = Release|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Release64|iPhone.ActiveCfg = Release|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Release64|iPhone.Build.0 = Release|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Release64|iPhoneSimulator.ActiveCfg = Release|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Release64|iPhoneSimulator.Build.0 = Release|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Release64|x86.ActiveCfg = Release|Any CPU - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A}.Release64|x86.Build.0 = Release|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.AppStore|iPhone.Build.0 = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.AppStore|x86.ActiveCfg = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.AppStore|x86.Build.0 = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Debug|iPhone.Build.0 = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Debug|x86.ActiveCfg = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Debug|x86.Build.0 = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Debug45|Any CPU.ActiveCfg = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Debug45|Any CPU.Build.0 = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Debug45|iPhone.ActiveCfg = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Debug45|iPhone.Build.0 = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Debug45|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Debug45|iPhoneSimulator.Build.0 = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Debug45|x86.ActiveCfg = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Debug45|x86.Build.0 = Debug|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Release|Any CPU.Build.0 = Release|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Release|iPhone.ActiveCfg = Release|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Release|iPhone.Build.0 = Release|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Release|x86.ActiveCfg = Release|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Release|x86.Build.0 = Release|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Release45|Any CPU.ActiveCfg = Release|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Release45|Any CPU.Build.0 = Release|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Release45|iPhone.ActiveCfg = Release|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Release45|iPhone.Build.0 = Release|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Release45|iPhoneSimulator.ActiveCfg = Release|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Release45|iPhoneSimulator.Build.0 = Release|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Release45|x86.ActiveCfg = Release|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Release45|x86.Build.0 = Release|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Release64|Any CPU.ActiveCfg = Release|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Release64|Any CPU.Build.0 = Release|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Release64|iPhone.ActiveCfg = Release|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Release64|iPhone.Build.0 = Release|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Release64|iPhoneSimulator.ActiveCfg = Release|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Release64|iPhoneSimulator.Build.0 = Release|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Release64|x86.ActiveCfg = Release|Any CPU - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9}.Release64|x86.Build.0 = Release|Any CPU {91ACD6FC-E152-41EB-BACA-F0AA283FA201}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU {91ACD6FC-E152-41EB-BACA-F0AA283FA201}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU {91ACD6FC-E152-41EB-BACA-F0AA283FA201}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU @@ -1914,6 +992,622 @@ Global {B824FFB2-D057-490A-8967-892C0E20C0B6}.Release64|x86.ActiveCfg = Release|Any CPU {B824FFB2-D057-490A-8967-892C0E20C0B6}.Release64|x86.Build.0 = Release|Any CPU {B824FFB2-D057-490A-8967-892C0E20C0B6}.Release64|x86.Deploy.0 = Release|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.AppStore|iPhone.Build.0 = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.AppStore|x86.ActiveCfg = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.AppStore|x86.Build.0 = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Debug|iPhone.Build.0 = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Debug|x86.ActiveCfg = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Debug|x86.Build.0 = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Debug45|Any CPU.ActiveCfg = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Debug45|Any CPU.Build.0 = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Debug45|iPhone.ActiveCfg = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Debug45|iPhone.Build.0 = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Debug45|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Debug45|iPhoneSimulator.Build.0 = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Debug45|x86.ActiveCfg = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Debug45|x86.Build.0 = Debug|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Release|Any CPU.Build.0 = Release|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Release|iPhone.ActiveCfg = Release|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Release|iPhone.Build.0 = Release|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Release|x86.ActiveCfg = Release|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Release|x86.Build.0 = Release|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Release45|Any CPU.ActiveCfg = Release|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Release45|Any CPU.Build.0 = Release|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Release45|iPhone.ActiveCfg = Release|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Release45|iPhone.Build.0 = Release|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Release45|iPhoneSimulator.ActiveCfg = Release|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Release45|iPhoneSimulator.Build.0 = Release|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Release45|x86.ActiveCfg = Release|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Release45|x86.Build.0 = Release|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Release64|Any CPU.ActiveCfg = Release|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Release64|Any CPU.Build.0 = Release|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Release64|iPhone.ActiveCfg = Release|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Release64|iPhone.Build.0 = Release|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Release64|iPhoneSimulator.ActiveCfg = Release|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Release64|iPhoneSimulator.Build.0 = Release|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Release64|x86.ActiveCfg = Release|Any CPU + {D4037FB8-0349-41B9-A0BF-8E6052D34D75}.Release64|x86.Build.0 = Release|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.AppStore|iPhone.Build.0 = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.AppStore|x86.ActiveCfg = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.AppStore|x86.Build.0 = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Debug|iPhone.Build.0 = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Debug|x86.ActiveCfg = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Debug|x86.Build.0 = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Debug45|Any CPU.ActiveCfg = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Debug45|Any CPU.Build.0 = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Debug45|iPhone.ActiveCfg = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Debug45|iPhone.Build.0 = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Debug45|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Debug45|iPhoneSimulator.Build.0 = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Debug45|x86.ActiveCfg = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Debug45|x86.Build.0 = Debug|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Release|Any CPU.Build.0 = Release|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Release|iPhone.ActiveCfg = Release|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Release|iPhone.Build.0 = Release|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Release|x86.ActiveCfg = Release|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Release|x86.Build.0 = Release|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Release45|Any CPU.ActiveCfg = Release|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Release45|Any CPU.Build.0 = Release|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Release45|iPhone.ActiveCfg = Release|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Release45|iPhone.Build.0 = Release|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Release45|iPhoneSimulator.ActiveCfg = Release|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Release45|iPhoneSimulator.Build.0 = Release|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Release45|x86.ActiveCfg = Release|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Release45|x86.Build.0 = Release|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Release64|Any CPU.ActiveCfg = Release|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Release64|Any CPU.Build.0 = Release|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Release64|iPhone.ActiveCfg = Release|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Release64|iPhone.Build.0 = Release|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Release64|iPhoneSimulator.ActiveCfg = Release|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Release64|iPhoneSimulator.Build.0 = Release|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Release64|x86.ActiveCfg = Release|Any CPU + {1E687C41-4086-44C1-9A64-8122925A48AF}.Release64|x86.Build.0 = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Ad-Hoc|x86.Build.0 = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.AppStore|Any CPU.ActiveCfg = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.AppStore|Any CPU.Build.0 = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.AppStore|iPhone.ActiveCfg = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.AppStore|iPhone.Build.0 = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.AppStore|x86.ActiveCfg = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.AppStore|x86.Build.0 = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Debug|iPhone.Build.0 = Debug|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Debug|x86.ActiveCfg = Debug|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Debug|x86.Build.0 = Debug|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Debug45|Any CPU.ActiveCfg = Debug|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Debug45|Any CPU.Build.0 = Debug|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Debug45|iPhone.ActiveCfg = Debug|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Debug45|iPhone.Build.0 = Debug|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Debug45|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Debug45|iPhoneSimulator.Build.0 = Debug|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Debug45|x86.ActiveCfg = Debug|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Debug45|x86.Build.0 = Debug|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Release|Any CPU.Build.0 = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Release|iPhone.ActiveCfg = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Release|iPhone.Build.0 = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Release|x86.ActiveCfg = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Release|x86.Build.0 = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Release45|Any CPU.ActiveCfg = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Release45|Any CPU.Build.0 = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Release45|iPhone.ActiveCfg = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Release45|iPhone.Build.0 = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Release45|iPhoneSimulator.ActiveCfg = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Release45|iPhoneSimulator.Build.0 = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Release45|x86.ActiveCfg = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Release45|x86.Build.0 = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Release64|Any CPU.ActiveCfg = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Release64|Any CPU.Build.0 = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Release64|iPhone.ActiveCfg = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Release64|iPhone.Build.0 = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Release64|iPhoneSimulator.ActiveCfg = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Release64|iPhoneSimulator.Build.0 = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Release64|x86.ActiveCfg = Release|Any CPU + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D}.Release64|x86.Build.0 = Release|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.AppStore|iPhone.Build.0 = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.AppStore|x86.ActiveCfg = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.AppStore|x86.Build.0 = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Debug|iPhone.Build.0 = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Debug|x86.ActiveCfg = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Debug|x86.Build.0 = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Debug45|Any CPU.ActiveCfg = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Debug45|Any CPU.Build.0 = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Debug45|iPhone.ActiveCfg = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Debug45|iPhone.Build.0 = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Debug45|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Debug45|iPhoneSimulator.Build.0 = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Debug45|x86.ActiveCfg = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Debug45|x86.Build.0 = Debug|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Release|Any CPU.Build.0 = Release|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Release|iPhone.ActiveCfg = Release|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Release|iPhone.Build.0 = Release|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Release|x86.ActiveCfg = Release|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Release|x86.Build.0 = Release|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Release45|Any CPU.ActiveCfg = Release|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Release45|Any CPU.Build.0 = Release|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Release45|iPhone.ActiveCfg = Release|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Release45|iPhone.Build.0 = Release|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Release45|iPhoneSimulator.ActiveCfg = Release|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Release45|iPhoneSimulator.Build.0 = Release|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Release45|x86.ActiveCfg = Release|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Release45|x86.Build.0 = Release|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Release64|Any CPU.ActiveCfg = Release|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Release64|Any CPU.Build.0 = Release|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Release64|iPhone.ActiveCfg = Release|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Release64|iPhone.Build.0 = Release|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Release64|iPhoneSimulator.ActiveCfg = Release|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Release64|iPhoneSimulator.Build.0 = Release|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Release64|x86.ActiveCfg = Release|Any CPU + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF}.Release64|x86.Build.0 = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Ad-Hoc|x86.Build.0 = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.AppStore|Any CPU.ActiveCfg = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.AppStore|Any CPU.Build.0 = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.AppStore|iPhone.ActiveCfg = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.AppStore|iPhone.Build.0 = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.AppStore|x86.ActiveCfg = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.AppStore|x86.Build.0 = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Debug|iPhone.Build.0 = Debug|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Debug|x86.ActiveCfg = Debug|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Debug|x86.Build.0 = Debug|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Debug45|Any CPU.ActiveCfg = Debug|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Debug45|Any CPU.Build.0 = Debug|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Debug45|iPhone.ActiveCfg = Debug|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Debug45|iPhone.Build.0 = Debug|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Debug45|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Debug45|iPhoneSimulator.Build.0 = Debug|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Debug45|x86.ActiveCfg = Debug|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Debug45|x86.Build.0 = Debug|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Release|Any CPU.Build.0 = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Release|iPhone.ActiveCfg = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Release|iPhone.Build.0 = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Release|x86.ActiveCfg = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Release|x86.Build.0 = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Release45|Any CPU.ActiveCfg = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Release45|Any CPU.Build.0 = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Release45|iPhone.ActiveCfg = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Release45|iPhone.Build.0 = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Release45|iPhoneSimulator.ActiveCfg = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Release45|iPhoneSimulator.Build.0 = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Release45|x86.ActiveCfg = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Release45|x86.Build.0 = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Release64|Any CPU.ActiveCfg = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Release64|Any CPU.Build.0 = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Release64|iPhone.ActiveCfg = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Release64|iPhone.Build.0 = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Release64|iPhoneSimulator.ActiveCfg = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Release64|iPhoneSimulator.Build.0 = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Release64|x86.ActiveCfg = Release|Any CPU + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C}.Release64|x86.Build.0 = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Ad-Hoc|x86.Build.0 = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.AppStore|Any CPU.ActiveCfg = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.AppStore|Any CPU.Build.0 = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.AppStore|iPhone.ActiveCfg = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.AppStore|iPhone.Build.0 = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.AppStore|x86.ActiveCfg = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.AppStore|x86.Build.0 = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Debug|iPhone.Build.0 = Debug|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Debug|x86.ActiveCfg = Debug|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Debug|x86.Build.0 = Debug|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Debug45|Any CPU.ActiveCfg = Debug|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Debug45|Any CPU.Build.0 = Debug|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Debug45|iPhone.ActiveCfg = Debug|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Debug45|iPhone.Build.0 = Debug|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Debug45|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Debug45|iPhoneSimulator.Build.0 = Debug|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Debug45|x86.ActiveCfg = Debug|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Debug45|x86.Build.0 = Debug|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Release|Any CPU.Build.0 = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Release|iPhone.ActiveCfg = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Release|iPhone.Build.0 = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Release|x86.ActiveCfg = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Release|x86.Build.0 = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Release45|Any CPU.ActiveCfg = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Release45|Any CPU.Build.0 = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Release45|iPhone.ActiveCfg = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Release45|iPhone.Build.0 = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Release45|iPhoneSimulator.ActiveCfg = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Release45|iPhoneSimulator.Build.0 = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Release45|x86.ActiveCfg = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Release45|x86.Build.0 = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Release64|Any CPU.ActiveCfg = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Release64|Any CPU.Build.0 = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Release64|iPhone.ActiveCfg = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Release64|iPhone.Build.0 = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Release64|iPhoneSimulator.ActiveCfg = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Release64|iPhoneSimulator.Build.0 = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Release64|x86.ActiveCfg = Release|Any CPU + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A}.Release64|x86.Build.0 = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Ad-Hoc|x86.Build.0 = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.AppStore|Any CPU.ActiveCfg = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.AppStore|Any CPU.Build.0 = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.AppStore|iPhone.ActiveCfg = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.AppStore|iPhone.Build.0 = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.AppStore|x86.ActiveCfg = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.AppStore|x86.Build.0 = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Debug|iPhone.Build.0 = Debug|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Debug|x86.ActiveCfg = Debug|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Debug|x86.Build.0 = Debug|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Debug45|Any CPU.ActiveCfg = Debug|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Debug45|Any CPU.Build.0 = Debug|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Debug45|iPhone.ActiveCfg = Debug|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Debug45|iPhone.Build.0 = Debug|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Debug45|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Debug45|iPhoneSimulator.Build.0 = Debug|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Debug45|x86.ActiveCfg = Debug|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Debug45|x86.Build.0 = Debug|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Release|Any CPU.Build.0 = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Release|iPhone.ActiveCfg = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Release|iPhone.Build.0 = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Release|x86.ActiveCfg = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Release|x86.Build.0 = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Release45|Any CPU.ActiveCfg = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Release45|Any CPU.Build.0 = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Release45|iPhone.ActiveCfg = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Release45|iPhone.Build.0 = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Release45|iPhoneSimulator.ActiveCfg = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Release45|iPhoneSimulator.Build.0 = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Release45|x86.ActiveCfg = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Release45|x86.Build.0 = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Release64|Any CPU.ActiveCfg = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Release64|Any CPU.Build.0 = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Release64|iPhone.ActiveCfg = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Release64|iPhone.Build.0 = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Release64|iPhoneSimulator.ActiveCfg = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Release64|iPhoneSimulator.Build.0 = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Release64|x86.ActiveCfg = Release|Any CPU + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD}.Release64|x86.Build.0 = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Ad-Hoc|x86.Build.0 = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.AppStore|Any CPU.ActiveCfg = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.AppStore|Any CPU.Build.0 = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.AppStore|iPhone.ActiveCfg = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.AppStore|iPhone.Build.0 = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.AppStore|x86.ActiveCfg = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.AppStore|x86.Build.0 = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Debug|iPhone.Build.0 = Debug|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Debug|x86.ActiveCfg = Debug|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Debug|x86.Build.0 = Debug|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Debug45|Any CPU.ActiveCfg = Debug|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Debug45|Any CPU.Build.0 = Debug|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Debug45|iPhone.ActiveCfg = Debug|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Debug45|iPhone.Build.0 = Debug|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Debug45|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Debug45|iPhoneSimulator.Build.0 = Debug|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Debug45|x86.ActiveCfg = Debug|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Debug45|x86.Build.0 = Debug|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Release|Any CPU.Build.0 = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Release|iPhone.ActiveCfg = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Release|iPhone.Build.0 = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Release|x86.ActiveCfg = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Release|x86.Build.0 = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Release45|Any CPU.ActiveCfg = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Release45|Any CPU.Build.0 = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Release45|iPhone.ActiveCfg = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Release45|iPhone.Build.0 = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Release45|iPhoneSimulator.ActiveCfg = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Release45|iPhoneSimulator.Build.0 = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Release45|x86.ActiveCfg = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Release45|x86.Build.0 = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Release64|Any CPU.ActiveCfg = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Release64|Any CPU.Build.0 = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Release64|iPhone.ActiveCfg = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Release64|iPhone.Build.0 = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Release64|iPhoneSimulator.ActiveCfg = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Release64|iPhoneSimulator.Build.0 = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Release64|x86.ActiveCfg = Release|Any CPU + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0}.Release64|x86.Build.0 = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Ad-Hoc|x86.Build.0 = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.AppStore|Any CPU.ActiveCfg = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.AppStore|Any CPU.Build.0 = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.AppStore|iPhone.ActiveCfg = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.AppStore|iPhone.Build.0 = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.AppStore|x86.ActiveCfg = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.AppStore|x86.Build.0 = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Debug|Any CPU.Build.0 = Debug|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Debug|iPhone.Build.0 = Debug|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Debug|x86.ActiveCfg = Debug|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Debug|x86.Build.0 = Debug|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Debug45|Any CPU.ActiveCfg = Debug|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Debug45|Any CPU.Build.0 = Debug|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Debug45|iPhone.ActiveCfg = Debug|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Debug45|iPhone.Build.0 = Debug|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Debug45|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Debug45|iPhoneSimulator.Build.0 = Debug|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Debug45|x86.ActiveCfg = Debug|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Debug45|x86.Build.0 = Debug|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Release|Any CPU.ActiveCfg = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Release|Any CPU.Build.0 = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Release|iPhone.ActiveCfg = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Release|iPhone.Build.0 = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Release|x86.ActiveCfg = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Release|x86.Build.0 = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Release45|Any CPU.ActiveCfg = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Release45|Any CPU.Build.0 = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Release45|iPhone.ActiveCfg = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Release45|iPhone.Build.0 = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Release45|iPhoneSimulator.ActiveCfg = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Release45|iPhoneSimulator.Build.0 = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Release45|x86.ActiveCfg = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Release45|x86.Build.0 = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Release64|Any CPU.ActiveCfg = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Release64|Any CPU.Build.0 = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Release64|iPhone.ActiveCfg = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Release64|iPhone.Build.0 = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Release64|iPhoneSimulator.ActiveCfg = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Release64|iPhoneSimulator.Build.0 = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Release64|x86.ActiveCfg = Release|Any CPU + {49F57B62-B937-4715-9CF5-E5431D049D56}.Release64|x86.Build.0 = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Ad-Hoc|x86.Build.0 = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.AppStore|Any CPU.ActiveCfg = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.AppStore|Any CPU.Build.0 = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.AppStore|iPhone.ActiveCfg = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.AppStore|iPhone.Build.0 = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.AppStore|x86.ActiveCfg = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.AppStore|x86.Build.0 = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Debug|iPhone.Build.0 = Debug|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Debug|x86.ActiveCfg = Debug|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Debug|x86.Build.0 = Debug|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Debug45|Any CPU.ActiveCfg = Debug|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Debug45|Any CPU.Build.0 = Debug|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Debug45|iPhone.ActiveCfg = Debug|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Debug45|iPhone.Build.0 = Debug|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Debug45|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Debug45|iPhoneSimulator.Build.0 = Debug|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Debug45|x86.ActiveCfg = Debug|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Debug45|x86.Build.0 = Debug|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Release|Any CPU.Build.0 = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Release|iPhone.ActiveCfg = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Release|iPhone.Build.0 = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Release|x86.ActiveCfg = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Release|x86.Build.0 = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Release45|Any CPU.ActiveCfg = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Release45|Any CPU.Build.0 = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Release45|iPhone.ActiveCfg = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Release45|iPhone.Build.0 = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Release45|iPhoneSimulator.ActiveCfg = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Release45|iPhoneSimulator.Build.0 = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Release45|x86.ActiveCfg = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Release45|x86.Build.0 = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Release64|Any CPU.ActiveCfg = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Release64|Any CPU.Build.0 = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Release64|iPhone.ActiveCfg = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Release64|iPhone.Build.0 = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Release64|iPhoneSimulator.ActiveCfg = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Release64|iPhoneSimulator.Build.0 = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Release64|x86.ActiveCfg = Release|Any CPU + {9C359551-463A-4D62-A6AE-EA72F41A7AEB}.Release64|x86.Build.0 = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Ad-Hoc|x86.Build.0 = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.AppStore|Any CPU.ActiveCfg = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.AppStore|Any CPU.Build.0 = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.AppStore|iPhone.ActiveCfg = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.AppStore|iPhone.Build.0 = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.AppStore|x86.ActiveCfg = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.AppStore|x86.Build.0 = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Debug|Any CPU.Build.0 = Debug|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Debug|iPhone.Build.0 = Debug|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Debug|x86.ActiveCfg = Debug|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Debug|x86.Build.0 = Debug|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Debug45|Any CPU.ActiveCfg = Debug|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Debug45|Any CPU.Build.0 = Debug|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Debug45|iPhone.ActiveCfg = Debug|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Debug45|iPhone.Build.0 = Debug|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Debug45|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Debug45|iPhoneSimulator.Build.0 = Debug|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Debug45|x86.ActiveCfg = Debug|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Debug45|x86.Build.0 = Debug|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Release|Any CPU.ActiveCfg = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Release|Any CPU.Build.0 = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Release|iPhone.ActiveCfg = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Release|iPhone.Build.0 = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Release|x86.ActiveCfg = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Release|x86.Build.0 = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Release45|Any CPU.ActiveCfg = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Release45|Any CPU.Build.0 = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Release45|iPhone.ActiveCfg = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Release45|iPhone.Build.0 = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Release45|iPhoneSimulator.ActiveCfg = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Release45|iPhoneSimulator.Build.0 = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Release45|x86.ActiveCfg = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Release45|x86.Build.0 = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Release64|Any CPU.ActiveCfg = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Release64|Any CPU.Build.0 = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Release64|iPhone.ActiveCfg = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Release64|iPhone.Build.0 = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Release64|iPhoneSimulator.ActiveCfg = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Release64|iPhoneSimulator.Build.0 = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Release64|x86.ActiveCfg = Release|Any CPU + {51D63482-5697-4B16-8401-506965624657}.Release64|x86.Build.0 = Release|Any CPU {A533E1C7-AB74-4BCF-BC7A-12D4DBBFA918}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU {A533E1C7-AB74-4BCF-BC7A-12D4DBBFA918}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU {A533E1C7-AB74-4BCF-BC7A-12D4DBBFA918}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU @@ -1983,14 +1677,10 @@ Global {923533FC-73FF-4E89-9F1F-ED26F12AFA33} = {EFD3FB30-FFF6-4717-9D2A-A909E6D01DEE} {235A071B-8D06-40AE-A5C5-B1CE59715EE9} = {EDF760BE-F3FA-4361-AFFA-5CB70A3E9E55} {D8861CF8-C506-472B-8A57-632BD6CA6496} = {EDF760BE-F3FA-4361-AFFA-5CB70A3E9E55} - {189B365C-127C-4377-88F3-C3D391B43993} = {CCC8D030-3F27-4560-B290-B95F4022DDB8} - {F7D71E61-9342-4DD7-9AFD-69045F2EC98B} = {189B365C-127C-4377-88F3-C3D391B43993} - {C6807D05-09BE-4313-9F8B-BD2D51C55819} = {189B365C-127C-4377-88F3-C3D391B43993} {A09B4BF0-2C5E-42E9-B23C-AFD0B5A8697D} = {923533FC-73FF-4E89-9F1F-ED26F12AFA33} {56DCAE82-671D-409E-A3B3-BF4834756D3F} = {B3080145-1DA3-4FCA-A0E5-D99A46F6B243} {7E00196D-3E47-412A-8F1D-41DF082502F0} = {B3080145-1DA3-4FCA-A0E5-D99A46F6B243} {2E1E828F-6D2C-4B0E-A2E2-DDF24798CACF} = {EFD3FB30-FFF6-4717-9D2A-A909E6D01DEE} - {FB5F78F5-C921-405D-8F21-42F7C15C2AD9} = {189B365C-127C-4377-88F3-C3D391B43993} {540A2EA6-DAE3-4625-8951-B2C3118603A4} = {C4F7BE3A-77E3-4B10-A6AB-839CBCCF5163} {9D2F3501-7705-4401-BE13-A7613CA0C4BD} = {C4F7BE3A-77E3-4B10-A6AB-839CBCCF5163} {6C9262B6-F6DD-4C42-A3EF-D8574B324E7A} = {C4F7BE3A-77E3-4B10-A6AB-839CBCCF5163} @@ -1999,28 +1689,24 @@ Global {9A99F103-B119-4A4D-8093-6A03BAA6D36B} = {EDF760BE-F3FA-4361-AFFA-5CB70A3E9E55} {7A8A63D2-2CB5-41F5-8E83-6F6E54398CF4} = {EDF760BE-F3FA-4361-AFFA-5CB70A3E9E55} {D07686EE-2618-4C20-8EB5-32AD4C4D3810} = {EDF760BE-F3FA-4361-AFFA-5CB70A3E9E55} - {9A3B8B84-56BE-4AA1-8D90-1B3B3FEF1F71} = {189B365C-127C-4377-88F3-C3D391B43993} - {333F3209-8DA9-4D33-A560-299ED4C6DFA5} = {189B365C-127C-4377-88F3-C3D391B43993} - {6B0E034B-0EBD-4907-AD7F-437DE66D78D4} = {189B365C-127C-4377-88F3-C3D391B43993} - {BC10CC51-A795-40D0-96F0-F87585D59D02} = {189B365C-127C-4377-88F3-C3D391B43993} {2E593FCA-B809-4270-9EB2-93F380AF2D6C} = {548A7FB1-834E-4197-B0BB-E32BF886D511} {C5E5802D-6A45-4FE9-BAE7-5F0AE91D72C1} = {C4F7BE3A-77E3-4B10-A6AB-839CBCCF5163} {4F435DA3-706A-4E6D-AE29-E1E95BD6F68A} = {C4F7BE3A-77E3-4B10-A6AB-839CBCCF5163} {CE0D5C56-C9DA-4F22-9AD8-3677D0E034A4} = {C4F7BE3A-77E3-4B10-A6AB-839CBCCF5163} - {901A60ED-BAEF-45F6-8919-6E07EE6BAD8D} = {189B365C-127C-4377-88F3-C3D391B43993} {466DD2AE-EADC-4E20-82B3-DA6D018006C5} = {C4F7BE3A-77E3-4B10-A6AB-839CBCCF5163} - {55C6CCFF-6BF9-45FE-BF86-406100E8D170} = {8DD7A804-99D0-41EE-9546-21E5A89223A2} - {8DD7A804-99D0-41EE-9546-21E5A89223A2} = {CCC8D030-3F27-4560-B290-B95F4022DDB8} - {7F481A1E-38F8-484C-960B-45EBB185A00E} = {8DD7A804-99D0-41EE-9546-21E5A89223A2} - {23624298-2E7B-4E44-8FF9-1543CAAB238A} = {8DD7A804-99D0-41EE-9546-21E5A89223A2} - {87A39D2B-A539-4077-8488-BB98D67AB660} = {8DD7A804-99D0-41EE-9546-21E5A89223A2} - {6C5F8D13-5D4E-405B-9BF2-F4C9E5AA405C} = {8DD7A804-99D0-41EE-9546-21E5A89223A2} - {9B1D6D45-7A2F-4ED1-95A6-54B3B892BBD1} = {8DD7A804-99D0-41EE-9546-21E5A89223A2} - {40D0DBFA-6427-478F-83B0-DAA0F0A8014A} = {8DD7A804-99D0-41EE-9546-21E5A89223A2} - {46EDD385-59F7-4402-A023-9314C55471BB} = {CCC8D030-3F27-4560-B290-B95F4022DDB8} - {95E23DEE-0AAA-4F93-94DD-A18AB84625F9} = {46EDD385-59F7-4402-A023-9314C55471BB} {91ACD6FC-E152-41EB-BACA-F0AA283FA201} = {B3080145-1DA3-4FCA-A0E5-D99A46F6B243} {B824FFB2-D057-490A-8967-892C0E20C0B6} = {2257F500-B273-4E78-851F-6188D639B6A6} + {D4037FB8-0349-41B9-A0BF-8E6052D34D75} = {CCC8D030-3F27-4560-B290-B95F4022DDB8} + {1E687C41-4086-44C1-9A64-8122925A48AF} = {CCC8D030-3F27-4560-B290-B95F4022DDB8} + {0E1CAB21-DA5B-4539-8BD6-3036CE29102D} = {CCC8D030-3F27-4560-B290-B95F4022DDB8} + {25F0BD32-E312-4060-A6B5-9EF76FF1C4DF} = {CCC8D030-3F27-4560-B290-B95F4022DDB8} + {22A6EFD2-D92E-448F-8459-8EB66D1AF15C} = {CCC8D030-3F27-4560-B290-B95F4022DDB8} + {DC8EE8CC-8882-4DE5-8405-B7452F83B30A} = {CCC8D030-3F27-4560-B290-B95F4022DDB8} + {65B22280-ED4D-43A2-947C-BBFAB44AD8FD} = {CCC8D030-3F27-4560-B290-B95F4022DDB8} + {6FAF0AD2-22F1-46D9-ADE4-ECE3FA670BD0} = {CCC8D030-3F27-4560-B290-B95F4022DDB8} + {49F57B62-B937-4715-9CF5-E5431D049D56} = {CCC8D030-3F27-4560-B290-B95F4022DDB8} + {9C359551-463A-4D62-A6AE-EA72F41A7AEB} = {CCC8D030-3F27-4560-B290-B95F4022DDB8} + {51D63482-5697-4B16-8401-506965624657} = {C4F7BE3A-77E3-4B10-A6AB-839CBCCF5163} {A533E1C7-AB74-4BCF-BC7A-12D4DBBFA918} = {C4F7BE3A-77E3-4B10-A6AB-839CBCCF5163} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution diff --git a/x_autogen_netstandard2.0/PixelFarm.MiniAgg.One/PixelFarm.MiniAgg.One.csproj b/x_autogen_netstandard2.0/PixelFarm.MiniAgg.One/PixelFarm.MiniAgg.One.csproj deleted file mode 100644 index 2768c315..00000000 --- a/x_autogen_netstandard2.0/PixelFarm.MiniAgg.One/PixelFarm.MiniAgg.One.csproj +++ /dev/null @@ -1,305 +0,0 @@ - - - netstandard2.0 - - - Debug - AnyCPU - 2.0 - Library - 512 - PixelFarm.MiniAgg.One - - - true - prompt - 4 - bin\Debug\ - false - full - true - TRACE; DEBUG; PIXEL_FARM; PIXEL_FARM_NET20; - - - true - prompt - 4 - bin\Release\ - true - pdbonly - TRACE; PIXEL_FARM; PIXEL_FARM_NET20; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file