Sfoglia il codice sorgente

* Merging revisions 48694,48696,48697 from trunk:
------------------------------------------------------------------------
r48694 | michael | 2021-02-17 14:26:18 +0100 (Wed, 17 Feb 2021) | 1 line

* Fix from Joellin to correctly read monospace fonts
------------------------------------------------------------------------
r48696 | michael | 2021-02-17 14:32:03 +0100 (Wed, 17 Feb 2021) | 1 line

* Fix issue ID #35251 (patch from Rumen Gyurov)
------------------------------------------------------------------------
r48697 | michael | 2021-02-17 14:35:48 +0100 (Wed, 17 Feb 2021) | 1 line

* Example for monospace fonts and subsetting
------------------------------------------------------------------------

git-svn-id: branches/fixes_3_2@48698 -

michael 4 anni fa
parent
commit
19126c8f4e

+ 1 - 0
.gitattributes

@@ -3678,6 +3678,7 @@ packages/fcl-pdf/Makefile svneol=native#text/plain
 packages/fcl-pdf/Makefile.fpc svneol=native#text/plain
 packages/fcl-pdf/examples/diamond.png -text svneol=unset#image/png
 packages/fcl-pdf/examples/metautf16.pp svneol=native#text/plain
+packages/fcl-pdf/examples/monospacetext.pp svneol=native#text/plain
 packages/fcl-pdf/examples/poppy.jpg -text
 packages/fcl-pdf/examples/testfppdf.lpi svneol=native#text/plain
 packages/fcl-pdf/examples/testfppdf.lpr svneol=native#text/plain

+ 56 - 0
packages/fcl-pdf/examples/monospacetext.pp

@@ -0,0 +1,56 @@
+program monospacetext;
+
+{$mode objfpc}{$H+}
+{$codepage UTF8}
+
+uses
+  Classes, SysUtils,
+  fpPDF;
+
+var
+  PDF: TPDFDocument;
+  Font1, Font2, Font3, Font4: integer;
+begin
+  if ParamCount<1 then
+    begin
+    Writeln(stderr,'Usage : monospacetext <fontdir>');
+    Writeln(stderr,'Needed fonts : cour.ttf, arial.ttf, verdanab.ttf consola.ttf');
+    Halt(1);
+    end;
+  PDF := TPDFDocument.Create(nil);
+  PDF.Infos.Producer := '';
+  PDF.Infos.CreationDate := Now;
+  PDF.Options := [poPageOriginAtTop, {poNoEmbeddedFonts,} poSubsetFont, poCompressFonts, poCompressImages];
+  PDF.DefaultOrientation := ppoPortrait;
+  PDF.DefaultPaperType := ptA4;
+  PDF.DefaultUnitOfMeasure := uomMillimeters;
+  PDF.FontDirectory := paramstr(1);
+  PDF.StartDocument;
+  PDF.Sections.AddSection;
+  PDF.Sections[0].AddPage(PDF.Pages.AddPage);;
+
+  //FontIndex := PDF.AddFont('Courier');
+  Font1 := PDF.AddFont('cour.ttf', 'Courier New');
+  Font2 := PDF.AddFont('arial.ttf', 'Arial');
+  Font3 := PDF.AddFont('verdanab.ttf', 'Verdana');
+  Font4 := PDF.AddFont('consola.ttf', 'Consolas');
+  PDF.Pages[0].SetFont(Font1, 10);
+  PDF.Pages[0].WriteText(10,10,'AEIOU-ÁÉÍÓÚ-ČŠŇŽ');
+  PDF.Pages[0].WriteText(10,15,'----------------');
+
+  PDF.Pages[0].SetFont(Font2, 10);
+  PDF.Pages[0].WriteText(10,30,'AEIOU-ÁÉÍÓÚ-ČŠŇŽ');
+  PDF.Pages[0].WriteText(10,35,'----------------');
+
+  PDF.Pages[0].SetFont(Font3, 10);
+  PDF.Pages[0].WriteText(10,40,'AEIOU-ÁÉÍÓÚ-ČŠŇŽ');
+  PDF.Pages[0].WriteText(10,45,'----------------');
+
+  PDF.Pages[0].SetFont(Font4, 10);
+  PDF.Pages[0].WriteText(10,50,'AEIOU-ÁÉÍÓÚ-ČŠŇŽ');
+  PDF.Pages[0].WriteText(10,55,'----------------');
+
+  PDF.SaveToFile('test.pdf');
+  PDF.Free;
+end.
+

