用于粗体文本的iTextSharp.text.pdf.FontSelector

时间:2014-09-10 10:33:09

标签: c# unicode fonts itextsharp

在Windows上打印PDF时,我需要根据文本中的字符选择字体。

我想使用iTextSharp FontSelector,但我希望粗体和普通字体的正确字体可能不同。但字体选择器没有粗体参数。

我不太了解中文字体,但我认为simsun.ttc中没有粗体字体,simhei.ttf可以选择粗体字体(如果我错了,请纠正我)。我应该为粗体选择不同的字体吗?怎么样?

        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);
        }

1 个答案:

答案 0 :(得分:1)

我的答案分为两部分:

我的答案的第1部分:

通常没有任何粗体版本的中文字体,因此如果您需要中文字体为粗体,则应使用中文文本更改Chunk的渲染模式以模仿粗体字体

例如,如果您的Chunk对象chunk包含普通字体的文字,您可以这样做,使其粗体看起来像是粗体:

chunk.setTextRenderMode(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE);

这在我的书的SayPeace示例中得到了证明。默认情况下,字形是填充颜色的形状。为了使它们看起来更粗体,我们改变渲染模式,使它们不仅仅被填充,而且还被抚摸。

我的回答第2部分:

您正在使用Phrase创建FontSelector。此phrase对象将是具有不同字体的Chunk个对象的集合。奇怪的是你问phrase对象的字体,因为这只返回一种字体,而短语中的不同块可以有不同的字体。

如果我是你,我将获得phrase的不同块,检查用于每个块的字体,在必要时更改文本呈现模式,并使用这些块创建一个新短语。