0

When printing PDF on windows, I need to choose font according to characters in the text.

I would like to use iTextSharp FontSelector, but I expect that the correct font could be different for bold and normal font. But the font selector does not have parametres for bold.

I don't understand chinese fonts too much, but I suppose that there is no bold font in simsun.ttc and the simhei.ttf could be choose for bold font instead (correct me if I am wrong). Should I choose different font for bold? And how?

        const int fontSizeforSelector = 12;
        static Font Arial;
        static Font SimplifiedArabic;
        static Font Andalus;
        static Font TraditionalArabic;
        static Font Tahoma;
        static Font Simpo;
        static Font Batang;
        static Font Simsun;
        static Font ArialUni;
        static Font Simpbdo;
        static Font Simhei;

        static iTextSharp.text.pdf.FontSelector _fontSelector = new iTextSharp.text.pdf.FontSelector();

        static MyFontSelector()
        {
            string winDir = Environment.GetEnvironmentVariable("WINDIR");//!-!
            if (winDir.IsNullOrEmpty())
                winDir = GetWindowsDirectory();

            string fontDir = winDir + "\\Fonts\\";//!-!

            Arial = TryCreateFont(fontDir, "arial.ttf");
            SimplifiedArabic = TryCreateFont(fontDir,"simpo.ttf");
            Andalus = TryCreateFont(fontDir,"andlso.ttf");
            TraditionalArabic = TryCreateFont(fontDir,"trado.ttf");
            Tahoma = TryCreateFontEmbedded(fontDir, "tahoma.ttf");
            Simpo = TryCreateFontEmbedded(fontDir, "simpo.ttc");//!-! 
            Batang = TryCreateFontEmbedded(fontDir, "batang.ttc");//!-! 
            Simsun = TryCreateFontEmbedded(fontDir, "simsun.ttc,1");//!-! 
            ArialUni = TryCreateFontEmbedded(fontDir, "arialuni.ttf");//!-! 
            Simpbdo = TryCreateFontEmbedded(fontDir, "simpbdo.ttf");//!-! 
            Simhei = TryCreateFontEmbedded(fontDir, "simhei.ttf");//!-! 

            //http://stackoverflow.com/questions/16415074/detecting-cjk-characters-in-a-string-c/16429065#16429065


            //http://www.computarat.com/files/java/Test9.java

            if (Arial != null)
                _fontSelector.AddFont(Arial);
            if (SimplifiedArabic != null)
                _fontSelector.AddFont(SimplifiedArabic);
            if (Andalus != null)
                _fontSelector.AddFont(Andalus);
            if (SimplifiedArabic != null)
                _fontSelector.AddFont(SimplifiedArabic);
            if (TraditionalArabic != null)
                _fontSelector.AddFont(TraditionalArabic);
            if (Tahoma != null)
                _fontSelector.AddFont(Tahoma);
            if (Batang != null)
                _fontSelector.AddFont(Batang);
            if (Simsun != null)
                _fontSelector.AddFont(Simsun);
            if (ArialUni != null)
                _fontSelector.AddFont(ArialUni);
            if (Simpbdo != null)
                _fontSelector.AddFont(Simpbdo);
            if (Simhei != null)
                _fontSelector.AddFont(Simhei);

        }

        private static Font TryCreateFont(string fontDir, string file)
        {
            try
            {
                return FontFactory.GetFont(fontDir + file, BaseFont.IDENTITY_H, fontSizeforSelector);
            }
            catch(Exception ex)
            {
                Trace.WriteLine(ex);                
            }
            return null;
        }

        private static Font TryCreateFontEmbedded(string fontDir, string file)
        {
            try
            {
                return FontFactory.GetFont(fontDir + file, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex);
            }
            return null;
        }

        public static iTextSharp.text.pdf.FontSelector FontSelector
        {
            get
            {
                return _fontSelector;                
            }
        }

        public static BaseFont GetBaseFont(string text)
        {
            Phrase phrase = _fontSelector.Process(text);
            return phrase.Font.GetCalculatedBaseFont(true);
        }
Tomas Kubes
  • 23,880
  • 18
  • 111
  • 148

1 Answers1

1

There are two parts in my answer:

Part 1 of my answer:

There usually aren't any bold versions of Chinese fonts, so if you need a Chinese font to be bold, you should change the render mode of the Chunk with the Chinese text to mimic a bold font.

For instance, if you have a Chunk object chunk with text in a regular font, you can do this to make the bold look as if it's bold:

chunk.setTextRenderMode(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE);

This is demonstrated in the SayPeace example of my book. By default, glyphs are shapes that are filled with color. To make them look bold, we change the render mode so that they aren't merely filled, but also stroked.

Part 2 of my answer:

You are creating a Phrase using FontSelector. This phrase object will be a collection of Chunk objects that will have different fonts. It is strange that you ask the phrase object for its font, as this will only return one font, whereas the different chunks in the phrase can have different fonts.

If I were you, I would get the different chunks of phrase, check the font that was used for each chunk, change the text render mode where necessary, and create a new phrase with these chunks.

Bruno Lowagie
  • 75,994
  • 9
  • 109
  • 165