#1 2015-02-17 11:43:40

Chaa
Member
Registered: 2011-03-26
Posts: 245

Symbol fonts in PDF

Symbol fonts, like "Wingdings" or "Symbol", not work properly with current SynPDF version (for example see http://synopse.info/forum/viewtopic.php?id=1352).

Symbol fonts are different from regular fonts in some way:
http://stackoverflow.com/questions/9291 … characters

I created patch, it's worked for me. But the code needs to be rewritten.

There are several changes:

1. Detect symbol font in TPdfTTF.Create.

if platformSpecificID=TTFCFP_SYMBOL_CHAR_SET then begin
  aUnicodeTTF.fIsSymbolFont := True;

2. In TPdfWrite.AddUnicodeHexTextNoUniScribe use AddGlyphFromChar for symbol fonts.

3. TPdfFontTrueType.FindOrAddUsedWideChar was added some code to convert ansi characters to unicode symbol space $F000...$F0FF.

if (i<0) and (UnicodeFont.fSymbolMap <> nil) then
begin
  UnicodeFont.fSymbolMap.UnicodeBufferToAnsi(@a, @aWideChar, 1);
  aWideChar := Chr($F000 + Ord(a));
  i := UnicodeFont.fUsedWideChar.IndexOf(ord(aWideChar));
end;

SynPdf-SymbolFont.diff

P.S.
Font embedding for symbol fonts works with this patch only in EmbeddedWholeTTF mode.

Last edited by Chaa (2015-02-19 04:42:08)

Offline

#2 2015-02-19 15:37:23

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,356
Website

Re: Symbol fonts in PDF

I think http://synopse.info/fossil/info/67f6191561 will include the patch.
I'm a little confused about the $F000...$F0FF Unicode symbol space use...

Offline

#3 2015-02-20 04:47:04

Chaa
Member
Registered: 2011-03-26
Posts: 245

Re: Symbol fonts in PDF

ab wrote:

I'm a little confused about the $F000...$F0FF Unicode symbol space use...

MS wrote in article:
http://support.microsoft.com/kb/241020

Note that Symbol fonts are supposed to have a Platform Id of 3 and a specific id of 0. If the TrueType spec. suggestions were followed then the Symbol font's Format 4 encoding could also be considered Unicode because the mapping would be in the Private Use Area of Unicode. We assume this here and allow Symbol fonts to be interpreted. If they do not contain a Format 4, we bail later. If they do not have a Unicode
character mapping, we'll get wrong results. Code could infer from the coverage whether 3-0 fonts are
Unicode or not by examining the segments for placement within the Private Use Area Subrange.

So I think that real problem may be in TPdfTTF.Create code.

I don't understand some aspects of PDF and SynPDF, for example, how you are using WinAnsiFont and UnicodeFont fonts. So I came up with this quick and dirty solution to the problem.

Offline

#4 2015-02-20 05:12:29

Chaa
Member
Registered: 2011-03-26
Posts: 245

Re: Symbol fonts in PDF

Minor patch for http://synopse.info/fossil/info/67f6191561

fIsSymbolFont initialized only for Unicode font.

--- SynPdf.orig
+++ SynPdf.pas
@@ -7633,7 +7633,7 @@ begin
     CreateAssociatedUnicodeFont;
   // update fUsedWide[result] for current glyph
   i := UnicodeFont.fUsedWideChar.IndexOf(ord(aWideChar));
-  if (i<0) and fIsSymbolFont then begin
+  if (i<0) and UnicodeFont.fIsSymbolFont then begin
     TSynAnsiConvert.Engine(fDoc.CodePage).UnicodeBufferToAnsi(
       @aSymbolAnsiChar,@aWideChar,1);
     aWideChar := WideChar($f000+ord(aSymbolAnsiChar));

SynPdf-SymbolFont2.diff

Last edited by Chaa (2015-02-20 05:14:19)

Offline

#5 2015-02-20 15:27:55

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,356
Website

Re: Symbol fonts in PDF

Should be fixed by http://synopse.info/fossil/info/162664c56e631

Thanks again!
smile

Offline

#6 2015-05-21 18:12:42

BetoVG
Member
Registered: 2014-05-03
Posts: 8

Re: Symbol fonts in PDF

I made these corrections but as you can see this link using bullet and editing the paragraph below it, the text was distorted
(http://www.sispaic.com.br/PFNSis/Test.pdf)

the bullet's image here is in symbol but the texts are in Times New Roman

Offline

#7 2015-05-22 06:21:46

Chaa
Member
Registered: 2011-03-26
Posts: 245

Re: Symbol fonts in PDF

i also use printing ScaleRichView to PDF with SynPDF. I use following code, that works.
Notice the EmbeddedWholeTTF := True is importrant.

procedure TMyDialog.CreatePDF;
var
    LDocument: TPdfDocumentGDI;
    i: Integer;
    LPage: TPdfPage;
    LCanvas: TCanvas;
    LPageSize: TSize;
    LTextRect: TRect;

    function CalcTextRect(const ADocument: TPdfDocumentGDI; const AText: TSRichViewEdit): TRect;
    var
        LMultiPixels: Extended;
    begin
        LMultiPixels := 1.0;
        Result.Left := Round(AText.LeftMargin100Pix * LMultiPixels);
        Result.Top := Round(AText.TopMargin100Pix * LMultiPixels);
        Result.Right := Round((AText.PageWidth100Pix - AText.LeftMargin100Pix - AText.RightMargin100Pix)  * LMultiPixels);
        Result.Bottom := Round((AText.PageHeight100Pix - AText.TopMargin100Pix - AText.BottomMargin100Pix)  * LMultiPixels);
    end;

begin
    LDocument := TPdfDocumentGDI.Create();
    try
        LDocument.DefaultPaperSize := psA4;
        LDocument.ScreenLogPixels := 300;
        LDocument.EmbeddedTTF := True;
        LDocument.EmbeddedWholeTTF := True;

        for i := 1 to ScaleRichViewEdit.PageCount do
        begin
            LPage := LDocument.AddPage();

            LCanvas := LDocument.VCLCanvas;
            LPageSize := LDocument.VCLCanvasSize;
            LTextRect := CalcTextRect(LDocument, ScaleRichViewEdit);

            ScaleRichViewEdit.DrawPageEx(i, LPageSize.cx, LPageSize.cy,
                0, 0, LCanvas, LTextRect, False, False, False);
        end;

        LDocument.SaveToFile(FFileName);
    finally
        LDocument.Free();
    end;
end;

Offline

#8 2015-05-23 00:48:18

BetoVG
Member
Registered: 2014-05-03
Posts: 8

Re: Symbol fonts in PDF

Hi, Thanks

your code worked! just had to cash margins

 
  function CalcTextRect(const ADocument: TPdfDocumentGDI; const AText: TSRichViewEdit): TRect;
    var
        LMultiPixels: Extended;
    begin
        LMultiPixels := 1.0;
        Result.Left := Round(AText.LeftMargin100Pix * LMultiPixels);
        Result.Top := Round(AText.TopMargin100Pix * LMultiPixels);
 //       Result.Right := Round((AText.PageWidth100Pix - AText.LeftMargin100Pix - AText.RightMargin100Pix)  * LMultiPixels);
       Result.Right := Round((AText.PageWidth100Pix )  * LMultiPixels); 
//        Result.Bottom := Round((AText.PageHeight100Pix - AText.TopMargin100Pix - AText.BottomMargin100Pix)  * LMultiPixels);
        Result.Bottom := Round((AText.PageHeight100Pix )  * LMultiPixels);
    end;
 

below the code I used:

 

function MakePageMetafile(srve:TSRichViewEdit;aPageNo, aWidth, aHeight: Integer): TMetafile;
var
  savTextDraw: Boolean;
begin
  savTextDraw := ScaleRichViewTextDrawAlwaysUseGlyphs;
  ScaleRichViewTextDrawAlwaysUseGlyphs := false;

  Result := TMetafile.Create;
  Result.Width := aWidth;
  Result.Height := aHeight;
  srve.CanUpdate := False;
  srve.UseDrawHyperlinksEvent := True;
  srve.DrawMetafile(aPageNo, Result, False, True, False);
  ScaleRichViewTextDrawAlwaysUseGlyphs := savTextDraw;
  srve.CanUpdate := True;
  srve.UseDrawHyperlinksEvent := False;
end;
procedure xExportaParaPdf ( handle:HWND; srve :TSRichViewEdit; Arquivo:String);
var
  i: Integer;
  Metafile: TMetafile;
  RVUnit: TRVUnits;
  R : TRect;
  //synopse
  PdfDoc : TPDFDocument;


begin
  PreencheCtrlShift(srve);
  srve.Update; //srve is ScaleRichViewComponent

  RVUnit := srve.UnitsProgram; //Get the current value
  srve.UnitsProgram := rvuPixels; //Change DBSRichviewEdit to pixels for PDF Conversion

  PdfDoc := TPdfDocument.Create;
  PdfDoc.GeneratePDF15File:=true;

  for i := 1 to srve.PageCount do
  begin

    Metafile := MakePageMetafile(srve,i, Round(srve.PageWidth100Pix),  
             Round(srve.PageHeight100Pix));

 
    try

        PdfDoc.DefaultPageWidth := MulDiv(srve.PageWidth100Pix,72,PdfDoc.ScreenLogPixels);
        PdfDoc.DefaultPageHeight := MulDiv(srve.PageHeight100Pix,72,PdfDoc.ScreenLogPixels);

        PdfDoc.AddPage;

       PdfDoc.Canvas.RenderMetaFile(MetaFile,1,0,0);


    finally
      Metafile.Free;
    end;
  end;
   
  PdfDoc.SaveToFile(Arquivo);
  PdfDoc.Free;

  ShellExecute(Handle, nil, PChar(Arquivo), nil,  nil, SW_SHOWNORMAL);

  srve.UnitsProgram := RVUnit; //Change back to the previous value before converted to pixels

end;

Offline

Board footer

Powered by FluxBB