From 0070234c446b2f17f559507e34556efbe50f5655 Mon Sep 17 00:00:00 2001 From: Fast Reports Date: Tue, 10 Sep 2019 13:06:27 +0300 Subject: [PATCH] * sync 9/10/2019 --- Demos/Reports/Polygon.frx | 29 +- ...t.OpenSource.Export.PdfSimple.Tests.csproj | 3 + .../PdfSimpleExportTests.cs | 10 + .../Watermark.fpx | Bin 0 -> 107700 bytes FastReport.Base/AssemblyInitializer.cs | 6 + FastReport.Base/BandBase.cs | 15 + FastReport.Base/Code/AssemblyDescriptor.cs | 2 +- FastReport.Base/Data/DataConnectionBase.cs | 4 +- FastReport.Base/Data/DataSourceBase.cs | 2 +- .../JsonDataSourceConnection.cs | 259 +++++ .../JsonDataSourceConnectionStringBuilder.cs | 96 ++ .../JsonConnection/JsonParser/JsonArray.cs | 110 ++ .../JsonConnection/JsonParser/JsonBase.cs | 576 ++++++++++ .../JsonConnection/JsonParser/JsonObject.cs | 118 ++ .../JsonConnection/JsonParser/JsonSchema.cs | 233 ++++ .../JsonParser/JsonTextReader.cs | 148 +++ .../JsonConnection/JsonTableDataSource.cs | 352 ++++++ FastReport.Base/Engine/ReportEngine.Bands.cs | 6 +- .../Engine/ReportEngine.PageNumbers.cs | 29 +- FastReport.Base/Engine/ReportEngine.Pages.cs | 16 +- FastReport.Base/Export/Html/HTMLExport.cs | 14 + FastReport.Base/Export/Html/HTMLExportDraw.cs | 18 +- .../Export/Html/HTMLExportLayers.cs | 85 +- .../Export/Html/HTMLExportUtils.cs | 3 - FastReport.Base/Gauge/GaugeLabel.cs | 2 +- FastReport.Base/Gauge/GaugeScale.cs | 2 +- FastReport.Base/GroupHeaderBand.cs | 2 +- FastReport.Base/PictureObject.cs | 4 +- FastReport.Base/PictureObjectBase.cs | 4 +- FastReport.Base/PolyLineObject.cs | 1010 +++++++++++++---- FastReport.Base/PolygonObject.cs | 10 +- FastReport.Base/Report.cs | 65 +- FastReport.Base/StyleBase.cs | 2 +- FastReport.Base/Table/TableResult.cs | 6 +- FastReport.Base/TextObject.cs | 32 +- FastReport.Base/Utils/CompileHelper.cs | 2 +- FastReport.Base/Utils/Config.cs | 16 +- FastReport.Base/Utils/Converter.cs | 16 +- FastReport.Base/Utils/DrawUtils.Win32.cs | 2 +- FastReport.Base/Utils/FRReader.cs | 8 +- FastReport.Base/Utils/ImageHelper.cs | 6 + FastReport.Base/Utils/MyEncodingInfo.cs | 109 ++ FastReport.Base/Utils/Res.cs | 6 +- FastReport.Base/Utils/Xml.cs | 3 +- FastReport.Base/Watermark.cs | 2 +- .../Application/WebReportDesigner.cs | 4 +- .../DotNetClasses/CSharpCodeProvider.cs | 6 +- .../DotNetClasses/CodeDomProvider.cs | 8 +- .../DotNetClasses/CodeGenerator.cs | 4 +- .../DotNetClasses/Color.Core.cs | 556 ++++++++- .../DotNetClasses/Color.Full.cs | 2 +- .../DotNetClasses/ColorConverter.cs | 4 +- .../DotNetClasses/ColorTranslator.cs | 340 +++--- .../DotNetClasses/CompilerError.cs | 5 +- .../DotNetClasses/CompilerParameters.cs | 5 +- .../DotNetClasses/CompilerResults.cs | 5 +- .../DotNetClasses/SystemColors.cs | 5 +- .../DotNetClasses/TempFileCollection.cs | 5 +- .../DotNetClasses/UITypeEditor.cs | 10 + .../DotNetClasses/VBCodeProvider.cs | 6 +- .../WindowsFormsReplacement.BindingSource.cs | 3 + ...ndowsFormsReplacement.ListBindingHelper.cs | 2 + .../DotNetClasses/WindowsFormsReplacement.cs | 4 +- .../FastReport.OpenSource.csproj | 16 +- .../TypeConverters/FontConverter.cs | 386 +++++++ FastReport/Resources/buttons.png | Bin 70757 -> 63401 bytes FastReport/Resources/en.xml | 22 +- .../Data/JsonConnectionTests.cs | 175 +++ .../FastReport.Tests.OpenSource.csproj | 2 +- 69 files changed, 4474 insertions(+), 544 deletions(-) create mode 100644 Extras/OpenSource/FastReport.OpenSource.Export.PdfSimple/FastReport.OpenSource.Export.PdfSimple.Tests/Watermark.fpx create mode 100644 FastReport.Base/Data/JsonConnection/JsonDataSourceConnection.cs create mode 100644 FastReport.Base/Data/JsonConnection/JsonDataSourceConnectionStringBuilder.cs create mode 100644 FastReport.Base/Data/JsonConnection/JsonParser/JsonArray.cs create mode 100644 FastReport.Base/Data/JsonConnection/JsonParser/JsonBase.cs create mode 100644 FastReport.Base/Data/JsonConnection/JsonParser/JsonObject.cs create mode 100644 FastReport.Base/Data/JsonConnection/JsonParser/JsonSchema.cs create mode 100644 FastReport.Base/Data/JsonConnection/JsonParser/JsonTextReader.cs create mode 100644 FastReport.Base/Data/JsonConnection/JsonTableDataSource.cs create mode 100644 FastReport.Base/Utils/MyEncodingInfo.cs create mode 100644 FastReport.OpenSource/DotNetClasses/UITypeEditor.cs create mode 100644 FastReport.OpenSource/TypeConverters/FontConverter.cs create mode 100644 Tools/FastReport.Tests.OpenSource/Data/JsonConnectionTests.cs diff --git a/Demos/Reports/Polygon.frx b/Demos/Reports/Polygon.frx index 85e2cab6..8a61e17f 100644 --- a/Demos/Reports/Polygon.frx +++ b/Demos/Reports/Polygon.frx @@ -1,26 +1,29 @@  - + - + - + - - - - - - - - - + + + + + + + + + + + + - + diff --git a/Extras/OpenSource/FastReport.OpenSource.Export.PdfSimple/FastReport.OpenSource.Export.PdfSimple.Tests/FastReport.OpenSource.Export.PdfSimple.Tests.csproj b/Extras/OpenSource/FastReport.OpenSource.Export.PdfSimple/FastReport.OpenSource.Export.PdfSimple.Tests/FastReport.OpenSource.Export.PdfSimple.Tests.csproj index ae3dbb80..95bfe599 100644 --- a/Extras/OpenSource/FastReport.OpenSource.Export.PdfSimple/FastReport.OpenSource.Export.PdfSimple.Tests/FastReport.OpenSource.Export.PdfSimple.Tests.csproj +++ b/Extras/OpenSource/FastReport.OpenSource.Export.PdfSimple/FastReport.OpenSource.Export.PdfSimple.Tests/FastReport.OpenSource.Export.PdfSimple.Tests.csproj @@ -20,6 +20,9 @@ PreserveNewest + + PreserveNewest + diff --git a/Extras/OpenSource/FastReport.OpenSource.Export.PdfSimple/FastReport.OpenSource.Export.PdfSimple.Tests/PdfSimpleExportTests.cs b/Extras/OpenSource/FastReport.OpenSource.Export.PdfSimple/FastReport.OpenSource.Export.PdfSimple.Tests/PdfSimpleExportTests.cs index 5db628a9..78a40471 100644 --- a/Extras/OpenSource/FastReport.OpenSource.Export.PdfSimple/FastReport.OpenSource.Export.PdfSimple.Tests/PdfSimpleExportTests.cs +++ b/Extras/OpenSource/FastReport.OpenSource.Export.PdfSimple/FastReport.OpenSource.Export.PdfSimple.Tests/PdfSimpleExportTests.cs @@ -80,6 +80,16 @@ public void TestExportPdfInfo() #pragma warning restore xUnit2009 // Do not use boolean check to check for substrings } + [Fact] + public void TestExportWatermark() + { + Report r = new Report(); + r.LoadPrepared("Watermark.fpx"); + + PDFSimpleExport export = new PDFSimpleExport(); + r.Export(export, "Watermark.pdf"); + } + [Fact] public void TestExportPdfImages() { diff --git a/Extras/OpenSource/FastReport.OpenSource.Export.PdfSimple/FastReport.OpenSource.Export.PdfSimple.Tests/Watermark.fpx b/Extras/OpenSource/FastReport.OpenSource.Export.PdfSimple/FastReport.OpenSource.Export.PdfSimple.Tests/Watermark.fpx new file mode 100644 index 0000000000000000000000000000000000000000..8858366aea16a866a83a3ec77c309691c19faf86 GIT binary patch literal 107700 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

9>c262th~ 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 literal 0 HcmV?d00001 diff --git a/FastReport.Base/AssemblyInitializer.cs b/FastReport.Base/AssemblyInitializer.cs index b0f472fc..22a13646 100644 --- a/FastReport.Base/AssemblyInitializer.cs +++ b/FastReport.Base/AssemblyInitializer.cs @@ -45,6 +45,12 @@ public AssemblyInitializer() RegisteredObjects.AddConnection(typeof(XmlDataConnection)); RegisteredObjects.AddConnection(typeof(CsvDataConnection)); + // json + RegisteredObjects.Add(typeof(Data.JsonConnection.JsonTableDataSource), "", 0); + //RegisteredObjects.Add(typeof(Data.JsonConnection.JsonObjectDataSource), "", 0); + //RegisteredObjects.Add(typeof(Data.JsonConnection.JsonArrayDataSource), "", 0); + RegisteredObjects.AddConnection(typeof(Data.JsonConnection.JsonDataSourceConnection)); + // formats RegisteredObjects.Add(typeof(BooleanFormat), "", 0); RegisteredObjects.Add(typeof(CurrencyFormat), "", 0); diff --git a/FastReport.Base/BandBase.cs b/FastReport.Base/BandBase.cs index 809ad99c..75e888f1 100644 --- a/FastReport.Base/BandBase.cs +++ b/FastReport.Base/BandBase.cs @@ -37,6 +37,7 @@ public abstract partial class BandBase : BreakableComponent, IParent private float reprintOffset; private string beforeLayoutEvent; private string afterLayoutEvent; + private int repeatBandNTimes = 1; #endregion @@ -67,6 +68,17 @@ public bool StartNewPage set { startNewPage = value; } } + ///

