diff --git a/src/ACadSharp.Pdf.Tests/PdfExporterTests.cs b/src/ACadSharp.Pdf.Tests/PdfExporterTests.cs index 1e20661..f97102a 100644 --- a/src/ACadSharp.Pdf.Tests/PdfExporterTests.cs +++ b/src/ACadSharp.Pdf.Tests/PdfExporterTests.cs @@ -1,5 +1,9 @@ +using ACadSharp.Entities; using ACadSharp.IO; +using CSMath; +using System.Globalization; using System.IO; +using System.Text; using Xunit; using Xunit.Abstractions; @@ -55,6 +59,42 @@ public void AddModelSpaceTest() exporter.Close(); } + [Fact] + public void InvariantDecimalSeparatorTest() + { + CultureInfo previousCulture = CultureInfo.CurrentCulture; + + try + { + //A culture such as fr-FR uses the comma as decimal separator, + //which would produce an invalid pdf stream if numbers were not + //formatted using the invariant culture. + CultureInfo.CurrentCulture = new CultureInfo("fr-FR"); + + CadDocument doc = new CadDocument(); + doc.Entities.Add(new Line(new XYZ(0, 0, 0), new XYZ(12.5, 7.25, 0))); + + string content; + using (MemoryStream stream = new MemoryStream()) + { + PdfExporter exporter = new PdfExporter(stream); + exporter.AddModelSpace(doc); + exporter.Close(); + + content = Encoding.ASCII.GetString(stream.ToArray()); + } + + //No number must use the comma as decimal separator. + Assert.DoesNotMatch(@"\d,\d", content); + //The decimal point must be used (e.g. MediaBox, coordinates). + Assert.Contains(".", content); + } + finally + { + CultureInfo.CurrentCulture = previousCulture; + } + } + [Theory] [MemberData(nameof(LayoutNames))] public void WriteLayouts(string name) diff --git a/src/ACadSharp.Pdf/Core/IO/PdfPen.cs b/src/ACadSharp.Pdf/Core/IO/PdfPen.cs index 43a67d6..6db4b8c 100644 --- a/src/ACadSharp.Pdf/Core/IO/PdfPen.cs +++ b/src/ACadSharp.Pdf/Core/IO/PdfPen.cs @@ -7,6 +7,7 @@ using CSMath; using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Text; @@ -123,7 +124,7 @@ private void applyStyle(Entity entity) { LineWeightType lw = entity.GetActiveLineWeightType(); double lwValue = lw.GetLineWeightValue(); - this._sb.AppendLine($"{lwValue.ToPdfUnit(PdfUnitType.Millimeter)} {PdfKey.LineWidth}"); + this._sb.AppendLine($"{lwValue.ToPdfUnit(PdfUnitType.Millimeter).ToString(this._configuration.DecimalFormat, CultureInfo.InvariantCulture)} {PdfKey.LineWidth}"); Color color = entity.GetActiveColor(); @@ -322,7 +323,7 @@ private void drawViewport(Viewport viewport) private string toPdfDouble(double value) { - return (value / this.DenominatorScale).ToPdfUnit(this.PaperUnits).ToString(this._configuration.DecimalFormat); + return (value / this.DenominatorScale).ToPdfUnit(this.PaperUnits).ToString(this._configuration.DecimalFormat, CultureInfo.InvariantCulture); } private void writeEntityEnd(Entity entity) diff --git a/src/ACadSharp.Pdf/Core/PdfReference.cs b/src/ACadSharp.Pdf/Core/PdfReference.cs index 5d816cd..31adc4c 100644 --- a/src/ACadSharp.Pdf/Core/PdfReference.cs +++ b/src/ACadSharp.Pdf/Core/PdfReference.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; namespace ACadSharp.Pdf.Core { @@ -20,7 +21,14 @@ public void Print() public override string GetPdfForm(PdfConfiguration configuration) { - return this._f.Invoke().ToString(); + T value = this._f.Invoke(); + + if (value is IFormattable formattable) + { + return formattable.ToString(null, CultureInfo.InvariantCulture); + } + + return value.ToString(); } } } diff --git a/src/ACadSharp.Pdf/Extensions/XYZExtensions.cs b/src/ACadSharp.Pdf/Extensions/XYZExtensions.cs index 2c38aa6..6ea2844 100644 --- a/src/ACadSharp.Pdf/Extensions/XYZExtensions.cs +++ b/src/ACadSharp.Pdf/Extensions/XYZExtensions.cs @@ -2,6 +2,7 @@ using ACadSharp.Pdf.Core; using CSMath; using System; +using System.Globalization; namespace ACadSharp.Pdf.Extensions { @@ -39,7 +40,7 @@ public static class ColorExtensions { public static string ToPdfString(this Color color) { - return $"{color.R / 255d} {color.G / 255d} {color.B / 255d} RG"; + return string.Format(CultureInfo.InvariantCulture, "{0} {1} {2} RG", color.R / 255d, color.G / 255d, color.B / 255d); } } } \ No newline at end of file