为iTextSharp增加CID-keyed 字体(简称CIDFont)支持,让你在没有中文(CJK)TrueType字体(.TTF,.TTC)环境下一样完美显示中文(CJK)

CID-keyed 字体(简称CIDFont)。这种字体是Adobe公司为大字符集语言设计的,其中包含了一象形文字,由字符ID(CID)进行索引。
为使这种文字有意义,Adobe提供了一套CMap文件,从CIDFont文件中产生的PS字体名词由CIDFont和CMap共同组成,中间用两个短横线相连,举例来说,由CIDFont`Munhwa-Regular'生成,使用CMap`UniKS-UCS2-H'的字体就叫做:

Munhwa-Regular--UniKS-UCS2-H
Java版本的iText为了实现对CJK字体的支持需要以下两个Jar包:

http://prdownloads.sourceforge.net/itextpdf/iTextAsian.jar
http://prdownloads.sourceforge.net/itextpdf/iTextAsianCmaps.jar

可是iTextSharp如何利用这两个包的资源呢?
比如,我们如何成功执行下面这条语句:
BaseFont bf  =  BaseFont.CreateFont( " STSong-Light " , " UniGB-UCS2-H " ,BaseFont.NOT_EMBEDDED); 

经过分析iTextSharp的源代码,可以发现,如果要在iTextSharp中使用CIDFont(上面两个包中的资源),需要做如下工作(具体查看CJKFont.cs的"internal CJKFont(string fontName, string enc, bool emb)"方法):

1.LoadProperties,先将加载cjkfonts.properties,cjkencodings.properties属性

LoadProperties

2.加载所需的CMap(比如,UniGB-UCS2-H)

     internal   static   char [] ReadCMap( string  name)  {
        Stream istr 
= null;
        
try {
            name 
= name + ".cmap";
            istr 
= GetResourceStream(RESOURCE_PATH + name);
            
char[] c = new char[0x10000];
            
for (int k = 0; k < 0x10000++k)
                c[k] 
= (char)((istr.ReadByte() << 8+ istr.ReadByte());
            
return c;
        }

        
catch {
            
// empty on purpose
        }

        
finally {
            
try{istr.Close();}catch{}
        }


        
return null;
    }

3.读取字体信息(比如,STSong-Light)
     internal   static  Hashtable ReadFontProperties(String name)  {
        
try {
            name 
+= ".properties";
            Stream isp 
= GetResourceStream(RESOURCE_PATH + name);
            Properties p 
= new Properties();
            p.Load(isp);
            isp.Close();
            IntHashtable W 
= CreateMetric(p["W"]);
            p.Remove(
"W");
            IntHashtable W2 
= CreateMetric(p["W2"]);
            p.Remove(
"W2");
            Hashtable map 
= new Hashtable();
            
foreach (string key in p) {
                map[key] 
= p[key];
            }

            map[
"W"= W;
            map[
"W2"= W2;
            
return map;
        }

        
catch {
            
// empty on purpose
        }

        
return null;
    }


不知道大家有没有注意,上面三个方法(函数)都是从Embeded Resource(嵌入资源)里加载的,而iTextSharp的资源文件里并没有上面两个Jar包中的资源(只有一些AFM的字体资源),那我们接下来要做的事情就是把CIDFont和CMAP文件嵌入到iTextSharp,但是该放在那个目录呢,自然是RESOURCE_PATH常量所指的地方了,看下RESOURCE_PATH的定义(在BaseFont.cs):
        /** The path to the font resources. */   
        public const string RESOURCE_PATH = "iTextSharp.text.pdf.fonts.";
下面该怎么做,也许不用我说了吧(稍微提醒下,这些文件需以资源嵌入的方式加入iTextSharp?

下面附上简单的利用代码:
 1 using  System;
 2 using  iTextSharp.text;
 3 using  iTextSharp.text.pdf;
 4 using  System.IO;
 5
 6 namespace  cjk
 7 {
 8    /// <summary>
 9    /// CIDFont Demo 的摘要说明。
10    /// </summary>

11    public class CIDFontDemo
12    {
13        /// <summary>
14        /// 应用程序的主入口点。
15        /// </summary>

16        [STAThread]
17        static void Main(string[] args)
18        {
19            Console.WriteLine("Japanese characters.");
20
21            Document document = new Document();
22            Document.Compress = false;
23            try 
24            {
25                PdfWriter.GetInstance(document, new FileStream(@"E:\java\Japanese.pdf",FileMode.Create));
26                document.Open();
27
28                BaseFont bf = BaseFont.CreateFont("STSong-Light","UniGB-UCS2-H",BaseFont.NOT_EMBEDDED); 
29                
30                Font font1=new Font(bf,12,Font.NORMAL);
31                document.Add(new Paragraph("顽石",font1));
32            }

33            catch (Exception ee)
34            {
35                Console.WriteLine(ee.Message);
36            }

37            document.Close();
38        }

39    }

40}

41

你可能感兴趣的:(itext)