+ /// Gets or sets a value that determines the number of repetitions of the same band. + /// + [Category("Behavior")] + [DefaultValue(1)] + public int RepeatBandNTimes + { + get { return repeatBandNTimes; } + set { repeatBandNTimes = value; } + } + /// /// Gets or sets a value indicating that the first row can start a new report page. /// @@ -512,6 +524,7 @@ public override void Assign(Base source) OutlineExpression = src.OutlineExpression; BeforeLayoutEvent = src.BeforeLayoutEvent; AfterLayoutEvent = src.AfterLayoutEvent; + RepeatBandNTimes = src.RepeatBandNTimes; } internal virtual void UpdateWidth() @@ -631,6 +644,8 @@ public override void Serialize(FRWriter writer) writer.WriteStr("BeforeLayoutEvent", BeforeLayoutEvent); if (AfterLayoutEvent != c.AfterLayoutEvent) writer.WriteStr("AfterLayoutEvent", AfterLayoutEvent); + if (RepeatBandNTimes != c.RepeatBandNTimes) + writer.WriteInt("RepeatBandNTimes", RepeatBandNTimes); } internal bool IsColumnDependentBand diff --git a/FastReport.Base/Code/AssemblyDescriptor.cs b/FastReport.Base/Code/AssemblyDescriptor.cs index 77249426..7e755b5f 100644 --- a/FastReport.Base/Code/AssemblyDescriptor.cs +++ b/FastReport.Base/Code/AssemblyDescriptor.cs @@ -181,7 +181,7 @@ private void AddReferencedAssemblies(StringCollection assemblies, string default foreach (string s in Report.ReferencedAssemblies) { //TODO thid core directive only for .net standard mode replace with checking the standard -#if NETSTANDARD2_0 +#if NETSTANDARD2_0 || NETSTANDARD2_1 if (s == "System.Windows.Forms.dll") continue; diff --git a/FastReport.Base/Data/DataConnectionBase.cs b/FastReport.Base/Data/DataConnectionBase.cs index 0a5f6f3d..97be1626 100644 --- a/FastReport.Base/Data/DataConnectionBase.cs +++ b/FastReport.Base/Data/DataConnectionBase.cs @@ -328,7 +328,7 @@ public void CreateAllTables() /// Fills the collection with all tables available in the database. /// /// Set to true to initialize each table's schema. - public void CreateAllTables(bool initSchema) + public virtual void CreateAllTables(bool initSchema) { List tableNames = new List(); tableNames.AddRange(GetTableNames()); @@ -404,7 +404,7 @@ public void CreateAllTables(bool initSchema) /// /// Creates the relations between tables. Applies to XmlDataConnection only. /// - public void CreateRelations() + public virtual void CreateRelations() { if (Report != null) { diff --git a/FastReport.Base/Data/DataSourceBase.cs b/FastReport.Base/Data/DataSourceBase.cs index 7c073695..face4648 100644 --- a/FastReport.Base/Data/DataSourceBase.cs +++ b/FastReport.Base/Data/DataSourceBase.cs @@ -19,7 +19,7 @@ public abstract class DataSourceBase : Column private ArrayList internalRows; private ArrayList rows; private int currentRowNo; - private object currentRow; + protected object currentRow; private Hashtable additionalFilter; private bool forceLoadData; private Hashtable columnIndices; diff --git a/FastReport.Base/Data/JsonConnection/JsonDataSourceConnection.cs b/FastReport.Base/Data/JsonConnection/JsonDataSourceConnection.cs new file mode 100644 index 00000000..b2343ccc --- /dev/null +++ b/FastReport.Base/Data/JsonConnection/JsonDataSourceConnection.cs @@ -0,0 +1,259 @@ +using FastReport.Data.JsonConnection.JsonParser; +using System; +using System.Data; +using System.Data.Common; +using System.Net; +using System.Text; + +namespace FastReport.Data.JsonConnection +{ + /// + /// FastReport json connection + /// + public partial class JsonDataSourceConnection : DataConnectionBase + { + #region Public Fields + + /// + /// Name of json object table + /// + public const string TABLE_NAME = "JSON"; + + #endregion Public Fields + + #region Private Fields + + private JsonArray jsonInternal = null; + private JsonSchema jsonSchema = null; + private string jsonSchemaString = ""; + + #endregion Private Fields + + #region Internal Properties + + internal JsonArray Json + { + get + { + if (jsonInternal == null) + InitConnection(); + return jsonInternal; + } + } + + internal JsonSchema JsonSchema + { + get + { + if (jsonSchema == null) + InitConnection(); + return jsonSchema; + } + } + + #endregion Internal Properties + + #region Public Constructors + + /// + /// Initialize a new instance + /// + public JsonDataSourceConnection() + { + IsSqlBased = false; + } + + #endregion Public Constructors + + #region Public Methods + + /// + public override void CreateAllTables(bool initSchema) + { + bool found = false; + foreach (Base b in Tables) + { + if (b is JsonTableDataSource) + { + (b as JsonTableDataSource).UpdateSchema = true; + (b as JsonTableDataSource).InitSchema(); + found = true; + break; + } + } + + if (!found) + { + JsonTableDataSource jsonDataSource = new JsonTableDataSource(); + + string fixedTableName = TABLE_NAME; + jsonDataSource.TableName = fixedTableName; + + if (Report != null) + { + jsonDataSource.Name = Report.Dictionary.CreateUniqueName(fixedTableName); + jsonDataSource.Alias = Report.Dictionary.CreateUniqueAlias(jsonDataSource.Alias); + } + else + jsonDataSource.Name = fixedTableName; + + jsonDataSource.Parent = this; + jsonDataSource.InitSchema(); + jsonDataSource.Enabled = true; + } + + // init table schema + if (initSchema) + { + foreach (TableDataSource table in Tables) + { + table.InitSchema(); + } + } + } + + /// + public override void CreateRelations() + { + } + + /// + public override void CreateTable(TableDataSource source) + { + //throw new NotImplementedException(); + } + + /// + public override void DeleteTable(TableDataSource source) + { + //throw new NotImplementedException(); + } + + /// + public override void FillTableData(DataTable table, string selectCommand, CommandParameterCollection parameters) + { + } + + /// + public override void FillTableSchema(DataTable table, string selectCommand, CommandParameterCollection parameters) + { + } + + /// + public override string[] GetTableNames() + { + return new string[] { TABLE_NAME }; + } + + /// + public override string QuoteIdentifier(string value, DbConnection connection) + { + return value; + } + + #endregion Public Methods + + #region Protected Methods + + /// + protected override DataSet CreateDataSet() + { + throw new NotImplementedException(); + } + + /// + protected override void SetConnectionString(string value) + { + jsonInternal = null; + base.SetConnectionString(value); + } + + #endregion Protected Methods + + #region Private Methods + + private void InitConnection() + { + InitConnection(false); + } + + private void InitConnection(bool rebuildSchema) + { + JsonDataSourceConnectionStringBuilder builder = new JsonDataSourceConnectionStringBuilder(ConnectionString); + JsonBase obj = null; + string jsonText = builder.Json.Trim(); + if(jsonText.Length >0) + { + if(!(jsonText[0] == '{' || jsonText[0] == '[')) + { + using (WebClient client = new WebClient()) + { + try + { + client.Encoding = Encoding.GetEncoding(builder.Encoding); + } + catch + { + client.Encoding = Encoding.UTF8; + } + jsonText = client.DownloadString(jsonText); + } + } + obj = JsonBase.FromString(jsonText) as JsonBase; + } + + string schema = builder.JsonSchema; + + // have to update schema + if (schema != jsonSchemaString || jsonSchema == null || String.IsNullOrEmpty(jsonSchemaString)) + { + JsonSchema schemaObj = null; + if (String.IsNullOrEmpty(schema) || rebuildSchema) + { + if (obj != null) + { + schemaObj = JsonSchema.FromJson(obj); + JsonObject child = new JsonObject(); + schemaObj.Save(child); + jsonSchemaString = child.ToString(); + } + } + else + { + schemaObj = JsonSchema.Load(JsonBase.FromString(schema) as JsonObject); + jsonSchemaString = schema; + } + + if (schemaObj == null) + { + schemaObj = new JsonSchema(); + schemaObj.Type = "array"; + } + + if (schemaObj.Type != "array") + { + JsonSchema parentSchema = new JsonSchema(); + parentSchema.Items = schemaObj; + parentSchema.Type = "array"; + schemaObj = parentSchema; + } + + jsonSchema = schemaObj; + } + + if (obj is JsonArray) + { + jsonInternal = obj as JsonArray; + } + else + { + JsonArray result = new JsonArray(); + if (obj != null) + result.Add(obj); + jsonInternal = result; + } + } + + #endregion Private Methods + } +} \ No newline at end of file diff --git a/FastReport.Base/Data/JsonConnection/JsonDataSourceConnectionStringBuilder.cs b/FastReport.Base/Data/JsonConnection/JsonDataSourceConnectionStringBuilder.cs new file mode 100644 index 00000000..08c2018d --- /dev/null +++ b/FastReport.Base/Data/JsonConnection/JsonDataSourceConnectionStringBuilder.cs @@ -0,0 +1,96 @@ +using System.Data.Common; + +namespace FastReport.Data.JsonConnection +{ + /// + /// Represents the JsonDataConnection connection string builder. + /// + /// + /// Use this class to parse connection string returned by the JsonDataConnection class. + /// + public class JsonDataSourceConnectionStringBuilder : DbConnectionStringBuilder + { + #region Public Properties + + /// + /// Gets or sets json data + /// + public string Json + { + get + { + object result; + if (TryGetValue("Json", out result) && result != null) + return (string)result; + return ""; + } + set + { + base["Json"] = value; + } + } + + /// + /// Gets or sets json schema + /// + public string JsonSchema + { + get + { + object result; + if (TryGetValue("JsonSchema", out result) && result != null) + return (string)result; + return ""; + } + set + { + base["JsonSchema"] = value; + } + } + + /// + /// Gets or sets json url encoding + /// + public string Encoding + { + get + { + object result; + if (TryGetValue("Encoding", out result) && result != null) + return (string)result; + return ""; + } + set + { + base["Encoding"] = value; + } + } + + + + #endregion Public Properties + + #region Public Constructors + + /// + /// Initializes a new instance of the class with default settings. + /// + public JsonDataSourceConnectionStringBuilder() + { + ConnectionString = ""; + } + + /// + /// Initializes a new instance of the class with + /// specified connection string. + /// + /// The connection string. + public JsonDataSourceConnectionStringBuilder(string connectionString) + : base() + { + ConnectionString = connectionString; + } + + #endregion Public Constructors + } +} \ No newline at end of file diff --git a/FastReport.Base/Data/JsonConnection/JsonParser/JsonArray.cs b/FastReport.Base/Data/JsonConnection/JsonParser/JsonArray.cs new file mode 100644 index 00000000..e1236d87 --- /dev/null +++ b/FastReport.Base/Data/JsonConnection/JsonParser/JsonArray.cs @@ -0,0 +1,110 @@ +using System.Collections; +using System.Collections.Generic; +using System.Text; + +namespace FastReport.Data.JsonConnection.JsonParser +{ + internal class JsonArray : JsonBase, IEnumerable + { + #region Private Fields + + private List array = new List(); + + #endregion Private Fields + + #region Public Indexers + + public override object this[int index] + { + get + { + if (index >= 0 && index < Count) + return array[index]; + return null; + } + + set + { + array[index] = value; + } + } + + #endregion Public Indexers + + #region Public Properties + + public override int Count + { + get + { + return array.Count; + } + } + + public override bool IsArray + { + get + { + return true; + } + } + + #endregion Public Properties + + #region Public Methods + + public void Add(object obj) + { + array.Add(obj); + } + + public IEnumerator GetEnumerator() + { + return array.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return array.GetEnumerator(); + } + + public void Insert(int index, object obj) + { + array.Insert(index, obj); + } + + public void Remove(int index) + { + array.RemoveAt(index); + } + + public override void WriteTo(StringBuilder sb, int indent) + { + sb.Append("["); + + bool notFirst = false; + foreach (object item in array) + { + if (notFirst) + sb.Append(","); + if (indent > 0) + { + sb.AppendLine(); + for (int i = 0; i < indent; i++) + sb.Append(' '); + } + WriteValue(sb, item, indent); + notFirst = true; + } + if (indent > 0 && notFirst) + { + sb.AppendLine(); + for (int i = 2; i < indent; i++) + sb.Append(' '); + } + sb.Append("]"); + } + + #endregion Public Methods + } +} \ No newline at end of file diff --git a/FastReport.Base/Data/JsonConnection/JsonParser/JsonBase.cs b/FastReport.Base/Data/JsonConnection/JsonParser/JsonBase.cs new file mode 100644 index 00000000..ea0010d3 --- /dev/null +++ b/FastReport.Base/Data/JsonConnection/JsonParser/JsonBase.cs @@ -0,0 +1,576 @@ +using FastReport.Data.JsonConnection.JsonParser; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Text; + +namespace FastReport +{ + /// + /// Allows working with JsonObject + /// + public abstract class JsonBase + { + #region Private Fields + + private static NumberFormatInfo format; + + #endregion Private Fields + + #region Public Indexers + + /// + /// Returns child object for JsonArray + /// + /// + /// + public virtual object this[int index] + { + get + { + return null; + } + set + { + } + } + + /// + /// Returns child object for JsonObject + /// + /// + /// + public virtual object this[string key] + { + get + { + return null; + } + set + { + } + } + + #endregion Public Indexers + + #region Public Properties + + /// + /// Returns count of child object + /// + public virtual int Count + { + get + { + return 0; + } + } + + /// + /// Returns true if this object is JsonArray + /// + public virtual bool IsArray + { + get + { + return false; + } + } + + /// + /// Returns true if this object is JsonObject + /// + public virtual bool IsObject + { + get + { + return false; + } + } + + /// + /// Returns list of JsonObject keys + /// + public virtual IEnumerable Keys + { + get + { + yield break; + } + } + + #endregion Public Properties + + #region Public Constructors + + static JsonBase() + { + format = new NumberFormatInfo(); + format.NumberGroupSeparator = String.Empty; + format.NumberDecimalSeparator = "."; + } + + #endregion Public Constructors + + #region Public Methods + + /// + /// Pars json text string and return a new JsonBase Object + /// + /// + /// + public static JsonBase FromString(string jsonText) + { + using (JsonTextReader reader = new JsonTextReader(jsonText)) + { + return FromTextReader(reader); + } + } + + /// + /// returns true + /// + /// + /// + public virtual bool ContainsKey(string key) + { + return false; + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + WriteTo(sb, 0); + return sb.ToString(); + } + + /// + /// Serialize this object to sb + /// + /// + /// + /// indent in space, 0 = without indent + public abstract void WriteTo(StringBuilder sb, int indent); + + #endregion Public Methods + + #region Internal Methods + + internal string ReadString(string key) + { + object result = this[key]; + if (result != null) + { + return result.ToString(); + } + return null; + } + + internal void WriteValue(StringBuilder sb, object item, int indent) + { + if (item is JsonBase) + { + if (indent > 0) + { + (item as JsonBase).WriteTo(sb, indent + 2); + } + else + { + (item as JsonBase).WriteTo(sb, 0); + } + } + else if (item is bool) + { + if (item.Equals(true)) + { + sb.Append("true"); + } + else + { + sb.Append("false"); + } + } + else if (IsNumber(sb, item)) + { + sb.Append(((IConvertible)item).ToString(format)); + } + else if (item == null) + { + sb.Append("null"); + } + else + { + sb.Append('"'); + + foreach (char c in item.ToString()) + { + switch (c) + { + case '"': sb.Append("\\\""); break; + case '\\': sb.Append("\\\\"); break; + case '/': sb.Append("\\/"); break; + case '\b': sb.Append("\\b"); break; + case '\f': sb.Append("\\f"); break; + case '\n': sb.Append("\\n"); break; + case '\r': sb.Append("\\r"); break; + case '\t': sb.Append("\\t"); break; + default: sb.Append(c); break; + } + } + sb.Append('"'); + } + } + + #endregion Internal Methods + + #region Private Methods + + private static JsonBase FromTextReader(JsonTextReader reader) + { + reader.SkipWhiteSpace(); + if (reader.IsNotEOF) + switch (reader.Char) + { + case '{': + return ReadObject(reader); + + case '[': + return ReadArray(reader); + + default: + throw reader.ThrowFormat('{', '['); + } + throw reader.ThrowEOF('{', '['); + } + + private static JsonArray ReadArray(JsonTextReader reader) + { + if (reader.Char != '[') + throw reader.ThrowFormat('['); + + JsonArray result = new JsonArray(); + + reader.ReadNext(); + reader.SkipWhiteSpace(); + + if (reader.IsEOF) + throw reader.ThrowEOF(']'); + else if (reader.Char != ']') + { + while (true) + { + result.Add(ReadValue(reader)); + reader.SkipWhiteSpace(); + + if (reader.IsEOF) + throw reader.ThrowEOF(']'); + else if (reader.Char == ',') + { + reader.ReadNext(); + reader.SkipWhiteSpace(); + continue; + } + else if (reader.Char == ']') + break; + else reader.ThrowFormat(',', ']'); + } + } + + reader.ReadNext(); + + return result; + } + + private static JsonObject ReadObject(JsonTextReader reader) + { + if (reader.Char != '{') + throw reader.ThrowFormat('{'); + + JsonObject result = new JsonObject(); + + reader.ReadNext(); + reader.SkipWhiteSpace(); + + if (reader.IsEOF) + throw reader.ThrowEOF('}'); + else if (reader.Char != '}') + { + while (true) + { + string key = reader.Dedublicate(ReadValueString(reader)); + + reader.SkipWhiteSpace(); + + if (reader.IsEOF) + throw reader.ThrowEOF(':'); + else if (reader.Char != ':') + reader.ThrowFormat(':'); + + reader.ReadNext(); + reader.SkipWhiteSpace(); + + result[key] = ReadValue(reader); + reader.SkipWhiteSpace(); + + if (reader.IsEOF) + throw reader.ThrowEOF('}'); + else if (reader.Char == ',') + { + reader.ReadNext(); + reader.SkipWhiteSpace(); + continue; + } + else if (reader.Char == '}') + break; + else reader.ThrowFormat(',', '}'); + } + } + + reader.ReadNext(); + + return result; + } + + private static object ReadValue(JsonTextReader reader) + { + if (reader.IsEOF) + throw reader.ThrowEOF('"', '[', '{', 'n', 't', 'f', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'); + switch (reader.Char) + { + case '"': + return ReadValueString(reader); + + case '[': + return ReadArray(reader); + + case '{': + return ReadObject(reader); + + case 'n': + return ReadValue(reader, "null", null); + + case 't': + return ReadValue(reader, "true", true); + + case 'f': + return ReadValue(reader, "false", false); + + case '-': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + return ReadValueNumber(reader); + + default: + throw reader.ThrowFormat('"', '[', '{', 'n', 't', 'f', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'); + } + } + + private static object ReadValue(JsonTextReader reader, string str, object result) + { + for (int i = 0; i < str.Length; i++) + { + if (reader.IsEOF) + throw reader.ThrowEOF(str[i]); + else if (reader.Char != str[i]) + throw reader.ThrowFormat(str[i]); + reader.ReadNext(); + } + return result; + } + + private static double ReadValueNumber(JsonTextReader reader) + { + int startPos = reader.Position; + if (reader.IsEOF) + throw reader.ThrowEOF('-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'); + + if (reader.Char == '-') + { + reader.ReadNext(); + if (reader.IsEOF) + throw reader.ThrowEOF('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'); + } + + if (reader.Char < '0' || '9' < reader.Char) + throw reader.ThrowFormat('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'); + + while (true) + { + reader.ReadNext(); + if (reader.IsEOF) + throw reader.ThrowEOF('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'); + + if (reader.Char < '0' || '9' < reader.Char) + break; + } + + if (reader.Char == '.') + { + reader.ReadNext(); + if (reader.IsEOF) + throw reader.ThrowEOF('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'); + + if (reader.Char < '0' || '9' < reader.Char) + throw reader.ThrowFormat('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'); + + while (true) + { + reader.ReadNext(); + if (reader.IsEOF) + throw reader.ThrowEOF('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'); + + if (reader.Char < '0' || '9' < reader.Char) + break; + } + } + + if (reader.Char == 'e' || reader.Char == 'E') + { + reader.ReadNext(); + if (reader.IsEOF) + throw reader.ThrowEOF('+', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'); + + bool signed = false; + if (reader.Char == '+') + { + reader.ReadNext(); + signed = true; + if (reader.IsEOF) + throw reader.ThrowEOF('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'); + } + else if (reader.Char == '-') + { + reader.ReadNext(); + signed = true; + if (reader.IsEOF) + throw reader.ThrowEOF('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'); + } + + if (reader.Char < '0' || '9' < reader.Char) + { + if (signed) + throw reader.ThrowFormat('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'); + else + throw reader.ThrowFormat('-', '+', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'); + } + + while (true) + { + reader.ReadNext(); + if (reader.IsEOF) + throw reader.ThrowEOF('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'); + + if (reader.Char < '0' || '9' < reader.Char) + break; + } + } + + string value = reader.Substring(startPos, reader.Position - startPos); + + return double.Parse(value, format); + } + + private static string ReadValueString(JsonTextReader reader) + { + if (reader.IsEOF) + throw reader.ThrowEOF('"'); + else if (reader.Char != '"') + throw reader.ThrowFormat('"'); + + reader.ReadNext(); + + StringBuilder sb = new StringBuilder(); + while (true) + { + if (reader.IsEOF) + throw reader.ThrowEOF('"'); + + if (reader.Char == '"') + break; + else if (reader.Char == '\\') + { + reader.ReadNext(); + if (reader.IsEOF) + throw reader.ThrowEOF('"', '\\', '/', 'b', 'f', 'n', 'r', 't', 'u'); + switch (reader.Char) + { + case '"': sb.Append('"'); break; + case '\\': sb.Append('\\'); break; + case '/': sb.Append('/'); break; + case 'b': sb.Append('\b'); break; + case 'f': sb.Append('\f'); break; + case 'n': sb.Append('\n'); break; + case 'r': sb.Append('\r'); break; + case 't': sb.Append('\t'); break; + case 'u': + int number = 0; + for (int i = 0; i < 4; i++) + { + reader.ReadNext(); + if (reader.IsEOF) + throw reader.ThrowEOF('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F'); + if ('0' <= reader.Char && reader.Char <= '9') + { + number = number * 0x10 + (int)(reader.Char - '0'); + } + else if ('a' <= reader.Char && reader.Char <= 'f') + { + number = number * 0x10 + 10 + (int)(reader.Char - 'a'); + } + else if ('A' <= reader.Char && reader.Char <= 'F') + { + number = number * 0x10 + 10 + (int)(reader.Char - 'A'); + } + else + { + throw reader.ThrowFormat('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F'); + } + } + + sb.Append((char)number); + + break; + + default: + throw reader.ThrowFormat('"', '\\', '/', 'b', 'f', 'n', 'r', 't', 'u'); + } + } + else + { + sb.Append(reader.Char); + } + + reader.ReadNext(); + } + + reader.ReadNext(); + + return sb.ToString(); + } + + private bool IsNumber(StringBuilder sb, object item) + { + return item is float + || item is double + || item is sbyte + || item is byte + || item is short + || item is ushort + || item is int + || item is uint + || item is long + || item is ulong + || item is decimal; + } + + #endregion Private Methods + } +} \ No newline at end of file diff --git a/FastReport.Base/Data/JsonConnection/JsonParser/JsonObject.cs b/FastReport.Base/Data/JsonConnection/JsonParser/JsonObject.cs new file mode 100644 index 00000000..0ad03e1b --- /dev/null +++ b/FastReport.Base/Data/JsonConnection/JsonParser/JsonObject.cs @@ -0,0 +1,118 @@ +using System.Collections; +using System.Collections.Generic; +using System.Text; + +namespace FastReport.Data.JsonConnection.JsonParser +{ + internal class JsonObject : JsonBase, IEnumerable> + { + #region Private Fields + + private Dictionary dict = new Dictionary(); + + #endregion Private Fields + + #region Public Indexers + + public override object this[string key] + { + get + { + object result; + if (dict.TryGetValue(key, out result)) + return result; + return null; + } + set + { + dict[key] = value; + } + } + + #endregion Public Indexers + + #region Public Properties + + public override int Count + { + get + { + return dict.Count; + } + } + + public override bool IsObject + { + get + { + return true; + } + } + + public override IEnumerable Keys + { + get + { + return dict.Keys; + } + } + + #endregion Public Properties + + #region Public Methods + + public override bool ContainsKey(string key) + { + return dict.ContainsKey(key); + } + + public bool DeleteKey(string key) + { + return dict.Remove(key); + } + + public IEnumerator> GetEnumerator() + { + return dict.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return dict.GetEnumerator(); + } + + public override void WriteTo(StringBuilder sb, int indent) + { + sb.Append("{"); + bool notFirst = false; + foreach (KeyValuePair kv in dict) + { + if (notFirst) + sb.Append(","); + if (indent > 0) + { + sb.AppendLine(); + for (int i = 0; i < indent; i++) + sb.Append(' '); + } + + WriteValue(sb, kv.Key, indent); + if (indent > 0) + sb.Append(": "); + else + sb.Append(":"); + WriteValue(sb, kv.Value, indent); + notFirst = true; + } + if (indent > 0 && notFirst) + { + sb.AppendLine(); + for (int i = 2; i < indent; i++) + sb.Append(' '); + } + sb.Append("}"); + } + + #endregion Public Methods + } +} \ No newline at end of file diff --git a/FastReport.Base/Data/JsonConnection/JsonParser/JsonSchema.cs b/FastReport.Base/Data/JsonConnection/JsonParser/JsonSchema.cs new file mode 100644 index 00000000..2daffd9f --- /dev/null +++ b/FastReport.Base/Data/JsonConnection/JsonParser/JsonSchema.cs @@ -0,0 +1,233 @@ +using System; +using System.Collections.Generic; + +namespace FastReport.Data.JsonConnection.JsonParser +{ + internal class JsonSchema + { + #region Private Fields + + private string description; + private JsonSchema items; + private Dictionary properties; + private string type; + + #endregion Private Fields + + #region Public Properties + + public Type DataType + { + get + { + switch (type) + { + case "object": return typeof(JsonBase); + case "array": return typeof(JsonBase); + case "integer": return typeof(int); + case "number": return typeof(double); + case "string": return typeof(string); + case "boolean": return typeof(bool); + default: return typeof(object); + } + } + } + + public string Description { get { return description; } set { description = value; } } + + public JsonSchema Items + { + get + { + return items; + } + set + { + items = value; + } + } + + public Dictionary Properties + { + get + { + return properties; + } + } + + public string Type { get { return type; } set { type = value; } } + + #endregion Public Properties + + #region Public Methods + + public static JsonSchema FromJson(object json) + { + JsonSchema result = new JsonSchema(); + if (json is JsonObject) + { + result.type = "object"; + result.properties = new Dictionary(); + + foreach (KeyValuePair kv in (json as JsonObject)) + { + result.Properties[kv.Key] = FromJson(kv.Value); + } + } + else if (json is JsonArray) + { + result.Type = "array"; + result.items = null; + foreach (object obj in (json as JsonArray)) + { + JsonSchema sub = FromJson(obj); + if (result.items == null) + result.items = sub; + else result.items.Union(sub); + } + + if (result.items == null) + result.items = new JsonSchema(); + } + else if (json is string) + { + result.Type = "string"; + } + else if (json is double) + { + result.Type = "number"; + } + else if (json is bool) + { + result.Type = "boolean"; + } + else + { + result.Type = "null"; + } + return result; + } + + public static JsonSchema Load(JsonObject obj) + { + if (obj == null) + { + throw new NullReferenceException("Unable to load schema from non-object"); + } + + JsonSchema result = new JsonSchema(); + if (obj != null) + { + result.Type = obj.ReadString("type"); + result.Description = obj.ReadString("description"); + switch (result.Type) + { + case "object": + result.properties = new Dictionary(); + if (obj.ContainsKey("properties")) + { + JsonObject child = obj["properties"] as JsonObject; + if (child != null) + { + foreach (KeyValuePair kv in child) + { + if (kv.Value is JsonObject) + { + result.Properties[kv.Key] = Load(kv.Value as JsonObject); + } + else + { + result.Properties[kv.Key] = new JsonSchema(); + } + } + } + } + break; + + case "array": + if (obj.ContainsKey("items")) + result.items = Load(obj["items"] as JsonObject); + else + result.items = new JsonSchema(); + break; + } + } + + return result; + } + + public void Save(JsonObject obj) + { + if (Type != null) + { + obj["type"] = Type; + } + if (Description != null) + { + obj["description"] = Description; + } + + if (Items != null) + { + JsonObject child = new JsonObject(); + Items.Save(child); + obj["items"] = child; + } + + if (Properties != null && Properties.Count > 0) + { + JsonObject child = new JsonObject(); + obj["properties"] = child; + foreach (KeyValuePair kv in Properties) + { + JsonObject sub_child = new JsonObject(); + kv.Value.Save(sub_child); + child[kv.Key] = sub_child; + } + } + } + + #endregion Public Methods + + #region Private Methods + + private void Union(JsonSchema sub) + { + if (sub == null || type != sub.type) + { + items = null; + properties = null; + type = "null"; + } + else if (type == "object") + { + if (properties == null) + properties = new Dictionary(); + if (sub.Properties != null) + foreach (KeyValuePair kv in sub.Properties) + { + JsonSchema child; + if (Properties.TryGetValue(kv.Key, out child)) + { + child.Union(kv.Value); + } + else + { + Properties[kv.Key] = kv.Value; + } + } + } + else if (type == "array") + { + if (items == null) + items = sub.items; + else + { + items.Union(sub.items); + } + } + } + + #endregion Private Methods + } +} \ No newline at end of file diff --git a/FastReport.Base/Data/JsonConnection/JsonParser/JsonTextReader.cs b/FastReport.Base/Data/JsonConnection/JsonParser/JsonTextReader.cs new file mode 100644 index 00000000..797d8b08 --- /dev/null +++ b/FastReport.Base/Data/JsonConnection/JsonParser/JsonTextReader.cs @@ -0,0 +1,148 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FastReport.Data.JsonConnection.JsonParser +{ + internal class JsonTextReader : IDisposable + { + #region Private Fields + + private string jsonText; + private Dictionary pool = new Dictionary(); + private int position; + private bool stringOptimization; + + #endregion Private Fields + + #region Public Properties + + public char Char + { + get + { + return jsonText[position]; + } + } + + public bool IsEOF + { + get + { + return position >= jsonText.Length; + } + } + + public bool IsNotEOF + { + get + { + return position < jsonText.Length; + } + } + + public string JsonText + { + get { return jsonText; } + set { jsonText = value; } + } + + public int Position + { + get { return position; } + set { position = value; } + } + + #endregion Public Properties + + #region Public Constructors + + public JsonTextReader(string jsonText) + { + stringOptimization = Utils.Config.IsStringOptimization; + + this.jsonText = jsonText; + position = 0; + } + + #endregion Public Constructors + + #region Public Methods + + public string Dedublicate(string value) + { + if (stringOptimization) + { + string result; + if (pool.TryGetValue(value, out result)) + return result; + return pool[value] = value; + } + return value; + } + + public void Dispose() + { + JsonText = null; + pool.Clear(); + pool = null; + } + + public void ReadNext() + { + position++; + } + + public void SkipWhiteSpace() + { + while (IsNotEOF && char.IsWhiteSpace(Char)) + position++; + } + + public Exception ThrowEOF(params char[] args) + { + StringBuilder sb = new StringBuilder(); + sb.Append("Unexpected end of input json, wait for"); + if (args.Length > 0) + { + sb.Append(" ").Append(args[0]); + } + for (int i = 1; i < args.Length; i++) + { + sb.Append(", ").Append(args[i]); + } + return new FormatException(sb.ToString()); + } + + public Exception ThrowEOF(string args) + { + return new FormatException("Unexpected end of input json, wait for " + args); + } + + public Exception ThrowFormat(params char[] args) + { + StringBuilder sb = new StringBuilder(); + sb.Append("Json text at position ").Append(Position).Append(", unexpected symbol ").Append(Char).Append(", wait for"); + if (args.Length > 0) + { + sb.Append(" ").Append(args[0]); + } + for (int i = 1; i < args.Length; i++) + { + sb.Append(", ").Append(args[i]); + } + return new FormatException(sb.ToString()); + } + + #endregion Public Methods + + #region Internal Methods + + internal string Substring(int startPos, int len) + { + return JsonText.Substring(startPos, len); + } + + #endregion Internal Methods + } +} \ No newline at end of file diff --git a/FastReport.Base/Data/JsonConnection/JsonTableDataSource.cs b/FastReport.Base/Data/JsonConnection/JsonTableDataSource.cs new file mode 100644 index 00000000..c65722df --- /dev/null +++ b/FastReport.Base/Data/JsonConnection/JsonTableDataSource.cs @@ -0,0 +1,352 @@ +using FastReport.Data.JsonConnection.JsonParser; +using System; +using System.Collections; +using System.Collections.Generic; + +namespace FastReport.Data.JsonConnection +{ + /// + /// JsonTableDataSource present a json array object + /// + public class JsonTableDataSource : TableDataSource + { + #region Private Fields + + private JsonArray _json; + private bool updateSchema; + + #endregion Private Fields + + #region Public Properties + + /// + /// Gets or sets value for force update schema on init schema + /// + public bool UpdateSchema + { + get + { + return updateSchema; + } + set + { + updateSchema = value; + } + } + + #endregion Public Properties + + #region Internal Properties + + internal JsonArray Json + { + get + { + if (_json == null) + { + _json = GetJson(Parent, this) as JsonArray; + if (_json == null) + _json = new JsonArray(); + } + return _json; + } + set + { + _json = value; + } + } + + #endregion Internal Properties + + #region Private Properties + + private int CurrentIndex + { + get + { + if (currentRow is int) + return (int)currentRow; + if (CurrentRowNo < Rows.Count) + { + object result = Rows[CurrentRowNo]; + if (result is int) + return (int)result; + } + return CurrentRowNo; + } + } + + #endregion Private Properties + + #region Public Constructors + + /// + public JsonTableDataSource() + { + DataType = typeof(JsonArray); + } + + #endregion Public Constructors + + #region Public Methods + + /// + public override void InitializeComponent() + { + base.InitializeComponent(); + Json = null; + } + + /// + public override void InitSchema() + { + if (Columns.Count == 0 || UpdateSchema) + { + if (Connection is JsonDataSourceConnection) + { + JsonDataSourceConnection con = Connection as JsonDataSourceConnection; + + InitSchema(this, con.JsonSchema); + } + } + UpdateSchema = false; + } + + /// + public override void LoadData(ArrayList rows) + { + Json = null; + if ( rows != null) + { + rows.Clear(); + int count = Json.Count; + for (int i = 0; i < count; i++) + { + rows.Add(i); + } + } + } + + #endregion Public Methods + + #region Internal Methods + + internal static object GetJsonBaseByColumn(Base parentColumn, Column column) + { + if (parentColumn is JsonTableDataSource) + { + switch (column.PropName) + { + case "item": + return (parentColumn as JsonTableDataSource).Json[(parentColumn as JsonTableDataSource).CurrentIndex]; + } + JsonTableDataSource source = column as JsonTableDataSource; + return source.Json; + } + if (parentColumn is Column && !String.IsNullOrEmpty(column.PropName)) + { + object json = GetJsonBaseByColumn(parentColumn.Parent, parentColumn as Column); + if (json is JsonBase) + { + return (json as JsonBase)[column.PropName]; + } + } + + return null; + } + + internal static object GetValueByColumn(Base parentColumn, Column column) + { + if (parentColumn is JsonTableDataSource) + { + switch (column.PropName) + { + case "index": + return (parentColumn as JsonTableDataSource).CurrentIndex; + + case "array": + return (parentColumn as JsonTableDataSource).Json; + } + } + + object json = GetJsonBaseByColumn(parentColumn, column); + + return json; + } + + internal static void InitSchema(Column table, JsonSchema schema) + { + List saveColumns = new List(); + switch (schema.Type) + { + case "object": + foreach (KeyValuePair kv in schema.Properties) + { + if (kv.Value.Type == "object") + { + Column c = new Column(); + c.Name = kv.Key; + c.Alias = kv.Key; + c.PropName = kv.Key; + c.DataType = kv.Value.DataType; + c = UpdateColumn(table, c, saveColumns); + InitSchema(c, kv.Value); + } + else if (kv.Value.Type == "array") + { + Column c = new JsonTableDataSource(); + c.Name = kv.Key; + c.Alias = kv.Key; + c.PropName = kv.Key; + c.DataType = kv.Value.DataType; + c = UpdateColumn(table, c, saveColumns); + InitSchema(c, kv.Value); + } + else + { + Column c = new Column(); + c.Name = kv.Key; + c.Alias = kv.Key; + c.PropName = kv.Key; + c.DataType = kv.Value.DataType; + c.SetBindableControlType(c.DataType); + UpdateColumn(table, c, saveColumns); + } + } + break; + + case "array": + JsonSchema items = schema.Items; + { + Column c = new Column(); + c.Name = "index"; + c.Alias = "index"; + c.PropName = "index"; + c.DataType = typeof(int); + UpdateColumn(table, c, saveColumns); + } + + { + Column c; + bool iSchema = false; + + if (items.Type == "object") + { + c = new Column(); + iSchema = true; + + } + else if (items.Type == "array") + { + c = new JsonTableDataSource(); + iSchema = true; + } + else + { + c = new Column(); + } + + c.Name = "item"; + c.Alias = "item"; + c.PropName = "item"; + c.DataType = items.DataType; + c = UpdateColumn(table, c, saveColumns); + + if (iSchema) + InitSchema(c, items); + } + + { + Column c = new Column(); + c.Name = "array"; + c.Alias = "array"; + c.PropName = "array"; + c.DataType = typeof(JsonBase); + UpdateColumn(table, c, saveColumns); + } + break; + } + + for (int i = 0; i < table.Columns.Count; i++) + { + if (!(table.Columns[i].Calculated || saveColumns.Contains(table.Columns[i]))) + { + table.Columns.RemoveAt(i); + i--; + } + } + } + + internal object GetJson(Base parentColumn, Column column) + { + if (parentColumn is JsonDataSourceConnection) + { + // return zero level json + return (parentColumn as JsonDataSourceConnection).Json; + } + else if (parentColumn is JsonTableDataSource) + { + JsonTableDataSource source = parentColumn as JsonTableDataSource; + return source.Json[source.CurrentRowNo] as object; + } + else if (parentColumn is Column) + { + object parentJson = GetJson(parentColumn.Parent, parentColumn as Column); + if (parentJson is JsonBase && !String.IsNullOrEmpty(column.PropName)) + { + return (parentJson as JsonBase)[column.PropName]; + } + } + return null; + } + + #endregion Internal Methods + + #region Protected Methods + + /// + protected override object GetValue(Column column) + { + return GetValueByColumn(column.Parent, column); + } + + /// + protected override object GetValue(string alias) + { + // TODO TEST + Column column = this; + string[] colAliases = alias.Split(new char[] { '.' }); + + foreach (string colAlias in colAliases) + { + column = column.Columns.FindByAlias(colAlias); + if (column == null) + return null; + } + + return GetValueByColumn(column.Parent, column); + } + + #endregion Protected Methods + + #region Private Methods + + private static Column UpdateColumn(Column table, Column c, List list) + { + foreach (Column child in table.Columns) + { + if (child.PropName == c.PropName) + { + child.DataType = c.DataType; + list.Add(child); + return child; + } + } + table.AddChild(c); + list.Add(c); + return c; + } + + #endregion Private Methods + } +} \ No newline at end of file diff --git a/FastReport.Base/Engine/ReportEngine.Bands.cs b/FastReport.Base/Engine/ReportEngine.Bands.cs index acfebd64..b6ea3b05 100644 --- a/FastReport.Base/Engine/ReportEngine.Bands.cs +++ b/FastReport.Base/Engine/ReportEngine.Bands.cs @@ -139,15 +139,15 @@ private void ShowBand(BandBase band, BandBase outputBand, float offsetX, float o /// public void ShowBand(BandBase band) { - ShowBand(band, true); + if (band != null) + for (int i = 0; i < band.RepeatBandNTimes; i++) + ShowBand(band, true); } private void ShowBand(BandBase band, bool getData) { if (band == null) - { return; - } BandBase saveCurBand = curBand; curBand = band; diff --git a/FastReport.Base/Engine/ReportEngine.PageNumbers.cs b/FastReport.Base/Engine/ReportEngine.PageNumbers.cs index 0d5647d6..b59ac0f5 100644 --- a/FastReport.Base/Engine/ReportEngine.PageNumbers.cs +++ b/FastReport.Base/Engine/ReportEngine.PageNumbers.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; namespace FastReport.Engine { @@ -10,10 +10,15 @@ private class PageNumberInfo { #region Fields - public int pageNo; + public readonly int pageNo; public int totalPages; #endregion Fields + + public PageNumberInfo(int pageNo) + { + this.pageNo = pageNo; + } } #endregion Private Classes @@ -74,9 +79,25 @@ internal void IncLogicalPageNumber() int index = CurPage - firstReportPage; if (FirstPass || index >= pageNumbers.Count) { - PageNumberInfo info = new PageNumberInfo(); + PageNumberInfo info = new PageNumberInfo(logicalPageNo); pageNumbers.Add(info); - info.pageNo = logicalPageNo; + } + } + + + /// + /// Called when the number of pages increased during DoublePass + /// + internal void ShiftLastPage() + { + PageNumberInfo info = new PageNumberInfo(pageNumbers.Count + 1); + pageNumbers.Add(info); + + + for (int i = pageNumbers.Count - 1; i >= 0; i--) + { + info = pageNumbers[i]; + info.totalPages = pageNumbers.Count; } } diff --git a/FastReport.Base/Engine/ReportEngine.Pages.cs b/FastReport.Base/Engine/ReportEngine.Pages.cs index 0bdda6b8..32cd364c 100644 --- a/FastReport.Base/Engine/ReportEngine.Pages.cs +++ b/FastReport.Base/Engine/ReportEngine.Pages.cs @@ -100,9 +100,17 @@ private void ShowPageHeader() ShowBand(page.PageHeader); } - private void ShowPageFooter() + private void ShowPageFooter(bool startPage) { - ShowBand(page.PageFooter); + if (!FirstPass && + (page.PageFooter.PrintOn & PrintOn.LastPage) > 0 && + CurPage == TotalPages - 1 && + startPage) + { + ShiftLastPage(); + } + else + ShowBand(page.PageFooter); } private bool StartFirstPage() @@ -245,7 +253,7 @@ private void EndLastPage() ShowBand(page.ColumnFooter); } - ShowPageFooter(); + ShowPageFooter(false); OutlineRoot(); page.FinalizeComponents(); } @@ -351,7 +359,7 @@ private void StartPage() internal void EndPage(bool startPage) { OnStateChanged(page, EngineState.PageFinished); - ShowPageFooter(); + ShowPageFooter(startPage); if (Report.MaxPages > 0 && PreparedPages.Count >= Report.MaxPages) Report.Abort(); diff --git a/FastReport.Base/Export/Html/HTMLExport.cs b/FastReport.Base/Export/Html/HTMLExport.cs index f8161703..c6dab280 100644 --- a/FastReport.Base/Export/Html/HTMLExport.cs +++ b/FastReport.Base/Export/Html/HTMLExport.cs @@ -135,10 +135,23 @@ public enum ExportType private ExportType exportMode; private bool enableVectorObjects = true; + /// + /// hash:base64Image + /// + private Dictionary embeddedImages; #endregion Private fields #region Public properties + /// + /// Gets or sets images, embedded in html (hash:base64Image) + /// + public Dictionary EmbeddedImages + { + get { return embeddedImages; } + set { embeddedImages = value; } + } + /// /// Sets a ID of report /// @@ -972,6 +985,7 @@ public HTMLExport() numberFormat.NumberDecimalSeparator = "."; exportMode = ExportType.Export; res = new MyRes("Export,Html"); + embeddedImages = new Dictionary(); } } diff --git a/FastReport.Base/Export/Html/HTMLExportDraw.cs b/FastReport.Base/Export/Html/HTMLExportDraw.cs index d507ad52..a671b8ca 100644 --- a/FastReport.Base/Export/Html/HTMLExportDraw.cs +++ b/FastReport.Base/Export/Html/HTMLExportDraw.cs @@ -6,9 +6,6 @@ namespace FastReport.Export.Html { - /// - /// Represents the HTML export filter. - /// public partial class HTMLExport : ExportBase { private void HTMLFontStyle(FastString FFontDesc, Font font, float LineHeight) @@ -319,7 +316,7 @@ private string HTMLGetImage(int PageNumber, int CurrentPage, int ImageNumber, st } if (EmbedPictures && PictureStream != null) { - return embedPreffix + Convert.ToBase64String(PictureStream.ToArray()); + return embedPreffix + GetBase64Image(PictureStream, hash); } else if (subFolder && singlePage && !navigator) return ExportUtils.HtmlURL(subFolderPath + ImageFileName); @@ -330,7 +327,7 @@ private string HTMLGetImage(int PageNumber, int CurrentPage, int ImageNumber, st { if (EmbedPictures) { - return embedPreffix + Convert.ToBase64String(PictureStream.ToArray()); + return embedPreffix + GetBase64Image(PictureStream, hash); } else { @@ -351,5 +348,16 @@ private string HTMLGetImage(int PageNumber, int CurrentPage, int ImageNumber, st else return String.Empty; } + + private string GetBase64Image(MemoryStream PictureStream, string hash) + { + string base64Image = String.Empty; + if (!EmbeddedImages.TryGetValue(hash, out base64Image)) + { + base64Image = Convert.ToBase64String(PictureStream.ToArray()); + EmbeddedImages.Add(hash, base64Image); + } + return base64Image; + } } } diff --git a/FastReport.Base/Export/Html/HTMLExportLayers.cs b/FastReport.Base/Export/Html/HTMLExportLayers.cs index d3ecb7a0..8235cd07 100644 --- a/FastReport.Base/Export/Html/HTMLExportLayers.cs +++ b/FastReport.Base/Export/Html/HTMLExportLayers.cs @@ -7,9 +7,6 @@ namespace FastReport.Export.Html { - /// - /// Represents the HTML export filter. - /// public partial class HTMLExport : ExportBase { private bool doPageBreak; @@ -189,7 +186,7 @@ private void Layer(FastString Page, ReportComponentBase obj, private string EncodeURL(string value) { -#if NETSTANDARD2_0 +#if NETSTANDARD2_0 || NETSTANDARD2_1 return System.Net.WebUtility.UrlEncode(value); #else return ExportUtils.HtmlURL(value); @@ -516,6 +513,7 @@ private string GetLayerPicture(ReportComponentBase obj, out float Width, out flo obj.Border.Lines = BorderLines.None; obj.Draw(new FRPaintEventArgs(g, Zoom, Zoom, Report.GraphicCache)); obj.Border.Lines = oldLines; + } if (FPictureFormat == System.Drawing.Imaging.ImageFormat.Jpeg) @@ -524,7 +522,38 @@ private string GetLayerPicture(ReportComponentBase obj, out float Width, out flo image.Save(PictureStream, FPictureFormat); } PictureStream.Position = 0; - result = HTMLGetImage(0, 0, 0, Crypter.ComputeHash(PictureStream), true, null, PictureStream, false); + + string hash = String.Empty; + if (obj is PictureObject) + { + PictureObject pic = (obj as PictureObject); + if (pic.Image == null) + { + + } + else + { + using (MemoryStream picStr = new MemoryStream()) + { + + ImageHelper.Save(pic.Image, picStr); + using(StreamWriter picWriter = new StreamWriter(picStr)) + { + picWriter.Write(pic.Width); + picWriter.Write(pic.Height); + picWriter.Write(pic.Angle); + picWriter.Write(pic.Transparency); + picWriter.Write(pic.TransparentColor.ToArgb()); + picWriter.Write(pic.CanShrink); + picWriter.Write(pic.CanGrow); + hash = Crypter.ComputeHash(picStr); + } + } + } + } + else + hash = Crypter.ComputeHash(PictureStream); + result = HTMLGetImage(0, 0, 0, hash, true, null, PictureStream, false); } } return result; @@ -535,7 +564,6 @@ private void LayerPicture(FastString Page, ReportComponentBase obj, FastString t if (pictures) { int styleindex = UpdateCSSTable(obj); - string style = GetStyleTag(styleindex); string old_text = String.Empty; if (IsMemo(obj)) @@ -550,8 +578,18 @@ private void LayerPicture(FastString Page, ReportComponentBase obj, FastString t if (IsMemo(obj)) (obj as TextObject).Text = old_text; - FastString addstyle = new FastString(128); - addstyle.Append(" background: url('").Append(pic).Append("') no-repeat !important;-webkit-print-color-adjust:exact;"); + FastString picStyleBuilder = new FastString("background: url('") + .Append(pic).Append("') no-repeat !important;-webkit-print-color-adjust:exact;"); + + int picStyleIndex = UpdateCSSTable(picStyleBuilder.ToString()); + + + string style = String.Format("class=\"{0}s{1} {0}s{2}\"", + stylePrefix, + styleindex.ToString(), picStyleIndex.ToString()); + + //FastString addstyle = new FastString(128); + //addstyle.Append(" background: url('").Append(pic).Append("') no-repeat !important;-webkit-print-color-adjust:exact;"); //if (String.IsNullOrEmpty(text)) // text = NBSP; @@ -559,12 +597,10 @@ private void LayerPicture(FastString Page, ReportComponentBase obj, FastString t float x = Width > 0 ? obj.AbsLeft : (obj.AbsLeft + Width); float y = Height > 0 ? hPos + obj.AbsTop : (hPos + obj.AbsTop + Height); - Layer(Page, obj, x, y, Width, Height, text, style, addstyle); + Layer(Page, obj, x, y, Width, Height, text, style, null); } } - - private void LayerShape(FastString Page, ShapeObject obj, FastString text) { int styleindex = UpdateCSSTable(obj); @@ -614,10 +650,13 @@ private void LayerBack(FastString Page, ReportComponentBase obj, FastString text } } - if (obj.Fill is SolidFill) - Layer(Page, obj, obj.AbsLeft, hPos + obj.AbsTop, obj.Width, obj.Height, text, GetStyleTag(UpdateCSSTable(obj)), null); - else - LayerPicture(Page, obj, text); + if (!(obj is PolyLineObject)) + { + if (obj.Fill is SolidFill) + Layer(Page, obj, obj.AbsLeft, hPos + obj.AbsTop, obj.Width, obj.Height, text, GetStyleTag(UpdateCSSTable(obj)), null); + else + LayerPicture(Page, obj, text); + } } private void LayerTable(FastString Page, FastString CSS, TableBase table) @@ -723,6 +762,7 @@ private void ExportHTMLPageLayeredBegin(HTMLData d) maxWidth = ExportUtils.GetPageWidth(reportPage) * Units.Millimeters; maxHeight = ExportUtils.GetPageHeight(reportPage) * Units.Millimeters; + if (enableMargins) { leftMargin = reportPage.LeftMargin * Units.Millimeters; @@ -745,8 +785,21 @@ private void ExportHTMLPageLayeredBegin(HTMLData d) htmlPage.Append(HTMLGetAncor((d.PageNumber).ToString())); htmlPage.Append("
- /// Represents the HTML export filter. - /// public partial class HTMLExport : ExportBase { private string Px(double pixel) diff --git a/FastReport.Base/Gauge/GaugeLabel.cs b/FastReport.Base/Gauge/GaugeLabel.cs index ac24876d..2d6c54b3 100644 --- a/FastReport.Base/Gauge/GaugeLabel.cs +++ b/FastReport.Base/Gauge/GaugeLabel.cs @@ -138,7 +138,7 @@ public virtual void Serialize(FRWriter writer, string prefix, GaugeLabel diff) { writer.WriteStr(prefix + ".Text", Text); } - if (writer.SerializeTo != SerializeTo.Preview || !Font.Equals(diff.Font)) + if ((writer.SerializeTo != SerializeTo.Preview || !Font.Equals(diff.Font)) && writer.ItemName != "inherited") { writer.WriteValue(prefix + ".Font", Font); } diff --git a/FastReport.Base/Gauge/GaugeScale.cs b/FastReport.Base/Gauge/GaugeScale.cs index 41d48ea8..0d858a2c 100644 --- a/FastReport.Base/Gauge/GaugeScale.cs +++ b/FastReport.Base/Gauge/GaugeScale.cs @@ -122,7 +122,7 @@ public virtual void Draw(FRPaintEventArgs e) public virtual void Serialize(FRWriter writer, string prefix, GaugeScale diff) { TextFill.Serialize(writer, prefix + ".TextFill", diff.TextFill); - if (writer.SerializeTo != SerializeTo.Preview || !Font.Equals(diff.Font)) + if ((writer.SerializeTo != SerializeTo.Preview || !Font.Equals(diff.Font)) && writer.ItemName != "inherited") { writer.WriteValue(prefix + ".Font", Font); } diff --git a/FastReport.Base/GroupHeaderBand.cs b/FastReport.Base/GroupHeaderBand.cs index 87862a07..aac575cd 100644 --- a/FastReport.Base/GroupHeaderBand.cs +++ b/FastReport.Base/GroupHeaderBand.cs @@ -287,7 +287,7 @@ public override bool CanContain(Base child) { return base.CanContain(child) || (child is DataBand && nestedGroup == null && data == null) || - (child is GroupHeaderBand && nestedGroup == null && data == null) || + (child is GroupHeaderBand && (nestedGroup == null || nestedGroup is GroupHeaderBand) && data == null) || child is GroupFooterBand || child is DataHeaderBand || child is DataFooterBand; } diff --git a/FastReport.Base/PictureObject.cs b/FastReport.Base/PictureObject.cs index 3cc4e0c1..f88570fb 100644 --- a/FastReport.Base/PictureObject.cs +++ b/FastReport.Base/PictureObject.cs @@ -482,9 +482,9 @@ public override void LoadImage() { Uri uri = CalculateUri(); if (uri.IsFile) - imageData = ImageHelper.Load(uri.LocalPath); + SetImageData(ImageHelper.Load(uri.LocalPath)); else - imageData = ImageHelper.LoadURL(uri.ToString()); + SetImageData(ImageHelper.LoadURL(uri.ToString())); } catch { diff --git a/FastReport.Base/PictureObjectBase.cs b/FastReport.Base/PictureObjectBase.cs index 55c3a658..84668733 100644 --- a/FastReport.Base/PictureObjectBase.cs +++ b/FastReport.Base/PictureObjectBase.cs @@ -762,7 +762,7 @@ internal virtual void DrawImageInternal(FRPaintEventArgs e, RectangleF drawRect) // TODO translate tranform matrix, WTF mono or coreCompat or both // cant work with negative transforms so need to fix it -#if NETSTANDARD2_0 +#if NETSTANDARD2_0 || NETSTANDARD2_1 System.Drawing.Drawing2D.Matrix matrixBack = e.Graphics.Transform; @@ -789,7 +789,7 @@ internal virtual void DrawImageInternal(FRPaintEventArgs e, RectangleF drawRect) DrawImageInternal2(e.Graphics, upperLeft, upperRight, lowerLeft); -#if NETSTANDARD2_0 +#if NETSTANDARD2_0 || NETSTANDARD2_1 e.Graphics.Transform = matrixBack; #endif } diff --git a/FastReport.Base/PolyLineObject.cs b/FastReport.Base/PolyLineObject.cs index 9052eb5d..a74b391d 100644 --- a/FastReport.Base/PolyLineObject.cs +++ b/FastReport.Base/PolyLineObject.cs @@ -1,5 +1,6 @@ using FastReport.Utils; using System; +using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; @@ -18,13 +19,36 @@ namespace FastReport /// public partial class PolyLineObject : ReportComponentBase { - #region Fields + #region Protected Internal Fields + + /// + /// do not set this value, internal use only + /// + protected internal PolygonSelectionMode polygonSelectionMode; + + #endregion Protected Internal Fields + + #region Private Fields + private PointF center; - private List points; - private List pointTypes; - #endregion Fields + private PolyPointCollection pointsCollection; + + #endregion Private Fields + + #region Public Properties + + /// + /// Return points collection. + /// You can modify the collection for change this object. + /// + public PolyPointCollection Points + { + get + { + return pointsCollection; + } + } - #region Properties /// /// Returns origin of coordinates relative to the top left corner /// @@ -39,110 +63,134 @@ public partial class PolyLineObject : ReportComponentBase /// /// Return points array of line + /// deprecated /// [Browsable(false)] + [Obsolete] public PointF[] PointsArray { get { - if (points == null || points.Count == 0) return new PointF[0]; - return points.ToArray(); + List result = new List(); + foreach (PolyPoint point in pointsCollection) + { + result.Add(new PointF(point.X, point.Y)); + } + return result.ToArray(); } } /// /// Return point types array. 0 - Start of line, 1 - Keep on line + /// deprecated /// [Browsable(false)] + [Obsolete] public byte[] PointTypesArray { get { - if (pointTypes == null || pointTypes.Count == 0) return new byte[0]; - return pointTypes.ToArray(); + List result = new List(); + result.Add(0); + for (int i = 1; i < pointsCollection.Count; i++) + result.Add(1); + return result.ToArray(); } } - #endregion Properties - #region Private Methods - private float getDistance(float px, float py, float px0, float py0, float px1, float py1, out int index) - { - float vx = px1 - px0; - float vy = py1 - py0; - float wx = px - px0; - float wy = py - py0; - float c1 = vx * wx + vy * wy; - if (c1 <= 0) { index = -1; return (px0 - px) * (px0 - px) + (py0 - py) * (py0 - py); } - float c2 = vx * vx + vy * vy; - if (c2 <= c1) { index = 1; return (px1 - px) * (px1 - px) + (py1 - py) * (py1 - py); } - float b = c1 / c2; - index = 0; - float bx = px0 + vx * b; - float by = py0 + vy * b; - return (bx - px) * (bx - px) + (by - py) * (by - py); - } - #endregion Private Methods + #endregion Public Properties + + #region Public Constructors - #region Protected Methods /// - /// Add point to end of polyline, need to recalculate bounds after add - /// First point must have zero coordinate and zero type + /// Initializes a new instance of the class with default settings. /// - /// local x - relative to left-top point - /// local y - relative to left-top point - /// 0-start,1-line - protected void addPoint(float localX, float localY, byte pointType) + public PolyLineObject() { - if (points == null) - { - points = new List(); - points.Add(new PointF(localX, localY)); - } - else - { - points.Add(new PointF(localX, localY)); - } - if (pointTypes == null) - { - pointTypes = new List(); - pointTypes.Add((byte)PathPointType.Start); - } - else - { - pointTypes.Add(pointType); - } + FlagSimpleBorder = true; + FlagUseFill = false; + pointsCollection = new PolyPointCollection(); + center = PointF.Empty; + InitDesign(); } - /// - /// Delete point from polyline by index - /// Recalculate bounds - /// - /// Index of point in polyline - protected void deletePoint(int index) + #endregion Public Constructors + + #region Public Methods + + /// + public override void Assign(Base source) { - if (points == null || points.Count == 0) - return; - if (pointTypes[index] == 0 && index < pointTypes.Count - 1) + base.Assign(source); + + PolyLineObject src = source as PolyLineObject; + + pointsCollection = src.pointsCollection.Clone(); + center = src.center; + //recalculateBounds(); + } + + /// + public override void Deserialize(FRReader reader) + { + base.Deserialize(reader); + pointsCollection.Clear(); + if (reader.HasProperty("PolyPoints")) { - pointTypes[index + 1] = 0; + string polyPoints = reader.ReadStr("PolyPoints"); + foreach (string str in polyPoints.Split('|')) + { + string[] point = str.Split('\\'); + if (point.Length == 3) + { + float f1 = float.Parse(point[0].Replace(',', '.'), CultureInfo.InvariantCulture); + float f2 = float.Parse(point[1].Replace(',', '.'), CultureInfo.InvariantCulture); + pointsCollection.Add(new PolyPoint(f1, f2)); + } + } } - if (points.Count > 1) + else if (reader.HasProperty("PolyPoints_v2")) { - points.RemoveAt(index); - pointTypes.RemoveAt(index); - recalculateBounds(); + string polyPoints = reader.ReadStr("PolyPoints_v2"); + foreach (string str in polyPoints.Split('|')) + { + PolyPoint point = new PolyPoint(); + point.Deserialize(str); + pointsCollection.Add(point); + } } + if (reader.HasProperty("CenterX")) + center.X = reader.ReadFloat("CenterX"); + if (reader.HasProperty("CenterY")) + center.Y = reader.ReadFloat("CenterY"); + //recalculateBounds(); } - /// - /// Draw polyline path to graphics - /// - /// Event arguments - protected virtual void drawPoly(FRPaintEventArgs e) + /// + public override void Draw(FRPaintEventArgs e) { - Pen pen = e.Cache.GetPen(Border.Color, Border.Width * e.ScaleX, Border.DashStyle); - using (GraphicsPath path = GetPath(pen, AbsLeft, AbsTop, AbsRight, AbsBottom, e.ScaleX, e.ScaleY)) - e.Graphics.DrawPath(pen, path); + switch (pointsCollection.Count) + { + case 0: + case 1: + Graphics g = e.Graphics; + float x = AbsLeft + CenterX; + float y = AbsTop + CenterY; + if(pointsCollection.Count == 1) + { + x += pointsCollection[0].X; + y += pointsCollection[0].Y; + } + g.DrawLine(Pens.Black, x * e.ScaleX - 6, y * e.ScaleY, x * e.ScaleX + 6, y * e.ScaleY); + g.DrawLine(Pens.Black, x * e.ScaleX, y * e.ScaleY - 6, x * e.ScaleX, y * e.ScaleY + 6); + break; + + default: + DoDrawPoly(e); + DrawDesign0(e); + break; + } + DrawDesign1(e); } /// @@ -158,222 +206,730 @@ protected virtual void drawPoly(FRPaintEventArgs e) /// Always returns a non-empty path public GraphicsPath GetPath(Pen pen, float left, float top, float right, float bottom, float scaleX, float scaleY) { - if (points == null) + if (pointsCollection.Count == 0) { GraphicsPath result = new GraphicsPath(); - result.AddLine(left, top, right + 1, bottom + 1); + result.AddLine(left * scaleX, top * scaleX, (right + 1) * scaleX, (bottom + 1) * scaleX); return result; } - GraphicsPath gp = null; - if (points.Count > 1) + else if (pointsCollection.Count == 1) { - PointF[] aPoints = new PointF[points.Count]; - int i = 0; - foreach (PointF point in points) + GraphicsPath result = new GraphicsPath(); + left = left + CenterX + pointsCollection[0].X; + top = top + CenterY + pointsCollection[0].Y; + result.AddLine(left * scaleX, top * scaleX, (left + 1) * scaleX, (top + 1) * scaleX); + return result; + } + + List aPoints = new List(); + List pointTypes = new List(); + + PolyPoint prev = null; + PolyPoint point = pointsCollection[0]; + + aPoints.Add(new PointF((point.X + left + center.X) * scaleX, (point.Y + top + center.Y) * scaleY)); + pointTypes.Add(0); + + int count = pointsCollection.Count; + if (this is PolygonObject) + { + count++; + } + + for (int i = 1; i < count; i++) + { + prev = point; + point = pointsCollection[i]; + + //is bezier? + if (prev.RightCurve != null || point.LeftCurve != null) + { + if (prev.RightCurve != null) + { + aPoints.Add(new PointF((prev.X + left + center.X + prev.RightCurve.X) * scaleX, (prev.Y + top + center.Y + prev.RightCurve.Y) * scaleY)); + pointTypes.Add(3); + } + else + { + PolyPoint pseudo = GetPseudoPoint(prev, point); + aPoints.Add(new PointF((pseudo.X + left + center.X) * scaleX, (pseudo.Y + top + center.Y) * scaleY)); + pointTypes.Add(3); + } + + if (point.LeftCurve != null) + { + aPoints.Add(new PointF((point.X + left + center.X + point.LeftCurve.X) * scaleX, (point.Y + top + center.Y + point.LeftCurve.Y) * scaleY)); + pointTypes.Add(3); + } + else + { + PolyPoint pseudo = GetPseudoPoint(point, prev); + aPoints.Add(new PointF((pseudo.X + left + center.X) * scaleX, (pseudo.Y + top + center.Y) * scaleY)); + pointTypes.Add(3); + } + + aPoints.Add(new PointF((point.X + left + center.X) * scaleX, (point.Y + top + center.Y) * scaleY)); + pointTypes.Add(3); + } + else { - aPoints[i] = new PointF((point.X + left + center.X) * scaleX, (point.Y + top + center.Y) * scaleY); - i++; + aPoints.Add(new PointF((point.X + left + center.X) * scaleX, (point.Y + top + center.Y) * scaleY)); + pointTypes.Add(1); } - gp = new GraphicsPath(aPoints, pointTypes.ToArray()); } - else gp = new GraphicsPath(); - return gp; + return new GraphicsPath(aPoints.ToArray(), pointTypes.ToArray()); } /// - /// Insert point to desired place of polyline + /// Recalculate position and size of element /// - /// Index of place from zero to count - /// local x - relative to left-top point - /// local y - relative to left-top point - /// 0-start,1-line - protected void insertPoint(int index, float localX, float localY, byte pointType) + public void RecalculateBounds() { - if (points == null || points.Count == 0) + if (pointsCollection.Count > 0) { - addPoint(localX, localY, pointType); - return; + // init + PolyPoint prev = null; + PolyPoint point = pointsCollection[0]; + float left = point.X; + float top = point.Y; + float right = point.X; + float bottom = point.Y; + int count = pointsCollection.Count; + if (this is PolygonObject) + count++; + + // stage 1 calculate min bounds + + foreach (PolyPoint pnt in pointsCollection) + { + if (pnt.X < left) + left = pnt.X; + else if (pnt.X > right) + right = pnt.X; + + if (pnt.Y < top) + top = pnt.Y; + else if (pnt.Y > bottom) + bottom = pnt.Y; + } + + // stage 2 check if one of bezier way point is outside + + for (int i = 1; i < count; i++) + { + prev = point; + point = pointsCollection[i]; + + bool haveToCalculate = false; + + + PolyPoint p_1 = null; + PolyPoint p_2 = null; + + if (prev.RightCurve != null) + { + p_1 = new PolyPoint(prev.X + prev.RightCurve.X, prev.Y + prev.RightCurve.Y); + + if (p_1.X < left) + haveToCalculate = true; + else if (p_1.X > right) + haveToCalculate = true; + + if (p_1.Y < top) + haveToCalculate = true; + else if (p_1.Y > bottom) + haveToCalculate = true; + } + + if (point.LeftCurve != null) + { + p_2 = new PolyPoint(point.X + point.LeftCurve.X, point.Y + point.LeftCurve.Y); + if (p_2.X < left) + haveToCalculate = true; + else if (p_2.X > right) + haveToCalculate = true; + + if (p_2.Y < top) + haveToCalculate = true; + else if (p_2.Y > bottom) + haveToCalculate = true; + } + + if (haveToCalculate) + { + if (p_1 == null) + p_1 = GetPseudoPoint(prev, point); + + if (p_2 == null) + p_2 = GetPseudoPoint(point, prev); + + + // now calculate extrema + + // x + float delta = RecalculateBounds_Delta(prev.X, p_1.X, p_2.X, point.X); + if (delta > 0) + { + delta = (float)Math.Sqrt(delta); + float t_1 = RecalculateBounds_Solve(prev.X, p_1.X, p_2.X, point.X, -delta); + if (0 < t_1 && t_1 < 1) + { + float x = RecalculateBounds_Value(prev.X, p_1.X, p_2.X, point.X, t_1); + if (x < left) + left = x; + else if (x > right) + right = x; + } + float t_2 = RecalculateBounds_Solve(prev.X, p_1.X, p_2.X, point.X, delta); + if (0 < t_2 && t_2 < 1) + { + float x = RecalculateBounds_Value(prev.X, p_1.X, p_2.X, point.X, t_2); + if (x < left) + left = x; + else if (x > right) + right = x; + } + } + + // y + delta = RecalculateBounds_Delta(prev.Y, p_1.Y, p_2.Y, point.Y); + if (delta > 0) + { + delta = (float)Math.Sqrt(delta); + float t_1 = RecalculateBounds_Solve(prev.Y, p_1.Y, p_2.Y, point.Y, -delta); + if (0 < t_1 && t_1 < 1) + { + float y = RecalculateBounds_Value(prev.Y, p_1.Y, p_2.Y, point.Y, t_1); + if (y < top) + top = y; + else if (y > bottom) + bottom = y; + } + float t_2 = RecalculateBounds_Solve(prev.Y, p_1.Y, p_2.Y, point.Y, delta); + if (0 < t_2 && t_2 < 1) + { + float y = RecalculateBounds_Value(prev.Y, p_1.Y, p_2.Y, point.Y, t_2); + if (y < top) + top = y; + else if (y > bottom) + bottom = y; + } + } + + + } + } + + + // update + float centerX = center.X; + float centerY = center.Y; + center.X = -left; + center.Y = -top; + base.Left += left + centerX; + base.Top += top + centerY; + base.Height = bottom - top; + base.Width = right - left; } + else + { + CenterX = 0; + CenterY = 0; + base.Width = 5; + base.Height = 5; + } + } - if (pointTypes.Count > index && pointTypes[index] == 0) { pointTypes[index] = 1; pointType = 0; } - points.Insert(index, new PointF(localX, localY)); - pointTypes.Insert(index, pointType); - //recalculateBounds(); + private float RecalculateBounds_Delta(float p_0,float p_1, float p_2, float p_3) + { + return p_1 * p_1 - p_0 * p_2 - p_1 * p_2 + p_2 * p_2 + p_0 * p_3 - p_1 * p_3; } - /// - /// Recalculate position and size of element - /// - protected void recalculateBounds() + private float RecalculateBounds_Solve(float p_0, float p_1, float p_2, float p_3, float deltaSqrt) { - float left = points[0].X; - float top = points[0].Y; - float right = points[0].X; - float bottom = points[0].Y; + return (p_0 - 2 * p_1 + p_2 + deltaSqrt) / (p_0 - 3 * p_1 + 3 * p_2 - p_3); + } + + private float RecalculateBounds_Value(float p_0, float p_1, float p_2, float p_3, float t) + { + float t1 = 1 - t; + return p_0 * t1 * t1 * t1 + 3 * p_1 * t1 * t1 * t + 3 * p_2 * t1 * t * t + p_3 * t * t * t; + } + + /// + public override void Serialize(FRWriter writer) + { + Border.SimpleBorder = true; + base.Serialize(writer); + PolyLineObject c = writer.DiffObject as PolyLineObject; - foreach (PointF point in points) + StringBuilder sb = new StringBuilder(pointsCollection.Count * 10); + foreach (PolyPoint point in pointsCollection) { - if (point.X < left) - left = point.X; - else if (point.X > right) - right = point.X; - if (point.Y < top) - top = point.Y; - else if (point.Y > bottom) - bottom = point.Y; + point.Serialize(sb); + sb.Append("|"); } - if (Math.Abs(right - left) == 0) + + if (sb.Length > 0) + sb.Length--; + + writer.WriteStr("PolyPoints_v2", sb.ToString()); + + writer.WriteFloat("CenterX", center.X); + writer.WriteFloat("CenterY", center.Y); + } + + public void SetPolyLine(PointF[] newPoints) + { + pointsCollection.Clear(); + if (newPoints != null) { - right += 1; + CenterX = 0; + CenterY = 0; + foreach (PointF point in newPoints) + { + pointsCollection.Add(new PolyPoint(point.X, point.Y)); + } } - if (Math.Abs(bottom - top) == 0) + float l = Left; + float t = Top; + RecalculateBounds(); + Left = l; + Top = t; + } + + #endregion Public Methods + + #region Internal Methods + + internal void DoDrawPoly(FRPaintEventArgs e) + { + Graphics g = e.Graphics; + Report report = Report; + if (report != null && report.SmoothGraphics) { - bottom += 1; + g.InterpolationMode = InterpolationMode.HighQualityBicubic; + g.SmoothingMode = SmoothingMode.AntiAlias; + } + + drawPoly(e); + + if (report != null && report.SmoothGraphics) + { + g.InterpolationMode = InterpolationMode.Default; + g.SmoothingMode = SmoothingMode.Default; } - Left += left + center.X; - center.X = -left; - base.Width = Math.Abs(right - left); - Top += top + center.Y; - center.Y = -top; - base.Height = Math.Abs(bottom - top); } - #endregion Protected Methods - #region Public Methods - /// - public override void Assign(Base source) + #endregion Internal Methods + + #region Protected Methods + + /// + /// Add point to end of polyline, need to recalculate bounds after add + /// First point must have zero coordinate and zero type. + /// Recalculate bounds. + /// Method is slow do not use this. + /// + /// local x - relative to left-top point + /// local y - relative to left-top point + /// depreceted + protected PolyPoint addPoint(float localX, float localY, byte pointType) { - base.Assign(source); + PolyPoint result; + pointsCollection.Add(result = new PolyPoint(localX, localY)); + RecalculateBounds(); + return result; + } - PolyLineObject src = source as PolyLineObject; - if (src.points == null) return; - if (src.pointTypes == null) return; - points = new List(src.points); - pointTypes = new List(src.pointTypes); - center = src.center; - //recalculateBounds(); + /// + /// Delete point from polyline by index. + /// Recalculate bounds. + /// Method is slow do not use this. + /// + /// Index of point in polyline + protected void deletePoint(int index) + { + pointsCollection.Remove(index); + RecalculateBounds(); } - /// - public override void Deserialize(FRReader reader) + /// + /// Draw polyline path to graphics + /// + /// Event arguments + protected virtual void drawPoly(FRPaintEventArgs e) { - base.Deserialize(reader); - points = new List(); - pointTypes = new List(); - string polyPoints = reader.ReadStr("PolyPoints"); - foreach (string str in polyPoints.Split('|')) - { - string[] point = str.Split('\\'); - if (point.Length == 3) - { - float f1 = float.Parse(point[0].Replace(',', '.'), CultureInfo.InvariantCulture); - float f2 = float.Parse(point[1].Replace(',', '.'), CultureInfo.InvariantCulture); - addPoint(f1, f2, byte.Parse(point[2])); - } - } - if (reader.HasProperty("CenterX")) - center.X = reader.ReadFloat("CenterX"); - if (reader.HasProperty("CenterY")) - center.Y = reader.ReadFloat("CenterY"); - //recalculateBounds(); + Pen pen; + if (polygonSelectionMode == PolygonSelectionMode.MoveAndScale) + pen = e.Cache.GetPen(Border.Color, Border.Width * e.ScaleX, Border.DashStyle); + else pen = e.Cache.GetPen(Border.Color, 1, DashStyle.Solid); + + using (GraphicsPath path = GetPath(pen, AbsLeft, AbsTop, AbsRight, AbsBottom, e.ScaleX, e.ScaleY)) + e.Graphics.DrawPath(pen, path); } - internal void DoDrawPoly(FRPaintEventArgs e) - { - Graphics g = e.Graphics; - Report report = Report; - if (report != null && report.SmoothGraphics) + /// + /// Insert point to desired place of polyline + /// recalculateBounds(); + /// Method is slow do not use this + /// + /// Index of place from zero to count + /// local x - relative to left-top point + /// local y - relative to left-top point + /// deprecated + protected PolyPoint insertPoint(int index, float localX, float localY, byte pointType) { - g.InterpolationMode = InterpolationMode.HighQualityBicubic; - g.SmoothingMode = SmoothingMode.AntiAlias; + PolyPoint result; + pointsCollection.Insert(index, result = new PolyPoint(localX, localY)); + RecalculateBounds(); + return result; } - drawPoly(e); + #endregion Protected Methods - if (report != null && report.SmoothGraphics) + #region Private Methods + + private float getDistance(float px, float py, float px0, float py0, float px1, float py1, out int index) { - g.InterpolationMode = InterpolationMode.Default; - g.SmoothingMode = SmoothingMode.Default; + float vx = px1 - px0; + float vy = py1 - py0; + float wx = px - px0; + float wy = py - py0; + float c1 = vx * wx + vy * wy; + if (c1 <= 0) { index = -1; return (px0 - px) * (px0 - px) + (py0 - py) * (py0 - py); } + float c2 = vx * vx + vy * vy; + if (c2 <= c1) { index = 1; return (px1 - px) * (px1 - px) + (py1 - py) * (py1 - py); } + float b = c1 / c2; + index = 0; + float bx = px0 + vx * b; + float by = py0 + vy * b; + return (bx - px) * (bx - px) + (by - py) * (by - py); } - } - /// - public override void Draw(FRPaintEventArgs e) + private PolyPoint GetPseudoPoint(PolyPoint start, PolyPoint end) { - if ((points == null || points.Count == 1)) + float vecX = end.X - start.X; + float vecY = end.Y - start.Y; + + float distance = (float)Math.Sqrt(vecX * vecX + vecY * vecY); + + vecX = vecX / 3; + vecY = vecY / 3; + + return new PolyPoint(start.X + vecX, start.Y + vecY); + } + + #endregion Private Methods + + #region Protected Internal Enums + + protected internal enum PolygonSelectionMode : int + { + MoveAndScale, + Normal, + AddToLine, + AddBezier, + Delete + } + + #endregion Protected Internal Enums + + #region Public Classes + + /// + /// Represent a point for polygon object + /// + public class PolyPoint + { + #region Private Fields + + private static readonly NumberFormatInfo invariant; + private PolyPoint left; + private PolyPoint right; + private float x; + private float y; + + #endregion Private Fields + + #region Public Properties + + public PolyPoint LeftCurve { - Graphics g = e.Graphics; - g.DrawLine(Pens.Black, AbsLeft * e.ScaleX - 6, AbsTop * e.ScaleY, AbsLeft * e.ScaleX + 6, AbsTop * e.ScaleY); - g.DrawLine(Pens.Black, AbsLeft * e.ScaleX, AbsTop * e.ScaleY - 6, AbsLeft * e.ScaleX, AbsTop * e.ScaleY + 6); + get { return left; } + set { left = value; } } - else + + public PolyPoint RightCurve { - DoDrawPoly(e); - DrawDesign0(e); + get { return right; } + set { right = value; } } - DrawDesign1(e); - } - /// - public override void Serialize(FRWriter writer) - { - Border.SimpleBorder = true; - base.Serialize(writer); - PolyLineObject c = writer.DiffObject as PolyLineObject; + public float X + { + get { return x; } + set { x = value; } + } - StringBuilder sb = new StringBuilder(points.Count * 10); - for (int i = 0; i < points.Count; i++) + public float Y { - sb.AppendFormat("{0}\\{1}\\{2}", points[i].X.ToString(CultureInfo.InvariantCulture), - points[i].Y.ToString(CultureInfo.InvariantCulture), - pointTypes[i]); - if (i < points.Count - 1) - sb.Append("|"); + get { return y; } + set { y = value; } } - writer.WriteStr("PolyPoints", sb.ToString()); + #endregion Public Properties - writer.WriteFloat("CenterX", center.X); - writer.WriteFloat("CenterY", center.Y); + #region Public Constructors + + static PolyPoint() + { + invariant = new NumberFormatInfo(); + invariant.NumberGroupSeparator = String.Empty; + invariant.NumberDecimalSeparator = "."; + } + + public PolyPoint() + { + } + + public PolyPoint(float x, float y) + { + this.x = x; + this.y = y; + } + + #endregion Public Constructors + + #region Public Methods + + public void Deserialize(string s) + { + string[] strs = s.Split('/'); + int index = 0; + Deserialize(strs, ref index); + if (index < strs.Length) + { + if (strs[index] == "L") + { + index++; + LeftCurve = new PolyPoint(); + LeftCurve.Deserialize(strs, ref index); + } + + if (index < strs.Length) + { + if (strs[index] == "R") + { + index++; + RightCurve = new PolyPoint(); + RightCurve.Deserialize(strs, ref index); + } + } + } + } + + public bool Near(PolyPoint p) + { + return (p != null) && (Math.Abs(x - p.x) < 0.0001) && (Math.Abs(y - p.y) < 0.0001); + } + + public void ScaleX(float scale) + { + x *= scale; + if (LeftCurve != null) + LeftCurve.X *= scale; + if (RightCurve != null) + RightCurve.X *= scale; + } + + public void ScaleY(float scale) + { + y *= scale; + if (LeftCurve != null) + LeftCurve.Y *= scale; + if (RightCurve != null) + RightCurve.Y *= scale; + } + + public void Serialize(StringBuilder sb) + { + sb.Append(Round(x)).Append("/").Append(Round(y)); + if (LeftCurve != null) + { + sb.Append("/L/").Append(Round(LeftCurve.X)).Append("/").Append(Round(LeftCurve.Y)); + } + if (RightCurve != null) + { + sb.Append("/R/").Append(Round(RightCurve.X)).Append("/").Append(Round(RightCurve.Y)); + } + } + + public override string ToString() + { + return "(" + Round(x) + ";" + Round(y) + ")"; + } + + #endregion Public Methods + + #region Private Methods + + private void Deserialize(string[] strs, ref int index) + { + for (int i = 0; i < 2 && index < strs.Length; i++) + { + switch (i) + { + case 0: + Single.TryParse(strs[index], NumberStyles.Float, invariant, out x); + break; + + case 1: + Single.TryParse(strs[index], NumberStyles.Float, invariant, out y); + break; + } + index++; + } + } + + private string Round(float value) + { + return Convert.ToString(Math.Round(value, 4), invariant); + } + + #endregion Private Methods } - public void SetPolyLine(PointF[] newPoints) + public class PolyPointCollection : IEnumerable { - if(newPoints == null || newPoints.Length == 1) + #region Private Fields + + private List points; + + #endregion Private Fields + + #region Public Indexers + + public PolyPoint this[int index] { - this.points = new List(); - this.pointTypes = new List(); + get + { + index = NormalizeIndex(index); + return points[index]; + } + set + { + index = NormalizeIndex(index); + points[index] = value; + } } - else + + #endregion Public Indexers + + #region Public Properties + + public int Count { - this.points = new List(newPoints); - byte[] pointTypes = new byte[newPoints.Length]; - if (pointTypes.Length > 0) - pointTypes[0] = 0; - for (int i = 1; i < pointTypes.Length; i++) - pointTypes[i] = 1; - this.pointTypes = new List(pointTypes); + get + { + return points.Count; + } } - recalculateBounds(); - } - #endregion Public Methods + public bool IsReadOnly + { + get + { + return false; + } + } - #region Public Constructors + #endregion Public Properties - /// - /// Initializes a new instance of the class with default settings. - /// - public PolyLineObject() - { - FlagSimpleBorder = true; - FlagUseFill = false; - points = null; - pointTypes = null; - center = PointF.Empty; - InitDesign(); + #region Public Constructors + + public PolyPointCollection() + { + points = new List(); + } + + #endregion Public Constructors + + #region Public Methods + + public void Add(PolyPoint item) + { + points.Add(item); + } + + public void Clear() + { + points.Clear(); + } + + public PolyPointCollection Clone() + { + PolyPointCollection result = new PolyPointCollection(); + result.points = new List(points); + return result; + } + + public IEnumerator GetEnumerator() + { + return points.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return points.GetEnumerator(); + } + + public int IndexOf(PolyPoint currentPoint) + { + return points.IndexOf(currentPoint); + } + + public void Insert(int index, PolyPoint item) + { + int count = points.Count; + + if (count > 0) + { + while (index < 0) + index += count; + while (index > count) + index -= count; + } + points.Insert(index, item); + } + + public void Remove(int index) + { + index = NormalizeIndex(index); + points.RemoveAt(index); + } + + #endregion Public Methods + + #region Private Methods + + private int NormalizeIndex(int index) + { + int count = points.Count; + if (count == 0) + return 0; + if (index >= 0 && index < count) + return index; + while (index < 0) + index += count; + while (index >= count) + index -= count; + return index; + } + + #endregion Private Methods } - #endregion Public Constructors + #endregion Public Classes } } \ No newline at end of file diff --git a/FastReport.Base/PolygonObject.cs b/FastReport.Base/PolygonObject.cs index 7e789f3a..bcc76083 100644 --- a/FastReport.Base/PolygonObject.cs +++ b/FastReport.Base/PolygonObject.cs @@ -41,14 +41,22 @@ protected override void drawPoly(FRPaintEventArgs e) float dx = (Width - Border.Width) * e.ScaleX - 1; float dy = (Height - Border.Width) * e.ScaleY - 1; - Pen pen = e.Cache.GetPen(Border.Color, Border.Width * e.ScaleX, Border.DashStyle); + Pen pen; + if (polygonSelectionMode == PolygonSelectionMode.MoveAndScale) + { + pen = e.Cache.GetPen(Border.Color, Border.Width * e.ScaleX, Border.DashStyle); + } + else pen = e.Cache.GetPen(Border.Color, 1, DashStyle.Solid); + Brush brush = null; if (Fill is SolidFill) brush = e.Cache.GetBrush((Fill as SolidFill).Color); else brush = Fill.CreateBrush(new RectangleF(x, y, dx, dy), e.ScaleX, e.ScaleY); + using (GraphicsPath path = getPolygonPath(pen, e.ScaleX, e.ScaleY)) { + if(polygonSelectionMode == PolygonSelectionMode.MoveAndScale) e.Graphics.FillPath(brush, path); e.Graphics.DrawPath(pen, path); } diff --git a/FastReport.Base/Report.cs b/FastReport.Base/Report.cs index a9fc27a1..aaf507df 100644 --- a/FastReport.Base/Report.cs +++ b/FastReport.Base/Report.cs @@ -804,7 +804,7 @@ internal Graphics MeasureGraphics { if (measureGraphics == null) { -#if NETSTANDARD2_0 +#if NETSTANDARD2_0 || NETSTANDARD2_1 measureBitmap = new Bitmap(1, 1); measureGraphics = Graphics.FromImage(measureBitmap); #else @@ -1266,32 +1266,9 @@ public object Calc(string expression, Variant value) DataSourceBase data = cachedItem.dataSource; Column column = cachedItem.column; - object val = column.Value; + object val = ConvertToColumnDataType(column.Value, column.DataType); - if (val == null || val is DBNull) - { - if (ConvertNulls) - val = Converter.ConvertNull(column.DataType); - } - else - { - if (val is IConvertible) - { - Type t = Nullable.GetUnderlyingType(column.DataType); - try - { - val = Convert.ChangeType(val, t != null ? t : column.DataType); - } - catch (InvalidCastException) - { - // do nothing - } - catch (FormatException) - { - // do nothing - } - } - } + if (CustomCalc != null) { @@ -1319,6 +1296,35 @@ public object Calc(string expression, Variant value) return CalcExpression(expression, value); } + private object ConvertToColumnDataType( object val, Type dataType) + { + if (val == null || val is DBNull) + { + if (ConvertNulls) + val = Converter.ConvertNull(dataType); + } + else + { + if (val is IConvertible) + { + Type t = Nullable.GetUnderlyingType(dataType); + try + { + val = Convert.ChangeType(val, t != null ? t : dataType); + } + catch (InvalidCastException) + { + // do nothing + } + catch (FormatException) + { + // do nothing + } + } + } + return val; + } + /// /// Returns an expression value. /// @@ -1381,12 +1387,7 @@ private object GetColumnValue(string complexName, bool convertNull) if (column == null) return null; - object value = column.Value; - - if (convertNull && (value == null || value is DBNull)) - value = Converter.ConvertNull(column.DataType); - - return value; + return ConvertToColumnDataType(column.Value, column.DataType); } private Variant GetTotalValue(string name, bool convertNull) diff --git a/FastReport.Base/StyleBase.cs b/FastReport.Base/StyleBase.cs index 6e082cbc..f80a9602 100644 --- a/FastReport.Base/StyleBase.cs +++ b/FastReport.Base/StyleBase.cs @@ -158,7 +158,7 @@ public virtual void Serialize(FRWriter writer) Border.Serialize(writer, "Border", c.Border); Fill.Serialize(writer, "Fill", c.Fill); TextFill.Serialize(writer, "TextFill", c.TextFill); - if (writer.SerializeTo != SerializeTo.Preview || !Font.Equals(c.Font)) + if ((writer.SerializeTo != SerializeTo.Preview || !Font.Equals(c.Font)) && writer.ItemName != "inherited") writer.WriteValue("Font", Font); if (ApplyBorder != c.ApplyBorder) writer.WriteBool("ApplyBorder", ApplyBorder); diff --git a/FastReport.Base/Table/TableResult.cs b/FastReport.Base/Table/TableResult.cs index cee19693..d9c28df3 100644 --- a/FastReport.Base/Table/TableResult.cs +++ b/FastReport.Base/Table/TableResult.cs @@ -101,7 +101,7 @@ private int GetRowsFit(int startRow, float freeSpace) while (startRow + rowsFit < Rows.Count && (rowsFit == 0 || !Rows[startRow + rowsFit].PageBreak) && - GetRowsHeight(startRow, rowsFit + 1) <= freeSpace + 0.1f) + (!this.CanBreak | GetRowsHeight(startRow, rowsFit + 1) <= freeSpace + 0.1f)) { if (keeping) { @@ -264,7 +264,7 @@ internal void CalcBounds() OnAfterData(); // calculate cells' bounds - CalcHeight(); + Height = CalcHeight(); // fire AfterCalcBounds event OnAfterCalcBounds(); @@ -325,7 +325,7 @@ private void GeneratePagesAcrossThenDown() engine.CurY = saveCurY; curY = GeneratePage(startColumn, startRow, columnsFit, rowsFit, - new RectangleF(0, 0, engine.PageWidth, freeSpace), spans) + saveCurY; + new RectangleF(0, 0, engine.PageWidth, CanBreak ? freeSpace : Height), spans) + saveCurY; Left = 0; startColumn += columnsFit; diff --git a/FastReport.Base/TextObject.cs b/FastReport.Base/TextObject.cs index 2f2dce88..6e4cbb08 100644 --- a/FastReport.Base/TextObject.cs +++ b/FastReport.Base/TextObject.cs @@ -82,7 +82,7 @@ public enum TextRenderType /// /// The format of paragraph /// - [TypeConverterAttribute(typeof(ExpandableObjectConverter))] + [TypeConverterAttribute(typeof(TypeConverters.FRExpandableObjectConverter))] public class ParagraphFormat { private float firstLineIndent; @@ -172,6 +172,26 @@ internal void Assign(ParagraphFormat p) firstLineIndent = p.firstLineIndent; skipFirstLineIndent = p.skipFirstLineIndent; } + + public override bool Equals(object obj) + { + ParagraphFormat format = obj as ParagraphFormat; + return format != null && + firstLineIndent == format.firstLineIndent && + lineSpacing == format.lineSpacing && + lineSpacingType == format.lineSpacingType && + skipFirstLineIndent == format.skipFirstLineIndent; + } + + public override int GetHashCode() + { + int hashCode = -1051315095; + hashCode = hashCode * -1521134295 + firstLineIndent.GetHashCode(); + hashCode = hashCode * -1521134295 + lineSpacing.GetHashCode(); + hashCode = hashCode * -1521134295 + lineSpacingType.GetHashCode(); + hashCode = hashCode * -1521134295 + skipFirstLineIndent.GetHashCode(); + return hashCode; + } } /// @@ -745,7 +765,7 @@ private SizeF CalcSize() return new SizeF(width, height); } } -#if !NETSTANDARD2_0 +#if !(NETSTANDARD2_0 || NETSTANDARD2_1) if (IsAdvancedRendererNeeded) #endif { @@ -763,7 +783,7 @@ private SizeF CalcSize() height += Padding.Vertical + 1; return new SizeF(width, height); } -#if !NETSTANDARD2_0 +#if !(NETSTANDARD2_0 || NETSTANDARD2_1) else { if (FontWidthRatio != 1) @@ -1278,7 +1298,7 @@ public override void Serialize(FRWriter writer) writer.WriteBool("WordWrap", WordWrap); if (Underlines != c.Underlines) writer.WriteBool("Underlines", Underlines); - if (writer.SerializeTo != SerializeTo.Preview || !Font.Equals(c.Font)) + if ((writer.SerializeTo != SerializeTo.Preview || !Font.Equals(c.Font)) && writer.ItemName != "inherited") writer.WriteValue("Font", Font); TextFill.Serialize(writer, "TextFill", c.TextFill); if (TextOutline != null) @@ -1374,7 +1394,7 @@ public override void Deserialize(FRReader reader) // skip break; default: - if (!reader.HasProperty("Font")) + if (!reader.HasProperty("Font") && reader.ItemName != "inherited") { string creatorVersion = reader.Root.GetProp("ReportInfo.CreatorVersion"); if (!String.IsNullOrEmpty(creatorVersion)) @@ -1399,8 +1419,8 @@ public override void Deserialize(FRReader reader) } break; } - } + public override void InitializeComponent() { base.InitializeComponent(); diff --git a/FastReport.Base/Utils/CompileHelper.cs b/FastReport.Base/Utils/CompileHelper.cs index 1cf41813..19539919 100644 --- a/FastReport.Base/Utils/CompileHelper.cs +++ b/FastReport.Base/Utils/CompileHelper.cs @@ -31,7 +31,7 @@ public static Assembly GenerateAssemblyInMemory(string sourceCode, params string parameters.ReferencedAssemblies.Add(asm); } -#if NETSTANDARD2_0 +#if NETSTANDARD2_0 || NETSTANDARD2_1 var mscorPath = compiler.GetReference("System.Private.CoreLib.dll").Display; parameters.ReferencedAssemblies.Add(mscorPath); diff --git a/FastReport.Base/Utils/Config.cs b/FastReport.Base/Utils/Config.cs index a5aac610..1ef196c2 100644 --- a/FastReport.Base/Utils/Config.cs +++ b/FastReport.Base/Utils/Config.cs @@ -23,6 +23,7 @@ public static partial class Config private static XmlDocument FDoc = new XmlDocument(); private static string FFolder = null; + private static string FFontListFolder = null; private static string FLogs = ""; private static ReportSettings FReportSettings = new ReportSettings(); private static bool FRightToLeft = false; @@ -84,6 +85,19 @@ public static string Folder set { FFolder = value; } } + /// + /// Gets or sets the path used to font.list file. + /// + /// + /// By default, the font.list file is saved to the FastReport.config folder + /// If WebMode enabled (or config file path is null), then file is saved in the application folder. + /// + public static string FontListFolder + { + get { return FFontListFolder; } + set { FFontListFolder = value; } + } + /// /// Gets or sets the settings for the Report component. /// @@ -165,7 +179,7 @@ internal static string GetTempFolder() internal static void Init() { -#if !NETSTANDARD2_0 +#if !(NETSTANDARD2_0 || NETSTANDARD2_1) string processName = System.Diagnostics.Process.GetCurrentProcess().ProcessName; WebMode = String.Compare(processName, "iisexpress") == 0 || String.Compare(processName, "w3wp") == 0; diff --git a/FastReport.Base/Utils/Converter.cs b/FastReport.Base/Utils/Converter.cs index 95d80274..0621c58c 100644 --- a/FastReport.Base/Utils/Converter.cs +++ b/FastReport.Base/Utils/Converter.cs @@ -13,6 +13,8 @@ namespace FastReport.Utils /// public static class Converter { + + /// /// Converts an object to a string. /// @@ -71,7 +73,13 @@ public static string ToString(object value) return type.FullName; return type.AssemblyQualifiedName; } - return TypeDescriptor.GetConverter(value).ConvertToInvariantString(value); +#if NETSTANDARD2_0 || NETSTANDARD2_1 + if (value is Font) + { + return FastReport.TypeConverters.FontConverter.Instance.ConvertToInvariantString(value); + } +#endif + return TypeDescriptor.GetConverter(value).ConvertToInvariantString(value); } /// @@ -118,6 +126,12 @@ public static object FromString(Type type, string value) value = value.Replace("\r\n", "\r"); return value.Split(new char[] { '\r' }); } +#if NETSTANDARD2_0 || NETSTANDARD2_1 + if (type == typeof(Font)) + { + return FastReport.TypeConverters.FontConverter.Instance.ConvertFromInvariantString(value); + } +#endif if (type == typeof(Color)) return new ColorConverter().ConvertFromInvariantString(value); return TypeDescriptor.GetConverter(type).ConvertFromInvariantString(value); diff --git a/FastReport.Base/Utils/DrawUtils.Win32.cs b/FastReport.Base/Utils/DrawUtils.Win32.cs index cc33b3f4..47bc4cb6 100644 --- a/FastReport.Base/Utils/DrawUtils.Win32.cs +++ b/FastReport.Base/Utils/DrawUtils.Win32.cs @@ -7,7 +7,7 @@ namespace FastReport.Utils { partial class DrawUtils { -#if NETSTANDARD2_0 +#if NETSTANDARD2_0 || NETSTANDARD2_1 static IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, DrawingOptions drawingOptions) { return IntPtr.Zero; diff --git a/FastReport.Base/Utils/FRReader.cs b/FastReport.Base/Utils/FRReader.cs index 0de22ffe..7ea6c25c 100644 --- a/FastReport.Base/Utils/FRReader.cs +++ b/FastReport.Base/Utils/FRReader.cs @@ -266,10 +266,10 @@ public IFRSerializable Read() } else { - if (!Config.WebMode) - MessageBox.Show(Res.Get("Messages,CantFindObject") + " " + curItem.Name); - else - throw new ClassException(curItem.Name); + if (!Config.WebMode) + MessageBox.Show(Res.Get("Messages,CantFindObject") + " " + curItem.Name); + else + throw new ClassException(curItem.Name); } } if (result != null) diff --git a/FastReport.Base/Utils/ImageHelper.cs b/FastReport.Base/Utils/ImageHelper.cs index 3fb444e8..e5c86c54 100644 --- a/FastReport.Base/Utils/ImageHelper.cs +++ b/FastReport.Base/Utils/ImageHelper.cs @@ -74,7 +74,13 @@ public static Image Load(byte[] bytes) { try { +#if NETSTANDARD2_0 || NETSTANDARD2_1 + // TODO memory leaks image converter + return Image.FromStream(new MemoryStream(bytes)); +#else return new ImageConverter().ConvertFrom(bytes) as Image; +#endif + } catch { diff --git a/FastReport.Base/Utils/MyEncodingInfo.cs b/FastReport.Base/Utils/MyEncodingInfo.cs new file mode 100644 index 00000000..a52aa0fb --- /dev/null +++ b/FastReport.Base/Utils/MyEncodingInfo.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FastReport.Utils +{ + internal class MyEncodingInfo + { + #region Private Fields + + private int codePage; + private string displayName; + private string name; + + #endregion Private Fields + + #region Public Properties + + public int CodePage + { + get + { + return codePage; + } + set + { + codePage = value; + } + } + + public string DisplayName + { + get { return displayName; } + set + { + displayName = value; + } + } + + public string Name + { + get + { + return name; + } + + set + { + name = value; + } + } + + #endregion Public Properties + + #region Public Constructors + + public MyEncodingInfo(Encoding encoding) + { + DisplayName = encoding.EncodingName; + Name = encoding.WebName; + CodePage = encoding.CodePage; + } + + public MyEncodingInfo(EncodingInfo info) + { + DisplayName = info.DisplayName; + Name = info.Name; + CodePage = info.CodePage; + } + + #endregion Public Constructors + + #region Public Methods + + public static IEnumerable GetEncodings() + { + List encodings = new List(); + + foreach (EncodingInfo info in Encoding.GetEncodings()) + { + encodings.Add(new MyEncodingInfo(info)); + } + + encodings.Sort(new Comparison(compareEncoding)); ; + + return encodings; + } + + public override string ToString() + { + return DisplayName; + } + + #endregion Public Methods + + #region Private Methods + + private static int compareEncoding(MyEncodingInfo x, MyEncodingInfo y) + { + if (x != null && y != null) + { + return String.Compare(x.DisplayName, y.DisplayName); + } + return 0; + } + + #endregion Private Methods + } +} \ No newline at end of file diff --git a/FastReport.Base/Utils/Res.cs b/FastReport.Base/Utils/Res.cs index 422b42e9..6845f360 100644 --- a/FastReport.Base/Utils/Res.cs +++ b/FastReport.Base/Utils/Res.cs @@ -35,7 +35,7 @@ public static string LocaleFolder Report.EnsureInit(); string folder = Config.Root.FindItem("Language").GetProp("Folder"); // check the registry -#if !NETSTANDARD2_0 +#if !(NETSTANDARD2_0 || NETSTANDARD2_1) if (String.IsNullOrEmpty(folder) && !Config.WebMode) { RegistryKey key = Registry.CurrentUser.OpenSubKey("Software").OpenSubKey("FastReports"); @@ -47,8 +47,8 @@ public static string LocaleFolder } } #endif - // get application folder - if (String.IsNullOrEmpty(folder)) + // get application folder + if (String.IsNullOrEmpty(folder)) folder = Config.ApplicationFolder; if (!folder.EndsWith("\\")) diff --git a/FastReport.Base/Utils/Xml.cs b/FastReport.Base/Utils/Xml.cs index 91962761..4489cf5f 100644 --- a/FastReport.Base/Utils/Xml.cs +++ b/FastReport.Base/Utils/Xml.cs @@ -6,8 +6,7 @@ namespace FastReport.Utils { /// - /// Represents a xml property. - /// + /// Represents a xml property./// public struct XmlProperty { private readonly string key; diff --git a/FastReport.Base/Watermark.cs b/FastReport.Base/Watermark.cs index 3023a438..93eab206 100644 --- a/FastReport.Base/Watermark.cs +++ b/FastReport.Base/Watermark.cs @@ -296,7 +296,7 @@ public void Serialize(FRWriter writer, string prefix, Watermark c) writer.WriteFloat(prefix + ".ImageTransparency", ImageTransparency); if (Text != c.Text) writer.WriteStr(prefix + ".Text", Text); - if (writer.SerializeTo != SerializeTo.Preview || !writer.AreEqual(Font, c.Font)) + if ((writer.SerializeTo != SerializeTo.Preview || !writer.AreEqual(Font, c.Font)) && writer.ItemName != "inherited") writer.WriteValue(prefix + ".Font", Font); TextFill.Serialize(writer, prefix + ".TextFill", c.TextFill); if (TextRotation != c.TextRotation) diff --git a/FastReport.Core.Web/Application/WebReportDesigner.cs b/FastReport.Core.Web/Application/WebReportDesigner.cs index 5d048755..5b1a715e 100644 --- a/FastReport.Core.Web/Application/WebReportDesigner.cs +++ b/FastReport.Core.Web/Application/WebReportDesigner.cs @@ -102,7 +102,9 @@ internal IActionResult DesignerSaveReport(HttpContext context) if (!DesignerSaveCallBack.IsNullOrWhiteSpace()) { string report = Report.SaveToString(); - string reportFileName = $"{ID}.frx"; + var reportName = (!String.IsNullOrEmpty(Report.ReportInfo.Name) ? + Report.ReportInfo.Name : Path.GetFileNameWithoutExtension(Report.FileName)); + string reportFileName = $"{reportName}.frx"; UriBuilder uri = new UriBuilder { diff --git a/FastReport.OpenSource/DotNetClasses/CSharpCodeProvider.cs b/FastReport.OpenSource/DotNetClasses/CSharpCodeProvider.cs index a6c6d7f0..a6196dd7 100644 --- a/FastReport.OpenSource/DotNetClasses/CSharpCodeProvider.cs +++ b/FastReport.OpenSource/DotNetClasses/CSharpCodeProvider.cs @@ -1,4 +1,5 @@ -using Microsoft.CodeAnalysis; +#if NETSTANDARD2_0 || NETSTANDARD2_1 +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using System; @@ -79,4 +80,5 @@ public override void Dispose() } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/FastReport.OpenSource/DotNetClasses/CodeDomProvider.cs b/FastReport.OpenSource/DotNetClasses/CodeDomProvider.cs index f06dcbdc..450006d0 100644 --- a/FastReport.OpenSource/DotNetClasses/CodeDomProvider.cs +++ b/FastReport.OpenSource/DotNetClasses/CodeDomProvider.cs @@ -1,4 +1,5 @@ -using Microsoft.CodeAnalysis; +#if NETSTANDARD2_0 || NETSTANDARD2_1 +using Microsoft.CodeAnalysis; using System; using System.Collections.Generic; using System.Reflection; @@ -19,7 +20,7 @@ protected void AddExtraAssemblies(Collections.Specialized.StringCollection refer "netstandard", "System.Runtime", "System.ComponentModel.Primitives", - "CoreCompat.System.Drawing" + "System.Drawing.Common" }; foreach(string assembly in assemblies) @@ -66,4 +67,5 @@ internal MetadataReference GetReference(string refDll) } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/FastReport.OpenSource/DotNetClasses/CodeGenerator.cs b/FastReport.OpenSource/DotNetClasses/CodeGenerator.cs index 7ab151dc..32ef525f 100644 --- a/FastReport.OpenSource/DotNetClasses/CodeGenerator.cs +++ b/FastReport.OpenSource/DotNetClasses/CodeGenerator.cs @@ -1,4 +1,5 @@ -using System; +#if NETSTANDARD2_0 || NETSTANDARD2_1 +using System; using System.Collections.Generic; using System.Text; @@ -13,3 +14,4 @@ internal static bool IsValidLanguageIndependentIdentifier(string value) } } } +#endif \ No newline at end of file diff --git a/FastReport.OpenSource/DotNetClasses/Color.Core.cs b/FastReport.OpenSource/DotNetClasses/Color.Core.cs index f59f8be6..5b54a878 100644 --- a/FastReport.OpenSource/DotNetClasses/Color.Core.cs +++ b/FastReport.OpenSource/DotNetClasses/Color.Core.cs @@ -1,27 +1,564 @@ -using System; +#if NETSTANDARD2_0 || NETSTANDARD2_1 +using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Text; namespace System.Drawing { + #if NETSTANDARD2_0 + public enum KnownColor + { + ActiveBorder = 1, + ActiveCaption = 2, + ActiveCaptionText = 3, + AppWorkspace = 4, + Control = 5, + ControlDark = 6, + ControlDarkDark = 7, + ControlLight = 8, + ControlLightLight = 9, + ControlText = 10, + Desktop = 11, + GrayText = 12, + Highlight = 13, + HighlightText = 14, + HotTrack = 15, + InactiveBorder = 16, + InactiveCaption = 17, + InactiveCaptionText = 18, + Info = 19, + InfoText = 20, + Menu = 21, + MenuText = 22, + ScrollBar = 23, + Window = 24, + WindowFrame = 25, + WindowText = 26, + Transparent = 27, + AliceBlue = 28, + AntiqueWhite = 29, + Aqua = 30, + Aquamarine = 31, + Azure = 32, + Beige = 33, + Bisque = 34, + Black = 35, + BlanchedAlmond = 36, + Blue = 37, + BlueViolet = 38, + Brown = 39, + BurlyWood = 40, + CadetBlue = 41, + Chartreuse = 42, + Chocolate = 43, + Coral = 44, + CornflowerBlue = 45, + Cornsilk = 46, + Crimson = 47, + Cyan = 48, + DarkBlue = 49, + DarkCyan = 50, + DarkGoldenrod = 51, + DarkGray = 52, + DarkGreen = 53, + DarkKhaki = 54, + DarkMagenta = 55, + DarkOliveGreen = 56, + DarkOrange = 57, + DarkOrchid = 58, + DarkRed = 59, + DarkSalmon = 60, + DarkSeaGreen = 61, + DarkSlateBlue = 62, + DarkSlateGray = 63, + DarkTurquoise = 64, + DarkViolet = 65, + DeepPink = 66, + DeepSkyBlue = 67, + DimGray = 68, + DodgerBlue = 69, + Firebrick = 70, + FloralWhite = 71, + ForestGreen = 72, + Fuchsia = 73, + Gainsboro = 74, + GhostWhite = 75, + Gold = 76, + Goldenrod = 77, + Gray = 78, + Green = 79, + GreenYellow = 80, + Honeydew = 81, + HotPink = 82, + IndianRed = 83, + Indigo = 84, + Ivory = 85, + Khaki = 86, + Lavender = 87, + LavenderBlush = 88, + LawnGreen = 89, + LemonChiffon = 90, + LightBlue = 91, + LightCoral = 92, + LightCyan = 93, + LightGoldenrodYellow = 94, + LightGray = 95, + LightGreen = 96, + LightPink = 97, + LightSalmon = 98, + LightSeaGreen = 99, + LightSkyBlue = 100, + LightSlateGray = 101, + LightSteelBlue = 102, + LightYellow = 103, + Lime = 104, + LimeGreen = 105, + Linen = 106, + Magenta = 107, + Maroon = 108, + MediumAquamarine = 109, + MediumBlue = 110, + MediumOrchid = 111, + MediumPurple = 112, + MediumSeaGreen = 113, + MediumSlateBlue = 114, + MediumSpringGreen = 115, + MediumTurquoise = 116, + MediumVioletRed = 117, + MidnightBlue = 118, + MintCream = 119, + MistyRose = 120, + Moccasin = 121, + NavajoWhite = 122, + Navy = 123, + OldLace = 124, + Olive = 125, + OliveDrab = 126, + Orange = 127, + OrangeRed = 128, + Orchid = 129, + PaleGoldenrod = 130, + PaleGreen = 131, + PaleTurquoise = 132, + PaleVioletRed = 133, + PapayaWhip = 134, + PeachPuff = 135, + Peru = 136, + Pink = 137, + Plum = 138, + PowderBlue = 139, + Purple = 140, + Red = 141, + RosyBrown = 142, + RoyalBlue = 143, + SaddleBrown = 144, + Salmon = 145, + SandyBrown = 146, + SeaGreen = 147, + SeaShell = 148, + Sienna = 149, + Silver = 150, + SkyBlue = 151, + SlateBlue = 152, + SlateGray = 153, + Snow = 154, + SpringGreen = 155, + SteelBlue = 156, + Tan = 157, + Teal = 158, + Thistle = 159, + Tomato = 160, + Turquoise = 161, + Violet = 162, + Wheat = 163, + White = 164, + WhiteSmoke = 165, + Yellow = 166, + YellowGreen = 167, + ButtonFace = 168, + ButtonHighlight = 169, + ButtonShadow = 170, + GradientActiveCaption = 171, + GradientInactiveCaption = 172, + MenuBar = 173, + MenuHighlight = 174 + } +#endif public class ColorExt { + private static readonly ConcurrentDictionary ColorToKnownColor = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary KnownColorToColor = new ConcurrentDictionary(); + + static ColorExt() + { + ColorToKnownColor[-4934476] = KnownColor.ActiveBorder; + KnownColorToColor[KnownColor.ActiveBorder] = Color.FromArgb(-4934476); + ColorToKnownColor[-6703919] = KnownColor.ActiveCaption; + KnownColorToColor[KnownColor.ActiveCaption] = Color.FromArgb(-6703919); + ColorToKnownColor[-16777216] = KnownColor.ActiveCaptionText; + KnownColorToColor[KnownColor.ActiveCaptionText] = Color.FromArgb(-16777216); + ColorToKnownColor[-5526613] = KnownColor.AppWorkspace; + KnownColorToColor[KnownColor.AppWorkspace] = Color.FromArgb(-5526613); + ColorToKnownColor[-986896] = KnownColor.Control; + KnownColorToColor[KnownColor.Control] = Color.FromArgb(-986896); + ColorToKnownColor[-6250336] = KnownColor.ControlDark; + KnownColorToColor[KnownColor.ControlDark] = Color.FromArgb(-6250336); + ColorToKnownColor[-9868951] = KnownColor.ControlDarkDark; + KnownColorToColor[KnownColor.ControlDarkDark] = Color.FromArgb(-9868951); + ColorToKnownColor[-1842205] = KnownColor.ControlLight; + KnownColorToColor[KnownColor.ControlLight] = Color.FromArgb(-1842205); + ColorToKnownColor[-1] = KnownColor.ControlLightLight; + KnownColorToColor[KnownColor.ControlLightLight] = Color.FromArgb(-1); + ColorToKnownColor[-16777216] = KnownColor.ControlText; + KnownColorToColor[KnownColor.ControlText] = Color.FromArgb(-16777216); + ColorToKnownColor[-16777216] = KnownColor.Desktop; + KnownColorToColor[KnownColor.Desktop] = Color.FromArgb(-16777216); + ColorToKnownColor[-9605779] = KnownColor.GrayText; + KnownColorToColor[KnownColor.GrayText] = Color.FromArgb(-9605779); + ColorToKnownColor[-16746281] = KnownColor.Highlight; + KnownColorToColor[KnownColor.Highlight] = Color.FromArgb(-16746281); + ColorToKnownColor[-1] = KnownColor.HighlightText; + KnownColorToColor[KnownColor.HighlightText] = Color.FromArgb(-1); + ColorToKnownColor[-16750900] = KnownColor.HotTrack; + KnownColorToColor[KnownColor.HotTrack] = Color.FromArgb(-16750900); + ColorToKnownColor[-722948] = KnownColor.InactiveBorder; + KnownColorToColor[KnownColor.InactiveBorder] = Color.FromArgb(-722948); + ColorToKnownColor[-4207141] = KnownColor.InactiveCaption; + KnownColorToColor[KnownColor.InactiveCaption] = Color.FromArgb(-4207141); + ColorToKnownColor[-16777216] = KnownColor.InactiveCaptionText; + KnownColorToColor[KnownColor.InactiveCaptionText] = Color.FromArgb(-16777216); + ColorToKnownColor[-31] = KnownColor.Info; + KnownColorToColor[KnownColor.Info] = Color.FromArgb(-31); + ColorToKnownColor[-16777216] = KnownColor.InfoText; + KnownColorToColor[KnownColor.InfoText] = Color.FromArgb(-16777216); + ColorToKnownColor[-986896] = KnownColor.Menu; + KnownColorToColor[KnownColor.Menu] = Color.FromArgb(-986896); + ColorToKnownColor[-16777216] = KnownColor.MenuText; + KnownColorToColor[KnownColor.MenuText] = Color.FromArgb(-16777216); + ColorToKnownColor[-3618616] = KnownColor.ScrollBar; + KnownColorToColor[KnownColor.ScrollBar] = Color.FromArgb(-3618616); + ColorToKnownColor[-1] = KnownColor.Window; + KnownColorToColor[KnownColor.Window] = Color.FromArgb(-1); + ColorToKnownColor[-10197916] = KnownColor.WindowFrame; + KnownColorToColor[KnownColor.WindowFrame] = Color.FromArgb(-10197916); + ColorToKnownColor[-16777216] = KnownColor.WindowText; + KnownColorToColor[KnownColor.WindowText] = Color.FromArgb(-16777216); + ColorToKnownColor[16777215] = KnownColor.Transparent; + KnownColorToColor[KnownColor.Transparent] = Color.FromArgb(16777215); + ColorToKnownColor[-984833] = KnownColor.AliceBlue; + KnownColorToColor[KnownColor.AliceBlue] = Color.FromArgb(-984833); + ColorToKnownColor[-332841] = KnownColor.AntiqueWhite; + KnownColorToColor[KnownColor.AntiqueWhite] = Color.FromArgb(-332841); + ColorToKnownColor[-16711681] = KnownColor.Aqua; + KnownColorToColor[KnownColor.Aqua] = Color.FromArgb(-16711681); + ColorToKnownColor[-8388652] = KnownColor.Aquamarine; + KnownColorToColor[KnownColor.Aquamarine] = Color.FromArgb(-8388652); + ColorToKnownColor[-983041] = KnownColor.Azure; + KnownColorToColor[KnownColor.Azure] = Color.FromArgb(-983041); + ColorToKnownColor[-657956] = KnownColor.Beige; + KnownColorToColor[KnownColor.Beige] = Color.FromArgb(-657956); + ColorToKnownColor[-6972] = KnownColor.Bisque; + KnownColorToColor[KnownColor.Bisque] = Color.FromArgb(-6972); + ColorToKnownColor[-16777216] = KnownColor.Black; + KnownColorToColor[KnownColor.Black] = Color.FromArgb(-16777216); + ColorToKnownColor[-5171] = KnownColor.BlanchedAlmond; + KnownColorToColor[KnownColor.BlanchedAlmond] = Color.FromArgb(-5171); + ColorToKnownColor[-16776961] = KnownColor.Blue; + KnownColorToColor[KnownColor.Blue] = Color.FromArgb(-16776961); + ColorToKnownColor[-7722014] = KnownColor.BlueViolet; + KnownColorToColor[KnownColor.BlueViolet] = Color.FromArgb(-7722014); + ColorToKnownColor[-5952982] = KnownColor.Brown; + KnownColorToColor[KnownColor.Brown] = Color.FromArgb(-5952982); + ColorToKnownColor[-2180985] = KnownColor.BurlyWood; + KnownColorToColor[KnownColor.BurlyWood] = Color.FromArgb(-2180985); + ColorToKnownColor[-10510688] = KnownColor.CadetBlue; + KnownColorToColor[KnownColor.CadetBlue] = Color.FromArgb(-10510688); + ColorToKnownColor[-8388864] = KnownColor.Chartreuse; + KnownColorToColor[KnownColor.Chartreuse] = Color.FromArgb(-8388864); + ColorToKnownColor[-2987746] = KnownColor.Chocolate; + KnownColorToColor[KnownColor.Chocolate] = Color.FromArgb(-2987746); + ColorToKnownColor[-32944] = KnownColor.Coral; + KnownColorToColor[KnownColor.Coral] = Color.FromArgb(-32944); + ColorToKnownColor[-10185235] = KnownColor.CornflowerBlue; + KnownColorToColor[KnownColor.CornflowerBlue] = Color.FromArgb(-10185235); + ColorToKnownColor[-1828] = KnownColor.Cornsilk; + KnownColorToColor[KnownColor.Cornsilk] = Color.FromArgb(-1828); + ColorToKnownColor[-2354116] = KnownColor.Crimson; + KnownColorToColor[KnownColor.Crimson] = Color.FromArgb(-2354116); + ColorToKnownColor[-16711681] = KnownColor.Cyan; + KnownColorToColor[KnownColor.Cyan] = Color.FromArgb(-16711681); + ColorToKnownColor[-16777077] = KnownColor.DarkBlue; + KnownColorToColor[KnownColor.DarkBlue] = Color.FromArgb(-16777077); + ColorToKnownColor[-16741493] = KnownColor.DarkCyan; + KnownColorToColor[KnownColor.DarkCyan] = Color.FromArgb(-16741493); + ColorToKnownColor[-4684277] = KnownColor.DarkGoldenrod; + KnownColorToColor[KnownColor.DarkGoldenrod] = Color.FromArgb(-4684277); + ColorToKnownColor[-5658199] = KnownColor.DarkGray; + KnownColorToColor[KnownColor.DarkGray] = Color.FromArgb(-5658199); + ColorToKnownColor[-16751616] = KnownColor.DarkGreen; + KnownColorToColor[KnownColor.DarkGreen] = Color.FromArgb(-16751616); + ColorToKnownColor[-4343957] = KnownColor.DarkKhaki; + KnownColorToColor[KnownColor.DarkKhaki] = Color.FromArgb(-4343957); + ColorToKnownColor[-7667573] = KnownColor.DarkMagenta; + KnownColorToColor[KnownColor.DarkMagenta] = Color.FromArgb(-7667573); + ColorToKnownColor[-11179217] = KnownColor.DarkOliveGreen; + KnownColorToColor[KnownColor.DarkOliveGreen] = Color.FromArgb(-11179217); + ColorToKnownColor[-29696] = KnownColor.DarkOrange; + KnownColorToColor[KnownColor.DarkOrange] = Color.FromArgb(-29696); + ColorToKnownColor[-6737204] = KnownColor.DarkOrchid; + KnownColorToColor[KnownColor.DarkOrchid] = Color.FromArgb(-6737204); + ColorToKnownColor[-7667712] = KnownColor.DarkRed; + KnownColorToColor[KnownColor.DarkRed] = Color.FromArgb(-7667712); + ColorToKnownColor[-1468806] = KnownColor.DarkSalmon; + KnownColorToColor[KnownColor.DarkSalmon] = Color.FromArgb(-1468806); + ColorToKnownColor[-7357301] = KnownColor.DarkSeaGreen; + KnownColorToColor[KnownColor.DarkSeaGreen] = Color.FromArgb(-7357301); + ColorToKnownColor[-12042869] = KnownColor.DarkSlateBlue; + KnownColorToColor[KnownColor.DarkSlateBlue] = Color.FromArgb(-12042869); + ColorToKnownColor[-13676721] = KnownColor.DarkSlateGray; + KnownColorToColor[KnownColor.DarkSlateGray] = Color.FromArgb(-13676721); + ColorToKnownColor[-16724271] = KnownColor.DarkTurquoise; + KnownColorToColor[KnownColor.DarkTurquoise] = Color.FromArgb(-16724271); + ColorToKnownColor[-7077677] = KnownColor.DarkViolet; + KnownColorToColor[KnownColor.DarkViolet] = Color.FromArgb(-7077677); + ColorToKnownColor[-60269] = KnownColor.DeepPink; + KnownColorToColor[KnownColor.DeepPink] = Color.FromArgb(-60269); + ColorToKnownColor[-16728065] = KnownColor.DeepSkyBlue; + KnownColorToColor[KnownColor.DeepSkyBlue] = Color.FromArgb(-16728065); + ColorToKnownColor[-9868951] = KnownColor.DimGray; + KnownColorToColor[KnownColor.DimGray] = Color.FromArgb(-9868951); + ColorToKnownColor[-14774017] = KnownColor.DodgerBlue; + KnownColorToColor[KnownColor.DodgerBlue] = Color.FromArgb(-14774017); + ColorToKnownColor[-5103070] = KnownColor.Firebrick; + KnownColorToColor[KnownColor.Firebrick] = Color.FromArgb(-5103070); + ColorToKnownColor[-1296] = KnownColor.FloralWhite; + KnownColorToColor[KnownColor.FloralWhite] = Color.FromArgb(-1296); + ColorToKnownColor[-14513374] = KnownColor.ForestGreen; + KnownColorToColor[KnownColor.ForestGreen] = Color.FromArgb(-14513374); + ColorToKnownColor[-65281] = KnownColor.Fuchsia; + KnownColorToColor[KnownColor.Fuchsia] = Color.FromArgb(-65281); + ColorToKnownColor[-2302756] = KnownColor.Gainsboro; + KnownColorToColor[KnownColor.Gainsboro] = Color.FromArgb(-2302756); + ColorToKnownColor[-460545] = KnownColor.GhostWhite; + KnownColorToColor[KnownColor.GhostWhite] = Color.FromArgb(-460545); + ColorToKnownColor[-10496] = KnownColor.Gold; + KnownColorToColor[KnownColor.Gold] = Color.FromArgb(-10496); + ColorToKnownColor[-2448096] = KnownColor.Goldenrod; + KnownColorToColor[KnownColor.Goldenrod] = Color.FromArgb(-2448096); + ColorToKnownColor[-8355712] = KnownColor.Gray; + KnownColorToColor[KnownColor.Gray] = Color.FromArgb(-8355712); + ColorToKnownColor[-16744448] = KnownColor.Green; + KnownColorToColor[KnownColor.Green] = Color.FromArgb(-16744448); + ColorToKnownColor[-5374161] = KnownColor.GreenYellow; + KnownColorToColor[KnownColor.GreenYellow] = Color.FromArgb(-5374161); + ColorToKnownColor[-983056] = KnownColor.Honeydew; + KnownColorToColor[KnownColor.Honeydew] = Color.FromArgb(-983056); + ColorToKnownColor[-38476] = KnownColor.HotPink; + KnownColorToColor[KnownColor.HotPink] = Color.FromArgb(-38476); + ColorToKnownColor[-3318692] = KnownColor.IndianRed; + KnownColorToColor[KnownColor.IndianRed] = Color.FromArgb(-3318692); + ColorToKnownColor[-11861886] = KnownColor.Indigo; + KnownColorToColor[KnownColor.Indigo] = Color.FromArgb(-11861886); + ColorToKnownColor[-16] = KnownColor.Ivory; + KnownColorToColor[KnownColor.Ivory] = Color.FromArgb(-16); + ColorToKnownColor[-989556] = KnownColor.Khaki; + KnownColorToColor[KnownColor.Khaki] = Color.FromArgb(-989556); + ColorToKnownColor[-1644806] = KnownColor.Lavender; + KnownColorToColor[KnownColor.Lavender] = Color.FromArgb(-1644806); + ColorToKnownColor[-3851] = KnownColor.LavenderBlush; + KnownColorToColor[KnownColor.LavenderBlush] = Color.FromArgb(-3851); + ColorToKnownColor[-8586240] = KnownColor.LawnGreen; + KnownColorToColor[KnownColor.LawnGreen] = Color.FromArgb(-8586240); + ColorToKnownColor[-1331] = KnownColor.LemonChiffon; + KnownColorToColor[KnownColor.LemonChiffon] = Color.FromArgb(-1331); + ColorToKnownColor[-5383962] = KnownColor.LightBlue; + KnownColorToColor[KnownColor.LightBlue] = Color.FromArgb(-5383962); + ColorToKnownColor[-1015680] = KnownColor.LightCoral; + KnownColorToColor[KnownColor.LightCoral] = Color.FromArgb(-1015680); + ColorToKnownColor[-2031617] = KnownColor.LightCyan; + KnownColorToColor[KnownColor.LightCyan] = Color.FromArgb(-2031617); + ColorToKnownColor[-329006] = KnownColor.LightGoldenrodYellow; + KnownColorToColor[KnownColor.LightGoldenrodYellow] = Color.FromArgb(-329006); + ColorToKnownColor[-2894893] = KnownColor.LightGray; + KnownColorToColor[KnownColor.LightGray] = Color.FromArgb(-2894893); + ColorToKnownColor[-7278960] = KnownColor.LightGreen; + KnownColorToColor[KnownColor.LightGreen] = Color.FromArgb(-7278960); + ColorToKnownColor[-18751] = KnownColor.LightPink; + KnownColorToColor[KnownColor.LightPink] = Color.FromArgb(-18751); + ColorToKnownColor[-24454] = KnownColor.LightSalmon; + KnownColorToColor[KnownColor.LightSalmon] = Color.FromArgb(-24454); + ColorToKnownColor[-14634326] = KnownColor.LightSeaGreen; + KnownColorToColor[KnownColor.LightSeaGreen] = Color.FromArgb(-14634326); + ColorToKnownColor[-7876870] = KnownColor.LightSkyBlue; + KnownColorToColor[KnownColor.LightSkyBlue] = Color.FromArgb(-7876870); + ColorToKnownColor[-8943463] = KnownColor.LightSlateGray; + KnownColorToColor[KnownColor.LightSlateGray] = Color.FromArgb(-8943463); + ColorToKnownColor[-5192482] = KnownColor.LightSteelBlue; + KnownColorToColor[KnownColor.LightSteelBlue] = Color.FromArgb(-5192482); + ColorToKnownColor[-32] = KnownColor.LightYellow; + KnownColorToColor[KnownColor.LightYellow] = Color.FromArgb(-32); + ColorToKnownColor[-16711936] = KnownColor.Lime; + KnownColorToColor[KnownColor.Lime] = Color.FromArgb(-16711936); + ColorToKnownColor[-13447886] = KnownColor.LimeGreen; + KnownColorToColor[KnownColor.LimeGreen] = Color.FromArgb(-13447886); + ColorToKnownColor[-331546] = KnownColor.Linen; + KnownColorToColor[KnownColor.Linen] = Color.FromArgb(-331546); + ColorToKnownColor[-65281] = KnownColor.Magenta; + KnownColorToColor[KnownColor.Magenta] = Color.FromArgb(-65281); + ColorToKnownColor[-8388608] = KnownColor.Maroon; + KnownColorToColor[KnownColor.Maroon] = Color.FromArgb(-8388608); + ColorToKnownColor[-10039894] = KnownColor.MediumAquamarine; + KnownColorToColor[KnownColor.MediumAquamarine] = Color.FromArgb(-10039894); + ColorToKnownColor[-16777011] = KnownColor.MediumBlue; + KnownColorToColor[KnownColor.MediumBlue] = Color.FromArgb(-16777011); + ColorToKnownColor[-4565549] = KnownColor.MediumOrchid; + KnownColorToColor[KnownColor.MediumOrchid] = Color.FromArgb(-4565549); + ColorToKnownColor[-7114533] = KnownColor.MediumPurple; + KnownColorToColor[KnownColor.MediumPurple] = Color.FromArgb(-7114533); + ColorToKnownColor[-12799119] = KnownColor.MediumSeaGreen; + KnownColorToColor[KnownColor.MediumSeaGreen] = Color.FromArgb(-12799119); + ColorToKnownColor[-8689426] = KnownColor.MediumSlateBlue; + KnownColorToColor[KnownColor.MediumSlateBlue] = Color.FromArgb(-8689426); + ColorToKnownColor[-16713062] = KnownColor.MediumSpringGreen; + KnownColorToColor[KnownColor.MediumSpringGreen] = Color.FromArgb(-16713062); + ColorToKnownColor[-12004916] = KnownColor.MediumTurquoise; + KnownColorToColor[KnownColor.MediumTurquoise] = Color.FromArgb(-12004916); + ColorToKnownColor[-3730043] = KnownColor.MediumVioletRed; + KnownColorToColor[KnownColor.MediumVioletRed] = Color.FromArgb(-3730043); + ColorToKnownColor[-15132304] = KnownColor.MidnightBlue; + KnownColorToColor[KnownColor.MidnightBlue] = Color.FromArgb(-15132304); + ColorToKnownColor[-655366] = KnownColor.MintCream; + KnownColorToColor[KnownColor.MintCream] = Color.FromArgb(-655366); + ColorToKnownColor[-6943] = KnownColor.MistyRose; + KnownColorToColor[KnownColor.MistyRose] = Color.FromArgb(-6943); + ColorToKnownColor[-6987] = KnownColor.Moccasin; + KnownColorToColor[KnownColor.Moccasin] = Color.FromArgb(-6987); + ColorToKnownColor[-8531] = KnownColor.NavajoWhite; + KnownColorToColor[KnownColor.NavajoWhite] = Color.FromArgb(-8531); + ColorToKnownColor[-16777088] = KnownColor.Navy; + KnownColorToColor[KnownColor.Navy] = Color.FromArgb(-16777088); + ColorToKnownColor[-133658] = KnownColor.OldLace; + KnownColorToColor[KnownColor.OldLace] = Color.FromArgb(-133658); + ColorToKnownColor[-8355840] = KnownColor.Olive; + KnownColorToColor[KnownColor.Olive] = Color.FromArgb(-8355840); + ColorToKnownColor[-9728477] = KnownColor.OliveDrab; + KnownColorToColor[KnownColor.OliveDrab] = Color.FromArgb(-9728477); + ColorToKnownColor[-23296] = KnownColor.Orange; + KnownColorToColor[KnownColor.Orange] = Color.FromArgb(-23296); + ColorToKnownColor[-47872] = KnownColor.OrangeRed; + KnownColorToColor[KnownColor.OrangeRed] = Color.FromArgb(-47872); + ColorToKnownColor[-2461482] = KnownColor.Orchid; + KnownColorToColor[KnownColor.Orchid] = Color.FromArgb(-2461482); + ColorToKnownColor[-1120086] = KnownColor.PaleGoldenrod; + KnownColorToColor[KnownColor.PaleGoldenrod] = Color.FromArgb(-1120086); + ColorToKnownColor[-6751336] = KnownColor.PaleGreen; + KnownColorToColor[KnownColor.PaleGreen] = Color.FromArgb(-6751336); + ColorToKnownColor[-5247250] = KnownColor.PaleTurquoise; + KnownColorToColor[KnownColor.PaleTurquoise] = Color.FromArgb(-5247250); + ColorToKnownColor[-2396013] = KnownColor.PaleVioletRed; + KnownColorToColor[KnownColor.PaleVioletRed] = Color.FromArgb(-2396013); + ColorToKnownColor[-4139] = KnownColor.PapayaWhip; + KnownColorToColor[KnownColor.PapayaWhip] = Color.FromArgb(-4139); + ColorToKnownColor[-9543] = KnownColor.PeachPuff; + KnownColorToColor[KnownColor.PeachPuff] = Color.FromArgb(-9543); + ColorToKnownColor[-3308225] = KnownColor.Peru; + KnownColorToColor[KnownColor.Peru] = Color.FromArgb(-3308225); + ColorToKnownColor[-16181] = KnownColor.Pink; + KnownColorToColor[KnownColor.Pink] = Color.FromArgb(-16181); + ColorToKnownColor[-2252579] = KnownColor.Plum; + KnownColorToColor[KnownColor.Plum] = Color.FromArgb(-2252579); + ColorToKnownColor[-5185306] = KnownColor.PowderBlue; + KnownColorToColor[KnownColor.PowderBlue] = Color.FromArgb(-5185306); + ColorToKnownColor[-8388480] = KnownColor.Purple; + KnownColorToColor[KnownColor.Purple] = Color.FromArgb(-8388480); + ColorToKnownColor[-65536] = KnownColor.Red; + KnownColorToColor[KnownColor.Red] = Color.FromArgb(-65536); + ColorToKnownColor[-4419697] = KnownColor.RosyBrown; + KnownColorToColor[KnownColor.RosyBrown] = Color.FromArgb(-4419697); + ColorToKnownColor[-12490271] = KnownColor.RoyalBlue; + KnownColorToColor[KnownColor.RoyalBlue] = Color.FromArgb(-12490271); + ColorToKnownColor[-7650029] = KnownColor.SaddleBrown; + KnownColorToColor[KnownColor.SaddleBrown] = Color.FromArgb(-7650029); + ColorToKnownColor[-360334] = KnownColor.Salmon; + KnownColorToColor[KnownColor.Salmon] = Color.FromArgb(-360334); + ColorToKnownColor[-744352] = KnownColor.SandyBrown; + KnownColorToColor[KnownColor.SandyBrown] = Color.FromArgb(-744352); + ColorToKnownColor[-13726889] = KnownColor.SeaGreen; + KnownColorToColor[KnownColor.SeaGreen] = Color.FromArgb(-13726889); + ColorToKnownColor[-2578] = KnownColor.SeaShell; + KnownColorToColor[KnownColor.SeaShell] = Color.FromArgb(-2578); + ColorToKnownColor[-6270419] = KnownColor.Sienna; + KnownColorToColor[KnownColor.Sienna] = Color.FromArgb(-6270419); + ColorToKnownColor[-4144960] = KnownColor.Silver; + KnownColorToColor[KnownColor.Silver] = Color.FromArgb(-4144960); + ColorToKnownColor[-7876885] = KnownColor.SkyBlue; + KnownColorToColor[KnownColor.SkyBlue] = Color.FromArgb(-7876885); + ColorToKnownColor[-9807155] = KnownColor.SlateBlue; + KnownColorToColor[KnownColor.SlateBlue] = Color.FromArgb(-9807155); + ColorToKnownColor[-9404272] = KnownColor.SlateGray; + KnownColorToColor[KnownColor.SlateGray] = Color.FromArgb(-9404272); + ColorToKnownColor[-1286] = KnownColor.Snow; + KnownColorToColor[KnownColor.Snow] = Color.FromArgb(-1286); + ColorToKnownColor[-16711809] = KnownColor.SpringGreen; + KnownColorToColor[KnownColor.SpringGreen] = Color.FromArgb(-16711809); + ColorToKnownColor[-12156236] = KnownColor.SteelBlue; + KnownColorToColor[KnownColor.SteelBlue] = Color.FromArgb(-12156236); + ColorToKnownColor[-2968436] = KnownColor.Tan; + KnownColorToColor[KnownColor.Tan] = Color.FromArgb(-2968436); + ColorToKnownColor[-16744320] = KnownColor.Teal; + KnownColorToColor[KnownColor.Teal] = Color.FromArgb(-16744320); + ColorToKnownColor[-2572328] = KnownColor.Thistle; + KnownColorToColor[KnownColor.Thistle] = Color.FromArgb(-2572328); + ColorToKnownColor[-40121] = KnownColor.Tomato; + KnownColorToColor[KnownColor.Tomato] = Color.FromArgb(-40121); + ColorToKnownColor[-12525360] = KnownColor.Turquoise; + KnownColorToColor[KnownColor.Turquoise] = Color.FromArgb(-12525360); + ColorToKnownColor[-1146130] = KnownColor.Violet; + KnownColorToColor[KnownColor.Violet] = Color.FromArgb(-1146130); + ColorToKnownColor[-663885] = KnownColor.Wheat; + KnownColorToColor[KnownColor.Wheat] = Color.FromArgb(-663885); + ColorToKnownColor[-1] = KnownColor.White; + KnownColorToColor[KnownColor.White] = Color.FromArgb(-1); + ColorToKnownColor[-657931] = KnownColor.WhiteSmoke; + KnownColorToColor[KnownColor.WhiteSmoke] = Color.FromArgb(-657931); + ColorToKnownColor[-256] = KnownColor.Yellow; + KnownColorToColor[KnownColor.Yellow] = Color.FromArgb(-256); + ColorToKnownColor[-6632142] = KnownColor.YellowGreen; + KnownColorToColor[KnownColor.YellowGreen] = Color.FromArgb(-6632142); + ColorToKnownColor[-986896] = KnownColor.ButtonFace; + KnownColorToColor[KnownColor.ButtonFace] = Color.FromArgb(-986896); + ColorToKnownColor[-1] = KnownColor.ButtonHighlight; + KnownColorToColor[KnownColor.ButtonHighlight] = Color.FromArgb(-1); + ColorToKnownColor[-6250336] = KnownColor.ButtonShadow; + KnownColorToColor[KnownColor.ButtonShadow] = Color.FromArgb(-6250336); + ColorToKnownColor[-4599318] = KnownColor.GradientActiveCaption; + KnownColorToColor[KnownColor.GradientActiveCaption] = Color.FromArgb(-4599318); + ColorToKnownColor[-2628366] = KnownColor.GradientInactiveCaption; + KnownColorToColor[KnownColor.GradientInactiveCaption] = Color.FromArgb(-2628366); + ColorToKnownColor[-986896] = KnownColor.MenuBar; + KnownColorToColor[KnownColor.MenuBar] = Color.FromArgb(-986896); + ColorToKnownColor[-16746281] = KnownColor.MenuHighlight; + KnownColorToColor[KnownColor.MenuHighlight] = Color.FromArgb(-16746281); + } + public static bool IsKnownColor(Color color) { - return color.IsNamedColor; + return ColorToKnownColor.ContainsKey(color.ToArgb()); } - public static KnownColor ToKnownColor(Color c) + public static KnownColor ToKnownColor(Color color) { - KnownColor color; - if (Enum.TryParse(c.Name, out color)) - return color; - return default(KnownColor); + if (ColorToKnownColor.TryGetValue(color.ToArgb(), out KnownColor result)) + return result; + return KnownColor.Transparent; } public static Color FromKnownColor(KnownColor knownColor) { - return Color.FromName(knownColor.ToString()); + if (KnownColorToColor.TryGetValue(knownColor, out Color result)) + return result; + return Color.Transparent; } public static bool IsSystemColor(Color c) @@ -35,3 +572,6 @@ public static bool IsSystemColor(Color c) } } } +#endif + + diff --git a/FastReport.OpenSource/DotNetClasses/Color.Full.cs b/FastReport.OpenSource/DotNetClasses/Color.Full.cs index bd82b647..f6cb89c9 100644 --- a/FastReport.OpenSource/DotNetClasses/Color.Full.cs +++ b/FastReport.OpenSource/DotNetClasses/Color.Full.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.Text; -#if !NETSTANDARD2_0 +#if !(NETSTANDARD2_0 || NETSTANDARD2_1) namespace System.Drawing { internal class ColorExt diff --git a/FastReport.OpenSource/DotNetClasses/ColorConverter.cs b/FastReport.OpenSource/DotNetClasses/ColorConverter.cs index 635a39ed..75c2c779 100644 --- a/FastReport.OpenSource/DotNetClasses/ColorConverter.cs +++ b/FastReport.OpenSource/DotNetClasses/ColorConverter.cs @@ -1,4 +1,5 @@ -using System; +#if NETSTANDARD2_0 || NETSTANDARD2_1 +using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; @@ -476,3 +477,4 @@ public int Compare(object left, object right) // return (Color)TypeDescriptor.GetConverter(typeof(Color)).ConvertFromInvariantString(value); //} } +#endif \ No newline at end of file diff --git a/FastReport.OpenSource/DotNetClasses/ColorTranslator.cs b/FastReport.OpenSource/DotNetClasses/ColorTranslator.cs index 95264c02..83a1bd39 100644 --- a/FastReport.OpenSource/DotNetClasses/ColorTranslator.cs +++ b/FastReport.OpenSource/DotNetClasses/ColorTranslator.cs @@ -1,4 +1,5 @@ -using System; +#if NETSTANDARD2_0 || NETSTANDARD2_1 +using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; @@ -7,172 +8,173 @@ namespace System.Drawing { - internal class ColorTranslator - { - - private static Hashtable htmlSysColorTable; - - - public static string ToHtml(Color c) - { - string colorString = String.Empty; - - if (c.IsEmpty) - return colorString; - bool flag = true; - if (ColorExt.IsKnownColor(c)) - { - flag = false; - switch (ColorExt.ToKnownColor(c)) - { - case KnownColor.ActiveBorder: colorString = "activeborder"; break; - case KnownColor.GradientActiveCaption: - case KnownColor.ActiveCaption: colorString = "activecaption"; break; - case KnownColor.AppWorkspace: colorString = "appworkspace"; break; - case KnownColor.Desktop: colorString = "background"; break; - case KnownColor.Control: colorString = "buttonface"; break; - case KnownColor.ControlLight: colorString = "buttonface"; break; - case KnownColor.ControlDark: colorString = "buttonshadow"; break; - case KnownColor.ControlText: colorString = "buttontext"; break; - case KnownColor.ActiveCaptionText: colorString = "captiontext"; break; - case KnownColor.GrayText: colorString = "graytext"; break; - case KnownColor.HotTrack: - case KnownColor.Highlight: colorString = "highlight"; break; - case KnownColor.MenuHighlight: - case KnownColor.HighlightText: colorString = "highlighttext"; break; - case KnownColor.InactiveBorder: colorString = "inactiveborder"; break; - case KnownColor.GradientInactiveCaption: - case KnownColor.InactiveCaption: colorString = "inactivecaption"; break; - case KnownColor.InactiveCaptionText: colorString = "inactivecaptiontext"; break; - case KnownColor.Info: colorString = "infobackground"; break; - case KnownColor.InfoText: colorString = "infotext"; break; - case KnownColor.MenuBar: - case KnownColor.Menu: colorString = "menu"; break; - case KnownColor.MenuText: colorString = "menutext"; break; - case KnownColor.ScrollBar: colorString = "scrollbar"; break; - case KnownColor.ControlDarkDark: colorString = "threeddarkshadow"; break; - case KnownColor.ControlLightLight: colorString = "buttonhighlight"; break; - case KnownColor.Window: colorString = "window"; break; - case KnownColor.WindowFrame: colorString = "windowframe"; break; - case KnownColor.WindowText: colorString = "windowtext"; break; - default: flag = true; break; - } - } - if (flag) - { - if (c.IsNamedColor) - { - if (c == Color.LightGray) - { - // special case due to mismatch between Html and enum spelling - colorString = "LightGrey"; - } - else - { - colorString = c.Name; - } - } - else - { - colorString = "#" + c.R.ToString("X2", null) + - c.G.ToString("X2", null) + - c.B.ToString("X2", null); - } - } - return colorString; - } - - public static Color FromHtml(string htmlColor) - { - Color c = Color.Empty; - - // empty color - if ((htmlColor == null) || (htmlColor.Length == 0)) - return c; - - // #RRGGBB or #RGB - if ((htmlColor[0] == '#') && - ((htmlColor.Length == 7) || (htmlColor.Length == 4))) - { - - if (htmlColor.Length == 7) - { - c = Color.FromArgb(Convert.ToInt32(htmlColor.Substring(1, 2), 16), - Convert.ToInt32(htmlColor.Substring(3, 2), 16), - Convert.ToInt32(htmlColor.Substring(5, 2), 16)); - } - else - { - string r = Char.ToString(htmlColor[1]); - string g = Char.ToString(htmlColor[2]); - string b = Char.ToString(htmlColor[3]); - - c = Color.FromArgb(Convert.ToInt32(r + r, 16), - Convert.ToInt32(g + g, 16), - Convert.ToInt32(b + b, 16)); - } - } - - // special case. Html requires LightGrey, but .NET uses LightGray - if (c.IsEmpty && String.Equals(htmlColor, "LightGrey", StringComparison.OrdinalIgnoreCase)) - { - c = Color.LightGray; - } - - // System color - if (c.IsEmpty) - { - if (htmlSysColorTable == null) - { - InitializeHtmlSysColorTable(); - } - - object o = htmlSysColorTable[htmlColor.ToLower(CultureInfo.InvariantCulture)]; - if (o != null) - { - c = (Color)o; - } - } - - // resort to type converter which will handle named colors - if (c.IsEmpty) - { - c = (Color)TypeDescriptor.GetConverter(typeof(Color)).ConvertFromString(htmlColor); - } - - return c; - } - - private static void InitializeHtmlSysColorTable() - { - htmlSysColorTable = new Hashtable(26); - htmlSysColorTable["activeborder"] = ColorExt.FromKnownColor(KnownColor.ActiveBorder); - htmlSysColorTable["activecaption"] = ColorExt.FromKnownColor(KnownColor.ActiveCaption); - htmlSysColorTable["appworkspace"] = ColorExt.FromKnownColor(KnownColor.AppWorkspace); - htmlSysColorTable["background"] = ColorExt.FromKnownColor(KnownColor.Desktop); - htmlSysColorTable["buttonface"] = ColorExt.FromKnownColor(KnownColor.Control); - htmlSysColorTable["buttonhighlight"] = ColorExt.FromKnownColor(KnownColor.ControlLightLight); - htmlSysColorTable["buttonshadow"] = ColorExt.FromKnownColor(KnownColor.ControlDark); - htmlSysColorTable["buttontext"] = ColorExt.FromKnownColor(KnownColor.ControlText); - htmlSysColorTable["captiontext"] = ColorExt.FromKnownColor(KnownColor.ActiveCaptionText); - htmlSysColorTable["graytext"] = ColorExt.FromKnownColor(KnownColor.GrayText); - htmlSysColorTable["highlight"] = ColorExt.FromKnownColor(KnownColor.Highlight); - htmlSysColorTable["highlighttext"] = ColorExt.FromKnownColor(KnownColor.HighlightText); - htmlSysColorTable["inactiveborder"] = ColorExt.FromKnownColor(KnownColor.InactiveBorder); - htmlSysColorTable["inactivecaption"] = ColorExt.FromKnownColor(KnownColor.InactiveCaption); - htmlSysColorTable["inactivecaptiontext"] = ColorExt.FromKnownColor(KnownColor.InactiveCaptionText); - htmlSysColorTable["infobackground"] = ColorExt.FromKnownColor(KnownColor.Info); - htmlSysColorTable["infotext"] = ColorExt.FromKnownColor(KnownColor.InfoText); - htmlSysColorTable["menu"] = ColorExt.FromKnownColor(KnownColor.Menu); - htmlSysColorTable["menutext"] = ColorExt.FromKnownColor(KnownColor.MenuText); - htmlSysColorTable["scrollbar"] = ColorExt.FromKnownColor(KnownColor.ScrollBar); - htmlSysColorTable["threeddarkshadow"] = ColorExt.FromKnownColor(KnownColor.ControlDarkDark); - htmlSysColorTable["threedface"] = ColorExt.FromKnownColor(KnownColor.Control); - htmlSysColorTable["threedhighlight"] = ColorExt.FromKnownColor(KnownColor.ControlLight); - htmlSysColorTable["threedlightshadow"] = ColorExt.FromKnownColor(KnownColor.ControlLightLight); - htmlSysColorTable["window"] = ColorExt.FromKnownColor(KnownColor.Window); - htmlSysColorTable["windowframe"] = ColorExt.FromKnownColor(KnownColor.WindowFrame); - htmlSysColorTable["windowtext"] = ColorExt.FromKnownColor(KnownColor.WindowText); - } - } + //internal class ColorTranslator + //{ + + // private static Hashtable htmlSysColorTable; + + + // public static string ToHtml(Color c) + // { + // string colorString = String.Empty; + + // if (c.IsEmpty) + // return colorString; + // bool flag = true; + // if (ColorExt.IsKnownColor(c)) + // { + // flag = false; + // switch (ColorExt.ToKnownColor(c)) + // { + // case KnownColor.ActiveBorder: colorString = "activeborder"; break; + // case KnownColor.GradientActiveCaption: + // case KnownColor.ActiveCaption: colorString = "activecaption"; break; + // case KnownColor.AppWorkspace: colorString = "appworkspace"; break; + // case KnownColor.Desktop: colorString = "background"; break; + // case KnownColor.Control: colorString = "buttonface"; break; + // case KnownColor.ControlLight: colorString = "buttonface"; break; + // case KnownColor.ControlDark: colorString = "buttonshadow"; break; + // case KnownColor.ControlText: colorString = "buttontext"; break; + // case KnownColor.ActiveCaptionText: colorString = "captiontext"; break; + // case KnownColor.GrayText: colorString = "graytext"; break; + // case KnownColor.HotTrack: + // case KnownColor.Highlight: colorString = "highlight"; break; + // case KnownColor.MenuHighlight: + // case KnownColor.HighlightText: colorString = "highlighttext"; break; + // case KnownColor.InactiveBorder: colorString = "inactiveborder"; break; + // case KnownColor.GradientInactiveCaption: + // case KnownColor.InactiveCaption: colorString = "inactivecaption"; break; + // case KnownColor.InactiveCaptionText: colorString = "inactivecaptiontext"; break; + // case KnownColor.Info: colorString = "infobackground"; break; + // case KnownColor.InfoText: colorString = "infotext"; break; + // case KnownColor.MenuBar: + // case KnownColor.Menu: colorString = "menu"; break; + // case KnownColor.MenuText: colorString = "menutext"; break; + // case KnownColor.ScrollBar: colorString = "scrollbar"; break; + // case KnownColor.ControlDarkDark: colorString = "threeddarkshadow"; break; + // case KnownColor.ControlLightLight: colorString = "buttonhighlight"; break; + // case KnownColor.Window: colorString = "window"; break; + // case KnownColor.WindowFrame: colorString = "windowframe"; break; + // case KnownColor.WindowText: colorString = "windowtext"; break; + // default: flag = true; break; + // } + // } + // if (flag) + // { + // if (c.IsNamedColor) + // { + // if (c == Color.LightGray) + // { + // // special case due to mismatch between Html and enum spelling + // colorString = "LightGrey"; + // } + // else + // { + // colorString = c.Name; + // } + // } + // else + // { + // colorString = "#" + c.R.ToString("X2", null) + + // c.G.ToString("X2", null) + + // c.B.ToString("X2", null); + // } + // } + // return colorString; + // } + + // public static Color FromHtml(string htmlColor) + // { + // Color c = Color.Empty; + + // // empty color + // if ((htmlColor == null) || (htmlColor.Length == 0)) + // return c; + + // // #RRGGBB or #RGB + // if ((htmlColor[0] == '#') && + // ((htmlColor.Length == 7) || (htmlColor.Length == 4))) + // { + + // if (htmlColor.Length == 7) + // { + // c = Color.FromArgb(Convert.ToInt32(htmlColor.Substring(1, 2), 16), + // Convert.ToInt32(htmlColor.Substring(3, 2), 16), + // Convert.ToInt32(htmlColor.Substring(5, 2), 16)); + // } + // else + // { + // string r = Char.ToString(htmlColor[1]); + // string g = Char.ToString(htmlColor[2]); + // string b = Char.ToString(htmlColor[3]); + + // c = Color.FromArgb(Convert.ToInt32(r + r, 16), + // Convert.ToInt32(g + g, 16), + // Convert.ToInt32(b + b, 16)); + // } + // } + + // // special case. Html requires LightGrey, but .NET uses LightGray + // if (c.IsEmpty && String.Equals(htmlColor, "LightGrey", StringComparison.OrdinalIgnoreCase)) + // { + // c = Color.LightGray; + // } + + // // System color + // if (c.IsEmpty) + // { + // if (htmlSysColorTable == null) + // { + // InitializeHtmlSysColorTable(); + // } + + // object o = htmlSysColorTable[htmlColor.ToLower(CultureInfo.InvariantCulture)]; + // if (o != null) + // { + // c = (Color)o; + // } + // } + + // // resort to type converter which will handle named colors + // if (c.IsEmpty) + // { + // c = (Color)TypeDescriptor.GetConverter(typeof(Color)).ConvertFromString(htmlColor); + // } + + // return c; + // } + + // private static void InitializeHtmlSysColorTable() + // { + // htmlSysColorTable = new Hashtable(26); + // htmlSysColorTable["activeborder"] = ColorExt.FromKnownColor(KnownColor.ActiveBorder); + // htmlSysColorTable["activecaption"] = ColorExt.FromKnownColor(KnownColor.ActiveCaption); + // htmlSysColorTable["appworkspace"] = ColorExt.FromKnownColor(KnownColor.AppWorkspace); + // htmlSysColorTable["background"] = ColorExt.FromKnownColor(KnownColor.Desktop); + // htmlSysColorTable["buttonface"] = ColorExt.FromKnownColor(KnownColor.Control); + // htmlSysColorTable["buttonhighlight"] = ColorExt.FromKnownColor(KnownColor.ControlLightLight); + // htmlSysColorTable["buttonshadow"] = ColorExt.FromKnownColor(KnownColor.ControlDark); + // htmlSysColorTable["buttontext"] = ColorExt.FromKnownColor(KnownColor.ControlText); + // htmlSysColorTable["captiontext"] = ColorExt.FromKnownColor(KnownColor.ActiveCaptionText); + // htmlSysColorTable["graytext"] = ColorExt.FromKnownColor(KnownColor.GrayText); + // htmlSysColorTable["highlight"] = ColorExt.FromKnownColor(KnownColor.Highlight); + // htmlSysColorTable["highlighttext"] = ColorExt.FromKnownColor(KnownColor.HighlightText); + // htmlSysColorTable["inactiveborder"] = ColorExt.FromKnownColor(KnownColor.InactiveBorder); + // htmlSysColorTable["inactivecaption"] = ColorExt.FromKnownColor(KnownColor.InactiveCaption); + // htmlSysColorTable["inactivecaptiontext"] = ColorExt.FromKnownColor(KnownColor.InactiveCaptionText); + // htmlSysColorTable["infobackground"] = ColorExt.FromKnownColor(KnownColor.Info); + // htmlSysColorTable["infotext"] = ColorExt.FromKnownColor(KnownColor.InfoText); + // htmlSysColorTable["menu"] = ColorExt.FromKnownColor(KnownColor.Menu); + // htmlSysColorTable["menutext"] = ColorExt.FromKnownColor(KnownColor.MenuText); + // htmlSysColorTable["scrollbar"] = ColorExt.FromKnownColor(KnownColor.ScrollBar); + // htmlSysColorTable["threeddarkshadow"] = ColorExt.FromKnownColor(KnownColor.ControlDarkDark); + // htmlSysColorTable["threedface"] = ColorExt.FromKnownColor(KnownColor.Control); + // htmlSysColorTable["threedhighlight"] = ColorExt.FromKnownColor(KnownColor.ControlLight); + // htmlSysColorTable["threedlightshadow"] = ColorExt.FromKnownColor(KnownColor.ControlLightLight); + // htmlSysColorTable["window"] = ColorExt.FromKnownColor(KnownColor.Window); + // htmlSysColorTable["windowframe"] = ColorExt.FromKnownColor(KnownColor.WindowFrame); + // htmlSysColorTable["windowtext"] = ColorExt.FromKnownColor(KnownColor.WindowText); + // } + //} } +#endif \ No newline at end of file diff --git a/FastReport.OpenSource/DotNetClasses/CompilerError.cs b/FastReport.OpenSource/DotNetClasses/CompilerError.cs index f3c10774..5a7a01ec 100644 --- a/FastReport.OpenSource/DotNetClasses/CompilerError.cs +++ b/FastReport.OpenSource/DotNetClasses/CompilerError.cs @@ -1,4 +1,5 @@ -using System; +#if NETSTANDARD2_0 || NETSTANDARD2_1 +using System; using System.Collections.Generic; using System.Text; @@ -12,3 +13,5 @@ internal class CompilerError public object ErrorNumber { get; internal set; } } } + +#endif \ No newline at end of file diff --git a/FastReport.OpenSource/DotNetClasses/CompilerParameters.cs b/FastReport.OpenSource/DotNetClasses/CompilerParameters.cs index b8308315..adae6d3e 100644 --- a/FastReport.OpenSource/DotNetClasses/CompilerParameters.cs +++ b/FastReport.OpenSource/DotNetClasses/CompilerParameters.cs @@ -1,4 +1,5 @@ -using System; +#if NETSTANDARD2_0 || NETSTANDARD2_1 +using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Text; @@ -12,3 +13,5 @@ internal class CompilerParameters public TempFileCollection TempFiles { get; internal set; } = new TempFileCollection("", false); } } + +#endif \ No newline at end of file diff --git a/FastReport.OpenSource/DotNetClasses/CompilerResults.cs b/FastReport.OpenSource/DotNetClasses/CompilerResults.cs index ecd09adb..9d77efe2 100644 --- a/FastReport.OpenSource/DotNetClasses/CompilerResults.cs +++ b/FastReport.OpenSource/DotNetClasses/CompilerResults.cs @@ -1,4 +1,5 @@ -using System; +#if NETSTANDARD2_0 || NETSTANDARD2_1 +using System; using System.Collections.Generic; using System.Reflection; using System.Text; @@ -11,3 +12,5 @@ internal class CompilerResults public Assembly CompiledAssembly { get; internal set; } = null; } } + +#endif \ No newline at end of file diff --git a/FastReport.OpenSource/DotNetClasses/SystemColors.cs b/FastReport.OpenSource/DotNetClasses/SystemColors.cs index d7bb74ab..4e22c9b0 100644 --- a/FastReport.OpenSource/DotNetClasses/SystemColors.cs +++ b/FastReport.OpenSource/DotNetClasses/SystemColors.cs @@ -1,4 +1,5 @@ -using System; +#if NETSTANDARD2_0 || NETSTANDARD2_1 +using System; using System.Collections.Generic; using System.Text; @@ -42,3 +43,5 @@ internal static class SystemColors public static Color WindowText => ColorExt.FromKnownColor(KnownColor.WindowText); } } + +#endif \ No newline at end of file diff --git a/FastReport.OpenSource/DotNetClasses/TempFileCollection.cs b/FastReport.OpenSource/DotNetClasses/TempFileCollection.cs index 23e562a3..fff11dba 100644 --- a/FastReport.OpenSource/DotNetClasses/TempFileCollection.cs +++ b/FastReport.OpenSource/DotNetClasses/TempFileCollection.cs @@ -1,4 +1,5 @@ -using System; +#if NETSTANDARD2_0 || NETSTANDARD2_1 +using System; using System.Collections.Generic; using System.Text; @@ -16,3 +17,5 @@ public TempFileCollection(string tempFolder, bool v) } } } + +#endif \ No newline at end of file diff --git a/FastReport.OpenSource/DotNetClasses/UITypeEditor.cs b/FastReport.OpenSource/DotNetClasses/UITypeEditor.cs new file mode 100644 index 00000000..717125ae --- /dev/null +++ b/FastReport.OpenSource/DotNetClasses/UITypeEditor.cs @@ -0,0 +1,10 @@ +#if NETSTANDARD2_1 || NETSTANDARD2_0 + +namespace System.Drawing.Design +{ + class UITypeEditor + { + + } +} +#endif \ No newline at end of file diff --git a/FastReport.OpenSource/DotNetClasses/VBCodeProvider.cs b/FastReport.OpenSource/DotNetClasses/VBCodeProvider.cs index 59171530..f31f0d63 100644 --- a/FastReport.OpenSource/DotNetClasses/VBCodeProvider.cs +++ b/FastReport.OpenSource/DotNetClasses/VBCodeProvider.cs @@ -1,4 +1,5 @@ -using Microsoft.CodeAnalysis; +#if NETSTANDARD2_0 || NETSTANDARD2_1 +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.VisualBasic; using System; using System.CodeDom.Compiler; @@ -31,6 +32,8 @@ public override CompilerResults CompileAssemblyFromSource(CompilerParameters cp, AddExtraAssemblies(cp.ReferencedAssemblies, references); + + Compilation compilation = VisualBasicCompilation.Create( "_" + Guid.NewGuid().ToString("D"), new SyntaxTree[] { codeTree }, references: references, options: options.WithEmbedVbCoreRuntime(true) @@ -78,3 +81,4 @@ public override void Dispose() } } +#endif \ No newline at end of file diff --git a/FastReport.OpenSource/DotNetClasses/WindowsFormsReplacement.BindingSource.cs b/FastReport.OpenSource/DotNetClasses/WindowsFormsReplacement.BindingSource.cs index 64eabd6b..5890b8d2 100644 --- a/FastReport.OpenSource/DotNetClasses/WindowsFormsReplacement.BindingSource.cs +++ b/FastReport.OpenSource/DotNetClasses/WindowsFormsReplacement.BindingSource.cs @@ -1,3 +1,4 @@ +#if NETSTANDARD2_0 || NETSTANDARD2_1 // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including @@ -145,3 +146,5 @@ public virtual PropertyDescriptorCollection GetItemProperties(PropertyDescriptor } } } + +#endif \ No newline at end of file diff --git a/FastReport.OpenSource/DotNetClasses/WindowsFormsReplacement.ListBindingHelper.cs b/FastReport.OpenSource/DotNetClasses/WindowsFormsReplacement.ListBindingHelper.cs index 1527ae18..06b4b724 100644 --- a/FastReport.OpenSource/DotNetClasses/WindowsFormsReplacement.ListBindingHelper.cs +++ b/FastReport.OpenSource/DotNetClasses/WindowsFormsReplacement.ListBindingHelper.cs @@ -1,3 +1,4 @@ +#if NETSTANDARD2_0 || NETSTANDARD2_1 // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including @@ -176,3 +177,4 @@ static PropertyInfo GetPropertyByReflection(Type type, string property_name) } } } +#endif \ No newline at end of file diff --git a/FastReport.OpenSource/DotNetClasses/WindowsFormsReplacement.cs b/FastReport.OpenSource/DotNetClasses/WindowsFormsReplacement.cs index 8e2f42a0..37df4074 100644 --- a/FastReport.OpenSource/DotNetClasses/WindowsFormsReplacement.cs +++ b/FastReport.OpenSource/DotNetClasses/WindowsFormsReplacement.cs @@ -1,3 +1,4 @@ +#if NETSTANDARD2_0 || NETSTANDARD2_1 using System; using System.Collections.Generic; using System.Text; @@ -870,4 +871,5 @@ public static void DoEvents() #pragma warning restore FR0000 // Field must be texted in lowerCamelCase. -#pragma warning restore 1591 \ No newline at end of file +#pragma warning restore 1591 +#endif \ No newline at end of file diff --git a/FastReport.OpenSource/FastReport.OpenSource.csproj b/FastReport.OpenSource/FastReport.OpenSource.csproj index d0edde21..3ee808a5 100644 --- a/FastReport.OpenSource/FastReport.OpenSource.csproj +++ b/FastReport.OpenSource/FastReport.OpenSource.csproj @@ -1,7 +1,7 @@  - net40;netstandard2.0 + net40;netstandard2.0;netstandard2.1 @@ -32,21 +32,23 @@ Various report objects will allow your report to look exactly how you want it to TRACE;DOTNET_4; - - + + + + - + - + @@ -54,6 +56,7 @@ Various report objects will allow your report to look exactly how you want it to + @@ -62,4 +65,5 @@ Various report objects will allow your report to look exactly how you want it to Resources\%(RecursiveDir)%(Filename)%(Extension) + \ No newline at end of file diff --git a/FastReport.OpenSource/TypeConverters/FontConverter.cs b/FastReport.OpenSource/TypeConverters/FontConverter.cs new file mode 100644 index 00000000..a5f7ca41 --- /dev/null +++ b/FastReport.OpenSource/TypeConverters/FontConverter.cs @@ -0,0 +1,386 @@ +// +// System.Drawing.FontConverter.cs +// +// Authors: +// Dennis Hayes (dennish@Raytek.com) +// Gonzalo Paniagua Javier (gonzalo@ximian.com) +// Ravindra (rkumar@novell.com) +// +// Copyright (C) 2002,2003 Ximian, Inc. http://www.ximian.com +// +// Copyright (C) 2004-2006 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +#if NETSTANDARD2_0 || NETSTANDARD2_1 +using System; +using System.Text; +using System.Collections; +using System.ComponentModel; +using System.Globalization; +using System.Drawing.Text; +using System.ComponentModel.Design.Serialization; +using System.Reflection; +using System.Drawing; + +namespace FastReport.TypeConverters +{ + public class FontConverter : TypeConverter + { + public static FontConverter Instance { get; } = new FontConverter(); + public FontConverter () + { + } + ~FontConverter () + { + // required to match API definition + } + public override bool CanConvertFrom (ITypeDescriptorContext context, Type sourceType) + { + if (sourceType == typeof (string)) + return true; + + return base.CanConvertFrom (context, sourceType); + } + + public override bool CanConvertTo (ITypeDescriptorContext context, Type destinationType) + { + if (destinationType == typeof (String)) + return true; + + if (destinationType == typeof (InstanceDescriptor)) + return true; + + return base.CanConvertTo (context, destinationType); + } + + public override object ConvertTo (ITypeDescriptorContext context, + CultureInfo culture, + object value, + Type destinationType) + { + if ((destinationType == typeof (string)) && (value is Font)) { + Font font = (Font) value; + StringBuilder sb = new StringBuilder (); + sb.Append (font.Name).Append (culture.TextInfo.ListSeparator[0] + " "); + sb.Append (font.Size); + + switch (font.Unit) { + // MS throws ArgumentException, if unit is set + // to GraphicsUnit.Display + // Don't know what to append for GraphicsUnit.Display + case GraphicsUnit.Display: + sb.Append ("display"); break; + + case GraphicsUnit.Document: + sb.Append ("doc"); break; + + case GraphicsUnit.Point: + sb.Append ("pt"); break; + + case GraphicsUnit.Inch: + sb.Append ("in"); break; + + case GraphicsUnit.Millimeter: + sb.Append ("mm"); break; + + case GraphicsUnit.Pixel: + sb.Append ("px"); break; + + case GraphicsUnit.World: + sb.Append ("world"); break; + } + + if (font.Style != FontStyle.Regular) + sb.Append (culture.TextInfo.ListSeparator[0] + " style=").Append (font.Style); + + return sb.ToString (); + } + + if ((destinationType == typeof (InstanceDescriptor)) && (value is Font)) { + Font font = (Font) value; + ConstructorInfo met = typeof(Font).GetTypeInfo ().GetConstructor (new Type[] {typeof(string), typeof(float), typeof(FontStyle), typeof(GraphicsUnit)}); + object[] args = new object[4]; + args [0] = font.Name; + args [1] = font.Size; + args [2] = font.Style; + args [3] = font.Unit; + return new InstanceDescriptor (met, args); + } + + return base.ConvertTo (context, culture, value, destinationType); + } + + public override object ConvertFrom (ITypeDescriptorContext context, CultureInfo culture, object value) + { + FontStyle f_style; + float f_size; + GraphicsUnit f_unit; + string font; + string units; + string[] fields; + + if (! (value is string)) { + return base.ConvertFrom (context, culture, value); + } + + font = (string)value; + font = font.Trim (); + + if (font.Length == 0) { + return null; + } + + if (culture == null) { + culture = CultureInfo.CurrentCulture; + } + + // Format is FontFamily, size[[, style=1,2,3]] + // This is a bit tricky since the comma can be used for styles and fields + fields = font.Split(new char[] {culture.TextInfo.ListSeparator[0]}); + if (fields.Length < 1) { + throw new ArgumentException("Failed to parse font format"); + } + + font = fields[0]; + f_size = 8f; + units = "px"; + f_unit = GraphicsUnit.Pixel; + if (fields.Length > 1) { // We have a size + for (int i = 0; i < fields[1].Length; i++) { + if (Char.IsLetter(fields[1][i])) { + f_size = (float)TypeDescriptor.GetConverter(typeof(float)).ConvertFromString(context, culture, fields[1].Substring(0, i)); + units = fields[1].Substring(i); + break; + } + } + if (units == "display") { + f_unit = GraphicsUnit.Display; + } else if (units == "doc") { + f_unit = GraphicsUnit.Document; + } else if (units == "pt") { + f_unit = GraphicsUnit.Point; + } else if (units == "in") { + f_unit = GraphicsUnit.Inch; + } else if (units == "mm") { + f_unit = GraphicsUnit.Millimeter; + } else if (units == "px") { + f_unit = GraphicsUnit.Pixel; + } else if (units == "world") { + f_unit = GraphicsUnit.World; + } + } + + f_style = FontStyle.Regular; + if (fields.Length > 2) { // We have style + string compare; + + for (int i = 2; i < fields.Length; i++) { + compare = fields[i]; + + if (compare.IndexOf("Regular") != -1) { + f_style |= FontStyle.Regular; + } + if (compare.IndexOf("Bold") != -1) { + f_style |= FontStyle.Bold; + } + if (compare.IndexOf("Italic") != -1) { + f_style |= FontStyle.Italic; + } + if (compare.IndexOf("Strikeout") != -1) { + f_style |= FontStyle.Strikeout; + } + if (compare.IndexOf("Underline") != -1) { + f_style |= FontStyle.Underline; + } + } + } + + return new Font (font, f_size, f_style, f_unit); + } + + public override object CreateInstance (ITypeDescriptorContext context, IDictionary propertyValues) + { + Object value; + byte charSet = 1; + float size = 8; + String name = null; + bool vertical = false; + FontStyle style = FontStyle.Regular; + FontFamily fontFamily = null; + GraphicsUnit unit = GraphicsUnit.Point; + + if ((value = propertyValues ["GdiCharSet"]) != null) + charSet = (byte) value; + + if ((value = propertyValues ["Size"]) != null) + size = (float) value; + + if ((value = propertyValues ["Unit"]) != null) + unit = (GraphicsUnit) value; + + if ((value = propertyValues ["Name"]) != null) + name = (String) value; + + if ((value = propertyValues ["GdiVerticalFont"]) != null) + vertical = (bool) value; + + if ((value = propertyValues ["Bold"]) != null) { + bool bold = (bool) value; + if (bold == true) + style |= FontStyle.Bold; + } + + if ((value = propertyValues ["Italic"]) != null) { + bool italic = (bool) value; + if (italic == true) + style |= FontStyle.Italic; + } + + if ((value = propertyValues ["Strikeout"]) != null) { + bool strike = (bool) value; + if (strike == true) + style |= FontStyle.Strikeout; + } + + if ((value = propertyValues ["Underline"]) != null) { + bool underline = (bool) value; + if (underline == true) + style |= FontStyle.Underline; + } + + /* ?? Should default font be culture dependent ?? */ + if (name == null) + fontFamily = new FontFamily ("Tahoma"); + else { + name = name.ToLower (); + FontCollection collection = new InstalledFontCollection (); + FontFamily [] installedFontList = collection.Families; + foreach (FontFamily font in installedFontList) { + if (name == font.Name.ToLower ()) { + fontFamily = font; + break; + } + } + + // font family not found in installed fonts + if (fontFamily == null) { + collection = new PrivateFontCollection (); + FontFamily [] privateFontList = collection.Families; + foreach (FontFamily font in privateFontList) { + if (name == font.Name.ToLower ()) { + fontFamily = font; + break; + } + } + } + + // font family not found in private fonts also + if (fontFamily == null) + fontFamily = FontFamily.GenericSansSerif; + } + + return new Font (fontFamily, size, style, unit, charSet, vertical); + } + + public override bool GetCreateInstanceSupported (ITypeDescriptorContext context) + { + return true; + } + + public override PropertyDescriptorCollection GetProperties + (ITypeDescriptorContext context, + object value, Attribute [] attributes) + { + if (value is Font) + return TypeDescriptor.GetProperties (value, attributes); + + return base.GetProperties (context, value, attributes); + } + + public override bool GetPropertiesSupported (ITypeDescriptorContext context) + { + return true; + } + + public sealed class FontNameConverter : TypeConverter + , IDisposable + { + FontFamily [] fonts; + + public FontNameConverter () + { + fonts = FontFamily.Families; + } + void IDisposable.Dispose () + { + } + public override bool CanConvertFrom (ITypeDescriptorContext context, Type sourceType) + { + if (sourceType == typeof (string)) + return true; + + return base.CanConvertFrom (context, sourceType); + } + + public override object ConvertFrom (ITypeDescriptorContext context, CultureInfo culture, object value) + { + if (value is string) + return value; + return base.ConvertFrom (context, culture, value); + } + + public override StandardValuesCollection GetStandardValues (ITypeDescriptorContext context) + { + string [] values = new string [fonts.Length]; + for (int i = fonts.Length; i > 0;){ + i--; + values [i] = fonts [i].Name; + } + + return new TypeConverter.StandardValuesCollection (values); + } + + public override bool GetStandardValuesExclusive (ITypeDescriptorContext context) + { + // We allow other values other than those in the font list. + return false; + } + + public override bool GetStandardValuesSupported (ITypeDescriptorContext context) + { + // Yes, we support picking an element from the list. + return true; + } + } + + public class FontUnitConverter : EnumConverter + { + public FontUnitConverter () : base (typeof (GraphicsUnit)) {} + + public override StandardValuesCollection GetStandardValues (ITypeDescriptorContext context) + { + return base.GetStandardValues (context); + } + + } + } +} +#endif \ No newline at end of file diff --git a/FastReport/Resources/buttons.png b/FastReport/Resources/buttons.png index 576d143906e47fdc271f93c35aba2218844378ca..971bc0c1c87071b856cc8bae022c8b07d7816014 100644 GIT binary patch literal 63401 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 dL@Dkn>yGro0vI#H)r;=bNs{x00cexKdW}; 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 + @@ -299,6 +300,7 @@ + @@ -427,6 +429,7 @@ + @@ -535,10 +538,12 @@ - + + + @@ -1586,6 +1591,8 @@ + + @@ -1760,6 +1767,13 @@ + + + + + + + @@ -1936,6 +1950,11 @@ + + + + + @@ -2136,6 +2155,7 @@ + diff --git a/Tools/FastReport.Tests.OpenSource/Data/JsonConnectionTests.cs b/Tools/FastReport.Tests.OpenSource/Data/JsonConnectionTests.cs new file mode 100644 index 00000000..b1e97cd5 --- /dev/null +++ b/Tools/FastReport.Tests.OpenSource/Data/JsonConnectionTests.cs @@ -0,0 +1,175 @@ +using FastReport.Data.JsonConnection; +using System; +using System.Collections.Generic; +using System.Text; +using Xunit; + +namespace FastReport.Tests.OpenSource.Data +{ + + public class JsonConnectionTests + { + + [Fact] + public void EmptyTextTest() + { + Assert.Throws(() => JsonBase.FromString("")); + } + + [Theory] + [InlineData("{}")] + [InlineData(" { } ")] + [InlineData(" {}")] + [InlineData("{ \n} ")] + public void EmptyObjectTest(string jsonText) + { + Assert.IsType(JsonBase.FromString(jsonText)); + } + + [Theory] + [InlineData("[]")] + [InlineData(" [ ] ")] + [InlineData(" []")] + [InlineData("[ \n] ")] + public void EmptyArrayTest(string jsonText) + { + Assert.IsType(JsonBase.FromString(jsonText)); + } + + [Theory] + [InlineData("[0.1]", 0.1)] + [InlineData("[0.1e010]", 0.1e010)] + [InlineData("[0.10]", 0.10)] + [InlineData("[0.01e010]", 0.01e010)] + [InlineData("[-0.1]", -0.1)] + [InlineData("[0.1e-010]", 0.1e-010)] + [InlineData("[51251.1]", 51251.1)] + [InlineData("[0.1e+010]", 0.1e+010)] + [InlineData("[-0010.1]", -0010.1)] + [InlineData("[5e110]", 5e110)] + [InlineData("[-1]", -1)] + [InlineData("[-5]", -5)] + [InlineData("[7]", 7)] + [InlineData("[7312312]", 7312312)] + [InlineData("[-12317]", -12317)] + public void ReadNumberTest(string jsonText, double number) + { + JsonBase obj = JsonBase.FromString(jsonText); + + Assert.IsType(obj); + Assert.Single(obj as JsonArray); + Assert.IsType((obj as JsonArray)[0]); + Assert.Equal(number, ((obj as JsonArray)[0] as JsonNumber).Value, 1); + } + + [Theory] + [InlineData("{\"key\":0}", "key")] + [InlineData("{\"\\uabcdkey\":0}", "\uabcdkey")] + [InlineData("{\"\\uabCdkey\":0}", "\uabCdkey")] + [InlineData("{\"\\u0001key\":0}", "\u0001key")] + [InlineData("{\"\\u00Cdkey\":0}", "\u00Cdkey")] + [InlineData("{\"\\uab00key\":0}", "\uab00key")] + [InlineData("{\"\\r\":0}", "\r")] + [InlineData("{\"\\t\":0}", "\t")] + [InlineData("{\"\\n\\n\":0}", "\n\n")] + [InlineData("{\"\\f\":0}", "\f")] + [InlineData("{\"\\b\":0}", "\b")] + [InlineData("{\"\\\\\":0}", "\\")] + [InlineData("{\"\\/\":0}", "/")] + [InlineData("{\"\\\"\":0}", "\"")] + public void ReadKeyTest(string jsonText, string key) + { + JsonBase obj = JsonBase.FromString(jsonText); + + Assert.IsType(obj); + Assert.Single(obj as JsonObject); + Assert.Contains(key, (obj as JsonObject).Keys); + } + + [Theory] + [InlineData("{ \n\t\"true\": true}", "true", true)] + [InlineData("{\"true\":false }", "true", false)] + public void ReadBool(string jsonText, string key, bool value) + { + JsonBase obj = JsonBase.FromString(jsonText); + + Assert.IsType(obj); + Assert.Single(obj as JsonObject); + Assert.Contains(key, (obj as JsonObject).Keys); + Assert.IsType((obj as JsonObject)[key]); + Assert.Equal(value, ((obj as JsonObject)[key] as JsonBoolean).Value); + } + + [Theory] + [InlineData("{ \n\t\"true\": null}", "true")] + [InlineData("{\"true\":null }", "true")] + public void ReadNull(string jsonText, string key) + { + JsonBase obj = JsonBase.FromString(jsonText); + + Assert.IsType(obj); + Assert.Single(obj as JsonObject); + Assert.Contains(key, (obj as JsonObject).Keys); + Assert.Null((obj as JsonObject)[key]); + } + + [Fact] + public void TestComplex() + { + string jsonText = @"{ + ""glossary"": { + ""title"": ""example glossary"", + ""GlossDiv"": { + ""title"": ""S"", + ""GlossList"": { + ""GlossEntry"": { + ""ID"": ""SGML"", + ""SortAs"": ""SGML"", + ""GlossTerm"": ""Standard Generalized Markup Language"", + ""Acronym"": ""SGML"", + ""Abbrev"": ""ISO 8879:1986"", + ""GlossDef"": { + ""para"": ""A meta-markup language, used to create markup languages such as DocBook."", + ""GlossSeeAlso"": [""GML"", ""XML""] + }, + ""GlossSee"": ""markup"" + } + } + } + } +}"; + + JsonBase jsonBase = JsonBase.FromString(jsonText); + + Assert.IsType(jsonBase); + + JsonObject obj = jsonBase as JsonObject; + + Assert.Single(obj); + + Assert.IsType(obj["glossary"]); + + obj = obj["glossary"] as JsonObject; + + Assert.Equal(2, obj.Count); + + Assert.IsType(obj["title"]); + + Assert.Equal("example glossary", (obj["title"] as JsonString).Value); + + Assert.IsType(obj["GlossDiv"]); + obj = obj["GlossDiv"] as JsonObject; + + Assert.IsType(obj["GlossList"]); + obj = obj["GlossList"] as JsonObject; + + Assert.IsType(obj["GlossEntry"]); + obj = obj["GlossEntry"] as JsonObject; + + Assert.IsType(obj["GlossDef"]); + obj = obj["GlossDef"] as JsonObject; + + Assert.IsType(obj["GlossSeeAlso"]); + } + } +} diff --git a/Tools/FastReport.Tests.OpenSource/FastReport.Tests.OpenSource.csproj b/Tools/FastReport.Tests.OpenSource/FastReport.Tests.OpenSource.csproj index a5fed2f9..d0f3ef67 100644 --- a/Tools/FastReport.Tests.OpenSource/FastReport.Tests.OpenSource.csproj +++ b/Tools/FastReport.Tests.OpenSource/FastReport.Tests.OpenSource.csproj @@ -1,4 +1,4 @@ - + netcoreapp2.1