Chinese Characters in wxPdfDc

Talk here about issues with one of the components hosted at wxCode, or suggest features for it.
Post Reply
EverythingsShiny
In need of some credit
In need of some credit
Posts: 6
Joined: Thu Dec 04, 2014 3:10 am

Chinese Characters in wxPdfDc

Post by EverythingsShiny »

Hi,

Is it possible to print Chinese characters on to a PdfDocument through the DrawText() or DrawRotatedText() functions of a wxPdfDc?

I've managed to get Chinese characters to print by using the wxPdfDocument::Write() command by setting the appropriate font beforehand etc. but I can't seem to find a way to accomplish the same thing through the DC interface. I have a page layout that incorporates graphics and text that I already run through regular wxDCs to display on screen, print and save to PdfDocument (in English) and now I'm trying to get it to work with Chinese.

I'm running:
wxpdfdoc-0.9.4
wxWidgets-3.0.2
I develop on Mac and PC but at the moment I'm running these tests on OSX Yosemite. Though the results seem to be the same on both.
utelle
Moderator
Moderator
Posts: 1125
Joined: Tue Jul 05, 2005 10:00 pm
Location: Cologne, Germany
Contact:

Re: Chinese Characters in wxPdfDc

Post by utelle »

EverythingsShiny wrote:Is it possible to print Chinese characters on to a PdfDocument through the DrawText() or DrawRotatedText() functions of a wxPdfDc?
Sure, this should definitely work, at least if the selected font supports Chinese characters and if wxWidgets is compiled in Unicode mode (which should always be true for wxWidgets 3.x).
EverythingsShiny wrote:I've managed to get Chinese characters to print by using the wxPdfDocument::Write() command by setting the appropriate font beforehand etc. but I can't seem to find a way to accomplish the same thing through the DC interface.
There is nothing special to do, just set the font you want to use as usual with the SetFont method of the wxDC class. If the font is not already registered in the wxPdfFontManager, the SetFont implementation of wxPdfDC will do that implicitly.

If you experienced problems, please show some code or describe what exacrly was going wrong.
EverythingsShiny wrote:I have a page layout that incorporates graphics and text that I already run through regular wxDCs to display on screen, print and save to PdfDocument (in English) and now I'm trying to get it to work with Chinese.
As said this should work exactly in the same way as it did for English.
EverythingsShiny wrote:I'm running:
wxpdfdoc-0.9.4
wxWidgets-3.0.2
I develop on Mac and PC but at the moment I'm running these tests on OSX Yosemite. Though the results seem to be the same on both.
I don't have access to an OS X system, therefore I can't test the font related methods of wxPdfDocument for myself. However, I know of users successfully using wxPdfDocument on OS X systems. So this shouldn't impose a problem.

Regards,

Ulrich
EverythingsShiny
In need of some credit
In need of some credit
Posts: 6
Joined: Thu Dec 04, 2014 3:10 am

Re: Chinese Characters in wxPdfDc

Post by EverythingsShiny »

Thanks Ulrich,

Based on your answers I think I'm missing the part about "if the selected font supports Chinese characters". My wxWidgets is definitely compiled as Unicode.

I'm using translation files so my Chinese is read in from a GetText .mo file at runtime. From what I can tell this means it is encoded in UTF8.

This is what is working for me writing directly to the PdfDocument:

Code: Select all

    // Create wxPdfDC from print data
    wxPdfDC dc(printData);

    // Set wxPdfDC mapping mode style so we can scale fonts and graphics coords with a
    // single setting.
    dc.SetMapModeStyle(wxPDF_MAPMODESTYLE_PDF);
    dc.SetMapMode(wxMM_POINTS);
    bool ok = dc.StartDoc(_("Printing ..."));

    // Start the current PDF page
    dc.StartPage();

    // Attempt to get the wxPdfDocument from the dc
    wxPdfDocument& pdf = *((wxPdfDC&) dc).GetPdfDocument();
    pdf.AddFontCJK(wxT("GB"));

    // Set the GB font
    pdf.SetFont(wxT("GB"),wxT(""),20);

    // Write translation of "Set" to PDF
    pdf.Write(30,_("Set"));

    // End the page
    dc.EndPage();
    dc.EndDoc();
But when I do the following I get the appropriate Chinese characters displayed on screen and on the printout but not when saving to pdf. Instead I just get "????".

