Recent

Author Topic: Chinese Fonts in fpPDF  (Read 3306 times)

paweld

  • Hero Member
  • *****
  • Posts: 1250
Re: Chinese Fonts in fpPDF
« Reply #45 on: October 03, 2024, 07:05:19 am »
Where can I get the file "pdftoppm"? Can you give me a download website?
I use Deian and here it is installed along with the system. You can also download from: https://www.xpdfreader.com/download.html , but here you must already use “pdftopng”, which does not have the “singlefile” parameter
Best regards / Pozdrawiam
paweld

dbannon

  • Hero Member
  • *****
  • Posts: 3156
    • tomboy-ng, a rewrite of the classic Tomboy
Re: Chinese Fonts in fpPDF
« Reply #46 on: October 03, 2024, 09:13:42 am »
Your last TestPDF runs very well in my linux system, and Chinese can be displayed.

Yippy, we've got it at last !

Quote
The previous ones all reported overflow errors,
That was because of the Latin fonts I, incorrectly, assumed were present on all systems.  So, all along you could show chinese fonts, but my code used some English fonts as well, they were the problem. Sigh ...

Thanks for not giving up jianwt.

Davo
Lazarus 3, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

jianwt

  • Full Member
  • ***
  • Posts: 125
Re: Chinese Fonts in fpPDF
« Reply #47 on: October 03, 2024, 10:05:42 am »
@paweld

@dbannon

Thanks to the friends who helped me.

jianwt

  • Full Member
  • ***
  • Posts: 125
Re: Chinese Fonts in fpPDF
« Reply #48 on: October 03, 2024, 11:02:05 am »
@paweld
I'm not really good with this. For example, when I use the Xpdf command line tools in windows system, I put "pdftopng.exe" and "project1.exe" in the same directory. Then, I changed the code according to the method you said. Run project1.exe but don't see the converted image. What's wrong? Please help. thank you.
Do you need anything else?
Do you still need to install the corresponding version (GPG signature)? Could you please help me check whether the code I modified is correct?

Code: Pascal  [Select][+][-]
  1.  // cmd := 'pdftoppm';
  2.  // if not RunCommand(cmd, ['-singlefile', filename + '.pdf', filename, '-png'], outstr, [poWaitOnExit], swoHIDE) or not FileExists(filename + '.png') then
  3.   //  exit;
  4.  
  5.   cmd := 'pdftopng';
  6.   if not RunCommand(cmd, [ filename, '-png'], outstr, [poWaitOnExit], swoHIDE) or not FileExists(filename + '.png') then
  7.     exit;        
  8.  
« Last Edit: October 03, 2024, 11:08:08 am by jianwt »

paweld

  • Hero Member
  • *****
  • Posts: 1250
Re: Chinese Fonts in fpPDF
« Reply #49 on: October 03, 2024, 04:17:28 pm »
if you want to use pdftopng then you need to modify the code a bit, to something like the following:
Code: Pascal  [Select][+][-]
  1.       cmd := {$IFDEF WINDOWS}'pdftopng.exe'{$ELSE}'pdftopng'{$ENDIF};
  2.       //run PDFTOPNG with parameters -f NUMBER_OF_FIRST_PAGE -l NUMBER_OF_LASTPAGE INPUT_PDF_FILENAME OUTPUT_PNG_FILENAME_WITHOUT_EXT
  3.       if not RunCommand(cmd, ['-f', '1', '-l', '1', filename + '.pdf', filename], outstr, [poWaitOnExit], swoHIDE) or not FileExists(filename + '-000001.png') then
  4.         exit;
  5.       Result := TMemoryStream.Create;
  6.       Result.LoadFromFile(filename + '-000001.png');
  7.       DeleteFile(filename + '.pdf');
  8.       DeleteFile(filename + '-000001.png');
It works on Windows and Linux, but under Windows at my place the preview for Chinese characters is not generated correctly.

However, as for RunCommand, it is a function that calls external commands - you need to provide the command (program), a list of parameters as an array, then there is an output string, run options (poWaitOnExit - wait for program execution) and window options (swoHide - hide window)
Best regards / Pozdrawiam
paweld

jianwt

  • Full Member
  • ***
  • Posts: 125
Re: Chinese Fonts in fpPDF
« Reply #50 on: October 04, 2024, 03:25:25 am »
@paweld
That's it. Thank you very much.

dbannon

  • Hero Member
  • *****
  • Posts: 3156
    • tomboy-ng, a rewrite of the classic Tomboy
Re: Chinese Fonts in fpPDF
« Reply #51 on: October 04, 2024, 05:13:21 am »
If you are trying to open that pdf and read it from a FPC/Lazarus program, maybe you would be better using the Operating System's ability to open a given file with the appropriate application.  Assuming you (or your end user) system is configured with an application that can open a PDF, you should use it.

