View Issue Details

IDProjectCategoryView StatusLast Update
0034077FPCFCLpublic2018-08-07 10:37
ReporterwpAssigned ToMichael Van Canneyt 
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Product Version3.0.4Product Build 
Target Version3.2.0Fixed in Version3.1.1 
Summary0034077: fppfd writing localized floating point strings
DescriptionUnit fpPDF contains several places in which floating point values are written to the pdf document as strings like this:

  t1 := FormatFloat('0.###;;0', Cos(rad));

or

  AddObject(TPDFFreeFormString.Create(Document,
    Format('%s %s %s %s %.4f %.4f cm', [t1, t2, t3, t1, p1.X, p1.Y]) + CRLF));

Since these FormatFloat() or Format() calls does not specifiy the FormatSettings as last parameter the string is created using the localized DefaultFormatSettings, i.e. it may contain a decimal comma in certain countries (e.g. Germany, like mine).

I think this is against PDF specification. Standard pdf readers at least cannot open such files.
Steps To ReproduceThe bug appears when rotated images are embedded into the PDF. Please run attached demo. It first sets the default decimal separator to a ',' so that everybody can see the bug. Then it adds a rotated jpeg image to the PDF.

Open the generated 'test.pdf' file in Adobe Reader, foxit reader, SumatraPDF, GoogleChrome, FireFox etc. The page with the rotated image will not be displayed. Adobe Reader will display a generic error message that the file is faulty.
Additional InformationThe provided patch fixed the issue. It adds its own non-localized FormatSettings to the PDFDocument and calls FormatFloat() and Format() with it as last parameter.
TagsNo tags attached.
Fixed in Revision39585
FPCOldBugId
FPCTarget
Attached Files
  • fpfpd-decimalcomma.zip (400,303 bytes)
  • fppdf-decimalcomma.patch (6,345 bytes)
    Index: packages/fcl-pdf/src/fppdf.pp
    ===================================================================
    --- packages/fcl-pdf/src/fppdf.pp	(revision 39401)
    +++ packages/fcl-pdf/src/fppdf.pp	(working copy)
    @@ -971,6 +971,7 @@
         FZoomValue: string;
         FGlobalXRefs: TFPObjectList; // list of TPDFXRef
         FUnitOfMeasure: TPDFUnitOfMeasure;
    +    FFormatSettings: TFormatSettings;
         function GetStdFontCharWidthsArray(const AFontName: string): TPDFFontWidthArray;
         function GetX(AIndex : Integer): TPDFXRef;
         function GetXC: Integer;
    @@ -1070,6 +1071,7 @@
         Property FontDirectory: string Read FFontDirectory Write FFontDirectory;
         Property Sections : TPDFSectionList Read FSections;
         Property ObjectCount : Integer Read FObjectCount;
    +    Property FormatSettings: TFormatSettings Read FFormatSettings;
       Published
         Property Options : TPDFOptions Read FOptions Write FOPtions;
         Property LineStyles : TPDFLineStyleDefs Read FLineStyleDefs Write SetLineStyles;
    @@ -2162,12 +2164,13 @@
       if ADegrees <> 0.0 then
       begin
         rad := DegToRad(-ADegrees);
    -    t1 := FormatFloat('0.###;;0', Cos(rad));
    -    t2 := FormatFloat('0.###;;0', -Sin(rad));
    -    t3 := FormatFloat('0.###;;0', Sin(rad));
    +    t1 := FormatFloat('0.###;;0', Cos(rad), Document.FormatSettings);
    +    t2 := FormatFloat('0.###;;0', -Sin(rad), Document.FormatSettings);
    +    t3 := FormatFloat('0.###;;0', Sin(rad), Document.FormatSettings);
         AddObject(TPDFPushGraphicsStack.Create(Document));
         // PDF v1.3 page 132 & 143
    -    AddObject(TPDFFreeFormString.Create(Document, Format('%s %s %s %s %.4f %.4f cm', [t1, t2, t3, t1, p1.X, p1.Y]) + CRLF));
    +    AddObject(TPDFFreeFormString.Create(Document, Format('%s %s %s %s %.4f %.4f cm',
    +      [t1, t2, t3, t1, p1.X, p1.Y], Document.FormatSettings) + CRLF));
         // co-ordinates are now based on the newly transformed matrix co-ordinates.
         R := Document.CreateRectangle(0, 0, p2.X, p2.Y, ALineWidth, AFill, AStroke);
       end
    @@ -2205,12 +2208,13 @@
       if ADegrees <> 0.0 then
       begin
         rad := DegToRad(-ADegrees);
    -    t1 := FormatFloat('0.###;;0', Cos(rad));
    -    t2 := FormatFloat('0.###;;0', -Sin(rad));
    -    t3 := FormatFloat('0.###;;0', Sin(rad));
    +    t1 := FormatFloat('0.###;;0', Cos(rad), Document.FormatSettings);
    +    t2 := FormatFloat('0.###;;0', -Sin(rad), Document.FormatSettings);
    +    t3 := FormatFloat('0.###;;0', Sin(rad), Document.FormatSettings);
         AddObject(TPDFPushGraphicsStack.Create(Document));
         // PDF v1.3 page 132 & 143
    -    AddObject(TPDFFreeFormString.Create(Document, Format('%s %s %s %s %.4f %.4f cm', [t1, t2, t3, t1, p1.X, p1.Y]) + CRLF));
    +    AddObject(TPDFFreeFormString.Create(Document, Format('%s %s %s %s %.4f %.4f cm',
    +      [t1, t2, t3, t1, p1.X, p1.Y], Document.FormatSettings) + CRLF));
         // co-ordinates are now based on the newly transformed matrix co-ordinates.
         R := Document.CreateRoundedRectangle(0, 0, p2.X, p2.Y, p3.X, ALineWidth, AFill, AStroke);
       end
    @@ -2235,12 +2239,13 @@
       if ADegrees <> 0.0 then
       begin
         rad := DegToRad(-ADegrees);
    -    t1 := FormatFloat('0.###;;0', Cos(rad));
    -    t2 := FormatFloat('0.###;;0', -Sin(rad));
    -    t3 := FormatFloat('0.###;;0', Sin(rad));
    +    t1 := FormatFloat('0.###;;0', Cos(rad), Document.FormatSettings);
    +    t2 := FormatFloat('0.###;;0', -Sin(rad), Document.FormatSettings);
    +    t3 := FormatFloat('0.###;;0', Sin(rad), Document.FormatSettings);
         AddObject(TPDFPushGraphicsStack.Create(Document));
         // PDF v1.3 page 132 & 143
    -    AddObject(TPDFFreeFormString.Create(Document, Format('%s %s %s %s %.4f %.4f cm', [t1, t2, t3, t1, p1.X, p1.Y]) + CRLF));
    +    AddObject(TPDFFreeFormString.Create(Document, Format('%s %s %s %s %.4f %.4f cm',
    +      [t1, t2, t3, t1, p1.X, p1.Y], Document.FormatSettings) + CRLF));
         // co-ordinates are now based on the newly transformed matrix co-ordinates.
         AddObject(Document.CreateImage(0, 0, APixelWidth, APixelHeight, ANumber));
       end
    @@ -2273,12 +2278,13 @@
       if ADegrees <> 0.0 then
       begin
         rad := DegToRad(-ADegrees);
    -    t1 := FormatFloat('0.###;;0', Cos(rad));
    -    t2 := FormatFloat('0.###;;0', -Sin(rad));
    -    t3 := FormatFloat('0.###;;0', Sin(rad));
    +    t1 := FormatFloat('0.###;;0', Cos(rad), Document.FormatSettings);
    +    t2 := FormatFloat('0.###;;0', -Sin(rad), Document.FormatSettings);
    +    t3 := FormatFloat('0.###;;0', Sin(rad), Document.FormatSettings);
         AddObject(TPDFPushGraphicsStack.Create(Document));
         // PDF v1.3 page 132 & 143
    -    AddObject(TPDFFreeFormString.Create(Document, Format('%s %s %s %s %.4f %.4f cm', [t1, t2, t3, t1, p1.X, p1.Y]) + CRLF));
    +    AddObject(TPDFFreeFormString.Create(Document, Format('%s %s %s %s %.4f %.4f cm',
    +      [t1, t2, t3, t1, p1.X, p1.Y], Document.FormatSettings) + CRLF));
         // co-ordinates are now based on the newly transformed matrix co-ordinates.
         AddObject(Document.CreateImage(0, 0, p2.X, p2.Y, ANumber));
       end
    @@ -2311,12 +2317,13 @@
       if ADegrees <> 0.0 then
       begin
         rad := DegToRad(-ADegrees);
    -    t1 := FormatFloat('0.###;;0', Cos(rad));
    -    t2 := FormatFloat('0.###;;0', -Sin(rad));
    -    t3 := FormatFloat('0.###;;0', Sin(rad));
    +    t1 := FormatFloat('0.###;;0', Cos(rad), Document.FormatSettings);
    +    t2 := FormatFloat('0.###;;0', -Sin(rad), Document.FormatSettings);
    +    t3 := FormatFloat('0.###;;0', Sin(rad), Document.FormatSettings);
         AddObject(TPDFPushGraphicsStack.Create(Document));
         // PDF v1.3 page 132 & 143
    -    AddObject(TPDFFreeFormString.Create(Document, Format('%s %s %s %s %.4f %.4f cm', [t1, t2, t3, t1, p1.X, p1.Y]) + CRLF));
    +    AddObject(TPDFFreeFormString.Create(Document, Format('%s %s %s %s %.4f %.4f cm',
    +      [t1, t2, t3, t1, p1.X, p1.Y], Document.FormatSettings) + CRLF));
         // co-ordinates are now based on the newly transformed matrix co-ordinates.
         AddObject(TPDFEllipse.Create(Document, 0, 0, p2.X, p2.Y, ALineWidth, AFill, AStroke));
       end
    @@ -4886,6 +4893,12 @@
       FZoomValue:='100';
       FOptions := [poCompressFonts, poCompressImages];
       FUnitOfMeasure:=uomMillimeters;
    +
    +  FFormatSettings := DefaultFormatSettings;
    +  FFormatSettings.DecimalSeparator := '.';
    +  FFormatSettings.ThousandSeparator := ',';
    +  FFormatSettings.DateSeparator := '/';
    +  FFormatSettings.TimeSeparator := ':';
     end;
     
     procedure TPDFDocument.StartDocument;
    
    fppdf-decimalcomma.patch (6,345 bytes)
  • fppdf-formatmask.patch (3,852 bytes)
    Index: packages/fcl-pdf/src/fppdf.pp
    ===================================================================
    --- packages/fcl-pdf/src/fppdf.pp	(revision 39582)
    +++ packages/fcl-pdf/src/fppdf.pp	(working copy)
    @@ -1126,6 +1126,7 @@
       PDF_MAX_GEN_NUM = 65535;
       PDF_UNICODE_HEADER = 'FEFF001B%s001B';
       PDF_LANG_STRING = 'en';
    +  PDF_NUMBER_MASK = '0.####';
     
       { Info from http://www.papersizes.org/a-sizes-all-units.htm }
       PDFPaperSizes : Array[TPDFPaperType,0..1] of Integer = (
    @@ -2313,9 +2314,9 @@
       if ADegrees <> 0.0 then
       begin
         rad := DegToRad(-ADegrees);
    -    t1 := FormatFloat('0.###;;0', Cos(rad), PDFFormatSettings);
    -    t2 := FormatFloat('0.###;;0', -Sin(rad), PDFFormatSettings);
    -    t3 := FormatFloat('0.###;;0', Sin(rad), PDFFormatSettings);
    +    t1 := FormatFloat(PDF_NUMBER_MASK, Cos(rad), PDFFormatSettings);
    +    t2 := FormatFloat(PDF_NUMBER_MASK, -Sin(rad), PDFFormatSettings);
    +    t3 := FormatFloat(PDF_NUMBER_MASK, Sin(rad), PDFFormatSettings);
         AddObject(TPDFPushGraphicsStack.Create(Document));
         // PDF v1.3 page 132 & 143
         AddObject(TPDFFreeFormString.Create(Document, Format('%s %s %s %s %.4f %.4f cm',
    @@ -2357,9 +2358,9 @@
       if ADegrees <> 0.0 then
       begin
         rad := DegToRad(-ADegrees);
    -    t1 := FormatFloat('0.###;;0', Cos(rad), PDFFormatSettings);
    -    t2 := FormatFloat('0.###;;0', -Sin(rad), PDFFormatSettings);
    -    t3 := FormatFloat('0.###;;0', Sin(rad), PDFFormatSettings);
    +    t1 := FormatFloat(PDF_NUMBER_MASK, Cos(rad), PDFFormatSettings);
    +    t2 := FormatFloat(PDF_NUMBER_MASK, -Sin(rad), PDFFormatSettings);
    +    t3 := FormatFloat(PDF_NUMBER_MASK, Sin(rad), PDFFormatSettings);
         AddObject(TPDFPushGraphicsStack.Create(Document));
         // PDF v1.3 page 132 & 143
         AddObject(TPDFFreeFormString.Create(Document, Format('%s %s %s %s %.4f %.4f cm',
    @@ -2388,9 +2389,9 @@
       if ADegrees <> 0.0 then
       begin
         rad := DegToRad(-ADegrees);
    -    t1 := FormatFloat('0.###;;0', Cos(rad), PDFFormatSettings);
    -    t2 := FormatFloat('0.###;;0', -Sin(rad), PDFFormatSettings);
    -    t3 := FormatFloat('0.###;;0', Sin(rad), PDFFormatSettings);
    +    t1 := FormatFloat(PDF_NUMBER_MASK, Cos(rad), PDFFormatSettings);
    +    t2 := FormatFloat(PDF_NUMBER_MASK, -Sin(rad), PDFFormatSettings);
    +    t3 := FormatFloat(PDF_NUMBER_MASK, Sin(rad), PDFFormatSettings);
         AddObject(TPDFPushGraphicsStack.Create(Document));
         // PDF v1.3 page 132 & 143
         AddObject(TPDFFreeFormString.Create(Document, Format('%s %s %s %s %.4f %.4f cm',
    @@ -2427,9 +2428,9 @@
       if ADegrees <> 0.0 then
       begin
         rad := DegToRad(-ADegrees);
    -    t1 := FormatFloat('0.###;;0', Cos(rad), PDFFormatSettings);
    -    t2 := FormatFloat('0.###;;0', -Sin(rad), PDFFormatSettings);
    -    t3 := FormatFloat('0.###;;0', Sin(rad), PDFFormatSettings);
    +    t1 := FormatFloat(PDF_NUMBER_MASK, Cos(rad), PDFFormatSettings);
    +    t2 := FormatFloat(PDF_NUMBER_MASK, -Sin(rad), PDFFormatSettings);
    +    t3 := FormatFloat(PDF_NUMBER_MASK, Sin(rad), PDFFormatSettings);
         AddObject(TPDFPushGraphicsStack.Create(Document));
         // PDF v1.3 page 132 & 143
         AddObject(TPDFFreeFormString.Create(Document, Format('%s %s %s %s %.4f %.4f cm',
    @@ -2466,9 +2467,9 @@
       if ADegrees <> 0.0 then
       begin
         rad := DegToRad(-ADegrees);
    -    t1 := FormatFloat('0.###;;0', Cos(rad), PDFFormatSettings);
    -    t2 := FormatFloat('0.###;;0', -Sin(rad), PDFFormatSettings);
    -    t3 := FormatFloat('0.###;;0', Sin(rad), PDFFormatSettings);
    +    t1 := FormatFloat(PDF_NUMBER_MASK, Cos(rad), PDFFormatSettings);
    +    t2 := FormatFloat(PDF_NUMBER_MASK, -Sin(rad), PDFFormatSettings);
    +    t3 := FormatFloat(PDF_NUMBER_MASK, Sin(rad), PDFFormatSettings);
         AddObject(TPDFPushGraphicsStack.Create(Document));
         // PDF v1.3 page 132 & 143
         AddObject(TPDFFreeFormString.Create(Document, Format('%s %s %s %s %.4f %.4f cm',
    
    fppdf-formatmask.patch (3,852 bytes)

Activities

wp

2018-08-01 19:19

reporter  

fpfpd-decimalcomma.zip (400,303 bytes)

wp

2018-08-01 19:19

reporter  

fppdf-decimalcomma.patch (6,345 bytes)
Index: packages/fcl-pdf/src/fppdf.pp
===================================================================
--- packages/fcl-pdf/src/fppdf.pp	(revision 39401)
+++ packages/fcl-pdf/src/fppdf.pp	(working copy)
@@ -971,6 +971,7 @@
     FZoomValue: string;
     FGlobalXRefs: TFPObjectList; // list of TPDFXRef
     FUnitOfMeasure: TPDFUnitOfMeasure;
+    FFormatSettings: TFormatSettings;
     function GetStdFontCharWidthsArray(const AFontName: string): TPDFFontWidthArray;
     function GetX(AIndex : Integer): TPDFXRef;
     function GetXC: Integer;
@@ -1070,6 +1071,7 @@
     Property FontDirectory: string Read FFontDirectory Write FFontDirectory;
     Property Sections : TPDFSectionList Read FSections;
     Property ObjectCount : Integer Read FObjectCount;
+    Property FormatSettings: TFormatSettings Read FFormatSettings;
   Published
     Property Options : TPDFOptions Read FOptions Write FOPtions;
     Property LineStyles : TPDFLineStyleDefs Read FLineStyleDefs Write SetLineStyles;
@@ -2162,12 +2164,13 @@
   if ADegrees <> 0.0 then
   begin
     rad := DegToRad(-ADegrees);
-    t1 := FormatFloat('0.###;;0', Cos(rad));
-    t2 := FormatFloat('0.###;;0', -Sin(rad));
-    t3 := FormatFloat('0.###;;0', Sin(rad));
+    t1 := FormatFloat('0.###;;0', Cos(rad), Document.FormatSettings);
+    t2 := FormatFloat('0.###;;0', -Sin(rad), Document.FormatSettings);
+    t3 := FormatFloat('0.###;;0', Sin(rad), Document.FormatSettings);
     AddObject(TPDFPushGraphicsStack.Create(Document));
     // PDF v1.3 page 132 & 143
-    AddObject(TPDFFreeFormString.Create(Document, Format('%s %s %s %s %.4f %.4f cm', [t1, t2, t3, t1, p1.X, p1.Y]) + CRLF));
+    AddObject(TPDFFreeFormString.Create(Document, Format('%s %s %s %s %.4f %.4f cm',
+      [t1, t2, t3, t1, p1.X, p1.Y], Document.FormatSettings) + CRLF));
     // co-ordinates are now based on the newly transformed matrix co-ordinates.
     R := Document.CreateRectangle(0, 0, p2.X, p2.Y, ALineWidth, AFill, AStroke);
   end
@@ -2205,12 +2208,13 @@
   if ADegrees <> 0.0 then
   begin
     rad := DegToRad(-ADegrees);
-    t1 := FormatFloat('0.###;;0', Cos(rad));
-    t2 := FormatFloat('0.###;;0', -Sin(rad));
-    t3 := FormatFloat('0.###;;0', Sin(rad));
+    t1 := FormatFloat('0.###;;0', Cos(rad), Document.FormatSettings);
+    t2 := FormatFloat('0.###;;0', -Sin(rad), Document.FormatSettings);
+    t3 := FormatFloat('0.###;;0', Sin(rad), Document.FormatSettings);
     AddObject(TPDFPushGraphicsStack.Create(Document));
     // PDF v1.3 page 132 & 143
-    AddObject(TPDFFreeFormString.Create(Document, Format('%s %s %s %s %.4f %.4f cm', [t1, t2, t3, t1, p1.X, p1.Y]) + CRLF));
+    AddObject(TPDFFreeFormString.Create(Document, Format('%s %s %s %s %.4f %.4f cm',
+      [t1, t2, t3, t1, p1.X, p1.Y], Document.FormatSettings) + CRLF));
     // co-ordinates are now based on the newly transformed matrix co-ordinates.
     R := Document.CreateRoundedRectangle(0, 0, p2.X, p2.Y, p3.X, ALineWidth, AFill, AStroke);
   end
@@ -2235,12 +2239,13 @@
   if ADegrees <> 0.0 then
   begin
     rad := DegToRad(-ADegrees);
-    t1 := FormatFloat('0.###;;0', Cos(rad));
-    t2 := FormatFloat('0.###;;0', -Sin(rad));
-    t3 := FormatFloat('0.###;;0', Sin(rad));
+    t1 := FormatFloat('0.###;;0', Cos(rad), Document.FormatSettings);
+    t2 := FormatFloat('0.###;;0', -Sin(rad), Document.FormatSettings);
+    t3 := FormatFloat('0.###;;0', Sin(rad), Document.FormatSettings);
     AddObject(TPDFPushGraphicsStack.Create(Document));
     // PDF v1.3 page 132 & 143
-    AddObject(TPDFFreeFormString.Create(Document, Format('%s %s %s %s %.4f %.4f cm', [t1, t2, t3, t1, p1.X, p1.Y]) + CRLF));
+    AddObject(TPDFFreeFormString.Create(Document, Format('%s %s %s %s %.4f %.4f cm',
+      [t1, t2, t3, t1, p1.X, p1.Y], Document.FormatSettings) + CRLF));
     // co-ordinates are now based on the newly transformed matrix co-ordinates.
     AddObject(Document.CreateImage(0, 0, APixelWidth, APixelHeight, ANumber));
   end
@@ -2273,12 +2278,13 @@
   if ADegrees <> 0.0 then
   begin
     rad := DegToRad(-ADegrees);
-    t1 := FormatFloat('0.###;;0', Cos(rad));
-    t2 := FormatFloat('0.###;;0', -Sin(rad));
-    t3 := FormatFloat('0.###;;0', Sin(rad));
+    t1 := FormatFloat('0.###;;0', Cos(rad), Document.FormatSettings);
+    t2 := FormatFloat('0.###;;0', -Sin(rad), Document.FormatSettings);
+    t3 := FormatFloat('0.###;;0', Sin(rad), Document.FormatSettings);
     AddObject(TPDFPushGraphicsStack.Create(Document));
     // PDF v1.3 page 132 & 143
-    AddObject(TPDFFreeFormString.Create(Document, Format('%s %s %s %s %.4f %.4f cm', [t1, t2, t3, t1, p1.X, p1.Y]) + CRLF));
+    AddObject(TPDFFreeFormString.Create(Document, Format('%s %s %s %s %.4f %.4f cm',
+      [t1, t2, t3, t1, p1.X, p1.Y], Document.FormatSettings) + CRLF));
     // co-ordinates are now based on the newly transformed matrix co-ordinates.
     AddObject(Document.CreateImage(0, 0, p2.X, p2.Y, ANumber));
   end
@@ -2311,12 +2317,13 @@
   if ADegrees <> 0.0 then
   begin
     rad := DegToRad(-ADegrees);
-    t1 := FormatFloat('0.###;;0', Cos(rad));
-    t2 := FormatFloat('0.###;;0', -Sin(rad));
-    t3 := FormatFloat('0.###;;0', Sin(rad));
+    t1 := FormatFloat('0.###;;0', Cos(rad), Document.FormatSettings);
+    t2 := FormatFloat('0.###;;0', -Sin(rad), Document.FormatSettings);
+    t3 := FormatFloat('0.###;;0', Sin(rad), Document.FormatSettings);
     AddObject(TPDFPushGraphicsStack.Create(Document));
     // PDF v1.3 page 132 & 143
-    AddObject(TPDFFreeFormString.Create(Document, Format('%s %s %s %s %.4f %.4f cm', [t1, t2, t3, t1, p1.X, p1.Y]) + CRLF));
+    AddObject(TPDFFreeFormString.Create(Document, Format('%s %s %s %s %.4f %.4f cm',
+      [t1, t2, t3, t1, p1.X, p1.Y], Document.FormatSettings) + CRLF));
     // co-ordinates are now based on the newly transformed matrix co-ordinates.
     AddObject(TPDFEllipse.Create(Document, 0, 0, p2.X, p2.Y, ALineWidth, AFill, AStroke));
   end
@@ -4886,6 +4893,12 @@
   FZoomValue:='100';
   FOptions := [poCompressFonts, poCompressImages];
   FUnitOfMeasure:=uomMillimeters;
+
+  FFormatSettings := DefaultFormatSettings;
+  FFormatSettings.DecimalSeparator := '.';
+  FFormatSettings.ThousandSeparator := ',';
+  FFormatSettings.DateSeparator := '/';
+  FFormatSettings.TimeSeparator := ':';
 end;
 
 procedure TPDFDocument.StartDocument;
fppdf-decimalcomma.patch (6,345 bytes)

Michael Van Canneyt

2018-08-01 21:15

administrator   ~0109820

Fixed, but using a global instance of PDFFormatSettings.
I see no need why you would want this to be settable on a document basis.

wp

2018-08-02 00:10

reporter   ~0109821

Thanks for the quick fix! It works.

wp

2018-08-06 20:02

reporter   ~0109918

Last edited: 2018-08-07 00:29

View 2 revisions

Since this issue is so closely related I am re-opening this report again:

A reader of the forum (https://forum.lazarus.freepascal.org/index.php/topic,42072.msg293629.html#msg293629) brought my attention to an issue with the format string '0.###;;0' used at several places. Since the negative section here is empty default formatting is used for negative numbers. This is no problem in fpc 3.0.4., but in trunk this creates exponential notation in case of very small values - which the Adobe Reader (and maybe others) does not like.

To demonstrate the issue see the demo attached to the forum post.

In the new patch I am proposing a format string '0.####' independently of sign. Since it is reused several times it is declared as a constant PDF_NUMBER_MASK.

wp

2018-08-06 20:03

reporter  

fppdf-formatmask.patch (3,852 bytes)
Index: packages/fcl-pdf/src/fppdf.pp
===================================================================
--- packages/fcl-pdf/src/fppdf.pp	(revision 39582)
+++ packages/fcl-pdf/src/fppdf.pp	(working copy)
@@ -1126,6 +1126,7 @@
   PDF_MAX_GEN_NUM = 65535;
   PDF_UNICODE_HEADER = 'FEFF001B%s001B';
   PDF_LANG_STRING = 'en';
+  PDF_NUMBER_MASK = '0.####';
 
   { Info from http://www.papersizes.org/a-sizes-all-units.htm }
   PDFPaperSizes : Array[TPDFPaperType,0..1] of Integer = (
@@ -2313,9 +2314,9 @@
   if ADegrees <> 0.0 then
   begin
     rad := DegToRad(-ADegrees);
-    t1 := FormatFloat('0.###;;0', Cos(rad), PDFFormatSettings);
-    t2 := FormatFloat('0.###;;0', -Sin(rad), PDFFormatSettings);
-    t3 := FormatFloat('0.###;;0', Sin(rad), PDFFormatSettings);
+    t1 := FormatFloat(PDF_NUMBER_MASK, Cos(rad), PDFFormatSettings);
+    t2 := FormatFloat(PDF_NUMBER_MASK, -Sin(rad), PDFFormatSettings);
+    t3 := FormatFloat(PDF_NUMBER_MASK, Sin(rad), PDFFormatSettings);
     AddObject(TPDFPushGraphicsStack.Create(Document));
     // PDF v1.3 page 132 & 143
     AddObject(TPDFFreeFormString.Create(Document, Format('%s %s %s %s %.4f %.4f cm',
@@ -2357,9 +2358,9 @@
   if ADegrees <> 0.0 then
   begin
     rad := DegToRad(-ADegrees);
-    t1 := FormatFloat('0.###;;0', Cos(rad), PDFFormatSettings);
-    t2 := FormatFloat('0.###;;0', -Sin(rad), PDFFormatSettings);
-    t3 := FormatFloat('0.###;;0', Sin(rad), PDFFormatSettings);
+    t1 := FormatFloat(PDF_NUMBER_MASK, Cos(rad), PDFFormatSettings);
+    t2 := FormatFloat(PDF_NUMBER_MASK, -Sin(rad), PDFFormatSettings);
+    t3 := FormatFloat(PDF_NUMBER_MASK, Sin(rad), PDFFormatSettings);
     AddObject(TPDFPushGraphicsStack.Create(Document));
     // PDF v1.3 page 132 & 143
     AddObject(TPDFFreeFormString.Create(Document, Format('%s %s %s %s %.4f %.4f cm',
@@ -2388,9 +2389,9 @@
   if ADegrees <> 0.0 then
   begin
     rad := DegToRad(-ADegrees);
-    t1 := FormatFloat('0.###;;0', Cos(rad), PDFFormatSettings);
-    t2 := FormatFloat('0.###;;0', -Sin(rad), PDFFormatSettings);
-    t3 := FormatFloat('0.###;;0', Sin(rad), PDFFormatSettings);
+    t1 := FormatFloat(PDF_NUMBER_MASK, Cos(rad), PDFFormatSettings);
+    t2 := FormatFloat(PDF_NUMBER_MASK, -Sin(rad), PDFFormatSettings);
+    t3 := FormatFloat(PDF_NUMBER_MASK, Sin(rad), PDFFormatSettings);
     AddObject(TPDFPushGraphicsStack.Create(Document));
     // PDF v1.3 page 132 & 143
     AddObject(TPDFFreeFormString.Create(Document, Format('%s %s %s %s %.4f %.4f cm',
@@ -2427,9 +2428,9 @@
   if ADegrees <> 0.0 then
   begin
     rad := DegToRad(-ADegrees);
-    t1 := FormatFloat('0.###;;0', Cos(rad), PDFFormatSettings);
-    t2 := FormatFloat('0.###;;0', -Sin(rad), PDFFormatSettings);
-    t3 := FormatFloat('0.###;;0', Sin(rad), PDFFormatSettings);
+    t1 := FormatFloat(PDF_NUMBER_MASK, Cos(rad), PDFFormatSettings);
+    t2 := FormatFloat(PDF_NUMBER_MASK, -Sin(rad), PDFFormatSettings);
+    t3 := FormatFloat(PDF_NUMBER_MASK, Sin(rad), PDFFormatSettings);
     AddObject(TPDFPushGraphicsStack.Create(Document));
     // PDF v1.3 page 132 & 143
     AddObject(TPDFFreeFormString.Create(Document, Format('%s %s %s %s %.4f %.4f cm',
@@ -2466,9 +2467,9 @@
   if ADegrees <> 0.0 then
   begin
     rad := DegToRad(-ADegrees);
-    t1 := FormatFloat('0.###;;0', Cos(rad), PDFFormatSettings);
-    t2 := FormatFloat('0.###;;0', -Sin(rad), PDFFormatSettings);
-    t3 := FormatFloat('0.###;;0', Sin(rad), PDFFormatSettings);
+    t1 := FormatFloat(PDF_NUMBER_MASK, Cos(rad), PDFFormatSettings);
+    t2 := FormatFloat(PDF_NUMBER_MASK, -Sin(rad), PDFFormatSettings);
+    t3 := FormatFloat(PDF_NUMBER_MASK, Sin(rad), PDFFormatSettings);
     AddObject(TPDFPushGraphicsStack.Create(Document));
     // PDF v1.3 page 132 & 143
     AddObject(TPDFFreeFormString.Create(Document, Format('%s %s %s %s %.4f %.4f cm',
fppdf-formatmask.patch (3,852 bytes)

Michael Van Canneyt

2018-08-07 10:13

administrator   ~0109926

Applied patch, thanks!

wp

2018-08-07 10:37

reporter   ~0109927

Thanks again.

Issue History

Date Modified Username Field Change
2018-08-01 19:19 wp New Issue
2018-08-01 19:19 wp File Added: fpfpd-decimalcomma.zip
2018-08-01 19:19 wp File Added: fppdf-decimalcomma.patch
2018-08-01 20:54 Michael Van Canneyt Assigned To => Michael Van Canneyt
2018-08-01 20:54 Michael Van Canneyt Status new => assigned
2018-08-01 21:15 Michael Van Canneyt Fixed in Revision => 39542
2018-08-01 21:15 Michael Van Canneyt Note Added: 0109820
2018-08-01 21:15 Michael Van Canneyt Status assigned => resolved
2018-08-01 21:15 Michael Van Canneyt Fixed in Version => 3.1.1
2018-08-01 21:15 Michael Van Canneyt Resolution open => fixed
2018-08-01 21:15 Michael Van Canneyt Target Version => 3.2.0
2018-08-02 00:10 wp Note Added: 0109821
2018-08-02 00:10 wp Status resolved => closed
2018-08-06 20:02 wp Note Added: 0109918
2018-08-06 20:02 wp Status closed => feedback
2018-08-06 20:02 wp Resolution fixed => reopened
2018-08-06 20:03 wp File Added: fppdf-formatmask.patch
2018-08-07 00:29 wp Note Edited: 0109918 View Revisions
2018-08-07 10:13 Michael Van Canneyt Fixed in Revision 39542 => 39585
2018-08-07 10:13 Michael Van Canneyt Note Added: 0109926
2018-08-07 10:13 Michael Van Canneyt Status feedback => resolved
2018-08-07 10:13 Michael Van Canneyt Resolution reopened => fixed
2018-08-07 10:37 wp Note Added: 0109927
2018-08-07 10:37 wp Status resolved => closed