Menu

#10 Text justify problem

2.0
closed
nobody
2019-02-20
2019-02-10
No

Hi,
Please note when using LitePDF for converting HTML to PDF the cell text is not well rendered (SynPDF did: https://github.com/synopse/SynPDF).

The renderer used is: https://github.com/BerndGabriel/HtmlViewer/tree/master

The code used:

procedure THTMLToXForm.HTMLViewerSynPDFClick(Sender: TObject);
var
  Size    : TSize;
  Viewer  : THtmlViewer;
  pdfForm : TForm;
  pdf     : TPdfDocumentGDI;
begin
  pdf                  := TPdfDocumentGDI.Create;
  pdfForm              := TForm.Create(nil);
  Viewer               := THtmlViewer.Create(pdfForm);
  Viewer.Parent        := pdfForm;
  Viewer.DefBackground := clWhite;
  Viewer.LoadFromFile(htmlFile);
  Size.cx := Round(HTMLWidthFromViewPort(viewer.Text)*pdf.ScreenLogPixels/25.4);
  Size    := viewer.FullDisplaySize(Size.cx);
  pdf.AddPage;
  pdf.DefaultPageWidth  := Size.cx;
  pdf.DefaultPageHeight := Size.cy;
  Viewer.Draw(pdf.VCLCanvas,0,Size.cx,Size.cx,Size.cy);
  pdf.SaveToFile(ChangeFileExt(htmlFile,'-HTML-To-SYNPDF.pdf'));
  pdf.Free;
  pdfForm.Free;
end;

procedure THTMLToXForm.HTMLViewerLitePDFClick(Sender: TObject);
var
  Size    : TSize;
  Viewer  : THtmlViewer;
  pdfForm : TForm;
  pdf     : TLitePDF;
  DC      : HDC;
  ACanvas : TCanvas;
begin
  pdf                  := TLitePDF.Create;
  pdfForm              := TForm.Create(nil);
  pdfForm.Visible      := False;
  Viewer               := THtmlViewer.Create(pdfForm);
  Viewer.Parent        := pdfForm;
  Viewer.DefBackground := clWhite;
  Viewer.LoadFromFile(htmlFile);
  Size.cx := Round(HTMLWidthFromViewPort(viewer.Text)*96/25.4);
  Size    := viewer.FullDisplaySize(Size.cx);
  pdf.SetUnit(LitePDFUnit_mm);
  pdf.CreateMemDocument;
  DC      := pdf.AddPage(Round(pdf.UnitToMMEx(LitePDFUnit_mm,Size.cx*25.4/96)),
                         Round(pdf.UnitToMMEx(LitePDFUnit_mm,Size.cy*25.4/96)),
                         Size.cx,Size.cy,Cardinal(LitePDFDrawFlag_None));
  ACanvas := TCanvas.Create;
  ACanvas.Handle := DC;
  Viewer.Draw(ACanvas,0,Size.cx,Size.cx,Size.cy);
  ACanvas.Free;
  PDF.FinishPage(DC);
  pdf.SaveToFileW(ChangeFileExt(htmlFile,'-HTML-To-LitePDF.pdf'));
  pdf.Free;
  pdfForm.Free;
end;

Best regards.

3 Attachments

Discussion

  • zyx

    zyx - 2019-02-11

    Thanks for a bug report. It seems to me it's due to too small scale. See the Known Issues section at https://litepdf.sourceforge.io/download.html . Scale the page size 10 or 100 times, and the font mapping will be more precise.

     
  • zyx

    zyx - 2019-02-11
    • status: open --> closed
     
    • Hafedh TRIMECHE

      Hafedh TRIMECHE - 2019-02-19

      Hello,
      Please note that the problem persisted even the page size scaled.
      Would rendering with anti-aliaising be used?

      procedure THTMLToXForm.HTMLViewerLitePDFClick(Sender: TObject);
      var
        pdf     : TLitePDF;
        DC      : HDC;
        ACanvas : TCanvas;
        mmX     ,
        mmY     : Double;
      begin
        pdf := TLitePDF.Create;
        pdf.SetUnit(LitePDFUnit_100th_mm);
        pdf.CreateMemDocument;
        mmX     := pdf.MMToUnit(Size.cx*25.4/96);
        mmY     := pdf.MMToUnit(Size.cy*25.4/96);
        DC      := pdf.AddPage(Round(mmX),Round(mmY),Size.cx,Size.cy,Cardinal(LitePDFDrawFlag_None));
        ACanvas := TCanvas.Create;
        ACanvas.Handle := DC;
        Viewer.Draw(ACanvas,0,Size.cx,Size.cx,Size.cy);
        ACanvas.Free;
        PDF.FinishPage(DC);
        pdf.SaveToFileW(ChangeFileExt(htmlFile,'-HTML-To-LitePDF.pdf'));
        pdf.Free;
      end;
      

      Best regards.

       

      Last edit: Hafedh TRIMECHE 2019-02-19
  • zyx

    zyx - 2019-02-20

    You didn't scale the page at all. Furthermore, the scale should be done with the pixel size, where you draw, not with the PDF page size. As you can see at line 41 here https://litepdf.sourceforge.io/helloworld.cpp.html#n41 the PDF page size is 210x297mm, aka A4 format, but the text is drawn into an HDC with 10-times larger pixel size, 2100x2970 (comparing pixels and millimeters is quite inaccurate here, but I hope you know what I mean). The larger scale you'll use, the higher font precision you get.

    To do the same in your code, you might do this (I chose scale by 10):

    DC := pdf.AddPage(Round(mmX),Round(mmY),Size.cx * 10,Size.cy * 10,Cardinal(LitePDFDrawFlag_None));
    ....
    Viewer.Draw(ACanvas,0 * 10,Size.cx * 10,Size.cx * 10,Size.cy * 10);

     
  • Hafedh TRIMECHE

    Hafedh TRIMECHE - 2019-02-20

    The viewer can't be scaled. Its resolution is set to 96 (Screen resolution).

    So, the scaling ratio should be maintained at value 1.

    To be scaled, the resolution of the device context on which the viewer will render, should be higher enough (72 x scale) and it's also valid for the viewer context (screen) itself. The 2 devices should offer the scaling possibility to get output result as expected.

     
    • zyx

      zyx - 2019-02-20

      So, the scaling ratio should be maintained at value 1.

      Oh, that's a pita. In that case there's a bad luck for you with litePDF, unless you happen to find some intermediate software bethween the Viewer and the litePDF HDC, which will scale the Viewer.

      By the way, I do not know what THtmlViewer component you use, they use to have something called zoom or scale (printscale?), which may have some influence on this. I also do not know the arguments of the Draw() method, I only guessed them. If it's rather "give me size of the canvas and where you want to draw it", then maybe
      Viewer.Draw(ACanvas,0,Size.cx,Size.cx * 10,Size.cy * 10);
      would do the trick? Eventually a different drah method? I really do not know, this is out of question for the litePDF project itself, you might ask the viewer component developers for a help.

       

Log in to post a comment.