FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour UTF8 text with FwPdf
Posts: 193
Joined: Wed Apr 04, 2007 06:54 AM
UTF8 text with FwPdf
Posted: Sun Nov 30, 2025 09:36 PM

I have created this little function to test the FwPdf class with UTF8 text (example: ciryllic alphabet).
This function doesn't display UTF8 text.
What am I doing wrong?
Thanks, Marzio

function PdfGen()

local oPrn, oFont

   FW_SetUnicode( .t. )
   HB_SETCODEPAGE( "UTF8" )
   oPrn := FWPdf():New( cFileSetExt( ExeName(), "pdf" ) )
   oPrn:lUnicode := .t.
   oPrn:lPreview := .t.
   oFont := oPrn:DefineFont( "Courier",  10 )

   if Empty( oPrn:hPdf )
      MsgStop("PDFs not available!")
Return( NIL )
   endif

   cText := MemoRead("utf8.txt")	// this file contains a few words of text UTF8
   oPrn:StartPage()
   oPrn:Say( 1, 1, cText, oFont )
   oPrn:EndPage()
   oPrn:end()

Return( NIL )
Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM
Re: UTF8 text with FwPdf
Posted: Mon Dec 01, 2025 03:24 AM

Hello Marzio,

The issue lies in the font selection, not strictly your coding logic.

In the PDF standard, the "Standard 14 fonts" (like Courier, Helvetica, Times) are usually limited to ANSI encodings (WinAnsiEncoding). They do not contain the glyphs required to render UTF-8 characters like Cyrillic, Chinese, or Arabic.

To display Cyrillic characters in a PDF, you must use an external TrueType Font (.ttf) that contains those specific Unicode glyphs, and it must be embedded into the PDF.

Here is the solution to fix your function.

The Solution: Use a .TTF File

Instead of asking for "Courier", you need to point the function to the actual path of a physical font file (like Arial or Courier New) that supports Unicode.

Here is the corrected code:

Code (hb): Select all Collapse
function PdfGen()
   local oPrn, oFont
   local cCyrillicFont := "C:\Windows\Fonts\arial.ttf" // Use a full path to a TTF

   // 1. Ensure Unicode is ON
   FW_SetUnicode( .t. )
   HB_SETCODEPAGE( "UTF8" )

   oPrn := FWPdf():New( cFileSetExt( ExeName(), "pdf" ) )
   oPrn:lUnicode := .t.
   oPrn:lPreview := .t.

   // 2. DEFINE FONT using the .TTF filename, not just the name "Courier"
   // Note: We use -10 for height to ensure scaling works correctly with TTFs in some versions
   if File( cCyrillicFont )
      oFont := oPrn:DefineFont( cCyrillicFont, 10 ) 
   else
      MsgStop( "Font file not found: " + cCyrillicFont )
      return nil
   endif

   if Empty( oPrn:hPdf )
      MsgStop("PDFs not available!")
      Return( NIL )
   endif

   // 3. Ensure your text file is saved as UTF-8 NO BOM (Byte Order Mark)
   // Or sanitize it after reading.
   cText := MemoRead("utf8.txt") 
   
   // Optional: Remove BOM if it exists at the start of the file
   if Left( cText, 3 ) == Chr(239) + Chr(187) + Chr(191)
      cText := SubStr( cText, 4 )
   endif

   oPrn:StartPage()
   oPrn:Say( 1, 1, cText, oFont )
   oPrn:EndPage()
   oPrn:end()

Return( NIL )

Key Changes Explained

  1. DefineFont( "Path\To\File.ttf", ... ):
    When FWPdf sees a filename extension (.ttf), it switches from using internal standard fonts to embedding the external font file. This embedding allows the PDF viewer to "see" the Cyrillic shapes.
  2. Font Choice:
    "Courier" (the standard PDF font) does not have Cyrillic characters. "Arial.ttf" or "Courier New.ttf" (found in Windows/Fonts) usually includes the full WGL4 character set, including Cyrillic.
  3. BOM Handling:
    If you edit utf8.txt in Notepad, it might add a "BOM" (3 invisible bytes) at the start. I added a small check to remove them, otherwise, the first character might look like garbage.

Summary Checklist

  • [ ] Does C:\Windows\Fonts\arial.ttf exist on your machine?
  • [ ] Is utf8.txt actually saved as UTF-8 encoding?
  • [ ] Did you use the full path to the .ttf in DefineFont?

-----
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 193
Joined: Wed Apr 04, 2007 06:54 AM
Re: UTF8 text with FwPdf
Posted: Mon Dec 01, 2025 10:05 AM

Thanks Antonio for your reply. I tried the change you posted, but it still doesn't work. with: ? cText := MemoRead("utf8.txt") I see the window with the Cyrillic text, but I don't see it in the PDF. I used the arial.ttf file in the "C:\Windows\Fonts\arial.ttf" folder.

what could be the problem?

Posts: 193
Joined: Wed Apr 04, 2007 06:54 AM
Re: UTF8 text with FwPdf
Posted: Thu Dec 04, 2025 08:20 PM

Hi Antonio,

Have you tried the change you suggested? Despite the change to loading the font "C:\Windows\Fonts\arial.ttf", I still don't see Cyrillic text in UTF8, but random characters.

What do you think?

Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM
Re: UTF8 text with FwPdf
Posted: Fri Dec 05, 2025 11:08 AM

Dear Marzio,

I don't have much experience with UTF8, so we need the advise and experience of someone who have them

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 193
Joined: Wed Apr 04, 2007 06:54 AM
Re: UTF8 text with FwPdf
Posted: Fri Dec 05, 2025 10:03 PM

I replaced fwPdf with urupdf and UTF8 works fine.

REQUEST FWHARU   // required for using HaruPdf

function PdfGen()
local oPrn, oFont

   FW_SetUnicode( .t. )
   HB_SETCODEPAGE( "UTF8" )

   PRINT oPrn PREVIEW FILE cFileSetExt( ExeName(), "pdf" )
   DEFINE FONT oFont NAME "Arial" SIZE 0, -10 OF oPrn

   cText := MemoRead("utf8.txt")

   if Left( cText, 3 ) == Chr(239) + Chr(187) + Chr(191)   // Optional: Remove BOM if it exists at the start of the file
      cText := SubStr( cText, 4 )
   endif

   PageBegin()

   oPrn:SayText( 10, 10, cText,,, oFont)

   PageEnd()
   PrintEnd()

Return( NIL )

Continue the discussion