mORMot and Open Source friends
Check-in [1ba26a0223]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:{6391} some other fixes to PDF font subset
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 1ba26a02238676c25646c37ddc5068cced81c3b2
User & Date: ab 2022-05-16 11:54:54
Context
2022-05-17
16:33
{6392} rewritten TSQLRestClientURI.RetryOnceOnTimeout documentation to make it expliclit that the timeout is a 408 error from the server side, not a client-side timeout, e.g. at HTTP level check-in: 0f62f18f66 user: ab tags: trunk
2022-05-16
11:54
{6391} some other fixes to PDF font subset check-in: 1ba26a0223 user: ab tags: trunk
11:23
{6390} fixed PDF font subset - backport from mORMot 2 check-in: a5e5d4c449 user: ab tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to SynPdf.pas.

844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
....
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
....
3782
3783
3784
3785
3786
3787
3788

3789
3790
3791
3792
3793
3794
3795
....
8267
8268
8269
8270
8271
8272
8273
8274

8275
8276
8277
8278
8279
8280
8281
....
8406
8407
8408
8409
8410
8411
8412

8413
8414
8415
8416
8417
8418
8419
8420
8421
  // - this object is stored as '/Value'
  TPdfName = class(TPdfText)
  protected
    procedure InternalWriteTo(W: TPdfWrite); override;
  public
    /// append the 'SUBSET+' prefix to the Value
    // - used e.g. to notify that a font is included as a subset
    procedure AppendPrefix;
  end;

  /// used to store an array of PDF objects
  TPdfArray = class(TPdfObject)
  private
    FArray: TList;
    FObjectMgr: TPdfObjectMgr;
................................................................................
{ TPdfName }

procedure TPdfName.InternalWriteTo(W: TPdfWrite);
begin
  W.Add('/').AddEscapeName(pointer(FValue));
end;

procedure TPdfName.AppendPrefix;
var prefix: RawUtf8;
    c: cardinal;
    i: PtrInt;
begin
  if self=nil then
    exit;
  SetLength(prefix, 7);
................................................................................
  for i := 1 to 6 do
  begin
    prefix[i] := AnsiChar((c and 15) + 65);
    c := c shr 4;
  end;
  prefix[7] := '+';
  FValue := prefix+FValue; // we ensured a single subset per font

end;


{ TPdfArray }

function TPdfArray.GetItems(Index: integer): TPdfObject;
begin
................................................................................
  try
    if Unicode then begin
      // 1. Unicode Font (see PDF 1.3 reference #5.9)
      // create descendant font
      Descendant := TPdfDictionary.Create(fDoc.FXref);
      Descendant.AddItem('Type','Font');
      Descendant.AddItem('Subtype','CIDFontType2');
      Descendant.AddItem('BaseFont',FName);

      if fDoc.PDFA<>pdfaNone then
        Descendant.AddItem('CIDToGIDMap','Identity');
      CIDSystemInfo := TPdfDictionary.Create(FDoc.FXref);
      CIDSystemInfo.AddItem('Supplement',0);
      CIDSystemInfo.AddItemText('Ordering','Identity');
      CIDSystemInfo.AddItemText('Registry','Adobe');
      Descendant.AddItem('CIDSystemInfo',CIDSystemInfo);
................................................................................
                    TTFCFP_MS_PLATFORMID,TTFCFP_DONT_CARE,
                    pointer(Used.Values),Used.Count,
                    @lpfnAllocate,@lpfnReAllocate,@lpfnFree,nil)=0 then begin
                  // subset was created successfully -> save to PDF file
                  ReduceTTF(ttf,SubSetData,SubSetSize);
                  FreeMem(SubSetData);
                  // see 5.5.3 Font Subsets: begins with a tag followed by a +

                  TPdfName(fFontDescriptor.ValueByName('FontName')).AppendPrefix;
                  TPdfName(Data.ValueByName('BaseFont')).AppendPrefix;
                end;
              end;
            end;
            fFontFile2.Writer.Add(ttf);
            fFontFile2.FAttributes.AddItem('Length1',length(ttf));
            // /FontDescriptor is common to WinAnsi and Unicode fonts
            fFontDescriptor.AddItem('FontFile2',fFontFile2);