Code: Select all

   // Same startup and end code.

    // Attempt to get the wxPdfDocument from the dc
    wxPdfDocument& pdf = *((wxPdfDC&) dc).GetPdfDocument();
    pdf.AddFontCJK(wxT("GB"));

    wxFont fontText(wxSize(0,20), wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
    dc.SetFont(fontText);

    // Draw the translated text
    dc.DrawText(_("Set"), wxPoint(0,0) /*Using appropriate coordinates*/);
How do i set a font to the dc using the "GB" format?
utelle
Moderator
Moderator
Posts: 1125
Joined: Tue Jul 05, 2005 10:00 pm
Location: Cologne, Germany
Contact:

Re: Chinese Characters in wxPdfDc

Post by utelle »

EverythingsShiny wrote:Based on your answers I think I'm missing the part about "if the selected font supports Chinese characters". My wxWidgets is definitely compiled as Unicode.
Unicode is the default for wxWidgets 3.x, and in fact wxPdfDocument requires Unicode to support CJK languages. Your environment meets these requirements.
EverythingsShiny wrote:I'm using translation files so my Chinese is read in from a GetText .mo file at runtime. From what I can tell this means it is encoded in UTF8.
For the .po files different encodings can be used. However, on loading a .mo file the text is stored in memory as Unicode. So this shouldn't be a problem.
EverythingsShiny wrote:This is what is working for me writing directly to the PdfDocument:

Code: Select all

    // Create wxPdfDC from print data
    wxPdfDC dc(printData);

    // Set wxPdfDC mapping mode style so we can scale fonts and graphics coords with a
    // single setting.
    dc.SetMapModeStyle(wxPDF_MAPMODESTYLE_PDF);
    dc.SetMapMode(wxMM_POINTS);
    bool ok = dc.StartDoc(_("Printing ..."));

    // Start the current PDF page
    dc.StartPage();

    // Attempt to get the wxPdfDocument from the dc
    wxPdfDocument& pdf = *((wxPdfDC&) dc).GetPdfDocument();
    pdf.AddFontCJK(wxT("GB"));

    // Set the GB font
    pdf.SetFont(wxT("GB"),wxT(""),20);

    // Write translation of "Set" to PDF
    pdf.Write(30,_("Set"));

    // End the page
    dc.EndPage();
    dc.EndDoc();
Here you actively set the builtin Chinese wxPdfDocument font support. This method references the standard Chinese fonts provided by Acrobat Reader, that is, font data are not saved to the resulting PDF document.
EverythingsShiny wrote:But when I do the following I get the appropriate Chinese characters displayed on screen and on the printout but not when saving to pdf. Instead I just get "????".
This clearly indicates that the underlying font referenced by wxPdfDocument does not contain Chinese characters.
EverythingsShiny wrote:

Code: Select all

   // Same startup and end code.

    // Attempt to get the wxPdfDocument from the dc
    wxPdfDocument& pdf = *((wxPdfDC&) dc).GetPdfDocument();
    pdf.AddFontCJK(wxT("GB"));

    wxFont fontText(wxSize(0,20), wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
    dc.SetFont(fontText);

    // Draw the translated text
    dc.DrawText(_("Set"), wxPoint(0,0) /*Using appropriate coordinates*/);
Associated with the selection "GB" is the font "STSongStd-Light-Acro". The font associated with wxFONTFAMILY_SWISS is certainly not that font, but most probably "Arial" (which does not include Chinese characters). And therefore you get questionmarks in the resulting PDF.

I don't know how exactly OS X handles the character output on screen. Probably the system automatically substitutes another font (like SimSun) transparently. Unfortunately wxPdfDocument does not have such an automatic mechanism for substituting fonts. Therefore you need to explicitly set a font of which you know that it contains the required Chinese characters.

For example, for one of my international applications I supply one of the Wen Quan Yi fonts together with the application. These fonts are TrueType/OpenType Unicode fonts, which wxPdfDocument can handle.

Independent of whether you use a font like Wen Quan Yi or a certain OS X font supporting Chinese being available usually on all Chinese OS X systems, you then specify the font by using its face name.

To find out how the default Chinese font is named on OS X you max use wxFontDialog to display a list of available fonts, selecting one that supports Chinese and then GetChosenFont on the wxFontData associated with wxFontDialog. The font returned by this method could be used in a call to wxDC method SetFont, or to find out the associated face name.
EverythingsShiny wrote:How do i set a font to the dc using the "GB" format?
I haven't tested it, but maybe calling AddCJK(wxT("GB")) followed by specifying the font face name as "STSongStd-Light-Acro" for a font object used in Setfont works. Something like

Code: Select all

wxFont font(wxFontInfo(12).FaceName("STSongStd-Light-Acro"));
might work. As said I didn't test this myself, so it may or may not work. However, you should have got the idea, that you need to explicitly specify a font that supports Chinese.

Regards,

Ulrich
EverythingsShiny
In need of some credit
In need of some credit
Posts: 6
Joined: Thu Dec 04, 2014 3:10 am

Re: Chinese Characters in wxPdfDc

Post by EverythingsShiny »

Hi Ulrich,

That definitely got me on the right track. Using that font I was able to see the Chinese characters in the resulting PDF using the dc::DrawText() function. Thank you!
Post Reply