This code, from my app, takes a full path to a file name and tries to open it. It does not need to know what application to use, it just asks the operating system to open it. You would probably be passing only PDF ?

Code: Pascal  [Select][+][-]
  1. uses     FileUtil, LCLIntf;     // probably a few more needed here ...
  2. ....
  3. function OpenFileLink(LinkText : string) : boolean;
  4. var
  5.     i : integer;
  6.     Msg : string;
  7.     {$ifdef WINDOWS}        // in Windows, any file is potentially executable, we'll test by extension
  8.     function WindowsFileIsExecutable() : boolean;                          // True if file has extension mentioned in PATHEXT
  9.     var WinExeExt, Extension : string;
  10.     begin
  11.         WinExeExt := GetEnvironmentVariable('PATHEXT');
  12.         // WinExeExt := '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH';   // just for testing purposes !!!!
  13.         if WinExeExt = '' then
  14.             exit(false);        // var not set, we will not test or warn for executable
  15.         WinExeExt := WinExeExt + ';';
  16.         Extension := ExtractFileExt(LinkText);
  17.         if Extension = '' then
  18.             exit(False);        // Again, not enough info, will not test or warn for executable
  19.         Extension := uppercase(Extension) + ';';
  20.         Result := (pos(Extension, WinExeExt) <> 0);
  21.     end;
  22.     {$endif}
  23.  
  24. begin
  25.     result := True;
  26.     if LinkText.StartsWith(FileLinkToken) then
  27.         LinkText := LinkText.Remove(0, FileLinkTokenLen)
  28.     else exit;                                                // thats an error, should not happen.
  29.     if (LinkText = '') or (LinkText = '""') then begin
  30.         showmessage(' Empty Link ');
  31.         exit;
  32.     end;                                                      // OK, we know its not empty, but does it use " ?
  33.     if (LinkText[1] = '"') then begin                         // Ah, wrapped in ".."
  34.         LinkText := LinkText.Remove(0, 1);                    // Lazarus code will re-wrap the text later in process
  35.         i := LinkText.IndexOf('"', 0);                        // Must have a second "
  36.         if i = -1 then begin
  37.             showmessage('Badly formed link : '#10 + LinkText);
  38.             exit;
  39.         end;
  40.         LinkText := LinkText.Remove(i, 99);                   // remove second " and anything after it too
  41.     end;
  42.     if LinkText = '' then begin                               // Probably redundant .....
  43.         showmessage('Empty Link');
  44.         exit;
  45.     end;
  46.  
  47.     { its not an absolute path (and therefore needs $HOME) if it does not start with a slash or eg c:/
  48.     So, prepend $HOME if it does not start with either a slash or ?:  !     }
  49.     // Is it an absolute path, if not, prepend $HOME
  50.     if not (LinkText[1] in ['\', '/']) then begin         // Relative path if first char after token is not a slash
  51.         {$ifdef WINDOWS}                                  // it might still be an absolute path, starts with eg c:\ ?
  52.         if (length(LinkText) < 4)                         // too short
  53.             or (LinkText[2] <> ':') then                  // not a drive specifier, not much of a test but its windows !
  54.                 LinkText := Sett.HomeDir + LinkText;
  55.         {$else}
  56.         LinkText := Sett.HomeDir + LinkText;
  57.         {$endif}
  58.     end;
  59.     if not (FileExists(LinkText) or DirectoryExists(LinkText)) then begin
  60.         showmessage('File does not exist : '#10 + LinkText);
  61.         exit;
  62.     end;
  63.  
  64.         {$ifdef WINDOWS}
  65.         // 'Executable' on Windows is a dogs breakfast. https://forum.lazarus.freepascal.org/index.php/topic,24615.0.html
  66.         if WindowsFileIsExecutable() then begin
  67.         {$else}
  68.         if FileIsExecutable(LinkText) then begin
  69.         {$endif}
  70.              Msg := 'Link is an executable file.';
  71.              if IDYES <> Application.MessageBox('Open an executable ?'
  72.                      ,pchar(Msg) , MB_ICONQUESTION + MB_YESNO) then
  73.                  exit;
  74.          end;
  75.         if not OpenDocument(LinkText) then
  76.              showmessage('Sorry, cannot open '#10 + LinkText);
  77.  
  78. end;  
                   

edit : guess at extra uses units needed
« Last Edit: October 04, 2024, 05:20:43 am by dbannon »
Lazarus 3, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

paweld

  • Hero Member
  • *****
  • Posts: 1250
Re: Chinese Fonts in fpPDF
« Reply #52 on: October 04, 2024, 07:48:09 am »
@dbannon: in LCLIntf unit there are functions OpenDocument and OpenURL
Best regards / Pozdrawiam
paweld

dbannon

  • Hero Member
  • *****
  • Posts: 3156
    • tomboy-ng, a rewrite of the classic Tomboy
Re: Chinese Fonts in fpPDF
« Reply #53 on: October 04, 2024, 10:00:53 am »
@dbannon: in LCLIntf unit there are functions OpenDocument and OpenURL

Yep, the code about, eventually, calls OpenDocument().  But does need to do some checks first. This particularly so with Windows that does not have a clear idea of 'executable'.

Davo
Lazarus 3, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

jianwt

  • Full Member
  • ***
  • Posts: 125
Re: Chinese Fonts in fpPDF
« Reply #54 on: October 05, 2024, 01:53:14 pm »
First of all, thanks to 'paweld' for writing this demo, I wanted to write a simple complete routine for fpPDF.

Now there is a problem: how to accurately base (TPDFpage.paper.w - left margin - right margin), and then write the text line into the TPDFPage work area. At present, there are problems in the function WrapLines(), one is that the overall content of SynEdit1.Text should be pressed to enter the paragraph branch, rather than the content branch of SynEdit1.Lines[J], and the second is that the branch calculation is inaccurate when encountering Chinese branches.

I am a novice, please help to complete this demo. Thank you all in advance.
« Last Edit: October 05, 2024, 02:09:15 pm by jianwt »

paweld

  • Hero Member
  • *****
  • Posts: 1250
Re: Chinese Fonts in fpPDF
« Reply #55 on: October 05, 2024, 03:19:01 pm »
This error I corrected, but the issue of too narrow text remains
Code: Pascal  [Select][+][-]
  1. procedure TForm1.WrapLines(aStr: String; aPageWidth, aFontSize: Single; var aLines: TStringList);
  2. var
  3.   textwidth: Single;
  4.   stmp: String;
  5.  
  6.   function Inseparable(aCheckStr: String): Boolean;
  7.   const
  8.     icarr: array [0..10] of char = ' ,.;/\+-|?!';
  9.   var
  10.     ii, ip, il: Integer;
  11.   begin
  12.     Result := True;
  13.     il := UTF8Length(aCheckStr);
  14.     for ii := 0 to High(icarr) do
  15.     begin
  16.       ip := UTF8Pos(icarr[ii], aCheckStr);
  17.       if (ip > 0) and (ip < il) then
  18.       begin
  19.         Result := False;
  20.         break;
  21.       end;
  22.     end;
  23.   end;
  24.  
  25.   function SeparatorPos(aCheckStr: String; startfrom: Integer; First: Boolean): Integer;   //first or last separator in string
  26.   const
  27.     icarr: array [0..10] of char = ' ,.;/\+-|?!';
  28.   var
  29.     ii, ip, il: Integer;
  30.     b: Boolean;
  31.   begin
  32.     if startfrom < 1 then
  33.       startfrom := 1;
  34.     il := UTF8Length(aCheckStr);
  35.     Result := UTF8Length(aCheckStr);
  36.     b := False;
  37.     if not First then
  38.     begin
  39.       aCheckStr := UTF8ReverseString(aCheckStr);
  40.       ii := 1;
  41.       while (Length(aCheckStr) > ii) and (aCheckStr[ii] in [' ', ',', '.', ';', '/', '\', '+', '-', '|', '?', '!']) do
  42.         Inc(ii);
  43.       if startfrom < ii then
  44.         startfrom := ii;
  45.     end;
  46.     for ii := 0 to High(icarr) do
  47.     begin
  48.       ip := UTF8Pos(icarr[ii], aCheckStr, startfrom);
  49.       if (ip > 0) and (ip < Result) then
  50.       begin
  51.         Result := ip;
  52.         b := True;
  53.       end;
  54.     end;
  55.     if not First and b then
  56.       Result := il + 1 - Result;
  57.   end;
  58.  
  59. begin
  60.   aLines.Clear;
  61.   textwidth := PdfToMm(fci.TextWidth(aStr, aFontSize));
  62.   //if inseparable text
  63.   if (aStr = '') or (textwidth <= aPageWidth) or Inseparable(aStr) then
  64.   begin
  65.     textwidth := 0;
  66.     if aStr = '' then
  67.       aStr := ' ';
  68.     aLines.Add(aStr);
  69.     aStr := '';
  70.   end;
  71.   while textwidth > aPageWidth do
  72.   begin
  73.     stmp := TrimRight(UTF8Copy(aStr, 1, SeparatorPos(aStr, trunc(RoundTo(UTF8Length(aStr) * aPageWidth / textwidth, 0)), True)));
  74.     if Inseparable(stmp) then
  75.       stmp := UTF8Copy(aStr, 1, SeparatorPos(aStr, 1, True))
  76.     else
  77.     begin
  78.       stmp := TrimRight(UTF8Copy(stmp, 1, SeparatorPos(stmp, 1, False)));
  79.       while (PdfToMm(fci.TextWidth(stmp, aFontSize)) > aPageWidth) and not Inseparable(stmp) do
  80.         stmp := TrimRight(UTF8Copy(stmp, 1, SeparatorPos(stmp, 1, False)));
  81.     end;
  82.     aStr := UTF8Copy(aStr, UTF8Length(stmp) + 1, UTF8Length(aStr) - UTF8Length(stmp));
  83.     if (aStr <> '') and (aStr[1] = ' ') then
  84.       Delete(aStr, 1, 1);
  85.     if stmp <> '' then
  86.       aLines.Add(stmp);
  87.     textwidth := PdfToMm(fci.TextWidth(aStr, aFontSize));
  88.   end;
  89.   if aStr <> '' then
  90.     aLines.Add(aStr);
  91. end;    
  92.  
Best regards / Pozdrawiam
paweld

jianwt

  • Full Member
  • ***
  • Posts: 125
Re: Chinese Fonts in fpPDF
« Reply #56 on: October 06, 2024, 07:34:56 am »
@paweld
There are still some issues to be addressed:
1.   SynEdit1.  Text needs to be split into lines based on the entire content, with specific requirements.   First, the number of paragraphs in SynEdit1.  Text needs to be calculated, and then each paragraph needs to be split into lines.   It is not possible to split lines using SynEdit1.Lines[J].
2.   The inaccurate calculation results are due to the fact that the parameter aPageWidth in the WrapLines() function is in millimeters, while textwidth := PdfToMm(fci.  TextWidth(aStr, aFontSize)) returns a numerical value in pixels.   They must be consistent in their unit of measurement.
3.   The function WrapLines() splits the text into paragraphs when it encounters a space in SynEdit1.  Text, which is incorrect.
4.   In Chinese writing tradition, the first character of each paragraph should be indented by 2 Chinese characters.
(The Internet translation may be mistranslated.)
See the diagram below for details:

jianwt

  • Full Member
  • ***
  • Posts: 125
Re: Chinese Fonts in fpPDF
« Reply #57 on: October 07, 2024, 10:07:44 am »
@dbannon
Actually, I originally wanted to upload a part of the files separated from your project, but since I didn't get your consent, I didn't upload those program files here.
It seems that my version of KMEMOA is not quite the same as yours, some constants or variables I can't run, very strange oh?

My idea is to generate a PDF document that matches the display effect of the "Chinese_editing_format_in_WORD.doc" document in the project using a method.  The text content for generating the document comes from KMEMO, and the illustrations are from the image "Inserted_picture.jpg" in the project folder.  Additionally, page numbers should be clearly marked at the bottom of each page (Page 1...  Page N) to make it perfect.

Due to the forum restriction that the attachment cannot be larger than 500KB, I have compressed the document in separate volumes. Please download the two compressed reports and then decompress them.

zip Package 1:

jianwt

  • Full Member
  • ***
  • Posts: 125
Re: Chinese Fonts in fpPDF
« Reply #58 on: October 07, 2024, 10:16:43 am »
zip Package 2:
Please download the "zip Package 2:" attachment and rename it from "Chinese_editing_format_in_WORD2.zip" to "Chinese_editing_format_in_WORD.z01". Then, extract it along with the "zip Package 1:" file to obtain the Word document.

dbannon

  • Hero Member
  • *****
  • Posts: 3156
    • tomboy-ng, a rewrite of the classic Tomboy
Re: Chinese Fonts in fpPDF
« Reply #59 on: October 12, 2024, 11:06:08 am »
Jianwt, sorry for the delay, attached is the zip with another project, again based on the original example. As we discussed in the PM.

It contains a text file that, I think, is what you sent me as Chinese Characters. Its called c.txt and might contain a utf8 error so, probably worth looking at it and see if it all makes sense.  Sadly, I cannot read a single Chinese character so I really don't know.

I have chose some silly font setting and layout numbers so that it spreads over three pages because I understand you want to know how to put page numbers in. Easy for you to change those, I am sure you will want to.

Now, layout, I do not know the correct way to layout Chinese text, for that I apologize but it is what it is.  I have assumed that you just put the text into a block, separated by new-lines. Please run it and see if this is what you expect. If not, it should be easy for you to see what I have got wrong !

All the best,

Davo
Lazarus 3, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

 

TinyPortal © 2005-2018