#1 2022-05-03 16:47:45

creitzel
Member
Registered: 2022-05-03
Posts: 1

Apparent bug in SynPDF?

I cannot get SynPDf to render anything when I try to use certain unicode characters.  I have been primarily testing with Chinese, but it also happens if I try Arabic characters, and probably others that I haven't tried. 

I have attempted to debug the code, and see what is going on, and It seems to be that the code points inserted into the pdf are always 0.  I am not familiar enough with your code to figure out why though. 

I have a little test app written in Delphi XE 10 that exhibits the problem.  In it, I allow text to be entered into an edit box, and then I render that text via a TMetaFile, displayed in a TImage, and directly to the TCanvas of a TPaintBox.  I then have a button to attempt to render the same text to a pdf document and save it to a file.  It's the pdf save that doesn't appear to be working correctly.

Here's my unit:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, RzCmboBx, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    GroupBox1: TGroupBox;
    PaintBox1: TPaintBox;
    GroupBox2: TGroupBox;
    Image1: TImage;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure PaintBox1Paint(Sender: TObject);
    procedure Edit1Change(Sender: TObject);
  private
    { Private declarations }
    procedure UpdateMeta;
    procedure WritePDF(AFilename: string);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses SynPDF;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
   with TSaveDialog.Create(nil) do
   try
      Filter := 'PDF File|*.pdf';
      FilterIndex := 0;
      if Execute then
         WritePDF(FileName);

   finally
      Free;
   end;
end;

procedure TForm1.Edit1Change(Sender: TObject);
begin
   PaintBox1.Invalidate;
   UpdateMeta;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
   Edit1Change(Edit1);
end;

procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
   PaintBox1.Canvas.Font.Assign(Self.Font);
   PaintBox1.Canvas.Font.Size := 14;
   PaintBox1.Canvas.Brush.Style := bsClear;
   PaintBox1.Canvas.TextOut(25, 25, Edit1.Text);
end;

procedure TForm1.UpdateMeta;
var
   emf: TMetaFile;
   c: TMetaFileCanvas;
begin
   emf := TMetaFile.Create;
   try
      emf.Width := Image1.Width;
      emf.Height := Image1.Height;

      c := TMetaFileCanvas.Create(emf, emf.Handle);
      try
         c.Font.Assign(Self.Font);
         c.Font.Size := 14;
         c.Font.PixelsPerInch := 72;

         c.Brush.Style := bsClear;
         c.TextOut(25, 25, Edit1.Text);

      finally
         c.Free;
      end;

      Image1.Picture.Metafile := emf;

   finally
      emf.Free;
   end;
end;

procedure TForm1.WritePDF(AFilename: string);
var
   pdf: TPdfDocumentGDI;
   pg: TPdfPage;
begin
   pdf := TPdfDocumentGDI.Create;
   try
      pdf.CompressionMethod := cmNone;
      pdf.ScreenLogPixels := 72;

      pg := pdf.AddPage;
      pg.PageWidth := 612;
      pg.PageHeight := 792;

      pdf.VCLCanvas.Font.Assign(Self.Font);
      pdf.VCLCanvas.Font.Size := 14;
      pdf.VCLCanvas.Font.PixelsPerInch := 72;


      pdf.VCLCanvas.Brush.Style := bsClear;
      pdf.VCLCanvas.TextOut(100, 100, Edit1.Text);

      pdf.SaveToFile(AFilename);
   finally
      pdf.Free;
   end;
end;

end.

and here's my dfm:

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 467
  ClientWidth = 812
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -15
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 18
  object Edit1: TEdit
    Left = 11
    Top = 11
    Width = 452
    Height = 26
    TabOrder = 0
    Text = #24555#36895#24067#26391#36339#36807'13'#25042#24816
    OnChange = Edit1Change
  end
  object Button1: TButton
    Left = 473
    Top = 11
    Width = 75
    Height = 25
    Caption = 'Save PDF'
    TabOrder = 1
    OnClick = Button1Click
  end
  object GroupBox1: TGroupBox
    Left = 385
    Top = 88
    Width = 353
    Height = 353
    Caption = 'Draw with Paintbox Canvas'
    TabOrder = 2
    object PaintBox1: TPaintBox
      Left = 2
      Top = 20
      Width = 349
      Height = 331
      Align = alClient
      OnPaint = PaintBox1Paint
      ExplicitLeft = 22
      ExplicitTop = 44
      ExplicitWidth = 309
      ExplicitHeight = 386
    end
  end
  object GroupBox2: TGroupBox
    Left = 11
    Top = 88
    Width = 353
    Height = 353
    Caption = 'Drawn to Metafile and displayed in TImage'
    TabOrder = 3
    object Image1: TImage
      Left = 2
      Top = 20
      Width = 349
      Height = 331
      Align = alClient
      ExplicitLeft = 88
      ExplicitTop = 132
      ExplicitWidth = 105
      ExplicitHeight = 105
    end
  end
end

Hopefully this is just something that I am missing, or doing incorrectly.

Thanks in advance for any help you can give me with this.

Chris

Offline

#2 2022-05-03 20:36:53

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 13,504
Website

Re: Apparent bug in SynPDF?

Enable Uniscribe support.

Online

#3 2022-05-04 19:03:57

rvk
Member
Registered: 2022-04-14
Posts: 47

Re: Apparent bug in SynPDF?

I don't think Uniscribe helps in this case (at least when I tried it).

Those characters don't seem to be "complex" so Uniscribe wouldn't be needed (found this out when tracing through AddUnicodeHexTextUniScribe).

If I use this it seems to work (setting the font to SimSun directly instead of Tahoma):

pdf.UseUniscribe := false; // <- no need to UseUniscribe ??
// ......
// pdf.VCLCanvas.Font.Assign(Self.Font); // <- don't use Tahoma

pdf.VCLCanvas.Font.Name := 'SimSun'; // <- but set SimSun directly

pdf.VCLCanvas.Font.Size := 14;
pdf.VCLCanvas.Font.PixelsPerInch := 72;
pdf.VCLCanvas.Brush.Style := bsClear;
pdf.VCLCanvas.TextOut(100, 100, Edit1.Text);

So somehow the automatic switch to SimSun (or extension) (which is done in TEdit/Windows) isn't done when creating a PDF.

(Disclaimer: I'm a novice concerning PDF and Font issues big_smile)

Edit:
Using SimSun as Fallbackfont will also work:

pdf.UseUniscribe := false;  // <-- maybe needed for other complex constructs of characters but not for this example
pdf.FontFallBackName := 'SimSun';
pdf.UseFontFallBack := true;
//...
pdf.VCLCanvas.Font.Assign(Self.Font);
pdf.VCLCanvas.Font.Size := 14;
pdf.VCLCanvas.Font.PixelsPerInch := 72;
pdf.VCLCanvas.Brush.Style := bsClear;
pdf.VCLCanvas.TextOut(100, 100, Edit1.Text);

Last edited by rvk (2022-05-04 19:16:39)

Offline

Board footer

Powered by FluxBB