|







 







|







 







>







 







|
>







 







>
|
<







844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
....
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
....
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
....
8268
8269
8270
8271
8272
8273
8274
8275
8276
8277
8278
8279
8280
8281
8282
8283
....
8408
8409
8410
8411
8412
8413
8414
8415
8416

8417
8418
8419
8420
8421
8422
8423
  // - this object is stored as '/Value'
  TPdfName = class(TPdfText)
  protected
    procedure InternalWriteTo(W: TPdfWrite); override;
  public
    /// append the 'SUBSET+' prefix to the Value
    // - used e.g. to notify that a font is included as a subset
    function AppendPrefix: RawUtf8;
  end;

  /// used to store an array of PDF objects
  TPdfArray = class(TPdfObject)
  private
    FArray: TList;
    FObjectMgr: TPdfObjectMgr;
................................................................................
{ TPdfName }

procedure TPdfName.InternalWriteTo(W: TPdfWrite);
begin
  W.Add('/').AddEscapeName(pointer(FValue));
end;

function TPdfName.AppendPrefix: RawUtf8;
var prefix: RawUtf8;
    c: cardinal;
    i: PtrInt;
begin
  if self=nil then
    exit;
  SetLength(prefix, 7);
................................................................................
  for i := 1 to 6 do
  begin
    prefix[i] := AnsiChar((c and 15) + 65);
    c := c shr 4;
  end;
  prefix[7] := '+';
  FValue := prefix+FValue; // we ensured a single subset per font
  result := FValue;
end;


{ TPdfArray }

function TPdfArray.GetItems(Index: integer): TPdfObject;
begin
................................................................................
  try
    if Unicode then begin
      // 1. Unicode Font (see PDF 1.3 reference #5.9)
      // create descendant font
      Descendant := TPdfDictionary.Create(fDoc.FXref);
      Descendant.AddItem('Type','Font');
      Descendant.AddItem('Subtype','CIDFontType2');
      Descendant.AddItem('BaseFont', // name may have been prefixed
        TPdfName(WinAnsiFont.Data.ValueByName('BaseFont')).Value);
      if fDoc.PDFA<>pdfaNone then
        Descendant.AddItem('CIDToGIDMap','Identity');
      CIDSystemInfo := TPdfDictionary.Create(FDoc.FXref);
      CIDSystemInfo.AddItem('Supplement',0);
      CIDSystemInfo.AddItemText('Ordering','Identity');
      CIDSystemInfo.AddItemText('Registry','Adobe');
      Descendant.AddItem('CIDSystemInfo',CIDSystemInfo);
................................................................................
                    TTFCFP_MS_PLATFORMID,TTFCFP_DONT_CARE,
                    pointer(Used.Values),Used.Count,
                    @lpfnAllocate,@lpfnReAllocate,@lpfnFree,nil)=0 then begin
                  // subset was created successfully -> save to PDF file
                  ReduceTTF(ttf,SubSetData,SubSetSize);
                  FreeMem(SubSetData);
                  // see 5.5.3 Font Subsets: begins with a tag followed by a +
                  TPdfName(Data.ValueByName('BaseFont')).Value :=
                    TPdfName(fFontDescriptor.ValueByName('FontName')).AppendPrefix;

                end;
              end;
            end;
            fFontFile2.Writer.Add(ttf);
            fFontFile2.FAttributes.AddItem('Length1',length(ttf));
            // /FontDescriptor is common to WinAnsi and Unicode fonts
            fFontDescriptor.AddItem('FontFile2',fFontFile2);

Changes to SynopseCommit.inc.

1
'1.18.6390'
|
1
'1.18.6391'