+ 18 - 7
packages/fcl-pdf/src/fpparsettf.pp

@@ -822,13 +822,13 @@ begin
   if embed and not Embeddable then
     raise ETTF.Create(rsFontEmbeddingNotAllowed);
   PrepareEncoding(Encoding);
-//  MissingWidth:=ToNatural(Widths[Chars[CharCodes^[32]]].AdvanceWidth);  // Char(32) - Space character
-  FMissingWidth := Widths[Chars[CharCodes^[32]]].AdvanceWidth;  // Char(32) - Space character
+//  MissingWidth:=ToNatural(GetAdvanceWidth(Chars[CharCodes^[32]]));  // Char(32) - Space character
+  FMissingWidth := GetAdvanceWidth(Chars[CharCodes^[32]]);  // Char(32) - Space character
   for I:=0 to 255 do
   begin
     if (CharCodes^[i]>=0) and (CharCodes^[i]<=High(Chars))
-    and (Widths[Chars[CharCodes^[i]]].AdvanceWidth> 0) and (CharNames^[i]<> '.notdef') then
-      CharWidth[I]:= ToNatural(Widths[Chars[CharCodes^[I]]].AdvanceWidth)
+    and (GetAdvanceWidth(Chars[CharCodes^[i]])> 0) and (CharNames^[i]<> '.notdef') then
+      CharWidth[I]:= ToNatural(GetAdvanceWidth(Chars[CharCodes^[I]]))
     else
       CharWidth[I]:= FMissingWidth;
   end;
@@ -930,8 +930,19 @@ begin
 end;
 
 function TTFFileInfo.GetAdvanceWidth(AIndex: word): word;
-begin
-  Result := Widths[AIndex].AdvanceWidth;
+var
+  i: SizeInt;
+begin
+  // There may be more glyphs than elements in the array, in which
+  // case the last entry is to be used.
+  // https://docs.microsoft.com/en-us/typography/opentype/spec/hmtx
+  i := Length(Widths);
+  if AIndex >= i then
+    Dec(i)
+  else
+    i := AIndex;
+
+  Result := Widths[i].AdvanceWidth;
 end;
 
 function TTFFileInfo.ItalicAngle: single;
@@ -972,7 +983,7 @@ function TTFFileInfo.GetMissingWidth: integer;
 begin
   if FMissingWidth = 0 then
   begin
-    FMissingWidth := Widths[Chars[CharCodes^[32]]].AdvanceWidth;  // 32 is in reference to the Space character
+    FMissingWidth := GetAdvanceWidth(Chars[CharCodes^[32]]);  // 32 is in reference to the Space character
   end;
   Result := FMissingWidth;
 end;

+ 8 - 2
packages/fcl-pdf/src/fpttfsubsetter.pp

@@ -940,12 +940,18 @@ end;
 function TFontSubsetter.buildHmtxTable: TStream;
 var
   n: integer;
+  GID: longint;
+  LastGID: longint;
 begin
   Result := TMemoryStream.Create;
+  LastGID := Length(FFontInfo.Widths)-1;
   for n := 0 to FGlyphIDs.Count-1 do
   begin
-    WriteUInt16(Result, FFontInfo.Widths[FGlyphIDs[n].GID].AdvanceWidth);
-    WriteInt16(Result, FFontInfo.Widths[FGlyphIDs[n].GID].LSB);
+    GID := FGlyphIDs[n].GID;
+    if GID > LastGID then
+      GID := LastGID;
+    WriteUInt16(Result, FFontInfo.Widths[GID].AdvanceWidth);
+    WriteInt16(Result, FFontInfo.Widths[GID].LSB);
   end;
 end;