@@ -0,0 +1,13 | |||||
|
1 | 1.00 Added view template functionality | |||
|
2 | 1.10 Added Chinese support | |||
|
3 | 1.11 Added Japanese support | |||
|
4 | 1.12 Added Korean support | |||
|
5 | 1.13 Updated to fpdf.rb 1.53d. | |||
|
6 | Added makefont and fpdf_eps. | |||
|
7 | Handle \n at the beginning of a string in MultiCell. | |||
|
8 | Tried to fix clipping issue in MultiCell - still needs some work. | |||
|
9 | 1.14 2006-09-26 | |||
|
10 | * Added support for @options_for_rfpdf hash for configuration: | |||
|
11 | * Added :filename option in this hash | |||
|
12 | If you're using the same settings for @options_for_rfpdf often, you might want to | |||
|
13 | put your assignment in a before_filter (perhaps overriding :filename, etc in your actions). |
@@ -0,0 +1,20 | |||||
|
1 | Copyright (c) 2006 4ssoM LLC <www.4ssoM.com> | |||
|
2 | ||||
|
3 | Permission is hereby granted, free of charge, to any person obtaining | |||
|
4 | a copy of this software and associated documentation files (the | |||
|
5 | "Software"), to deal in the Software without restriction, including | |||
|
6 | without limitation the rights to use, copy, modify, merge, publish, | |||
|
7 | distribute, sublicense, and/or sell copies of the Software, and to | |||
|
8 | permit persons to whom the Software is furnished to do so, subject to | |||
|
9 | the following conditions: | |||
|
10 | ||||
|
11 | The above copyright notice and this permission notice shall be | |||
|
12 | included in all copies or substantial portions of the Software. | |||
|
13 | ||||
|
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |||
|
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||
|
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOa AND | |||
|
17 | NONINFRINGEMENT. IN NO EVENT SaALL THE AUTHORS OR COPYRIGHT HOLDERS BE | |||
|
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | |||
|
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |||
|
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. No newline at end of file |
@@ -0,0 +1,99 | |||||
|
1 | = RFPDF Template Plugin | |||
|
2 | ||||
|
3 | A template plugin allowing the inclusion of ERB-enabled RFPDF template files. | |||
|
4 | ||||
|
5 | == Example .rb method Usage | |||
|
6 | ||||
|
7 | In the controller, something like: | |||
|
8 | ||||
|
9 | def mypdf | |||
|
10 | pdf = FPDF.new() | |||
|
11 | ||||
|
12 | # | |||
|
13 | # Chinese | |||
|
14 | # | |||
|
15 | pdf.extend(PDF_Chinese) | |||
|
16 | pdf.AddPage | |||
|
17 | pdf.AddBig5Font | |||
|
18 | pdf.SetFont('Big5','',18) | |||
|
19 | pdf.Write(5, '²{®É®ð·Å 18 C Àã«× 83 %') | |||
|
20 | icBig5 = Iconv.new('Big5', 'UTF-8') | |||
|
21 | pdf.Write(15, icBig5.iconv("宋体 should be working")) | |||
|
22 | send_data pdf.Output, :filename => "something.pdf", :type => "application/pdf" | |||
|
23 | end | |||
|
24 | ||||
|
25 | == Example .rfdf Usage | |||
|
26 | ||||
|
27 | In the controller, something like: | |||
|
28 | ||||
|
29 | def mypdf | |||
|
30 | @options_for_rfpdf ||= {} | |||
|
31 | @options_for_rfpdf[:file_name] = "nice_looking.pdf" | |||
|
32 | end | |||
|
33 | ||||
|
34 | In the layout (make sure this is the only item in the layout): | |||
|
35 | <%= @content_for_layout %> | |||
|
36 | ||||
|
37 | In the view (mypdf.rfpdf): | |||
|
38 | ||||
|
39 | <% | |||
|
40 | pdf = FPDF.new() | |||
|
41 | # | |||
|
42 | # Chinese | |||
|
43 | # | |||
|
44 | pdf.extend(PDF_Chinese) | |||
|
45 | pdf.AddPage | |||
|
46 | pdf.AddBig5Font | |||
|
47 | pdf.SetFont('Big5','',18) | |||
|
48 | pdf.Write(5, '²{®É®ð·Å 18 C Àã«× 83 %') | |||
|
49 | icBig5 = Iconv.new('Big5', 'UTF-8') | |||
|
50 | pdf.Write(15, icBig5.iconv("宋体 should be working")) | |||
|
51 | ||||
|
52 | # | |||
|
53 | # Japanese | |||
|
54 | # | |||
|
55 | pdf.extend(PDF_Japanese) | |||
|
56 | pdf.AddSJISFont(); | |||
|
57 | pdf.AddPage(); | |||
|
58 | pdf.SetFont('SJIS','',18); | |||
|
59 | pdf.Write(5,'9ÉñåéÇÃåˆäJÉeÉXÉgÇåoǃPHP 3.0ÇÕ1998îN6åéÇ…åˆéÆÇ…ÉäÉäÅ[ÉXÇ≥ÇÍNjǵÇΩÅB'); | |||
|
60 | icSJIS = Iconv.new('SJIS', 'UTF-8') | |||
|
61 | pdf.Write(15, icSJIS.iconv("これはテキストである should be working")) | |||
|
62 | ||||
|
63 | # | |||
|
64 | # Korean | |||
|
65 | # | |||
|
66 | pdf.extend(PDF_Korean) | |||
|
67 | pdf.AddUHCFont(); | |||
|
68 | pdf.AddPage(); | |||
|
69 | pdf.SetFont('UHC','',18); | |||
|
70 | pdf.Write(5,'PHP 3.0Àº 1998³â 6¿ù¿¡ °ø½ÄÀûÀ¸·Î ¸±¸®ÁîµÇ¾ú´Ù. °ø°³ÀûÀÎ Å×½ºÆ® ÀÌÈľà 9°³¿ù¸¸À̾ú´Ù.'); | |||
|
71 | icUHC = Iconv.new('UHC', 'UTF-8') | |||
|
72 | pdf.Write(15, icUHC.iconv("이것은 원본 이다")) | |||
|
73 | ||||
|
74 | # | |||
|
75 | # English | |||
|
76 | # | |||
|
77 | pdf.AddPage(); | |||
|
78 | pdf.SetFont('Arial', '', 10) | |||
|
79 | pdf.Write(5, "should be working") | |||
|
80 | %> | |||
|
81 | <%= pdf.Output() %> | |||
|
82 | ||||
|
83 | ||||
|
84 | == Configuring | |||
|
85 | ||||
|
86 | You can configure Rfpdf by using an @options_for_rfpdf hash in your controllers. | |||
|
87 | ||||
|
88 | Here are a few options: | |||
|
89 | ||||
|
90 | :filename (default: action_name.pdf) | |||
|
91 | Filename of PDF to generate | |||
|
92 | ||||
|
93 | Note: If you're using the same settings for @options_for_rfpdf often, you might want to | |||
|
94 | put your assignment in a before_filter (perhaps overriding :filename, etc in your actions). | |||
|
95 | ||||
|
96 | == Problems | |||
|
97 | ||||
|
98 | Layouts and partials are currently not supported; just need | |||
|
99 | to wrap the PDF generation differently. |
@@ -0,0 +1,3 | |||||
|
1 | require 'rfpdf' | |||
|
2 | ||||
|
3 | ActionView::Base::register_template_handler 'rfpdf', RFPDF::View No newline at end of file |
@@ -0,0 +1,31 | |||||
|
1 | # Copyright (c) 2006 4ssoM LLC <www.4ssoM.com> | |||
|
2 | # | |||
|
3 | # The MIT License | |||
|
4 | # | |||
|
5 | # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
|
6 | # of this software and associated documentation files (the "Software"), to deal | |||
|
7 | # in the Software without restriction, including without limitation the rights | |||
|
8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||
|
9 | # copies of the Software, and to permit persons to whom the Software is | |||
|
10 | # furnished to do so, subject to the following conditions: | |||
|
11 | # | |||
|
12 | # The above copyright notice and this permission notice shall be included in | |||
|
13 | # all copies or substantial portions of the Software. | |||
|
14 | # | |||
|
15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
|
16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
|
17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
|
18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
|
19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||
|
20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |||
|
21 | # THE SOFTWARE. | |||
|
22 | ||||
|
23 | $LOAD_PATH.unshift(File.dirname(__FILE__)) | |||
|
24 | ||||
|
25 | require 'rfpdf/errors' | |||
|
26 | require 'rfpdf/view' | |||
|
27 | require 'rfpdf/fpdf' | |||
|
28 | require 'rfpdf/rfpdf' | |||
|
29 | require 'rfpdf/chinese' | |||
|
30 | require 'rfpdf/japanese' | |||
|
31 | require 'rfpdf/korean' |
@@ -0,0 +1,99 | |||||
|
1 | # Translation of the bookmark class from the PHP FPDF script from Olivier Plathey | |||
|
2 | # Translated by Sylvain Lafleur and ?? with the help of Brian Ollenberger | |||
|
3 | # | |||
|
4 | # First added in 1.53b | |||
|
5 | # | |||
|
6 | # Usage is as follows: | |||
|
7 | # | |||
|
8 | # require 'fpdf' | |||
|
9 | # require 'bookmark' | |||
|
10 | # pdf = FPDF.new | |||
|
11 | # pdf.extend(PDF_Bookmark) | |||
|
12 | # | |||
|
13 | # This allows it to be combined with other extensions, such as the Chinese | |||
|
14 | # module. | |||
|
15 | ||||
|
16 | module PDF_Bookmark | |||
|
17 | def PDF_Bookmark.extend_object(o) | |||
|
18 | o.instance_eval('@outlines,@OutlineRoot=[],0') | |||
|
19 | super(o) | |||
|
20 | end | |||
|
21 | ||||
|
22 | def Bookmark(txt,level=0,y=0) | |||
|
23 | y=self.GetY() if y==-1 | |||
|
24 | @outlines.push({'t'=>txt,'l'=>level,'y'=>y,'p'=>self.PageNo()}) | |||
|
25 | end | |||
|
26 | ||||
|
27 | def putbookmarks | |||
|
28 | @nb=@outlines.size | |||
|
29 | return if @nb==0 | |||
|
30 | lru=[] | |||
|
31 | level=0 | |||
|
32 | @outlines.each_index do |i| | |||
|
33 | o=@outlines[i] | |||
|
34 | if o['l']>0 | |||
|
35 | parent=lru[o['l']-1] | |||
|
36 | # Set parent and last pointers | |||
|
37 | @outlines[i]['parent']=parent | |||
|
38 | @outlines[parent]['last']=i | |||
|
39 | if o['l']>level | |||
|
40 | # Level increasing: set first pointer | |||
|
41 | @outlines[parent]['first']=i | |||
|
42 | end | |||
|
43 | else | |||
|
44 | @outlines[i]['parent']=@nb | |||
|
45 | end | |||
|
46 | if o['l']<=level and i>0 | |||
|
47 | # Set prev and next pointers | |||
|
48 | prev=lru[o['l']] | |||
|
49 | @outlines[prev]['next']=i | |||
|
50 | @outlines[i]['prev']=prev | |||
|
51 | end | |||
|
52 | lru[o['l']]=i | |||
|
53 | level=o['l'] | |||
|
54 | end | |||
|
55 | # Outline items | |||
|
56 | n=@n+1 | |||
|
57 | @outlines.each_index do |i| | |||
|
58 | o=@outlines[i] | |||
|
59 | newobj | |||
|
60 | out('<</Title '+(textstring(o['t']))) | |||
|
61 | out('/Parent '+(n+o['parent']).to_s+' 0 R') | |||
|
62 | if o['prev'] | |||
|
63 | out('/Prev '+(n+o['prev']).to_s+' 0 R') | |||
|
64 | end | |||
|
65 | if o['next'] | |||
|
66 | out('/Next '+(n+o['next']).to_s+' 0 R') | |||
|
67 | end | |||
|
68 | if o['first'] | |||
|
69 | out('/First '+(n+o['first']).to_s+' 0 R') | |||
|
70 | end | |||
|
71 | if o['last'] | |||
|
72 | out('/Last '+(n+o['last']).to_s+' 0 R') | |||
|
73 | end | |||
|
74 | out(sprintf('/Dest [%d 0 R /XYZ 0 %.2f | |||
|
75 | null]',1+2*o['p'],(@h-o['y'])*@k)) | |||
|
76 | out('/Count 0>>') | |||
|
77 | out('endobj') | |||
|
78 | end | |||
|
79 | # Outline root | |||
|
80 | newobj | |||
|
81 | @OutlineRoot=@n | |||
|
82 | out('<</Type /Outlines /First '+n.to_s+' 0 R') | |||
|
83 | out('/Last '+(n+lru[0]).to_s+' 0 R>>') | |||
|
84 | out('endobj') | |||
|
85 | end | |||
|
86 | ||||
|
87 | def putresources | |||
|
88 | super | |||
|
89 | putbookmarks | |||
|
90 | end | |||
|
91 | ||||
|
92 | def putcatalog | |||
|
93 | super | |||
|
94 | if not @outlines.empty? | |||
|
95 | out('/Outlines '+@OutlineRoot.to_s+' 0 R') | |||
|
96 | out('/PageMode /UseOutlines') | |||
|
97 | end | |||
|
98 | end | |||
|
99 | end |
@@ -0,0 +1,473 | |||||
|
1 | # Copyright (c) 2006 4ssoM LLC <www.4ssoM.com> | |||
|
2 | # 1.12 contributed by Ed Moss. | |||
|
3 | # | |||
|
4 | # The MIT License | |||
|
5 | # | |||
|
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
|
7 | # of this software and associated documentation files (the "Software"), to deal | |||
|
8 | # in the Software without restriction, including without limitation the rights | |||
|
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||
|
10 | # copies of the Software, and to permit persons to whom the Software is | |||
|
11 | # furnished to do so, subject to the following conditions: | |||
|
12 | # | |||
|
13 | # The above copyright notice and this permission notice shall be included in | |||
|
14 | # all copies or substantial portions of the Software. | |||
|
15 | # | |||
|
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
|
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
|
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
|
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
|
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||
|
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |||
|
22 | # THE SOFTWARE. | |||
|
23 | # | |||
|
24 | # This is direct port of chinese.php | |||
|
25 | # | |||
|
26 | # Chinese PDF support. | |||
|
27 | # | |||
|
28 | # Usage is as follows: | |||
|
29 | # | |||
|
30 | # require 'fpdf' | |||
|
31 | # require 'chinese' | |||
|
32 | # pdf = FPDF.new | |||
|
33 | # pdf.extend(PDF_Chinese) | |||
|
34 | # | |||
|
35 | # This allows it to be combined with other extensions, such as the bookmark | |||
|
36 | # module. | |||
|
37 | ||||
|
38 | module PDF_Chinese | |||
|
39 | ||||
|
40 | Big5_widths={' '=>250,'!'=>250,'"'=>408,'#'=>668,''=>490,'%'=>875,'&'=>698,'\''=>250, | |||
|
41 | '('=>240,')'=>240,'*'=>417,'+'=>667,','=>250,'-'=>313,'.'=>250,'/'=>520,'0'=>500,'1'=>500, | |||
|
42 | '2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>250,''=>250, | |||
|
43 | '<'=>667,'='=>667,'>'=>667,'?'=>396,'@'=>921,'A'=>677,'B'=>615,'C'=>719,'D'=>760,'E'=>625, | |||
|
44 | 'F'=>552,'G'=>771,'H'=>802,'I'=>354,'J'=>354,'K'=>781,'L'=>604,'M'=>927,'N'=>750,'O'=>823, | |||
|
45 | 'P'=>563,'Q'=>823,'R'=>729,'S'=>542,'T'=>698,'U'=>771,'V'=>729,'W'=>948,'X'=>771,'Y'=>677, | |||
|
46 | 'Z'=>635,'['=>344,'\\'=>520,']'=>344,'^'=>469,'_'=>500,'`'=>250,'a'=>469,'b'=>521,'c'=>427, | |||
|
47 | 'd'=>521,'e'=>438,'f'=>271,'g'=>469,'h'=>531,'i'=>250,'j'=>250,'k'=>458,'l'=>240,'m'=>802, | |||
|
48 | 'n'=>531,'o'=>500,'p'=>521,'q'=>521,'r'=>365,'s'=>333,'t'=>292,'u'=>521,'v'=>458,'w'=>677, | |||
|
49 | 'x'=>479,'y'=>458,'z'=>427,'{'=>480,'|'=>496,'end'=>480,'~'=>667} | |||
|
50 | ||||
|
51 | GB_widths={' '=>207,'!'=>270,'"'=>342,'#'=>467,''=>462,'%'=>797,'&'=>710,'\''=>239, | |||
|
52 | '('=>374,')'=>374,'*'=>423,'+'=>605,','=>238,'-'=>375,'.'=>238,'/'=>334,'0'=>462,'1'=>462, | |||
|
53 | '2'=>462,'3'=>462,'4'=>462,'5'=>462,'6'=>462,'7'=>462,'8'=>462,'9'=>462,':'=>238,''=>238, | |||
|
54 | '<'=>605,'='=>605,'>'=>605,'?'=>344,'@'=>748,'A'=>684,'B'=>560,'C'=>695,'D'=>739,'E'=>563, | |||
|
55 | 'F'=>511,'G'=>729,'H'=>793,'I'=>318,'J'=>312,'K'=>666,'L'=>526,'M'=>896,'N'=>758,'O'=>772, | |||
|
56 | 'P'=>544,'Q'=>772,'R'=>628,'S'=>465,'T'=>607,'U'=>753,'V'=>711,'W'=>972,'X'=>647,'Y'=>620, | |||
|
57 | 'Z'=>607,'['=>374,'\\'=>333,']'=>374,'^'=>606,'_'=>500,'`'=>239,'a'=>417,'b'=>503,'c'=>427, | |||
|
58 | 'd'=>529,'e'=>415,'f'=>264,'g'=>444,'h'=>518,'i'=>241,'j'=>230,'k'=>495,'l'=>228,'m'=>793, | |||
|
59 | 'n'=>527,'o'=>524,'p'=>524,'q'=>504,'r'=>338,'s'=>336,'t'=>277,'u'=>517,'v'=>450,'w'=>652, | |||
|
60 | 'x'=>466,'y'=>452,'z'=>407,'{'=>370,'|'=>258,'end'=>370,'~'=>605} | |||
|
61 | ||||
|
62 | def AddCIDFont(family,style,name,cw,cMap,registry) | |||
|
63 | #ActionController::Base::logger.debug registry.to_a.join(":").to_s | |||
|
64 | fontkey=family.downcase+style.upcase | |||
|
65 | unless @fonts[fontkey].nil? | |||
|
66 | Error("Font already added: family style") | |||
|
67 | end | |||
|
68 | i=@fonts.length+1 | |||
|
69 | name=name.gsub(' ','') | |||
|
70 | @fonts[fontkey]={'i'=>i,'type'=>'Type0','name'=>name,'up'=>-130,'ut'=>40,'cw'=>cw, 'CMap'=>cMap,'registry'=>registry} | |||
|
71 | end | |||
|
72 | ||||
|
73 | def AddCIDFonts(family,name,cw,cMap,registry) | |||
|
74 | AddCIDFont(family,'',name,cw,cMap,registry) | |||
|
75 | AddCIDFont(family,'B',name+',Bold',cw,cMap,registry) | |||
|
76 | AddCIDFont(family,'I',name+',Italic',cw,cMap,registry) | |||
|
77 | AddCIDFont(family,'BI',name+',BoldItalic',cw,cMap,registry) | |||
|
78 | end | |||
|
79 | ||||
|
80 | def AddBig5Font(family='Big5',name='MSungStd-Light-Acro') | |||
|
81 | #Add Big5 font with proportional Latin | |||
|
82 | cw=Big5_widths | |||
|
83 | cMap='ETenms-B5-H' | |||
|
84 | registry={'ordering'=>'CNS1','supplement'=>0} | |||
|
85 | #ActionController::Base::logger.debug registry.to_a.join(":").to_s | |||
|
86 | AddCIDFonts(family,name,cw,cMap,registry) | |||
|
87 | end | |||
|
88 | ||||
|
89 | def AddBig5hwFont(family='Big5-hw',name='MSungStd-Light-Acro') | |||
|
90 | #Add Big5 font with half-witdh Latin | |||
|
91 | cw = {} | |||
|
92 | 32.upto(126) do |i| | |||
|
93 | cw[i.chr]=500 | |||
|
94 | end | |||
|
95 | cMap='ETen-B5-H' | |||
|
96 | registry={'ordering'=>'CNS1','supplement'=>0} | |||
|
97 | AddCIDFonts(family,name,cw,cMap,registry) | |||
|
98 | end | |||
|
99 | ||||
|
100 | def AddGBFont(family='GB',name='STSongStd-Light-Acro') | |||
|
101 | #Add GB font with proportional Latin | |||
|
102 | cw=GB_widths | |||
|
103 | cMap='GBKp-EUC-H' | |||
|
104 | registry={'ordering'=>'GB1','supplement'=>2} | |||
|
105 | AddCIDFonts(family,name,cw,cMap,registry) | |||
|
106 | end | |||
|
107 | ||||
|
108 | def AddGBhwFont(family='GB-hw',name='STSongStd-Light-Acro') | |||
|
109 | #Add GB font with half-width Latin | |||
|
110 | 32.upto(126) do |i| | |||
|
111 | cw[i.chr]=500 | |||
|
112 | end | |||
|
113 | cMap='GBK-EUC-H' | |||
|
114 | registry={'ordering'=>'GB1','supplement'=>2} | |||
|
115 | AddCIDFonts(family,name,cw,cMap,registry) | |||
|
116 | end | |||
|
117 | ||||
|
118 | def GetStringWidth(s) | |||
|
119 | if(@CurrentFont['type']=='Type0') | |||
|
120 | return GetMBStringWidth(s) | |||
|
121 | else | |||
|
122 | return super(s) | |||
|
123 | end | |||
|
124 | end | |||
|
125 | ||||
|
126 | def GetMBStringWidth(s) | |||
|
127 | #Multi-byte version of GetStringWidth() | |||
|
128 | l=0 | |||
|
129 | cw=@CurrentFont['cw'] | |||
|
130 | nb=s.length | |||
|
131 | i=0 | |||
|
132 | while(i<nb) | |||
|
133 | c=s[i] | |||
|
134 | if(c<128) | |||
|
135 | l+=cw[c.chr] | |||
|
136 | i+=1 | |||
|
137 | else | |||
|
138 | l+=1000 | |||
|
139 | i+=2 | |||
|
140 | end | |||
|
141 | end | |||
|
142 | return l*@FontSize/1000 | |||
|
143 | end | |||
|
144 | ||||
|
145 | def MultiCell(w,h,txt,border=0,align='L',fill=0) | |||
|
146 | if(@CurrentFont['type']=='Type0') | |||
|
147 | MBMultiCell(w,h,txt,border,align,fill) | |||
|
148 | else | |||
|
149 | super(w,h,txt,border,align,fill) | |||
|
150 | end | |||
|
151 | end | |||
|
152 | ||||
|
153 | def MBMultiCell(w,h,txt,border=0,align='L',fill=0) | |||
|
154 | #Multi-byte version of MultiCell() | |||
|
155 | cw=@CurrentFont['cw'] | |||
|
156 | if(w==0) | |||
|
157 | w=@w-@rMargin-@x | |||
|
158 | end | |||
|
159 | wmax=(w-2*@cMargin)*1000/@FontSize | |||
|
160 | s=txt.gsub("\r",'') | |||
|
161 | nb=s.length | |||
|
162 | if(nb>0 and s[nb-1]=="\n") | |||
|
163 | nb-=1 | |||
|
164 | end | |||
|
165 | b=0 | |||
|
166 | if(border) | |||
|
167 | if(border==1) | |||
|
168 | border='LTRB' | |||
|
169 | b='LRT' | |||
|
170 | b2='LR' | |||
|
171 | else | |||
|
172 | b2='' | |||
|
173 | if(border.index('L').nil?) | |||
|
174 | b2+='L' | |||
|
175 | end | |||
|
176 | if(border.index('R').nil?) | |||
|
177 | b2+='R' | |||
|
178 | end | |||
|
179 | b=border.index('T').nil? ? b2+'T' : b2 | |||
|
180 | end | |||
|
181 | end | |||
|
182 | sep=-1 | |||
|
183 | i=0 | |||
|
184 | j=0 | |||
|
185 | l=0 | |||
|
186 | nl=1 | |||
|
187 | while(i<nb) | |||
|
188 | #Get next character | |||
|
189 | c=s[i] | |||
|
190 | #Check if ASCII or MB | |||
|
191 | ascii=(c<128) | |||
|
192 | if(c=="\n") | |||
|
193 | #Explicit line break | |||
|
194 | Cell(w,h,s[j,i-j],b,2,align,fill) | |||
|
195 | i+=1 | |||
|
196 | sep=-1 | |||
|
197 | j=i | |||
|
198 | l=0 | |||
|
199 | nl+=1 | |||
|
200 | if(border and nl==2) | |||
|
201 | b=b2 | |||
|
202 | end | |||
|
203 | next | |||
|
204 | end | |||
|
205 | if(!ascii) | |||
|
206 | sep=i | |||
|
207 | ls=l | |||
|
208 | elsif(c==' ') | |||
|
209 | sep=i | |||
|
210 | ls=l | |||
|
211 | end | |||
|
212 | l+=ascii ? cw[c.chr] : 1000 | |||
|
213 | if(l>wmax) | |||
|
214 | #Automatic line break | |||
|
215 | if(sep==-1 or i==j) | |||
|
216 | if(i==j) | |||
|
217 | i+=ascii ? 1 : 2 | |||
|
218 | end | |||
|
219 | Cell(w,h,s[j,i-j],b,2,align,fill) | |||
|
220 | else | |||
|
221 | Cell(w,h,s[j,sep-j],b,2,align,fill) | |||
|
222 | i=(s[sep]==' ') ? sep+1 : sep | |||
|
223 | end | |||
|
224 | sep=-1 | |||
|
225 | j=i | |||
|
226 | l=0 | |||
|
227 | # nl+=1 | |||
|
228 | if(border and nl==2) | |||
|
229 | b=b2 | |||
|
230 | end | |||
|
231 | else | |||
|
232 | i+=ascii ? 1 : 2 | |||
|
233 | end | |||
|
234 | end | |||
|
235 | #Last chunk | |||
|
236 | if(border and not border.index('B').nil?) | |||
|
237 | b+='B' | |||
|
238 | end | |||
|
239 | Cell(w,h,s[j,i-j],b,2,align,fill) | |||
|
240 | @x=@lMargin | |||
|
241 | end | |||
|
242 | ||||
|
243 | def Write(h,txt,link='') | |||
|
244 | if(@CurrentFont['type']=='Type0') | |||
|
245 | MBWrite(h,txt,link) | |||
|
246 | else | |||
|
247 | super(h,txt,link) | |||
|
248 | end | |||
|
249 | end | |||
|
250 | ||||
|
251 | def MBWrite(h,txt,link) | |||
|
252 | #Multi-byte version of Write() | |||
|
253 | cw=@CurrentFont['cw'] | |||
|
254 | w=@w-@rMargin-@x | |||
|
255 | wmax=(w-2*@cMargin)*1000/@FontSize | |||
|
256 | s=txt.gsub("\r",'') | |||
|
257 | nb=s.length | |||
|
258 | sep=-1 | |||
|
259 | i=0 | |||
|
260 | j=0 | |||
|
261 | l=0 | |||
|
262 | nl=1 | |||
|
263 | while(i<nb) | |||
|
264 | #Get next character | |||
|
265 | c=s[i] | |||
|
266 | #Check if ASCII or MB | |||
|
267 | ascii=(c<128) | |||
|
268 | if(c=="\n") | |||
|
269 | #Explicit line break | |||
|
270 | Cell(w,h,s[j,i-j],0,2,'',0,link) | |||
|
271 | i+=1 | |||
|
272 | sep=-1 | |||
|
273 | j=i | |||
|
274 | l=0 | |||
|
275 | if(nl==1) | |||
|
276 | @x=@lMargin | |||
|
277 | w=@w-@rMargin-@x | |||
|
278 | wmax=(w-2*@cMargin)*1000/@FontSize | |||
|
279 | end | |||
|
280 | nl+=1 | |||
|
281 | next | |||
|
282 | end | |||
|
283 | if(!ascii or c==' ') | |||
|
284 | sep=i | |||
|
285 | end | |||
|
286 | l+=ascii ? cw[c.chr] : 1000 | |||
|
287 | if(l>wmax) | |||
|
288 | #Automatic line break | |||
|
289 | if(sep==-1 or i==j) | |||
|
290 | if(@x>@lMargin) | |||
|
291 | #Move to next line | |||
|
292 | @x=@lMargin | |||
|
293 | @y+=h | |||
|
294 | w=@w-@rMargin-@x | |||
|
295 | wmax=(w-2*@cMargin)*1000/@FontSize | |||
|
296 | i+=1 | |||
|
297 | nl+=1 | |||
|
298 | next | |||
|
299 | end | |||
|
300 | if(i==j) | |||
|
301 | i+=ascii ? 1 : 2 | |||
|
302 | end | |||
|
303 | Cell(w,h,s[j,i-j],0,2,'',0,link) | |||
|
304 | else | |||
|
305 | Cell(w,h,s[j,sep-j],0,2,'',0,link) | |||
|
306 | i=(s[sep]==' ') ? sep+1 : sep | |||
|
307 | end | |||
|
308 | sep=-1 | |||
|
309 | j=i | |||
|
310 | l=0 | |||
|
311 | if(nl==1) | |||
|
312 | @x=@lMargin | |||
|
313 | w=@w-@rMargin-@x | |||
|
314 | wmax=(w-2*@cMargin)*1000/@FontSize | |||
|
315 | end | |||
|
316 | nl+=1 | |||
|
317 | else | |||
|
318 | i+=ascii ? 1 : 2 | |||
|
319 | end | |||
|
320 | end | |||
|
321 | #Last chunk | |||
|
322 | if(i!=j) | |||
|
323 | Cell(l/1000*@FontSize,h,s[j,i-j],0,0,'',0,link) | |||
|
324 | end | |||
|
325 | end | |||
|
326 | ||||
|
327 | private | |||
|
328 | ||||
|
329 | def putfonts() | |||
|
330 | nf=@n | |||
|
331 | @diffs.each do |diff| | |||
|
332 | #Encodings | |||
|
333 | newobj() | |||
|
334 | out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['+diff+']>>') | |||
|
335 | out('endobj') | |||
|
336 | end | |||
|
337 | # mqr=get_magic_quotes_runtime() | |||
|
338 | # set_magic_quotes_runtime(0) | |||
|
339 | @FontFiles.each_pair do |file, info| | |||
|
340 | #Font file embedding | |||
|
341 | newobj() | |||
|
342 | @FontFiles[file]['n']=@n | |||
|
343 | if(defined('FPDF_FONTPATH')) | |||
|
344 | file=FPDF_FONTPATH+file | |||
|
345 | end | |||
|
346 | size=filesize(file) | |||
|
347 | if(!size) | |||
|
348 | Error('Font file not found') | |||
|
349 | end | |||
|
350 | out('<</Length '+size) | |||
|
351 | if(file[-2]=='.z') | |||
|
352 | out('/Filter /FlateDecode') | |||
|
353 | end | |||
|
354 | out('/Length1 '+info['length1']) | |||
|
355 | unless info['length2'].nil? | |||
|
356 | out('/Length2 '+info['length2']+' /Length3 0') | |||
|
357 | end | |||
|
358 | out('>>') | |||
|
359 | f=fopen(file,'rb') | |||
|
360 | putstream(fread(f,size)) | |||
|
361 | fclose(f) | |||
|
362 | out('endobj') | |||
|
363 | end | |||
|
364 | # | |||
|
365 | # set_magic_quotes_runtime(mqr) | |||
|
366 | # | |||
|
367 | @fonts.each_pair do |k, font| | |||
|
368 | #Font objects | |||
|
369 | newobj() | |||
|
370 | @fonts[k]['n']=@n | |||
|
371 | out('<</Type /Font') | |||
|
372 | if(font['type']=='Type0') | |||
|
373 | putType0(font) | |||
|
374 | else | |||
|
375 | name=font['name'] | |||
|
376 | out('/BaseFont /'+name) | |||
|
377 | if(font['type']=='core') | |||
|
378 | #Standard font | |||
|
379 | out('/Subtype /Type1') | |||
|
380 | if(name!='Symbol' and name!='ZapfDingbats') | |||
|
381 | out('/Encoding /WinAnsiEncoding') | |||
|
382 | end | |||
|
383 | else | |||
|
384 | #Additional font | |||
|
385 | out('/Subtype /'+font['type']) | |||
|
386 | out('/FirstChar 32') | |||
|
387 | out('/LastChar 255') | |||
|
388 | out('/Widths '+(@n+1)+' 0 R') | |||
|
389 | out('/FontDescriptor '+(@n+2)+' 0 R') | |||
|
390 | if(font['enc']) | |||
|
391 | if !font['diff'].nil? | |||
|
392 | out('/Encoding '+(nf+font['diff'])+' 0 R') | |||
|
393 | else | |||
|
394 | out('/Encoding /WinAnsiEncoding') | |||
|
395 | end | |||
|
396 | end | |||
|
397 | end | |||
|
398 | out('>>') | |||
|
399 | out('endobj') | |||
|
400 | if(font['type']!='core') | |||
|
401 | #Widths | |||
|
402 | newobj() | |||
|
403 | cw=font['cw'] | |||
|
404 | s='[' | |||
|
405 | 32.upto(255) do |i| | |||
|
406 | s+=cw[i.chr]+' ' | |||
|
407 | end | |||
|
408 | out(s+']') | |||
|
409 | out('endobj') | |||
|
410 | #Descriptor | |||
|
411 | newobj() | |||
|
412 | s='<</Type /FontDescriptor /FontName /'+name | |||
|
413 | font['desc'].each_pair do |k, v| | |||
|
414 | s+=' /'+k+' '+v | |||
|
415 | end | |||
|
416 | file=font['file'] | |||
|
417 | if(file) | |||
|
418 | s+=' /FontFile'+(font['type']=='Type1' ? '' : '2')+' '+@FontFiles[file]['n']+' 0 R' | |||
|
419 | end | |||
|
420 | out(s+'>>') | |||
|
421 | out('endobj') | |||
|
422 | end | |||
|
423 | end | |||
|
424 | end | |||
|
425 | end | |||
|
426 | ||||
|
427 | def putType0(font) | |||
|
428 | #Type0 | |||
|
429 | out('/Subtype /Type0') | |||
|
430 | out('/BaseFont /'+font['name']+'-'+font['CMap']) | |||
|
431 | out('/Encoding /'+font['CMap']) | |||
|
432 | out('/DescendantFonts ['+(@n+1).to_s+' 0 R]') | |||
|
433 | out('>>') | |||
|
434 | out('endobj') | |||
|
435 | #CIDFont | |||
|
436 | newobj() | |||
|
437 | out('<</Type /Font') | |||
|
438 | out('/Subtype /CIDFontType0') | |||
|
439 | out('/BaseFont /'+font['name']) | |||
|
440 | out('/CIDSystemInfo <</Registry '+textstring('Adobe')+' /Ordering '+textstring(font['registry']['ordering'])+' /Supplement '+font['registry']['supplement'].to_s+'>>') | |||
|
441 | out('/FontDescriptor '+(@n+1).to_s+' 0 R') | |||
|
442 | if(font['CMap']=='ETen-B5-H') | |||
|
443 | w='13648 13742 500' | |||
|
444 | elsif(font['CMap']=='GBK-EUC-H') | |||
|
445 | w='814 907 500 7716 [500]' | |||
|
446 | else | |||
|
447 | # ActionController::Base::logger.debug font['cw'].keys.sort.join(' ').to_s | |||
|
448 | # ActionController::Base::logger.debug font['cw'].values.join(' ').to_s | |||
|
449 | w='1 [' | |||
|
450 | font['cw'].keys.sort.each {|key| | |||
|
451 | w+=font['cw'][key].to_s + " " | |||
|
452 | # ActionController::Base::logger.debug key.to_s | |||
|
453 | # ActionController::Base::logger.debug font['cw'][key].to_s | |||
|
454 | } | |||
|
455 | w +=']' | |||
|
456 | end | |||
|
457 | out('/W ['+w+']>>') | |||
|
458 | out('endobj') | |||
|
459 | #Font descriptor | |||
|
460 | newobj() | |||
|
461 | out('<</Type /FontDescriptor') | |||
|
462 | out('/FontName /'+font['name']) | |||
|
463 | out('/Flags 6') | |||
|
464 | out('/FontBBox [0 -200 1000 900]') | |||
|
465 | out('/ItalicAngle 0') | |||
|
466 | out('/Ascent 800') | |||
|
467 | out('/Descent -200') | |||
|
468 | out('/CapHeight 800') | |||
|
469 | out('/StemV 50') | |||
|
470 | out('>>') | |||
|
471 | out('endobj') | |||
|
472 | end | |||
|
473 | end |
@@ -0,0 +1,4 | |||||
|
1 | module RFPDF | |||
|
2 | class GenerationError < StandardError #:nodoc: | |||
|
3 | end | |||
|
4 | end No newline at end of file |
This diff has been collapsed as it changes many lines, (1550 lines changed) Show them Hide them | |||||
@@ -0,0 +1,1550 | |||||
|
1 | # Ruby FPDF 1.53d | |||
|
2 | # FPDF 1.53 by Olivier Plathey ported to Ruby by Brian Ollenberger | |||
|
3 | # Copyright 2005 Brian Ollenberger | |||
|
4 | # Please retain this entire copyright notice. If you distribute any | |||
|
5 | # modifications, place an additional comment here that clearly indicates | |||
|
6 | # that it was modified. You may (but are not send any useful modifications that you make | |||
|
7 | # back to me at http://zeropluszero.com/software/fpdf/ | |||
|
8 | ||||
|
9 | # Bug fixes, examples, external fonts, JPEG support, and upgrade to version | |||
|
10 | # 1.53 contributed by Kim Shrier. | |||
|
11 | # | |||
|
12 | # Bookmark support contributed by Sylvain Lafleur. | |||
|
13 | # | |||
|
14 | # EPS support contributed by Thiago Jackiw, ported from the PHP version by Valentin Schmidt. | |||
|
15 | # | |||
|
16 | # Bookmarks contributed by Sylvain Lafleur. | |||
|
17 | # | |||
|
18 | # 1.53 contributed by Ed Moss | |||
|
19 | # Handle '\n' at the beginning of a string | |||
|
20 | # Bookmarks contributed by Sylvain Lafleur. | |||
|
21 | ||||
|
22 | require 'date' | |||
|
23 | require 'zlib' | |||
|
24 | ||||
|
25 | class FPDF | |||
|
26 | FPDF_VERSION = '1.53d' | |||
|
27 | ||||
|
28 | Charwidths = { | |||
|
29 | 'courier'=>[600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600], | |||
|
30 | ||||
|
31 | 'courierB'=>[600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600], | |||
|
32 | ||||
|
33 | 'courierI'=>[600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600], | |||
|
34 | ||||
|
35 | 'courierBI'=>[600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600], | |||
|
36 | ||||
|
37 | 'helvetica'=>[278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 355, 556, 556, 889, 667, 191, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 278, 278, 584, 584, 584, 556, 1015, 667, 667, 722, 722, 667, 611, 778, 722, 278, 500, 667, 556, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 278, 278, 278, 469, 556, 333, 556, 556, 500, 556, 556, 278, 556, 556, 222, 222, 500, 222, 833, 556, 556, 556, 556, 333, 500, 278, 556, 500, 722, 500, 500, 500, 334, 260, 334, 584, 350, 556, 350, 222, 556, 333, 1000, 556, 556, 333, 1000, 667, 333, 1000, 350, 611, 350, 350, 222, 222, 333, 333, 350, 556, 1000, 333, 1000, 500, 333, 944, 350, 500, 667, 278, 333, 556, 556, 556, 556, 260, 556, 333, 737, 370, 556, 584, 333, 737, 333, 400, 584, 333, 333, 333, 556, 537, 278, 333, 333, 365, 556, 834, 834, 834, 611, 667, 667, 667, 667, 667, 667, 1000, 722, 667, 667, 667, 667, 278, 278, 278, 278, 722, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611, 556, 556, 556, 556, 556, 556, 889, 500, 556, 556, 556, 556, 278, 278, 278, 278, 556, 556, 556, 556, 556, 556, 556, 584, 611, 556, 556, 556, 556, 500, 556, 500], | |||
|
38 | ||||
|
39 | 'helveticaB'=>[278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 333, 474, 556, 556, 889, 722, 238, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 333, 333, 584, 584, 584, 611, 975, 722, 722, 722, 722, 667, 611, 778, 722, 278, 556, 722, 611, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 333, 278, 333, 584, 556, 333, 556, 611, 556, 611, 556, 333, 611, 611, 278, 278, 556, 278, 889, 611, 611, 611, 611, 389, 556, 333, 611, 556, 778, 556, 556, 500, 389, 280, 389, 584, 350, 556, 350, 278, 556, 500, 1000, 556, 556, 333, 1000, 667, 333, 1000, 350, 611, 350, 350, 278, 278, 500, 500, 350, 556, 1000, 333, 1000, 556, 333, 944, 350, 500, 667, 278, 333, 556, 556, 556, 556, 280, 556, 333, 737, 370, 556, 584, 333, 737, 333, 400, 584, 333, 333, 333, 611, 556, 278, 333, 333, 365, 556, 834, 834, 834, 611, 722, 722, 722, 722, 722, 722, 1000, 722, 667, 667, 667, 667, 278, 278, 278, 278, 722, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611, 556, 556, 556, 556, 556, 556, 889, 556, 556, 556, 556, 556, 278, 278, 278, 278, 611, 611, 611, 611, 611, 611, 611, 584, 611, 611, 611, 611, 611, 556, 611, 556], | |||
|
40 | ||||
|
41 | 'helveticaI'=>[278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 355, 556, 556, 889, 667, 191, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 278, 278, 584, 584, 584, 556, 1015, 667, 667, 722, 722, 667, 611, 778, 722, 278, 500, 667, 556, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 278, 278, 278, 469, 556, 333, 556, 556, 500, 556, 556, 278, 556, 556, 222, 222, 500, 222, 833, 556, 556, 556, 556, 333, 500, 278, 556, 500, 722, 500, 500, 500, 334, 260, 334, 584, 350, 556, 350, 222, 556, 333, 1000, 556, 556, 333, 1000, 667, 333, 1000, 350, 611, 350, 350, 222, 222, 333, 333, 350, 556, 1000, 333, 1000, 500, 333, 944, 350, 500, 667, 278, 333, 556, 556, 556, 556, 260, 556, 333, 737, 370, 556, 584, 333, 737, 333, 400, 584, 333, 333, 333, 556, 537, 278, 333, 333, 365, 556, 834, 834, 834, 611, 667, 667, 667, 667, 667, 667, 1000, 722, 667, 667, 667, 667, 278, 278, 278, 278, 722, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611, 556, 556, 556, 556, 556, 556, 889, 500, 556, 556, 556, 556, 278, 278, 278, 278, 556, 556, 556, 556, 556, 556, 556, 584, 611, 556, 556, 556, 556, 500, 556, 500], | |||
|
42 | ||||
|
43 | 'helveticaBI'=>[278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 333, 474, 556, 556, 889, 722, 238, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 333, 333, 584, 584, 584, 611, 975, 722, 722, 722, 722, 667, 611, 778, 722, 278, 556, 722, 611, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 333, 278, 333, 584, 556, 333, 556, 611, 556, 611, 556, 333, 611, 611, 278, 278, 556, 278, 889, 611, 611, 611, 611, 389, 556, 333, 611, 556, 778, 556, 556, 500, 389, 280, 389, 584, 350, 556, 350, 278, 556, 500, 1000, 556, 556, 333, 1000, 667, 333, 1000, 350, 611, 350, 350, 278, 278, 500, 500, 350, 556, 1000, 333, 1000, 556, 333, 944, 350, 500, 667, 278, 333, 556, 556, 556, 556, 280, 556, 333, 737, 370, 556, 584, 333, 737, 333, 400, 584, 333, 333, 333, 611, 556, 278, 333, 333, 365, 556, 834, 834, 834, 611, 722, 722, 722, 722, 722, 722, 1000, 722, 667, 667, 667, 667, 278, 278, 278, 278, 722, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611, 556, 556, 556, 556, 556, 556, 889, 556, 556, 556, 556, 556, 278, 278, 278, 278, 611, 611, 611, 611, 611, 611, 611, 584, 611, 611, 611, 611, 611, 556, 611, 556], | |||
|
44 | ||||
|
45 | 'times'=>[250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 333, 408, 500, 500, 833, 778, 180, 333, 333, 500, 564, 250, 333, 250, 278, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 278, 564, 564, 564, 444, 921, 722, 667, 667, 722, 611, 556, 722, 722, 333, 389, 722, 611, 889, 722, 722, 556, 722, 667, 556, 611, 722, 722, 944, 722, 722, 611, 333, 278, 333, 469, 500, 333, 444, 500, 444, 500, 444, 333, 500, 500, 278, 278, 500, 278, 778, 500, 500, 500, 500, 333, 389, 278, 500, 500, 722, 500, 500, 444, 480, 200, 480, 541, 350, 500, 350, 333, 500, 444, 1000, 500, 500, 333, 1000, 556, 333, 889, 350, 611, 350, 350, 333, 333, 444, 444, 350, 500, 1000, 333, 980, 389, 333, 722, 350, 444, 722, 250, 333, 500, 500, 500, 500, 200, 500, 333, 760, 276, 500, 564, 333, 760, 333, 400, 564, 300, 300, 333, 500, 453, 250, 333, 300, 310, 500, 750, 750, 750, 444, 722, 722, 722, 722, 722, 722, 889, 667, 611, 611, 611, 611, 333, 333, 333, 333, 722, 722, 722, 722, 722, 722, 722, 564, 722, 722, 722, 722, 722, 722, 556, 500, 444, 444, 444, 444, 444, 444, 667, 444, 444, 444, 444, 444, 278, 278, 278, 278, 500, 500, 500, 500, 500, 500, 500, 564, 500, 500, 500, 500, 500, 500, 500, 500], | |||
|
46 | ||||
|
47 | 'timesB'=>[250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 333, 555, 500, 500, 1000, 833, 278, 333, 333, 500, 570, 250, 333, 250, 278, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 333, 570, 570, 570, 500, 930, 722, 667, 722, 722, 667, 611, 778, 778, 389, 500, 778, 667, 944, 722, 778, 611, 778, 722, 556, 667, 722, 722, 1000, 722, 722, 667, 333, 278, 333, 581, 500, 333, 500, 556, 444, 556, 444, 333, 500, 556, 278, 333, 556, 278, 833, 556, 500, 556, 556, 444, 389, 333, 556, 500, 722, 500, 500, 444, 394, 220, 394, 520, 350, 500, 350, 333, 500, 500, 1000, 500, 500, 333, 1000, 556, 333, 1000, 350, 667, 350, 350, 333, 333, 500, 500, 350, 500, 1000, 333, 1000, 389, 333, 722, 350, 444, 722, 250, 333, 500, 500, 500, 500, 220, 500, 333, 747, 300, 500, 570, 333, 747, 333, 400, 570, 300, 300, 333, 556, 540, 250, 333, 300, 330, 500, 750, 750, 750, 500, 722, 722, 722, 722, 722, 722, 1000, 722, 667, 667, 667, 667, 389, 389, 389, 389, 722, 722, 778, 778, 778, 778, 778, 570, 778, 722, 722, 722, 722, 722, 611, 556, 500, 500, 500, 500, 500, 500, 722, 444, 444, 444, 444, 444, 278, 278, 278, 278, 500, 556, 500, 500, 500, 500, 500, 570, 500, 556, 556, 556, 556, 500, 556, 500], | |||
|
48 | ||||
|
49 | 'timesI'=>[250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 333, 420, 500, 500, 833, 778, 214, 333, 333, 500, 675, 250, 333, 250, 278, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 333, 675, 675, 675, 500, 920, 611, 611, 667, 722, 611, 611, 722, 722, 333, 444, 667, 556, 833, 667, 722, 611, 722, 611, 500, 556, 722, 611, 833, 611, 556, 556, 389, 278, 389, 422, 500, 333, 500, 500, 444, 500, 444, 278, 500, 500, 278, 278, 444, 278, 722, 500, 500, 500, 500, 389, 389, 278, 500, 444, 667, 444, 444, 389, 400, 275, 400, 541, 350, 500, 350, 333, 500, 556, 889, 500, 500, 333, 1000, 500, 333, 944, 350, 556, 350, 350, 333, 333, 556, 556, 350, 500, 889, 333, 980, 389, 333, 667, 350, 389, 556, 250, 389, 500, 500, 500, 500, 275, 500, 333, 760, 276, 500, 675, 333, 760, 333, 400, 675, 300, 300, 333, 500, 523, 250, 333, 300, 310, 500, 750, 750, 750, 500, 611, 611, 611, 611, 611, 611, 889, 667, 611, 611, 611, 611, 333, 333, 333, 333, 722, 667, 722, 722, 722, 722, 722, 675, 722, 722, 722, 722, 722, 556, 611, 500, 500, 500, 500, 500, 500, 500, 667, 444, 444, 444, 444, 444, 278, 278, 278, 278, 500, 500, 500, 500, 500, 500, 500, 675, 500, 500, 500, 500, 500, 444, 500, 444], | |||
|
50 | ||||
|
51 | 'timesBI'=>[250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 389, 555, 500, 500, 833, 778, 278, 333, 333, 500, 570, 250, 333, 250, 278, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 333, 570, 570, 570, 500, 832, 667, 667, 667, 722, 667, 667, 722, 778, 389, 500, 667, 611, 889, 722, 722, 611, 722, 667, 556, 611, 722, 667, 889, 667, 611, 611, 333, 278, 333, 570, 500, 333, 500, 500, 444, 500, 444, 333, 500, 556, 278, 278, 500, 278, 778, 556, 500, 500, 500, 389, 389, 278, 556, 444, 667, 500, 444, 389, 348, 220, 348, 570, 350, 500, 350, 333, 500, 500, 1000, 500, 500, 333, 1000, 556, 333, 944, 350, 611, 350, 350, 333, 333, 500, 500, 350, 500, 1000, 333, 1000, 389, 333, 722, 350, 389, 611, 250, 389, 500, 500, 500, 500, 220, 500, 333, 747, 266, 500, 606, 333, 747, 333, 400, 570, 300, 300, 333, 576, 500, 250, 333, 300, 300, 500, 750, 750, 750, 500, 667, 667, 667, 667, 667, 667, 944, 667, 667, 667, 667, 667, 389, 389, 389, 389, 722, 722, 722, 722, 722, 722, 722, 570, 722, 722, 722, 722, 722, 611, 611, 500, 500, 500, 500, 500, 500, 500, 722, 444, 444, 444, 444, 444, 278, 278, 278, 278, 500, 556, 500, 500, 500, 500, 500, 570, 500, 556, 556, 556, 556, 444, 500, 444], | |||
|
52 | ||||
|
53 | 'symbol'=>[250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 333, 713, 500, 549, 833, 778, 439, 333, 333, 500, 549, 250, 549, 250, 278, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 278, 549, 549, 549, 444, 549, 722, 667, 722, 612, 611, 763, 603, 722, 333, 631, 722, 686, 889, 722, 722, 768, 741, 556, 592, 611, 690, 439, 768, 645, 795, 611, 333, 863, 333, 658, 500, 500, 631, 549, 549, 494, 439, 521, 411, 603, 329, 603, 549, 549, 576, 521, 549, 549, 521, 549, 603, 439, 576, 713, 686, 493, 686, 494, 480, 200, 480, 549, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 750, 620, 247, 549, 167, 713, 500, 753, 753, 753, 753, 1042, 987, 603, 987, 603, 400, 549, 411, 549, 549, 713, 494, 460, 549, 549, 549, 549, 1000, 603, 1000, 658, 823, 686, 795, 987, 768, 768, 823, 768, 768, 713, 713, 713, 713, 713, 713, 713, 768, 713, 790, 790, 890, 823, 549, 250, 713, 603, 603, 1042, 987, 603, 987, 603, 494, 329, 790, 790, 786, 713, 384, 384, 384, 384, 384, 384, 494, 494, 494, 494, 0, 329, 274, 686, 686, 686, 384, 384, 384, 384, 384, 384, 494, 494, 494, 0], | |||
|
54 | ||||
|
55 | 'zapfdingbats'=>[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 278, 974, 961, 974, 980, 719, 789, 790, 791, 690, 960, 939, 549, 855, 911, 933, 911, 945, 974, 755, 846, 762, 761, 571, 677, 763, 760, 759, 754, 494, 552, 537, 577, 692, 786, 788, 788, 790, 793, 794, 816, 823, 789, 841, 823, 833, 816, 831, 923, 744, 723, 749, 790, 792, 695, 776, 768, 792, 759, 707, 708, 682, 701, 826, 815, 789, 789, 707, 687, 696, 689, 786, 787, 713, 791, 785, 791, 873, 761, 762, 762, 759, 759, 892, 892, 788, 784, 438, 138, 277, 415, 392, 392, 668, 668, 0, 390, 390, 317, 317, 276, 276, 509, 509, 410, 410, 234, 234, 334, 334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 732, 544, 544, 910, 667, 760, 760, 776, 595, 694, 626, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 894, 838, 1016, 458, 748, 924, 748, 918, 927, 928, 928, 834, 873, 828, 924, 924, 917, 930, 931, 463, 883, 836, 836, 867, 867, 696, 696, 874, 0, 874, 760, 946, 771, 865, 771, 888, 967, 888, 831, 873, 927, 970, 918, 0] | |||
|
56 | } | |||
|
57 | ||||
|
58 | def initialize(orientation='P', unit='mm', format='A4') | |||
|
59 | # Initialization of properties | |||
|
60 | @page=0 | |||
|
61 | @n=2 | |||
|
62 | @buffer='' | |||
|
63 | @pages=[] | |||
|
64 | @OrientationChanges=[] | |||
|
65 | @state=0 | |||
|
66 | @fonts={} | |||
|
67 | @FontFiles={} | |||
|
68 | @diffs=[] | |||
|
69 | @images={} | |||
|
70 | @links=[] | |||
|
71 | @PageLinks={} | |||
|
72 | @InFooter=false | |||
|
73 | @FontFamily='' | |||
|
74 | @FontStyle='' | |||
|
75 | @FontSizePt=12 | |||
|
76 | @underline= false | |||
|
77 | @DrawColor='0 G' | |||
|
78 | @FillColor='0 g' | |||
|
79 | @TextColor='0 g' | |||
|
80 | @ColorFlag=false | |||
|
81 | @ws=0 | |||
|
82 | @offsets=[] | |||
|
83 | ||||
|
84 | # Standard fonts | |||
|
85 | @CoreFonts={} | |||
|
86 | @CoreFonts['courier']='Courier' | |||
|
87 | @CoreFonts['courierB']='Courier-Bold' | |||
|
88 | @CoreFonts['courierI']='Courier-Oblique' | |||
|
89 | @CoreFonts['courierBI']='Courier-BoldOblique' | |||
|
90 | @CoreFonts['helvetica']='Helvetica' | |||
|
91 | @CoreFonts['helveticaB']='Helvetica-Bold' | |||
|
92 | @CoreFonts['helveticaI']='Helvetica-Oblique' | |||
|
93 | @CoreFonts['helveticaBI']='Helvetica-BoldOblique' | |||
|
94 | @CoreFonts['times']='Times-Roman' | |||
|
95 | @CoreFonts['timesB']='Times-Bold' | |||
|
96 | @CoreFonts['timesI']='Times-Italic' | |||
|
97 | @CoreFonts['timesBI']='Times-BoldItalic' | |||
|
98 | @CoreFonts['symbol']='Symbol' | |||
|
99 | @CoreFonts['zapfdingbats']='ZapfDingbats' | |||
|
100 | ||||
|
101 | # Scale factor | |||
|
102 | if unit=='pt' | |||
|
103 | @k=1 | |||
|
104 | elsif unit=='mm' | |||
|
105 | @k=72/25.4 | |||
|
106 | elsif unit=='cm' | |||
|
107 | @k=72/2.54; | |||
|
108 | elsif unit=='in' | |||
|
109 | @k=72 | |||
|
110 | else | |||
|
111 | raise 'Incorrect unit: '+unit | |||
|
112 | end | |||
|
113 | ||||
|
114 | # Page format | |||
|
115 | if format.is_a? String | |||
|
116 | format.downcase! | |||
|
117 | if format=='a3' | |||
|
118 | format=[841.89,1190.55] | |||
|
119 | elsif format=='a4' | |||
|
120 | format=[595.28,841.89] | |||
|
121 | elsif format=='a5' | |||
|
122 | format=[420.94,595.28] | |||
|
123 | elsif format=='letter' | |||
|
124 | format=[612,792] | |||
|
125 | elsif format=='legal' | |||
|
126 | format=[612,1008] | |||
|
127 | else | |||
|
128 | raise 'Unknown page format: '+format | |||
|
129 | end | |||
|
130 | @fwPt,@fhPt=format | |||
|
131 | else | |||
|
132 | @fwPt=format[0]*@k | |||
|
133 | @fhPt=format[1]*@k | |||
|
134 | end | |||
|
135 | @fw=@fwPt/@k; | |||
|
136 | @fh=@fhPt/@k; | |||
|
137 | ||||
|
138 | # Page orientation | |||
|
139 | orientation.downcase! | |||
|
140 | if orientation=='p' or orientation=='portrait' | |||
|
141 | @DefOrientation='P' | |||
|
142 | @wPt=@fwPt | |||
|
143 | @hPt=@fhPt | |||
|
144 | elsif orientation=='l' or orientation=='landscape' | |||
|
145 | @DefOrientation='L' | |||
|
146 | @wPt=@fhPt | |||
|
147 | @hPt=@fwPt | |||
|
148 | else | |||
|
149 | raise 'Incorrect orientation: '+orientation | |||
|
150 | end | |||
|
151 | @CurOrientation=@DefOrientation | |||
|
152 | @w=@wPt/@k | |||
|
153 | @h=@hPt/@k | |||
|
154 | ||||
|
155 | # Page margins (1 cm) | |||
|
156 | margin=28.35/@k | |||
|
157 | SetMargins(margin,margin) | |||
|
158 | # Interior cell margin (1 mm) | |||
|
159 | @cMargin=margin/10 | |||
|
160 | # Line width (0.2 mm) | |||
|
161 | @LineWidth=0.567/@k | |||
|
162 | # Automatic page break | |||
|
163 | SetAutoPageBreak(true,2*margin) | |||
|
164 | # Full width display mode | |||
|
165 | SetDisplayMode('fullwidth') | |||
|
166 | # Enable compression | |||
|
167 | SetCompression(true) | |||
|
168 | # Set default PDF version number | |||
|
169 | @PDFVersion='1.3' | |||
|
170 | end | |||
|
171 | ||||
|
172 | def SetMargins(left, top, right=-1) | |||
|
173 | # Set left, top and right margins | |||
|
174 | @lMargin=left | |||
|
175 | @tMargin=top | |||
|
176 | right=left if right==-1 | |||
|
177 | @rMargin=right | |||
|
178 | end | |||
|
179 | ||||
|
180 | def SetLeftMargin(margin) | |||
|
181 | # Set left margin | |||
|
182 | @lMargin=margin | |||
|
183 | @x=margin if @page>0 and @x<margin | |||
|
184 | end | |||
|
185 | ||||
|
186 | def SetTopMargin(margin) | |||
|
187 | # Set top margin | |||
|
188 | @tMargin=margin | |||
|
189 | end | |||
|
190 | ||||
|
191 | def SetRightMargin(margin) | |||
|
192 | #Set right margin | |||
|
193 | @rMargin=margin | |||
|
194 | end | |||
|
195 | ||||
|
196 | def SetAutoPageBreak(auto, margin=0) | |||
|
197 | # Set auto page break mode and triggering margin | |||
|
198 | @AutoPageBreak=auto | |||
|
199 | @bMargin=margin | |||
|
200 | @PageBreakTrigger=@h-margin | |||
|
201 | end | |||
|
202 | ||||
|
203 | def SetDisplayMode(zoom, layout='continuous') | |||
|
204 | # Set display mode in viewer | |||
|
205 | if zoom=='fullpage' or zoom=='fullwidth' or zoom=='real' or | |||
|
206 | zoom=='default' or not zoom.kind_of? String | |||
|
207 | ||||
|
208 | @ZoomMode=zoom; | |||
|
209 | elsif zoom=='zoom' | |||
|
210 | @ZoomMode=layout | |||
|
211 | else | |||
|
212 | raise 'Incorrect zoom display mode: '+zoom | |||
|
213 | end | |||
|
214 | if layout=='single' or layout=='continuous' or layout=='two' or | |||
|
215 | layout=='default' | |||
|
216 | ||||
|
217 | @LayoutMode=layout | |||
|
218 | elsif zoom!='zoom' | |||
|
219 | raise 'Incorrect layout display mode: '+layout | |||
|
220 | end | |||
|
221 | end | |||
|
222 | ||||
|
223 | def SetCompression(compress) | |||
|
224 | # Set page compression | |||
|
225 | @compress = compress | |||
|
226 | end | |||
|
227 | ||||
|
228 | def SetTitle(title) | |||
|
229 | # Title of document | |||
|
230 | @title=title | |||
|
231 | end | |||
|
232 | ||||
|
233 | def SetSubject(subject) | |||
|
234 | # Subject of document | |||
|
235 | @subject=subject | |||
|
236 | end | |||
|
237 | ||||
|
238 | def SetAuthor(author) | |||
|
239 | # Author of document | |||
|
240 | @author=author | |||
|
241 | end | |||
|
242 | ||||
|
243 | def SetKeywords(keywords) | |||
|
244 | # Keywords of document | |||
|
245 | @keywords=keywords | |||
|
246 | end | |||
|
247 | ||||
|
248 | def SetCreator(creator) | |||
|
249 | # Creator of document | |||
|
250 | @creator=creator | |||
|
251 | end | |||
|
252 | ||||
|
253 | def AliasNbPages(aliasnb='{nb}') | |||
|
254 | # Define an alias for total number of pages | |||
|
255 | @AliasNbPages=aliasnb | |||
|
256 | end | |||
|
257 | ||||
|
258 | def Error(msg) | |||
|
259 | raise 'FPDF error: '+msg | |||
|
260 | end | |||
|
261 | ||||
|
262 | def Open | |||
|
263 | # Begin document | |||
|
264 | @state=1 | |||
|
265 | end | |||
|
266 | ||||
|
267 | def Close | |||
|
268 | # Terminate document | |||
|
269 | return if @state==3 | |||
|
270 | self.AddPage if @page==0 | |||
|
271 | # Page footer | |||
|
272 | @InFooter=true | |||
|
273 | self.Footer | |||
|
274 | @InFooter=false | |||
|
275 | # Close page | |||
|
276 | endpage | |||
|
277 | # Close document | |||
|
278 | enddoc | |||
|
279 | end | |||
|
280 | ||||
|
281 | def AddPage(orientation='') | |||
|
282 | # Start a new page | |||
|
283 | self.Open if @state==0 | |||
|
284 | family=@FontFamily | |||
|
285 | style=@FontStyle+(@underline ? 'U' : '') | |||
|
286 | size=@FontSizePt | |||
|
287 | lw=@LineWidth | |||
|
288 | dc=@DrawColor | |||
|
289 | fc=@FillColor | |||
|
290 | tc=@TextColor | |||
|
291 | cf=@ColorFlag | |||
|
292 | if @page>0 | |||
|
293 | # Page footer | |||
|
294 | @InFooter=true | |||
|
295 | self.Footer | |||
|
296 | @InFooter=false | |||
|
297 | # Close page | |||
|
298 | endpage | |||
|
299 | end | |||
|
300 | # Start new page | |||
|
301 | beginpage(orientation) | |||
|
302 | # Set line cap style to square | |||
|
303 | out('2 J') | |||
|
304 | # Set line width | |||
|
305 | @LineWidth=lw | |||
|
306 | out(sprintf('%.2f w',lw*@k)) | |||
|
307 | # Set font | |||
|
308 | SetFont(family,style,size) if family | |||
|
309 | # Set colors | |||
|
310 | @DrawColor=dc | |||
|
311 | out(dc) if dc!='0 G' | |||
|
312 | @FillColor=fc | |||
|
313 | out(fc) if fc!='0 g' | |||
|
314 | @TextColor=tc | |||
|
315 | @ColorFlag=cf | |||
|
316 | # Page header | |||
|
317 | self.Header | |||
|
318 | # Restore line width | |||
|
319 | if @LineWidth!=lw | |||
|
320 | @LineWidth=lw | |||
|
321 | out(sprintf('%.2f w',lw*@k)) | |||
|
322 | end | |||
|
323 | # Restore font | |||
|
324 | self.SetFont(family,style,size) if family | |||
|
325 | # Restore colors | |||
|
326 | if @DrawColor!=dc | |||
|
327 | @DrawColor=dc | |||
|
328 | out(dc) | |||
|
329 | end | |||
|
330 | if @FillColor!=fc | |||
|
331 | @FillColor=fc | |||
|
332 | out(fc) | |||
|
333 | end | |||
|
334 | @TextColor=tc | |||
|
335 | @ColorFlag=cf | |||
|
336 | end | |||
|
337 | ||||
|
338 | def Header | |||
|
339 | # To be implemented in your inherited class | |||
|
340 | end | |||
|
341 | ||||
|
342 | def Footer | |||
|
343 | # To be implemented in your inherited class | |||
|
344 | end | |||
|
345 | ||||
|
346 | def PageNo | |||
|
347 | # Get current page number | |||
|
348 | @page | |||
|
349 | end | |||
|
350 | ||||
|
351 | def SetDrawColor(r,g=-1,b=-1) | |||
|
352 | # Set color for all stroking operations | |||
|
353 | if (r==0 and g==0 and b==0) or g==-1 | |||
|
354 | @DrawColor=sprintf('%.3f G',r/255.0) | |||
|
355 | else | |||
|
356 | @DrawColor=sprintf('%.3f %.3f %.3f RG',r/255.0,g/255.0,b/255.0) | |||
|
357 | end | |||
|
358 | out(@DrawColor) if(@page>0) | |||
|
359 | end | |||
|
360 | ||||
|
361 | def SetFillColor(r,g=-1,b=-1) | |||
|
362 | # Set color for all filling operations | |||
|
363 | if (r==0 and g==0 and b==0) or g==-1 | |||
|
364 | @FillColor=sprintf('%.3f g',r/255.0) | |||
|
365 | else | |||
|
366 | @FillColor=sprintf('%.3f %.3f %.3f rg',r/255.0,g/255.0,b/255.0) | |||
|
367 | end | |||
|
368 | @ColorFlag=(@FillColor!=@TextColor) | |||
|
369 | out(@FillColor) if(@page>0) | |||
|
370 | end | |||
|
371 | ||||
|
372 | def SetTextColor(r,g=-1,b=-1) | |||
|
373 | # Set color for text | |||
|
374 | if (r==0 and g==0 and b==0) or g==-1 | |||
|
375 | @TextColor=sprintf('%.3f g',r/255.0) | |||
|
376 | else | |||
|
377 | @TextColor=sprintf('%.3f %.3f %.3f rg',r/255.0,g/255.0,b/255.0) | |||
|
378 | end | |||
|
379 | @ColorFlag=(@FillColor!=@TextColor) | |||
|
380 | end | |||
|
381 | ||||
|
382 | def GetStringWidth(s) | |||
|
383 | # Get width of a string in the current font | |||
|
384 | cw=@CurrentFont['cw'] | |||
|
385 | w=0 | |||
|
386 | s.each_byte do |c| | |||
|
387 | w=w+cw[c] | |||
|
388 | end | |||
|
389 | w*@FontSize/1000.0 | |||
|
390 | end | |||
|
391 | ||||
|
392 | def SetLineWidth(width) | |||
|
393 | # Set line width | |||
|
394 | @LineWidth=width | |||
|
395 | out(sprintf('%.2f w',width*@k)) if @page>0 | |||
|
396 | end | |||
|
397 | ||||
|
398 | def Line(x1, y1, x2, y2) | |||
|
399 | # Draw a line | |||
|
400 | out(sprintf('%.2f %.2f m %.2f %.2f l S', | |||
|
401 | x1*@k,(@h-y1)*@k,x2*@k,(@h-y2)*@k)) | |||
|
402 | end | |||
|
403 | ||||
|
404 | def Rect(x, y, w, h, style='') | |||
|
405 | # Draw a rectangle | |||
|
406 | if style=='F' | |||
|
407 | op='f' | |||
|
408 | elsif style=='FD' or style=='DF' | |||
|
409 | op='B' | |||
|
410 | else | |||
|
411 | op='S' | |||
|
412 | end | |||
|
413 | out(sprintf('%.2f %.2f %.2f %.2f re %s', x*@k,(@h-y)*@k,w*@k,-h*@k,op)) | |||
|
414 | end | |||
|
415 | ||||
|
416 | def AddFont(family, style='', file='') | |||
|
417 | # Add a TrueType or Type1 font | |||
|
418 | family = family.downcase | |||
|
419 | family = 'helvetica' if family == 'arial' | |||
|
420 | ||||
|
421 | style = style.upcase | |||
|
422 | style = 'BI' if style == 'IB' | |||
|
423 | ||||
|
424 | fontkey = family + style | |||
|
425 | ||||
|
426 | if @fonts.has_key?(fontkey) | |||
|
427 | self.Error("Font already added: #{family} #{style}") | |||
|
428 | end | |||
|
429 | ||||
|
430 | file = family.gsub(' ', '') + style.downcase + '.rb' if file == '' | |||
|
431 | ||||
|
432 | if self.class.const_defined? 'FPDF_FONTPATH' | |||
|
433 | if FPDF_FONTPATH[-1,1] == '/' | |||
|
434 | file = FPDF_FONTPATH + file | |||
|
435 | else | |||
|
436 | file = FPDF_FONTPATH + '/' + file | |||
|
437 | end | |||
|
438 | end | |||
|
439 | ||||
|
440 | # Changed from "require file" to fix bug reported by Hans Allis. | |||
|
441 | load file | |||
|
442 | ||||
|
443 | if FontDef.desc.nil? | |||
|
444 | self.Error("Could not include font definition file #{file}") | |||
|
445 | end | |||
|
446 | ||||
|
447 | i = @fonts.length + 1 | |||
|
448 | ||||
|
449 | @fonts[fontkey] = {'i' => i, | |||
|
450 | 'type' => FontDef.type, | |||
|
451 | 'name' => FontDef.name, | |||
|
452 | 'desc' => FontDef.desc, | |||
|
453 | 'up' => FontDef.up, | |||
|
454 | 'ut' => FontDef.ut, | |||
|
455 | 'cw' => FontDef.cw, | |||
|
456 | 'enc' => FontDef.enc, | |||
|
457 | 'file' => FontDef.file | |||
|
458 | } | |||
|
459 | ||||
|
460 | if FontDef.diff | |||
|
461 | # Search existing encodings | |||
|
462 | unless @diffs.include?(FontDef.diff) | |||
|
463 | @diffs.push(FontDef.diff) | |||
|
464 | @fonts[fontkey]['diff'] = @diffs.length - 1 | |||
|
465 | end | |||
|
466 | end | |||
|
467 | ||||
|
468 | if FontDef.file | |||
|
469 | if FontDef.type == 'TrueType' | |||
|
470 | @FontFiles[FontDef.file] = {'length1' => FontDef.originalsize} | |||
|
471 | else | |||
|
472 | @FontFiles[FontDef.file] = {'length1' => FontDef.size1, 'length2' => FontDef.size2} | |||
|
473 | end | |||
|
474 | end | |||
|
475 | ||||
|
476 | return self | |||
|
477 | end | |||
|
478 | ||||
|
479 | def SetFont(family, style='', size=0) | |||
|
480 | # Select a font; size given in points | |||
|
481 | family.downcase! | |||
|
482 | family=@FontFamily if family=='' | |||
|
483 | if family=='arial' | |||
|
484 | family='helvetica' | |||
|
485 | elsif family=='symbol' or family=='zapfdingbats' | |||
|
486 | style='' | |||
|
487 | end | |||
|
488 | style.upcase! | |||
|
489 | unless style.index('U').nil? | |||
|
490 | @underline=true | |||
|
491 | style.gsub!('U','') | |||
|
492 | else | |||
|
493 | @underline=false; | |||
|
494 | end | |||
|
495 | style='BI' if style=='IB' | |||
|
496 | size=@FontSizePt if size==0 | |||
|
497 | # Test if font is already selected | |||
|
498 | return if @FontFamily==family and | |||
|
499 | @FontStyle==style and @FontSizePt==size | |||
|
500 | # Test if used for the first time | |||
|
501 | fontkey=family+style | |||
|
502 | unless @fonts.has_key?(fontkey) | |||
|
503 | if @CoreFonts.has_key?(fontkey) | |||
|
504 | unless Charwidths.has_key?(fontkey) | |||
|
505 | raise 'Font unavailable' | |||
|
506 | end | |||
|
507 | @fonts[fontkey]={ | |||
|
508 | 'i'=>@fonts.size, | |||
|
509 | 'type'=>'core', | |||
|
510 | 'name'=>@CoreFonts[fontkey], | |||
|
511 | 'up'=>-100, | |||
|
512 | 'ut'=>50, | |||
|
513 | 'cw'=>Charwidths[fontkey]} | |||
|
514 | else | |||
|
515 | raise 'Font unavailable' | |||
|
516 | end | |||
|
517 | end | |||
|
518 | ||||
|
519 | #Select it | |||
|
520 | @FontFamily=family | |||
|
521 | @FontStyle=style; | |||
|
522 | @FontSizePt=size | |||
|
523 | @FontSize=size/@k; | |||
|
524 | @CurrentFont=@fonts[fontkey] | |||
|
525 | if @page>0 | |||
|
526 | out(sprintf('BT /F%d %.2f Tf ET', @CurrentFont['i'], @FontSizePt)) | |||
|
527 | end | |||
|
528 | end | |||
|
529 | ||||
|
530 | def SetFontSize(size) | |||
|
531 | # Set font size in points | |||
|
532 | return if @FontSizePt==size | |||
|
533 | @FontSizePt=size | |||
|
534 | @FontSize=size/@k | |||
|
535 | if @page>0 | |||
|
536 | out(sprintf('BT /F%d %.2f Tf ET',@CurrentFont['i'],@FontSizePt)) | |||
|
537 | end | |||
|
538 | end | |||
|
539 | ||||
|
540 | def AddLink | |||
|
541 | # Create a new internal link | |||
|
542 | @links.push([0, 0]) | |||
|
543 | @links.size | |||
|
544 | end | |||
|
545 | ||||
|
546 | def SetLink(link, y=0, page=-1) | |||
|
547 | # Set destination of internal link | |||
|
548 | y=@y if y==-1 | |||
|
549 | page=@page if page==-1 | |||
|
550 | @links[link]=[page, y] | |||
|
551 | end | |||
|
552 | ||||
|
553 | def Link(x, y, w, h, link) | |||
|
554 | # Put a link on the page | |||
|
555 | @PageLinks[@page]=Array.new unless @PageLinks.has_key?(@Page) | |||
|
556 | @PageLinks[@page].push([x*@k,@hPt-y*@k,w*@k,h*@k,link]) | |||
|
557 | end | |||
|
558 | ||||
|
559 | def Text(x, y, txt) | |||
|
560 | # Output a string | |||
|
561 | txt.gsub!(')', '\\)') | |||
|
562 | txt.gsub!('(', '\\(') | |||
|
563 | txt.gsub!('\\', '\\\\') | |||
|
564 | s=sprintf('BT %.2f %.2f Td (%s) Tj ET',x*@k,(@h-y)*@k,txt); | |||
|
565 | s=s+' '+dounderline(x,y,txt) if @underline and txt!='' | |||
|
566 | s='q '+@TextColor+' '+s+' Q' if @ColorFlag | |||
|
567 | out(s) | |||
|
568 | end | |||
|
569 | ||||
|
570 | def AcceptPageBreak | |||
|
571 | # Accept automatic page break or not | |||
|
572 | @AutoPageBreak | |||
|
573 | end | |||
|
574 | ||||
|
575 | def Cell(w,h=0,txt='',border=0,ln=0,align='',fill=0,link='') | |||
|
576 | # Output a cell | |||
|
577 | if @y+h>@PageBreakTrigger and !@InFooter and self.AcceptPageBreak | |||
|
578 | # Automatic page break | |||
|
579 | x=@x | |||
|
580 | ws=@ws | |||
|
581 | if ws>0 | |||
|
582 | @ws=0 | |||
|
583 | out('0 Tw') | |||
|
584 | end | |||
|
585 | self.AddPage(@CurOrientation) | |||
|
586 | @x=x | |||
|
587 | if ws>0 | |||
|
588 | @ws=ws | |||
|
589 | out(sprintf('%.3f Tw',ws*@k)) | |||
|
590 | end | |||
|
591 | end | |||
|
592 | w=@w-@rMargin-@x if w==0 | |||
|
593 | s='' | |||
|
594 | if fill==1 or border==1 | |||
|
595 | if fill==1 | |||
|
596 | op=(border==1) ? 'B' : 'f' | |||
|
597 | else | |||
|
598 | op='S' | |||
|
599 | end | |||
|
600 | s=sprintf('%.2f %.2f %.2f %.2f re %s ',@x*@k,(@h-@y)*@k,w*@k,-h*@k,op) | |||
|
601 | end | |||
|
602 | if border.is_a? String | |||
|
603 | x=@x | |||
|
604 | y=@y | |||
|
605 | unless border.index('L').nil? | |||
|
606 | s=s+sprintf('%.2f %.2f m %.2f %.2f l S ', | |||
|
607 | x*@k,(@h-y)*@k,x*@k,(@h-(y+h))*@k) | |||
|
608 | end | |||
|
609 | unless border.index('T').nil? | |||
|
610 | s=s+sprintf('%.2f %.2f m %.2f %.2f l S ', | |||
|
611 | x*@k,(@h-y)*@k,(x+w)*@k,(@h-y)*@k) | |||
|
612 | end | |||
|
613 | unless border.index('R').nil? | |||
|
614 | s=s+sprintf('%.2f %.2f m %.2f %.2f l S ', | |||
|
615 | (x+w)*@k,(@h-y)*@k,(x+w)*@k,(@h-(y+h))*@k) | |||
|
616 | end | |||
|
617 | unless border.index('B').nil? | |||
|
618 | s=s+sprintf('%.2f %.2f m %.2f %.2f l S ', | |||
|
619 | x*@k,(@h-(y+h))*@k,(x+w)*@k,(@h-(y+h))*@k) | |||
|
620 | end | |||
|
621 | end | |||
|
622 | if txt!='' | |||
|
623 | if align=='R' | |||
|
624 | dx=w-@cMargin-self.GetStringWidth(txt) | |||
|
625 | elsif align=='C' | |||
|
626 | dx=(w-self.GetStringWidth(txt))/2 | |||
|
627 | else | |||
|
628 | dx=@cMargin | |||
|
629 | end | |||
|
630 | txt = txt.gsub(')', '\\)') | |||
|
631 | txt.gsub!('(', '\\(') | |||
|
632 | txt.gsub!('\\', '\\\\') | |||
|
633 | if @ColorFlag | |||
|
634 | s=s+'q '+@TextColor+' ' | |||
|
635 | end | |||
|
636 | s=s+sprintf('BT %.2f %.2f Td (%s) Tj ET', | |||
|
637 | (@x+dx)*@k,(@h-(@y+0.5*h+0.3*@FontSize))*@k,txt) | |||
|
638 | s=s+' '+dounderline(@x+dx,@y+0.5*h+0.3*@FontSize,txt) if @underline | |||
|
639 | s=s+' Q' if @ColorFlag | |||
|
640 | if link and link != '' | |||
|
641 | Link(@x+dx,@y+0.5*h-0.5*@FontSize,GetStringWidth(txt),@FontSize,link) | |||
|
642 | end | |||
|
643 | end | |||
|
644 | out(s) if s | |||
|
645 | @lasth=h | |||
|
646 | if ln>0 | |||
|
647 | # Go to next line | |||
|
648 | @y=@y+h | |||
|
649 | @x=@lMargin if ln==1 | |||
|
650 | else | |||
|
651 | @x=@x+w | |||
|
652 | end | |||
|
653 | end | |||
|
654 | ||||
|
655 | def MultiCell(w,h,txt,border=0,align='J',fill=0) | |||
|
656 | # Output text with automatic or explicit line breaks | |||
|
657 | cw=@CurrentFont['cw'] | |||
|
658 | w=@w-@rMargin-@x if w==0 | |||
|
659 | wmax=(w-2*@cMargin)*1000/@FontSize | |||
|
660 | s=txt.gsub('\r','') | |||
|
661 | nb=s.length | |||
|
662 | nb=nb-1 if nb>0 and s[nb-1].chr=='\n' | |||
|
663 | b=0 | |||
|
664 | if border!=0 | |||
|
665 | if border==1 | |||
|
666 | border='LTRB' | |||
|
667 | b='LRT' | |||
|
668 | b2='LR' | |||
|
669 | else | |||
|
670 | b2='' | |||
|
671 | b2='L' unless border.index('L').nil? | |||
|
672 | b2=b2+'R' unless border.index('R').nil? | |||
|
673 | b=(not border.index('T').nil?) ? (b2+'T') : b2 | |||
|
674 | end | |||
|
675 | end | |||
|
676 | sep=-1 | |||
|
677 | i=0 | |||
|
678 | j=0 | |||
|
679 | l=0 | |||
|
680 | ns=0 | |||
|
681 | nl=1 | |||
|
682 | while i<nb | |||
|
683 | # Get next character | |||
|
684 | c=s[i].chr | |||
|
685 | if c=="\n" | |||
|
686 | # Explicit line break | |||
|
687 | if @ws>0 | |||
|
688 | @ws=0 | |||
|
689 | out('0 Tw') | |||
|
690 | end | |||
|
691 | #Ed Moss | |||
|
692 | # Don't let i go negative | |||
|
693 | end_i = i == 0 ? 0 : i - 1 | |||
|
694 | # Changed from s[j..i] to fix bug reported by Hans Allis. | |||
|
695 | self.Cell(w,h,s[j..end_i],b,2,align,fill) | |||
|
696 | # | |||
|
697 | i=i+1 | |||
|
698 | sep=-1 | |||
|
699 | j=i | |||
|
700 | l=0 | |||
|
701 | ns=0 | |||
|
702 | nl=nl+1 | |||
|
703 | b=b2 if border and nl==2 | |||
|
704 | else | |||
|
705 | if c==' ' | |||
|
706 | sep=i | |||
|
707 | ls=l | |||
|
708 | ns=ns+1 | |||
|
709 | end | |||
|
710 | l=l+cw[c[0]] | |||
|
711 | if l>wmax | |||
|
712 | # Automatic line break | |||
|
713 | if sep==-1 | |||
|
714 | i=i+1 if i==j | |||
|
715 | if @ws>0 | |||
|
716 | @ws=0 | |||
|
717 | out('0 Tw') | |||
|
718 | end | |||
|
719 | self.Cell(w,h,s[j..i],b,2,align,fill) | |||
|
720 | #Ed Moss | |||
|
721 | # Added so that it wouldn't print the last character of the string if it got close | |||
|
722 | #FIXME 2006-07-18 Level=0 - but it still puts out an extra new line | |||
|
723 | i += 1 | |||
|
724 | # | |||
|
725 | else | |||
|
726 | if align=='J' | |||
|
727 | @ws=(ns>1) ? (wmax-ls)/1000.0*@FontSize/(ns-1) : 0 | |||
|
728 | out(sprintf('%.3f Tw',@ws*@k)) | |||
|
729 | end | |||
|
730 | self.Cell(w,h,s[j..sep],b,2,align,fill) | |||
|
731 | i=sep+1 | |||
|
732 | end | |||
|
733 | sep=-1 | |||
|
734 | j=i | |||
|
735 | l=0 | |||
|
736 | ns=0 | |||
|
737 | nl=nl+1 | |||
|
738 | b=b2 if border and nl==2 | |||
|
739 | else | |||
|
740 | i=i+1 | |||
|
741 | end | |||
|
742 | end | |||
|
743 | end | |||
|
744 | ||||
|
745 | # Last chunk | |||
|
746 | if @ws>0 | |||
|
747 | @ws=0 | |||
|
748 | out('0 Tw') | |||
|
749 | end | |||
|
750 | b=b+'B' if border!=0 and not border.index('B').nil? | |||
|
751 | self.Cell(w,h,s[j..i],b,2,align,fill) | |||
|
752 | @x=@lMargin | |||
|
753 | end | |||
|
754 | ||||
|
755 | def Write(h,txt,link='') | |||
|
756 | # Output text in flowing mode | |||
|
757 | cw=@CurrentFont['cw'] | |||
|
758 | w=@w-@rMargin-@x | |||
|
759 | wmax=(w-2*@cMargin)*1000/@FontSize | |||
|
760 | s=txt.gsub("\r",'') | |||
|
761 | nb=s.length | |||
|
762 | sep=-1 | |||
|
763 | i=0 | |||
|
764 | j=0 | |||
|
765 | l=0 | |||
|
766 | nl=1 | |||
|
767 | while i<nb | |||
|
768 | # Get next character | |||
|
769 | c=s[i] | |||
|
770 | if c=="\n"[0] | |||
|
771 | # Explicit line break | |||
|
772 | self.Cell(w,h,s[j,i-j],0,2,'',0,link) | |||
|
773 | i=i+1 | |||
|
774 | sep=-1 | |||
|
775 | j=i | |||
|
776 | l=0 | |||
|
777 | if nl==1 | |||
|
778 | @x=@lMargin | |||
|
779 | w=@w-@rMargin-@x | |||
|
780 | wmax=(w-2*@cMargin)*1000/@FontSize | |||
|
781 | end | |||
|
782 | nl=nl+1 | |||
|
783 | next | |||
|
784 | end | |||
|
785 | if c==' '[0] | |||
|
786 | sep=i | |||
|
787 | ls=l | |||
|
788 | end | |||
|
789 | l=l+cw[c]; | |||
|
790 | if l>wmax | |||
|
791 | # Automatic line break | |||
|
792 | if sep==-1 | |||
|
793 | if @x>@lMargin | |||
|
794 | # Move to next line | |||
|
795 | @x=@lMargin | |||
|
796 | @y=@y+h | |||
|
797 | w=@w-@rMargin-@x | |||
|
798 | wmax=(w-2*@cMargin)*1000/@FontSize | |||
|
799 | i=i+1 | |||
|
800 | nl=nl+1 | |||
|
801 | next | |||
|
802 | end | |||
|
803 | i=i+1 if i==j | |||
|
804 | self.Cell(w,h,s[j,i-j],0,2,'',0,link) | |||
|
805 | else | |||
|
806 | self.Cell(w,h,s[j,sep-j],0,2,'',0,link) | |||
|
807 | i=sep+1 | |||
|
808 | end | |||
|
809 | sep=-1 | |||
|
810 | j=i | |||
|
811 | l=0 | |||
|
812 | if nl==1 | |||
|
813 | @x=@lMargin | |||
|
814 | w=@w-@rMargin-@x | |||
|
815 | wmax=(w-2*@cMargin)*1000/@FontSize | |||
|
816 | end | |||
|
817 | nl=nl+1 | |||
|
818 | else | |||
|
819 | i=i+1 | |||
|
820 | end | |||
|
821 | end | |||
|
822 | # Last chunk | |||
|
823 | self.Cell(l/1000.0*@FontSize,h,s[j,i],0,0,'',0,link) if i!=j | |||
|
824 | end | |||
|
825 | ||||
|
826 | def Image(file,x,y,w=0,h=0,type='',link='') | |||
|
827 | # Put an image on the page | |||
|
828 | unless @images.has_key?(file) | |||
|
829 | # First use of image, get info | |||
|
830 | if type=='' | |||
|
831 | pos=file.rindex('.') | |||
|
832 | if pos.nil? | |||
|
833 | self.Error('Image file has no extension and no type was '+ | |||
|
834 | 'specified: '+file) | |||
|
835 | end | |||
|
836 | type=file[pos+1..-1] | |||
|
837 | end | |||
|
838 | type.downcase! | |||
|
839 | if type=='jpg' or type=='jpeg' | |||
|
840 | info=parsejpg(file) | |||
|
841 | elsif type=='png' | |||
|
842 | info=parsepng(file) | |||
|
843 | else | |||
|
844 | self.Error('Unsupported image file type: '+type) | |||
|
845 | end | |||
|
846 | info['i']=@images.length+1 | |||
|
847 | @images[file]=info | |||
|
848 | else | |||
|
849 | info=@images[file] | |||
|
850 | end | |||
|
851 | #Ed Moss | |||
|
852 | if(w==0 && h==0) | |||
|
853 | #Put image at 72 dpi | |||
|
854 | w=info['w']/@k; | |||
|
855 | h=info['h']/@k; | |||
|
856 | end | |||
|
857 | # | |||
|
858 | # Automatic width or height calculation | |||
|
859 | w=h*info['w']/info['h'] if w==0 | |||
|
860 | h=w*info['h']/info['w'] if h==0 | |||
|
861 | out(sprintf('q %.2f 0 0 %.2f %.2f %.2f cm /I%d Do Q', | |||
|
862 | w*@k,h*@k,x*@k,(@h-(y+h))*@k,info['i'])) | |||
|
863 | Link(x,y,w,h,link) if link and link != '' | |||
|
864 | end | |||
|
865 | ||||
|
866 | def Ln(h='') | |||
|
867 | # Line feed; default value is last cell height | |||
|
868 | @x=@lMargin | |||
|
869 | if h.kind_of?(String) | |||
|
870 | @y=@y+@lasth | |||
|
871 | else | |||
|
872 | @y=@y+h | |||
|
873 | end | |||
|
874 | end | |||
|
875 | ||||
|
876 | def GetX | |||
|
877 | # Get x position | |||
|
878 | @x | |||
|
879 | end | |||
|
880 | ||||
|
881 | def SetX(x) | |||
|
882 | # Set x position | |||
|
883 | if x>=0 | |||
|
884 | @x=x | |||
|
885 | else | |||
|
886 | @x=@w+x | |||
|
887 | end | |||
|
888 | end | |||
|
889 | ||||
|
890 | def GetY | |||
|
891 | # Get y position | |||
|
892 | @y | |||
|
893 | end | |||
|
894 | ||||
|
895 | def SetY(y) | |||
|
896 | # Set y position and reset x | |||
|
897 | @x=@lMargin | |||
|
898 | if y>=0 | |||
|
899 | @y=y | |||
|
900 | else | |||
|
901 | @y=@h+y | |||
|
902 | end | |||
|
903 | end | |||
|
904 | ||||
|
905 | def SetXY(x,y) | |||
|
906 | # Set x and y positions | |||
|
907 | SetY(y) | |||
|
908 | SetX(x) | |||
|
909 | end | |||
|
910 | ||||
|
911 | def Output(file=nil) | |||
|
912 | # Output PDF to file or return as a string | |||
|
913 | ||||
|
914 | # Finish document if necessary | |||
|
915 | self.Close if(@state<3) | |||
|
916 | ||||
|
917 | if file.nil? | |||
|
918 | # Return as a string | |||
|
919 | return @buffer | |||
|
920 | else | |||
|
921 | # Save file locally | |||
|
922 | open(file,'wb') do |f| | |||
|
923 | f.write(@buffer) | |||
|
924 | end | |||
|
925 | end | |||
|
926 | end | |||
|
927 | ||||
|
928 | private | |||
|
929 | ||||
|
930 | def putpages | |||
|
931 | nb=@page | |||
|
932 | unless @AliasNbPages.nil? or @AliasNbPages=='' | |||
|
933 | # Replace number of pages | |||
|
934 | 1.upto(nb) do |n| | |||
|
935 | @pages[n].gsub!(@AliasNbPages,nb.to_s) | |||
|
936 | end | |||
|
937 | end | |||
|
938 | if @DefOrientation=='P' | |||
|
939 | wPt=@fwPt | |||
|
940 | hPt=@fhPt | |||
|
941 | else | |||
|
942 | wPt=@fhPt | |||
|
943 | hPt=@fwPt | |||
|
944 | end | |||
|
945 | filter=(@compress) ? '/Filter /FlateDecode ' : '' | |||
|
946 | 1.upto(nb) do |n| | |||
|
947 | # Page | |||
|
948 | newobj | |||
|
949 | out('<</Type /Page') | |||
|
950 | out('/Parent 1 0 R') | |||
|
951 | unless @OrientationChanges[n].nil? | |||
|
952 | out(sprintf('/MediaBox [0 0 %.2f %.2f]',hPt,wPt)) | |||
|
953 | end | |||
|
954 | out('/Resources 2 0 R') | |||
|
955 | if @PageLinks[n] | |||
|
956 | # Links | |||
|
957 | annots='/Annots [' | |||
|
958 | @PageLinks[n].each do |pl| | |||
|
959 | rect=sprintf('%.2f %.2f %.2f %.2f', | |||
|
960 | pl[0],pl[1],pl[0]+pl[2],pl[1]-pl[3]) | |||
|
961 | annots=annots+'<</Type /Annot /Subtype /Link /Rect ['+rect+ | |||
|
962 | '] /Border [0 0 0] ' | |||
|
963 | if pl[4].kind_of?(String) | |||
|
964 | annots=annots+'/A <</S /URI /URI '+textstring(pl[4])+ | |||
|
965 | '>>>>' | |||
|
966 | else | |||
|
967 | l=@links[pl[4]] | |||
|
968 | h=@OrientationChanges[l[0]].nil? ? hPt : wPt | |||
|
969 | annots=annots+sprintf( | |||
|
970 | '/Dest [%d 0 R /XYZ 0 %.2f null]>>', | |||
|
971 | 1+2*l[0],h-l[1]*@k) | |||
|
972 | end | |||
|
973 | end | |||
|
974 | out(annots+']') | |||
|
975 | end | |||
|
976 | out('/Contents '+(@n+1).to_s+' 0 R>>') | |||
|
977 | out('endobj') | |||
|
978 | # Page content | |||
|
979 | p=(@compress) ? Zlib::Deflate.deflate(@pages[n]) : @pages[n] | |||
|
980 | newobj | |||
|
981 | out('<<'+filter+'/Length '+p.length.to_s+'>>') | |||
|
982 | putstream(p) | |||
|
983 | out('endobj') | |||
|
984 | end | |||
|
985 | # Pages root | |||
|
986 | @offsets[1]=@buffer.length | |||
|
987 | out('1 0 obj') | |||
|
988 | out('<</Type /Pages') | |||
|
989 | kids='/Kids [' | |||
|
990 | nb.times do |i| | |||
|
991 | kids=kids+(3+2*i).to_s+' 0 R ' | |||
|
992 | end | |||
|
993 | out(kids+']') | |||
|
994 | out('/Count '+nb.to_s) | |||
|
995 | out(sprintf('/MediaBox [0 0 %.2f %.2f]',wPt,hPt)) | |||
|
996 | out('>>') | |||
|
997 | out('endobj') | |||
|
998 | end | |||
|
999 | ||||
|
1000 | def putfonts | |||
|
1001 | nf=@n | |||
|
1002 | @diffs.each do |diff| | |||
|
1003 | # Encodings | |||
|
1004 | newobj | |||
|
1005 | out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences '+ | |||
|
1006 | '['+diff+']>>') | |||
|
1007 | out('endobj') | |||
|
1008 | end | |||
|
1009 | ||||
|
1010 | @FontFiles.each do |file, info| | |||
|
1011 | # Font file embedding | |||
|
1012 | newobj | |||
|
1013 | @FontFiles[file]['n'] = @n | |||
|
1014 | ||||
|
1015 | if self.class.const_defined? 'FPDF_FONTPATH' then | |||
|
1016 | if FPDF_FONTPATH[-1,1] == '/' then | |||
|
1017 | file = FPDF_FONTPATH + file | |||
|
1018 | else | |||
|
1019 | file = FPDF_FONTPATH + '/' + file | |||
|
1020 | end | |||
|
1021 | end | |||
|
1022 | ||||
|
1023 | size = File.size(file) | |||
|
1024 | unless File.exists?(file) | |||
|
1025 | Error('Font file not found') | |||
|
1026 | end | |||
|
1027 | ||||
|
1028 | out('<</Length ' + size.to_s) | |||
|
1029 | ||||
|
1030 | if file[-2, 2] == '.z' then | |||
|
1031 | out('/Filter /FlateDecode') | |||
|
1032 | end | |||
|
1033 | out('/Length1 ' + info['length1']) | |||
|
1034 | out('/Length2 ' + info['length2'] + ' /Length3 0') if info['length2'] | |||
|
1035 | out('>>') | |||
|
1036 | open(file, 'rb') do |f| | |||
|
1037 | putstream(f.read()) | |||
|
1038 | end | |||
|
1039 | out('endobj') | |||
|
1040 | end | |||
|
1041 | ||||
|
1042 | file = 0 | |||
|
1043 | @fonts.each do |k, font| | |||
|
1044 | # Font objects | |||
|
1045 | @fonts[k]['n']=@n+1 | |||
|
1046 | type=font['type'] | |||
|
1047 | name=font['name'] | |||
|
1048 | if type=='core' | |||
|
1049 | # Standard font | |||
|
1050 | newobj | |||
|
1051 | out('<</Type /Font') | |||
|
1052 | out('/BaseFont /'+name) | |||
|
1053 | out('/Subtype /Type1') | |||
|
1054 | if name!='Symbol' and name!='ZapfDingbats' | |||
|
1055 | out('/Encoding /WinAnsiEncoding') | |||
|
1056 | end | |||
|
1057 | out('>>') | |||
|
1058 | out('endobj') | |||
|
1059 | elsif type=='Type1' or type=='TrueType' | |||
|
1060 | # Additional Type1 or TrueType font | |||
|
1061 | newobj | |||
|
1062 | out('<</Type /Font') | |||
|
1063 | out('/BaseFont /'+name) | |||
|
1064 | out('/Subtype /'+type) | |||
|
1065 | out('/FirstChar 32 /LastChar 255') | |||
|
1066 | out('/Widths '+(@n+1).to_s+' 0 R') | |||
|
1067 | out('/FontDescriptor '+(@n+2).to_s+' 0 R') | |||
|
1068 | if font['enc'] and font['enc'] != '' | |||
|
1069 | unless font['diff'].nil? | |||
|
1070 | out('/Encoding '+(nf+font['diff']).to_s+' 0 R') | |||
|
1071 | else | |||
|
1072 | out('/Encoding /WinAnsiEncoding') | |||
|
1073 | end | |||
|
1074 | end | |||
|
1075 | out('>>') | |||
|
1076 | out('endobj') | |||
|
1077 | # Widths | |||
|
1078 | newobj | |||
|
1079 | cw=font['cw'] | |||
|
1080 | s='[' | |||
|
1081 | 32.upto(255) do |i| | |||
|
1082 | s << cw[i].to_s+' ' | |||
|
1083 | end | |||
|
1084 | out(s+']') | |||
|
1085 | out('endobj') | |||
|
1086 | # Descriptor | |||
|
1087 | newobj | |||
|
1088 | s='<</Type /FontDescriptor /FontName /'+name | |||
|
1089 | font['desc'].each do |k, v| | |||
|
1090 | s << ' /'+k+' '+v | |||
|
1091 | end | |||
|
1092 | file=font['file'] | |||
|
1093 | if file | |||
|
1094 | s << ' /FontFile'+(type=='Type1' ? '' : '2')+' '+ | |||
|
1095 | @FontFiles[file]['n'].to_s+' 0 R' | |||
|
1096 | end | |||
|
1097 | out(s+'>>') | |||
|
1098 | out('endobj') | |||
|
1099 | else | |||
|
1100 | # Allow for additional types | |||
|
1101 | mtd='put'+type.downcase | |||
|
1102 | unless self.respond_to?(mtd) | |||
|
1103 | self.Error('Unsupported font type: '+type) | |||
|
1104 | end | |||
|
1105 | self.send(mtd, font) | |||
|
1106 | end | |||
|
1107 | end | |||
|
1108 | end | |||
|
1109 | ||||
|
1110 | def putimages | |||
|
1111 | filter=(@compress) ? '/Filter /FlateDecode ' : '' | |||
|
1112 | @images.each do |file, info| | |||
|
1113 | newobj | |||
|
1114 | @images[file]['n']=@n | |||
|
1115 | out('<</Type /XObject') | |||
|
1116 | out('/Subtype /Image') | |||
|
1117 | out('/Width '+info['w'].to_s) | |||
|
1118 | out('/Height '+info['h'].to_s) | |||
|
1119 | if info['cs']=='Indexed' | |||
|
1120 | out("/ColorSpace [/Indexed /DeviceRGB #{info['pal'].length/3-1} #{(@n+1)} 0 R]") | |||
|
1121 | else | |||
|
1122 | out('/ColorSpace /'+info['cs']) | |||
|
1123 | if info['cs']=='DeviceCMYK' | |||
|
1124 | out('/Decode [1 0 1 0 1 0 1 0]') | |||
|
1125 | end | |||
|
1126 | end | |||
|
1127 | out('/BitsPerComponent '+info['bpc'].to_s) | |||
|
1128 | out('/Filter /'+info['f']) if info['f'] | |||
|
1129 | unless info['parms'].nil? | |||
|
1130 | out(info['parms']) | |||
|
1131 | end | |||
|
1132 | if info['trns'] and info['trns'].kind_of?(Array) | |||
|
1133 | trns='' | |||
|
1134 | info['trns'].length.times do |i| | |||
|
1135 | trns=trns+info['trns'][i].to_s+' '+info['trns'][i].to_s+' ' | |||
|
1136 | end | |||
|
1137 | out('/Mask ['+trns+']') | |||
|
1138 | end | |||
|
1139 | out('/Length '+info['data'].length.to_s+'>>') | |||
|
1140 | putstream(info['data']) | |||
|
1141 | @images[file]['data']=nil | |||
|
1142 | out('endobj') | |||
|
1143 | # Palette | |||
|
1144 | if info['cs']=='Indexed' | |||
|
1145 | newobj | |||
|
1146 | pal=(@compress) ? Zlib::Deflate.deflate(info['pal']) : info['pal'] | |||
|
1147 | out('<<'+filter+'/Length '+pal.length.to_s+'>>') | |||
|
1148 | putstream(pal) | |||
|
1149 | out('endobj') | |||
|
1150 | end | |||
|
1151 | end | |||
|
1152 | end | |||
|
1153 | ||||
|
1154 | def putxobjectdict | |||
|
1155 | @images.each_value do |image| | |||
|
1156 | out('/I'+image['i'].to_s+' '+image['n'].to_s+' 0 R') | |||
|
1157 | end | |||
|
1158 | end | |||
|
1159 | ||||
|
1160 | def putresourcedict | |||
|
1161 | out('/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]') | |||
|
1162 | out('/Font <<') | |||
|
1163 | @fonts.each_value do |font| | |||
|
1164 | out('/F'+font['i'].to_s+' '+font['n'].to_s+' 0 R') | |||
|
1165 | end | |||
|
1166 | out('>>') | |||
|
1167 | out('/XObject <<') | |||
|
1168 | putxobjectdict | |||
|
1169 | out('>>') | |||
|
1170 | end | |||
|
1171 | ||||
|
1172 | def putresources | |||
|
1173 | putfonts | |||
|
1174 | putimages | |||
|
1175 | # Resource dictionary | |||
|
1176 | @offsets[2]=@buffer.length | |||
|
1177 | out('2 0 obj') | |||
|
1178 | out('<<') | |||
|
1179 | putresourcedict | |||
|
1180 | out('>>') | |||
|
1181 | out('endobj') | |||
|
1182 | end | |||
|
1183 | ||||
|
1184 | def putinfo | |||
|
1185 | out('/Producer '+textstring('Ruby FPDF '+FPDF_VERSION)); | |||
|
1186 | unless @title.nil? | |||
|
1187 | out('/Title '+textstring(@title)) | |||
|
1188 | end | |||
|
1189 | unless @subject.nil? | |||
|
1190 | out('/Subject '+textstring(@subject)) | |||
|
1191 | end | |||
|
1192 | unless @author.nil? | |||
|
1193 | out('/Author '+textstring(@author)) | |||
|
1194 | end | |||
|
1195 | unless @keywords.nil? | |||
|
1196 | out('/Keywords '+textstring(@keywords)) | |||
|
1197 | end | |||
|
1198 | unless @creator.nil? | |||
|
1199 | out('/Creator '+textstring(@creator)) | |||
|
1200 | end | |||
|
1201 | out('/CreationDate '+textstring('D: '+DateTime.now.to_s)) | |||
|
1202 | end | |||
|
1203 | ||||
|
1204 | def putcatalog | |||
|
1205 | out('/Type /Catalog') | |||
|
1206 | out('/Pages 1 0 R') | |||
|
1207 | if @ZoomMode=='fullpage' | |||
|
1208 | out('/OpenAction [3 0 R /Fit]') | |||
|
1209 | elsif @ZoomMode=='fullwidth' | |||
|
1210 | out('/OpenAction [3 0 R /FitH null]') | |||
|
1211 | elsif @ZoomMode=='real' | |||
|
1212 | out('/OpenAction [3 0 R /XYZ null null 1]') | |||
|
1213 | elsif not @ZoomMode.kind_of?(String) | |||
|
1214 | out('/OpenAction [3 0 R /XYZ null null '+(@ZoomMode/100)+']') | |||
|
1215 | end | |||
|
1216 | ||||
|
1217 | if @LayoutMode=='single' | |||
|
1218 | out('/PageLayout /SinglePage') | |||
|
1219 | elsif @LayoutMode=='continuous' | |||
|
1220 | out('/PageLayout /OneColumn') | |||
|
1221 | elsif @LayoutMode=='two' | |||
|
1222 | out('/PageLayout /TwoColumnLeft') | |||
|
1223 | end | |||
|
1224 | end | |||
|
1225 | ||||
|
1226 | def putheader | |||
|
1227 | out('%PDF-'+@PDFVersion) | |||
|
1228 | end | |||
|
1229 | ||||
|
1230 | def puttrailer | |||
|
1231 | out('/Size '+(@n+1).to_s) | |||
|
1232 | out('/Root '+@n.to_s+' 0 R') | |||
|
1233 | out('/Info '+(@n-1).to_s+' 0 R') | |||
|
1234 | end | |||
|
1235 | ||||
|
1236 | def enddoc | |||
|
1237 | putheader | |||
|
1238 | putpages | |||
|
1239 | putresources | |||
|
1240 | # Info | |||
|
1241 | newobj | |||
|
1242 | out('<<') | |||
|
1243 | putinfo | |||
|
1244 | out('>>') | |||
|
1245 | out('endobj') | |||
|
1246 | # Catalog | |||
|
1247 | newobj | |||
|
1248 | out('<<') | |||
|
1249 | putcatalog | |||
|
1250 | out('>>') | |||
|
1251 | out('endobj') | |||
|
1252 | # Cross-ref | |||
|
1253 | o=@buffer.length | |||
|
1254 | out('xref') | |||
|
1255 | out('0 '+(@n+1).to_s) | |||
|
1256 | out('0000000000 65535 f ') | |||
|
1257 | 1.upto(@n) do |i| | |||
|
1258 | out(sprintf('%010d 00000 n ',@offsets[i])) | |||
|
1259 | end | |||
|
1260 | # Trailer | |||
|
1261 | out('trailer') | |||
|
1262 | out('<<') | |||
|
1263 | puttrailer | |||
|
1264 | out('>>') | |||
|
1265 | out('startxref') | |||
|
1266 | out(o) | |||
|
1267 | out('%%EOF') | |||
|
1268 | state=3 | |||
|
1269 | end | |||
|
1270 | ||||
|
1271 | def beginpage(orientation) | |||
|
1272 | @page=@page+1 | |||
|
1273 | @pages[@page]='' | |||
|
1274 | @state=2 | |||
|
1275 | @x=@lMargin | |||
|
1276 | @y=@tMargin | |||
|
1277 | @lasth=0 | |||
|
1278 | @FontFamily='' | |||
|
1279 | # Page orientation | |||
|
1280 | if orientation=='' | |||
|
1281 | orientation=@DefOrientation | |||
|
1282 | else | |||
|
1283 | orientation=orientation[0].chr.upcase | |||
|
1284 | if orientation!=@DefOrientation | |||
|
1285 | @OrientationChanges[@page]=true | |||
|
1286 | end | |||
|
1287 | end | |||
|
1288 | if orientation!=@CurOrientation | |||
|
1289 | # Change orientation | |||
|
1290 | if orientation=='P' | |||
|
1291 | @wPt=@fwPt | |||
|
1292 | @hPt=@fhPt | |||
|
1293 | @w=@fw | |||
|
1294 | @h=@fh | |||
|
1295 | else | |||
|
1296 | @wPt=@fhPt | |||
|
1297 | @hPt=@fwPt | |||
|
1298 | @w=@fh | |||
|
1299 | @h=@fw | |||
|
1300 | end | |||
|
1301 | @PageBreakTrigger=@h-@bMargin | |||
|
1302 | @CurOrientation=orientation | |||
|
1303 | end | |||
|
1304 | end | |||
|
1305 | ||||
|
1306 | def endpage | |||
|
1307 | # End of page contents | |||
|
1308 | @state=1 | |||
|
1309 | end | |||
|
1310 | ||||
|
1311 | def newobj | |||
|
1312 | # Begin a new object | |||
|
1313 | @n=@n+1 | |||
|
1314 | @offsets[@n]=@buffer.length | |||
|
1315 | out(@n.to_s+' 0 obj') | |||
|
1316 | end | |||
|
1317 | ||||
|
1318 | def dounderline(x,y,txt) | |||
|
1319 | # Underline text | |||
|
1320 | up=@CurrentFont['up'] | |||
|
1321 | ut=@CurrentFont['ut'] | |||
|
1322 | w=GetStringWidth(txt)+@ws*txt.count(' ') | |||
|
1323 | sprintf('%.2f %.2f %.2f %.2f re f', | |||
|
1324 | x*@k,(@h-(y-up/1000.0*@FontSize))*@k,w*@k,-ut/1000.0*@FontSizePt) | |||
|
1325 | end | |||
|
1326 | ||||
|
1327 | def parsejpg(file) | |||
|
1328 | # Extract info from a JPEG file | |||
|
1329 | a=extractjpginfo(file) | |||
|
1330 | raise "Missing or incorrect JPEG file: #{file}" if a.nil? | |||
|
1331 | ||||
|
1332 | if a['channels'].nil? || a['channels']==3 then | |||
|
1333 | colspace='DeviceRGB' | |||
|
1334 | elsif a['channels']==4 then | |||
|
1335 | colspace='DeviceCMYK' | |||
|
1336 | else | |||
|
1337 | colspace='DeviceGray' | |||
|
1338 | end | |||
|
1339 | bpc= a['bits'] ? a['bits'].to_i : 8 | |||
|
1340 | ||||
|
1341 | # Read whole file | |||
|
1342 | data = nil | |||
|
1343 | open(file, 'rb') do |f| | |||
|
1344 | data = f.read | |||
|
1345 | end | |||
|
1346 | return {'w'=>a['width'],'h'=>a['height'],'cs'=>colspace,'bpc'=>bpc,'f'=>'DCTDecode','data'=>data} | |||
|
1347 | end | |||
|
1348 | ||||
|
1349 | def parsepng(file) | |||
|
1350 | # Extract info from a PNG file | |||
|
1351 | f=open(file,'rb') | |||
|
1352 | # Check signature | |||
|
1353 | unless f.read(8)==137.chr+'PNG'+13.chr+10.chr+26.chr+10.chr | |||
|
1354 | self.Error('Not a PNG file: '+file) | |||
|
1355 | end | |||
|
1356 | # Read header chunk | |||
|
1357 | f.read(4) | |||
|
1358 | if f.read(4)!='IHDR' | |||
|
1359 | self.Error('Incorrect PNG file: '+file) | |||
|
1360 | end | |||
|
1361 | w=freadint(f) | |||
|
1362 | h=freadint(f) | |||
|
1363 | bpc=f.read(1)[0] | |||
|
1364 | if bpc>8 | |||
|
1365 | self.Error('16-bit depth not supported: '+file) | |||
|
1366 | end | |||
|
1367 | ct=f.read(1)[0] | |||
|
1368 | if ct==0 | |||
|
1369 | colspace='DeviceGray' | |||
|
1370 | elsif ct==2 | |||
|
1371 | colspace='DeviceRGB' | |||
|
1372 | elsif ct==3 | |||
|
1373 | colspace='Indexed' | |||
|
1374 | else | |||
|
1375 | self.Error('Alpha channel not supported: '+file) | |||
|
1376 | end | |||
|
1377 | if f.read(1)[0]!=0 | |||
|
1378 | self.Error('Unknown compression method: '+file) | |||
|
1379 | end | |||
|
1380 | if f.read(1)[0]!=0 | |||
|
1381 | self.Error('Unknown filter method: '+file) | |||
|
1382 | end | |||
|
1383 | if f.read(1)[0]!=0 | |||
|
1384 | self.Error('Interlacing not supported: '+file) | |||
|
1385 | end | |||
|
1386 | f.read(4) | |||
|
1387 | parms='/DecodeParms <</Predictor 15 /Colors '+(ct==2 ? '3' : '1')+ | |||
|
1388 | ' /BitsPerComponent '+bpc.to_s+' /Columns '+w.to_s+'>>' | |||
|
1389 | # Scan chunks looking for palette, transparency and image data | |||
|
1390 | pal='' | |||
|
1391 | trns='' | |||
|
1392 | data='' | |||
|
1393 | begin | |||
|
1394 | n=freadint(f) | |||
|
1395 | type=f.read(4) | |||
|
1396 | if type=='PLTE' | |||
|
1397 | # Read palette | |||
|
1398 | pal=f.read(n) | |||
|
1399 | f.read(4) | |||
|
1400 | elsif type=='tRNS' | |||
|
1401 | # Read transparency info | |||
|
1402 | t=f.read(n) | |||
|
1403 | if ct==0 | |||
|
1404 | trns=[t[1]] | |||
|
1405 | elsif ct==2 | |||
|
1406 | trns=[t[1],t[3],t[5]] | |||
|
1407 | else | |||
|
1408 | pos=t.index(0) | |||
|
1409 | trns=[pos] unless pos.nil? | |||
|
1410 | end | |||
|
1411 | f.read(4) | |||
|
1412 | elsif type=='IDAT' | |||
|
1413 | # Read image data block | |||
|
1414 | data << f.read(n) | |||
|
1415 | f.read(4) | |||
|
1416 | elsif type=='IEND' | |||
|
1417 | break | |||
|
1418 | else | |||
|
1419 | f.read(n+4) | |||
|
1420 | end | |||
|
1421 | end while n | |||
|
1422 | if colspace=='Indexed' and pal=='' | |||
|
1423 | self.Error('Missing palette in '+file) | |||
|
1424 | end | |||
|
1425 | f.close | |||
|
1426 | {'w'=>w,'h'=>h,'cs'=>colspace,'bpc'=>bpc,'f'=>'FlateDecode', | |||
|
1427 | 'parms'=>parms,'pal'=>pal,'trns'=>trns,'data'=>data} | |||
|
1428 | end | |||
|
1429 | ||||
|
1430 | def freadint(f) | |||
|
1431 | # Read a 4-byte integer from file | |||
|
1432 | a = f.read(4).unpack('N') | |||
|
1433 | return a[0] | |||
|
1434 | end | |||
|
1435 | ||||
|
1436 | def freadshort(f) | |||
|
1437 | a = f.read(2).unpack('n') | |||
|
1438 | return a[0] | |||
|
1439 | end | |||
|
1440 | ||||
|
1441 | def freadbyte(f) | |||
|
1442 | a = f.read(1).unpack('C') | |||
|
1443 | return a[0] | |||
|
1444 | end | |||
|
1445 | ||||
|
1446 | def textstring(s) | |||
|
1447 | # Format a text string | |||
|
1448 | '('+escape(s)+')' | |||
|
1449 | end | |||
|
1450 | ||||
|
1451 | def escape(s) | |||
|
1452 | # Add \ before \, ( and ) | |||
|
1453 | s.gsub('\\','\\\\').gsub('(','\\(').gsub(')','\\)') | |||
|
1454 | end | |||
|
1455 | ||||
|
1456 | def putstream(s) | |||
|
1457 | out('stream') | |||
|
1458 | out(s) | |||
|
1459 | out('endstream') | |||
|
1460 | end | |||
|
1461 | ||||
|
1462 | def out(s) | |||
|
1463 | # Add a line to the document | |||
|
1464 | if @state==2 | |||
|
1465 | @pages[@page]=@pages[@page]+s+"\n" | |||
|
1466 | else | |||
|
1467 | @buffer=@buffer+s.to_s+"\n" | |||
|
1468 | end | |||
|
1469 | end | |||
|
1470 | ||||
|
1471 | # jpeg marker codes | |||
|
1472 | ||||
|
1473 | M_SOF0 = 0xc0 | |||
|
1474 | M_SOF1 = 0xc1 | |||
|
1475 | M_SOF2 = 0xc2 | |||
|
1476 | M_SOF3 = 0xc3 | |||
|
1477 | ||||
|
1478 | M_SOF5 = 0xc5 | |||
|
1479 | M_SOF6 = 0xc6 | |||
|
1480 | M_SOF7 = 0xc7 | |||
|
1481 | ||||
|
1482 | M_SOF9 = 0xc9 | |||
|
1483 | M_SOF10 = 0xca | |||
|
1484 | M_SOF11 = 0xcb | |||
|
1485 | ||||
|
1486 | M_SOF13 = 0xcd | |||
|
1487 | M_SOF14 = 0xce | |||
|
1488 | M_SOF15 = 0xcf | |||
|
1489 | ||||
|
1490 | M_SOI = 0xd8 | |||
|
1491 | M_EOI = 0xd9 | |||
|
1492 | M_SOS = 0xda | |||
|
1493 | ||||
|
1494 | def extractjpginfo(file) | |||
|
1495 | result = nil | |||
|
1496 | ||||
|
1497 | open(file, "rb") do |f| | |||
|
1498 | marker = jpegnextmarker(f) | |||
|
1499 | ||||
|
1500 | if marker != M_SOI | |||
|
1501 | return nil | |||
|
1502 | end | |||
|
1503 | ||||
|
1504 | while true | |||
|
1505 | marker = jpegnextmarker(f) | |||
|
1506 | ||||
|
1507 | case marker | |||
|
1508 | when M_SOF0, M_SOF1, M_SOF2, M_SOF3, | |||
|
1509 | M_SOF5, M_SOF6, M_SOF7, M_SOF9, | |||
|
1510 | M_SOF10, M_SOF11, M_SOF13, M_SOF14, | |||
|
1511 | M_SOF15 then | |||
|
1512 | ||||
|
1513 | length = freadshort(f) | |||
|
1514 | ||||
|
1515 | if result.nil? | |||
|
1516 | result = {} | |||
|
1517 | ||||
|
1518 | result['bits'] = freadbyte(f) | |||
|
1519 | result['height'] = freadshort(f) | |||
|
1520 | result['width'] = freadshort(f) | |||
|
1521 | result['channels'] = freadbyte(f) | |||
|
1522 | ||||
|
1523 | f.seek(length - 8, IO::SEEK_CUR) | |||
|
1524 | else | |||
|
1525 | f.seek(length - 2, IO::SEEK_CUR) | |||
|
1526 | end | |||
|
1527 | when M_SOS, M_EOI then | |||
|
1528 | return result | |||
|
1529 | else | |||
|
1530 | length = freadshort(f) | |||
|
1531 | f.seek(length - 2, IO::SEEK_CUR) | |||
|
1532 | end | |||
|
1533 | end | |||
|
1534 | end | |||
|
1535 | end | |||
|
1536 | ||||
|
1537 | def jpegnextmarker(f) | |||
|
1538 | while true | |||
|
1539 | # look for 0xff | |||
|
1540 | while (c = freadbyte(f)) != 0xff | |||
|
1541 | end | |||
|
1542 | ||||
|
1543 | c = freadbyte(f) | |||
|
1544 | ||||
|
1545 | if c != 0 | |||
|
1546 | return c | |||
|
1547 | end | |||
|
1548 | end | |||
|
1549 | end | |||
|
1550 | end |
@@ -0,0 +1,139 | |||||
|
1 | # Information | |||
|
2 | # | |||
|
3 | # PDF_EPS class from Valentin Schmidt ported to ruby by Thiago Jackiw (tjackiw@gmail.com) | |||
|
4 | # working for Mingle LLC (www.mingle.com) | |||
|
5 | # Release Date: July 13th, 2006 | |||
|
6 | # | |||
|
7 | # Description | |||
|
8 | # | |||
|
9 | # This script allows to embed vector-based Adobe Illustrator (AI) or AI-compatible EPS files. | |||
|
10 | # Only vector drawing is supported, not text or bitmap. Although the script was successfully | |||
|
11 | # tested with various AI format versions, best results are probably achieved with files that | |||
|
12 | # were exported in the AI3 format (tested with Illustrator CS2, Freehand MX and Photoshop CS2). | |||
|
13 | # | |||
|
14 | # ImageEps(string file, float x, float y [, float w [, float h [, string link [, boolean useBoundingBox]]]]) | |||
|
15 | # | |||
|
16 | # Same parameters as for regular FPDF::Image() method, with an additional one: | |||
|
17 | # | |||
|
18 | # useBoundingBox: specifies whether to position the bounding box (true) or the complete canvas (false) | |||
|
19 | # at location (x,y). Default value is true. | |||
|
20 | # | |||
|
21 | # First added to the Ruby FPDF distribution in 1.53c | |||
|
22 | # | |||
|
23 | # Usage is as follows: | |||
|
24 | # | |||
|
25 | # require 'fpdf' | |||
|
26 | # require 'fpdf_eps' | |||
|
27 | # pdf = FPDF.new | |||
|
28 | # pdf.extend(PDF_EPS) | |||
|
29 | # pdf.ImageEps(...) | |||
|
30 | # | |||
|
31 | # This allows it to be combined with other extensions, such as the bookmark | |||
|
32 | # module. | |||
|
33 | ||||
|
34 | module PDF_EPS | |||
|
35 | def ImageEps(file, x, y, w=0, h=0, link='', use_bounding_box=true) | |||
|
36 | data = nil | |||
|
37 | if File.exists?(file) | |||
|
38 | File.open(file, 'rb') do |f| | |||
|
39 | data = f.read() | |||
|
40 | end | |||
|
41 | else | |||
|
42 | Error('EPS file not found: '+file) | |||
|
43 | end | |||
|
44 | ||||
|
45 | # Find BoundingBox param | |||
|
46 | regs = data.scan(/%%BoundingBox: [^\r\n]*/m) | |||
|
47 | regs << regs[0].gsub(/%%BoundingBox: /, '') | |||
|
48 | if regs.size > 1 | |||
|
49 | tmp = regs[1].to_s.split(' ') | |||
|
50 | @x1 = tmp[0].to_i | |||
|
51 | @y1 = tmp[1].to_i | |||
|
52 | @x2 = tmp[2].to_i | |||
|
53 | @y2 = tmp[3].to_i | |||
|
54 | else | |||
|
55 | Error('No BoundingBox found in EPS file: '+file) | |||
|
56 | end | |||
|
57 | f_start = data.index('%%EndSetup') | |||
|
58 | f_start = data.index('%%EndProlog') if f_start === false | |||
|
59 | f_start = data.index('%%BoundingBox') if f_start === false | |||
|
60 | ||||
|
61 | data = data.slice(f_start, data.length) | |||
|
62 | ||||
|
63 | f_end = data.index('%%PageTrailer') | |||
|
64 | f_end = data.index('showpage') if f_end === false | |||
|
65 | data = data.slice(0, f_end) if f_end | |||
|
66 | ||||
|
67 | # save the current graphic state | |||
|
68 | out('q') | |||
|
69 | ||||
|
70 | k = @k | |||
|
71 | ||||
|
72 | # Translate | |||
|
73 | if use_bounding_box | |||
|
74 | dx = x*k-@x1 | |||
|
75 | dy = @hPt-@y2-y*k | |||
|
76 | else | |||
|
77 | dx = x*k | |||
|
78 | dy = -y*k | |||
|
79 | end | |||
|
80 | tm = [1,0,0,1,dx,dy] | |||
|
81 | out(sprintf('%.3f %.3f %.3f %.3f %.3f %.3f cm', | |||
|
82 | tm[0], tm[1], tm[2], tm[3], tm[4], tm[5])) | |||
|
83 | ||||
|
84 | if w > 0 | |||
|
85 | scale_x = w/((@x2-@x1)/k) | |||
|
86 | if h > 0 | |||
|
87 | scale_y = h/((@y2-@y1)/k) | |||
|
88 | else | |||
|
89 | scale_y = scale_x | |||
|
90 | h = (@y2-@y1)/k * scale_y | |||
|
91 | end | |||
|
92 | else | |||
|
93 | if h > 0 | |||
|
94 | scale_y = $h/((@y2-@y1)/$k) | |||
|
95 | scale_x = scale_y | |||
|
96 | w = (@x2-@x1)/k * scale_x | |||
|
97 | else | |||
|
98 | w = (@x2-@x1)/k | |||
|
99 | h = (@y2-@y1)/k | |||
|
100 | end | |||
|
101 | end | |||
|
102 | ||||
|
103 | if !scale_x.nil? | |||
|
104 | # Scale | |||
|
105 | tm = [scale_x,0,0,scale_y,0,@hPt*(1-scale_y)] | |||
|
106 | out(sprintf('%.3f %.3f %.3f %.3f %.3f %.3f cm', | |||
|
107 | tm[0], tm[1], tm[2], tm[3], tm[4], tm[5])) | |||
|
108 | end | |||
|
109 | ||||
|
110 | data.split(/\r\n|[\r\n]/).each do |line| | |||
|
111 | next if line == '' || line[0,1] == '%' | |||
|
112 | len = line.length | |||
|
113 | # next if (len > 2 && line[len-2,len] != ' ') | |||
|
114 | cmd = line[len-2,len].strip | |||
|
115 | case cmd | |||
|
116 | when 'm', 'l', 'v', 'y', 'c', 'k', 'K', 'g', 'G', 's', 'S', 'J', 'j', 'w', 'M', 'd': | |||
|
117 | out(line) | |||
|
118 | ||||
|
119 | when 'L': | |||
|
120 | line[len-1,len]='l' | |||
|
121 | out(line) | |||
|
122 | ||||
|
123 | when 'C': | |||
|
124 | line[len-1,len]='c' | |||
|
125 | out(line) | |||
|
126 | ||||
|
127 | when 'f', 'F': | |||
|
128 | out('f*') | |||
|
129 | ||||
|
130 | when 'b', 'B': | |||
|
131 | out(cmd + '*') | |||
|
132 | end | |||
|
133 | end | |||
|
134 | ||||
|
135 | # restore previous graphic state | |||
|
136 | out('Q') | |||
|
137 | Link(x,y,w,h,link) if link | |||
|
138 | end | |||
|
139 | end |
@@ -0,0 +1,468 | |||||
|
1 | # Copyright (c) 2006 4ssoM LLC <www.4ssoM.com> | |||
|
2 | # 1.12 contributed by Ed Moss. | |||
|
3 | # | |||
|
4 | # The MIT License | |||
|
5 | # | |||
|
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
|
7 | # of this software and associated documentation files (the "Software"), to deal | |||
|
8 | # in the Software without restriction, including without limitation the rights | |||
|
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||
|
10 | # copies of the Software, and to permit persons to whom the Software is | |||
|
11 | # furnished to do so, subject to the following conditions: | |||
|
12 | # | |||
|
13 | # The above copyright notice and this permission notice shall be included in | |||
|
14 | # all copies or substantial portions of the Software. | |||
|
15 | # | |||
|
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
|
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
|
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
|
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
|
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||
|
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |||
|
22 | # THE SOFTWARE. | |||
|
23 | # | |||
|
24 | # This is direct port of japanese.php | |||
|
25 | # | |||
|
26 | # Japanese PDF support. | |||
|
27 | # | |||
|
28 | # Usage is as follows: | |||
|
29 | # | |||
|
30 | # require 'fpdf' | |||
|
31 | # require 'chinese' | |||
|
32 | # pdf = FPDF.new | |||
|
33 | # pdf.extend(PDF_Japanese) | |||
|
34 | # | |||
|
35 | # This allows it to be combined with other extensions, such as the bookmark | |||
|
36 | # module. | |||
|
37 | ||||
|
38 | module PDF_Japanese | |||
|
39 | ||||
|
40 | SJIS_widths={' ' => 278, '!' => 299, '"' => 353, '#' => 614, '$' => 614, '%' => 721, '&' => 735, '\'' => 216, | |||
|
41 | '(' => 323, ')' => 323, '*' => 449, '+' => 529, ',' => 219, '-' => 306, '.' => 219, '/' => 453, '0' => 614, '1' => 614, | |||
|
42 | '2' => 614, '3' => 614, '4' => 614, '5' => 614, '6' => 614, '7' => 614, '8' => 614, '9' => 614, ':' => 219, ';' => 219, | |||
|
43 | '<' => 529, '=' => 529, '>' => 529, '?' => 486, '@' => 744, 'A' => 646, 'B' => 604, 'C' => 617, 'D' => 681, 'E' => 567, | |||
|
44 | 'F' => 537, 'G' => 647, 'H' => 738, 'I' => 320, 'J' => 433, 'K' => 637, 'L' => 566, 'M' => 904, 'N' => 710, 'O' => 716, | |||
|
45 | 'P' => 605, 'Q' => 716, 'R' => 623, 'S' => 517, 'T' => 601, 'U' => 690, 'V' => 668, 'W' => 990, 'X' => 681, 'Y' => 634, | |||
|
46 | 'Z' => 578, '[' => 316, '\\' => 614, ']' => 316, '^' => 529, '_' => 500, '`' => 387, 'a' => 509, 'b' => 566, 'c' => 478, | |||
|
47 | 'd' => 565, 'e' => 503, 'f' => 337, 'g' => 549, 'h' => 580, 'i' => 275, 'j' => 266, 'k' => 544, 'l' => 276, 'm' => 854, | |||
|
48 | 'n' => 579, 'o' => 550, 'p' => 578, 'q' => 566, 'r' => 410, 's' => 444, 't' => 340, 'u' => 575, 'v' => 512, 'w' => 760, | |||
|
49 | 'x' => 503, 'y' => 529, 'z' => 453, '{' => 326, '|' => 380, '}' => 326, '~' => 387} | |||
|
50 | ||||
|
51 | def AddCIDFont(family,style,name,cw,cMap,registry) | |||
|
52 | fontkey=family.downcase+style.upcase | |||
|
53 | unless @fonts[fontkey].nil? | |||
|
54 | Error("CID font already added: family style") | |||
|
55 | end | |||
|
56 | i=@fonts.length+1 | |||
|
57 | @fonts[fontkey]={'i'=>i,'type'=>'Type0','name'=>name,'up'=>-120,'ut'=>40,'cw'=>cw, | |||
|
58 | 'CMap'=>cMap,'registry'=>registry} | |||
|
59 | end | |||
|
60 | ||||
|
61 | def AddCIDFonts(family,name,cw,cMap,registry) | |||
|
62 | AddCIDFont(family,'',name,cw,cMap,registry) | |||
|
63 | AddCIDFont(family,'B',name+',Bold',cw,cMap,registry) | |||
|
64 | AddCIDFont(family,'I',name+',Italic',cw,cMap,registry) | |||
|
65 | AddCIDFont(family,'BI',name+',BoldItalic',cw,cMap,registry) | |||
|
66 | end | |||
|
67 | ||||
|
68 | def AddSJISFont(family='SJIS') | |||
|
69 | #Add SJIS font with proportional Latin | |||
|
70 | name='KozMinPro-Regular-Acro' | |||
|
71 | cw=SJIS_widths | |||
|
72 | cMap='90msp-RKSJ-H' | |||
|
73 | registry={'ordering'=>'Japan1','supplement'=>2} | |||
|
74 | AddCIDFonts(family,name,cw,cMap,registry) | |||
|
75 | end | |||
|
76 | ||||
|
77 | def AddSJIShwFont(family='SJIS-hw') | |||
|
78 | #Add SJIS font with half-width Latin | |||
|
79 | name='KozMinPro-Regular-Acro' | |||
|
80 | 32.upto(126) do |i| | |||
|
81 | cw[i.chr]=500 | |||
|
82 | end | |||
|
83 | cMap='90ms-RKSJ-H' | |||
|
84 | registry={'ordering'=>'Japan1','supplement'=>2} | |||
|
85 | AddCIDFonts(family,name,cw,cMap,registry) | |||
|
86 | end | |||
|
87 | ||||
|
88 | def GetStringWidth(s) | |||
|
89 | if(@CurrentFont['type']=='Type0') | |||
|
90 | return GetSJISStringWidth(s) | |||
|
91 | else | |||
|
92 | return super(s) | |||
|
93 | end | |||
|
94 | end | |||
|
95 | ||||
|
96 | def GetSJISStringWidth(s) | |||
|
97 | #SJIS version of GetStringWidth() | |||
|
98 | l=0 | |||
|
99 | cw=@CurrentFont['cw'] | |||
|
100 | nb=s.length | |||
|
101 | i=0 | |||
|
102 | while(i<nb) | |||
|
103 | o=s[i] | |||
|
104 | if(o<128) | |||
|
105 | #ASCII | |||
|
106 | l+=cw[o.chr] | |||
|
107 | i+=1 | |||
|
108 | elsif(o>=161 and o<=223) | |||
|
109 | #Half-width katakana | |||
|
110 | l+=500 | |||
|
111 | i+=1 | |||
|
112 | else | |||
|
113 | #Full-width character | |||
|
114 | l+=1000 | |||
|
115 | i+=2 | |||
|
116 | end | |||
|
117 | end | |||
|
118 | return l*@FontSize/1000 | |||
|
119 | end | |||
|
120 | ||||
|
121 | def MultiCell(w,h,txt,border=0,align='L',fill=0) | |||
|
122 | if(@CurrentFont['type']=='Type0') | |||
|
123 | SJISMultiCell(w,h,txt,border,align,fill) | |||
|
124 | else | |||
|
125 | super(w,h,txt,border,align,fill) | |||
|
126 | end | |||
|
127 | end | |||
|
128 | ||||
|
129 | def SJISMultiCell(w,h,txt,border=0,align='L',fill=0) | |||
|
130 | #Output text with automatic or explicit line breaks | |||
|
131 | cw=@CurrentFont['cw'] | |||
|
132 | if(w==0) | |||
|
133 | w=@w-@rMargin-@x | |||
|
134 | end | |||
|
135 | wmax=(w-2*@cMargin)*1000/@FontSize | |||
|
136 | s=txt.gsub("\r",'') | |||
|
137 | nb=s.length | |||
|
138 | if(nb>0 and s[nb-1]=="\n") | |||
|
139 | nb-=1 | |||
|
140 | end | |||
|
141 | b=0 | |||
|
142 | if(border) | |||
|
143 | if(border==1) | |||
|
144 | border='LTRB' | |||
|
145 | b='LRT' | |||
|
146 | b2='LR' | |||
|
147 | else | |||
|
148 | b2='' | |||
|
149 | if(border.index('L').nil?) | |||
|
150 | b2+='L' | |||
|
151 | end | |||
|
152 | if(border.index('R').nil?) | |||
|
153 | b2+='R' | |||
|
154 | end | |||
|
155 | b=border.index('T').nil? ? b2+'T' : b2 | |||
|
156 | end | |||
|
157 | end | |||
|
158 | sep=-1 | |||
|
159 | i=0 | |||
|
160 | j=0 | |||
|
161 | l=0 | |||
|
162 | nl=1 | |||
|
163 | while(i<nb) | |||
|
164 | #Get next character | |||
|
165 | c=s[i] | |||
|
166 | o=ord(c) | |||
|
167 | if(o==10) | |||
|
168 | #Explicit line break | |||
|
169 | Cell(w,h,s[j,i-j],b,2,align,fill) | |||
|
170 | i+=1 | |||
|
171 | sep=-1 | |||
|
172 | j=i | |||
|
173 | l=0 | |||
|
174 | nl+=1 | |||
|
175 | if(border and nl==2) | |||
|
176 | b=b2 | |||
|
177 | end | |||
|
178 | next | |||
|
179 | end | |||
|
180 | if(o<128) | |||
|
181 | #ASCII | |||
|
182 | l+=cw[c.chr] | |||
|
183 | n=1 | |||
|
184 | if(o==32) | |||
|
185 | sep=i | |||
|
186 | end | |||
|
187 | elsif(o>=161 and o<=223) | |||
|
188 | #Half-width katakana | |||
|
189 | l+=500 | |||
|
190 | n=1 | |||
|
191 | sep=i | |||
|
192 | else | |||
|
193 | #Full-width character | |||
|
194 | l+=1000 | |||
|
195 | n=2 | |||
|
196 | sep=i | |||
|
197 | end | |||
|
198 | if(l>wmax) | |||
|
199 | #Automatic line break | |||
|
200 | if(sep==-1 or i==j) | |||
|
201 | if(i==j) | |||
|
202 | i+=n | |||
|
203 | end | |||
|
204 | Cell(w,h,s[j,i-j],b,2,align,fill) | |||
|
205 | else | |||
|
206 | Cell(w,h,s[j,sep-j],b,2,align,fill) | |||
|
207 | i=(s[sep]==' ') ? sep+1 : sep | |||
|
208 | end | |||
|
209 | sep=-1 | |||
|
210 | j=i | |||
|
211 | l=0 | |||
|
212 | nl+=1 | |||
|
213 | if(border and nl==2) | |||
|
214 | b=b2 | |||
|
215 | end | |||
|
216 | else | |||
|
217 | i+=n | |||
|
218 | if(o>=128) | |||
|
219 | sep=i | |||
|
220 | end | |||
|
221 | end | |||
|
222 | end | |||
|
223 | #Last chunk | |||
|
224 | if(border and not border.index('B').nil?) | |||
|
225 | b+='B' | |||
|
226 | end | |||
|
227 | Cell(w,h,s[j,i-j],b,2,align,fill) | |||
|
228 | @x=@lMargin | |||
|
229 | end | |||
|
230 | ||||
|
231 | def Write(h,txt,link='') | |||
|
232 | if(@CurrentFont['type']=='Type0') | |||
|
233 | SJISWrite(h,txt,link) | |||
|
234 | else | |||
|
235 | super(h,txt,link) | |||
|
236 | end | |||
|
237 | end | |||
|
238 | ||||
|
239 | def SJISWrite(h,txt,link) | |||
|
240 | #SJIS version of Write() | |||
|
241 | cw=@CurrentFont['cw'] | |||
|
242 | w=@w-@rMargin-@x | |||
|
243 | wmax=(w-2*@cMargin)*1000/@FontSize | |||
|
244 | s=txt.gsub("\r",'') | |||
|
245 | nb=s.length | |||
|
246 | sep=-1 | |||
|
247 | i=0 | |||
|
248 | j=0 | |||
|
249 | l=0 | |||
|
250 | nl=1 | |||
|
251 | while(i<nb) | |||
|
252 | #Get next character | |||
|
253 | c=s[i] | |||
|
254 | o=c | |||
|
255 | if(o==10) | |||
|
256 | #Explicit line break | |||
|
257 | Cell(w,h,s[j,i-j],0,2,'',0,link) | |||
|
258 | i+=1 | |||
|
259 | sep=-1 | |||
|
260 | j=i | |||
|
261 | l=0 | |||
|
262 | if(nl==1) | |||
|
263 | #Go to left margin | |||
|
264 | @x=@lMargin | |||
|
265 | w=@w-@rMargin-@x | |||
|
266 | wmax=(w-2*@cMargin)*1000/@FontSize | |||
|
267 | end | |||
|
268 | nl+=1 | |||
|
269 | next | |||
|
270 | end | |||
|
271 | if(o<128) | |||
|
272 | #ASCII | |||
|
273 | l+=cw[c.chr] | |||
|
274 | n=1 | |||
|
275 | if(o==32) | |||
|
276 | sep=i | |||
|
277 | end | |||
|
278 | elsif(o>=161 and o<=223) | |||
|
279 | #Half-width katakana | |||
|
280 | l+=500 | |||
|
281 | n=1 | |||
|
282 | sep=i | |||
|
283 | else | |||
|
284 | #Full-width character | |||
|
285 | l+=1000 | |||
|
286 | n=2 | |||
|
287 | sep=i | |||
|
288 | end | |||
|
289 | if(l>wmax) | |||
|
290 | #Automatic line break | |||
|
291 | if(sep==-1 or i==j) | |||
|
292 | if(@x>@lMargin) | |||
|
293 | #Move to next line | |||
|
294 | @x=@lMargin | |||
|
295 | @y+=h | |||
|
296 | w=@w-@rMargin-@x | |||
|
297 | wmax=(w-2*@cMargin)*1000/@FontSize | |||
|
298 | i+=n | |||
|
299 | nl+=1 | |||
|
300 | next | |||
|
301 | end | |||
|
302 | if(i==j) | |||
|
303 | i+=n | |||
|
304 | end | |||
|
305 | Cell(w,h,s[j,i-j],0,2,'',0,link) | |||
|
306 | else | |||
|
307 | Cell(w,h,s[j,sep-j],0,2,'',0,link) | |||
|
308 | i=(s[sep]==' ') ? sep+1 : sep | |||
|
309 | end | |||
|
310 | sep=-1 | |||
|
311 | j=i | |||
|
312 | l=0 | |||
|
313 | if(nl==1) | |||
|
314 | @x=@lMargin | |||
|
315 | w=@w-@rMargin-@x | |||
|
316 | wmax=(w-2*@cMargin)*1000/@FontSize | |||
|
317 | end | |||
|
318 | nl+=1 | |||
|
319 | else | |||
|
320 | i+=n | |||
|
321 | if(o>=128) | |||
|
322 | sep=i | |||
|
323 | end | |||
|
324 | end | |||
|
325 | end | |||
|
326 | #Last chunk | |||
|
327 | if(i!=j) | |||
|
328 | Cell(l/1000*@FontSize,h,s[j,i-j],0,0,'',0,link) | |||
|
329 | end | |||
|
330 | end | |||
|
331 | ||||
|
332 | private | |||
|
333 | ||||
|
334 | def putfonts() | |||
|
335 | nf=@n | |||
|
336 | @diffs.each do |diff| | |||
|
337 | #Encodings | |||
|
338 | newobj() | |||
|
339 | out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['+diff+']>>') | |||
|
340 | out('endobj') | |||
|
341 | end | |||
|
342 | # mqr=get_magic_quotes_runtime() | |||
|
343 | # set_magic_quotes_runtime(0) | |||
|
344 | @FontFiles.each_pair do |file, info| | |||
|
345 | #Font file embedding | |||
|
346 | newobj() | |||
|
347 | @FontFiles[file]['n']=@n | |||
|
348 | if(defined('FPDF_FONTPATH')) | |||
|
349 | file=FPDF_FONTPATH+file | |||
|
350 | end | |||
|
351 | size=filesize(file) | |||
|
352 | if(!size) | |||
|
353 | Error('Font file not found') | |||
|
354 | end | |||
|
355 | out('<</Length '+size) | |||
|
356 | if(file[-2]=='.z') | |||
|
357 | out('/Filter /FlateDecode') | |||
|
358 | end | |||
|
359 | out('/Length1 '+info['length1']) | |||
|
360 | unless info['length2'].nil? | |||
|
361 | out('/Length2 '+info['length2']+' /Length3 0') | |||
|
362 | end | |||
|
363 | out('>>') | |||
|
364 | f=fopen(file,'rb') | |||
|
365 | putstream(fread(f,size)) | |||
|
366 | fclose(f) | |||
|
367 | out('endobj') | |||
|
368 | end | |||
|
369 | # set_magic_quotes_runtime(mqr) | |||
|
370 | @fonts.each_pair do |k, font| | |||
|
371 | #Font objects | |||
|
372 | newobj() | |||
|
373 | @fonts[k]['n']=@n | |||
|
374 | out('<</Type /Font') | |||
|
375 | if(font['type']=='Type0') | |||
|
376 | putType0(font) | |||
|
377 | else | |||
|
378 | name=font['name'] | |||
|
379 | out('/BaseFont /'+name) | |||
|
380 | if(font['type']=='core') | |||
|
381 | #Standard font | |||
|
382 | out('/Subtype /Type1') | |||
|
383 | if(name!='Symbol' and name!='ZapfDingbats') | |||
|
384 | out('/Encoding /WinAnsiEncoding') | |||
|
385 | end | |||
|
386 | else | |||
|
387 | #Additional font | |||
|
388 | out('/Subtype /'+font['type']) | |||
|
389 | out('/FirstChar 32') | |||
|
390 | out('/LastChar 255') | |||
|
391 | out('/Widths '+(@n+1)+' 0 R') | |||
|
392 | out('/FontDescriptor '+(@n+2)+' 0 R') | |||
|
393 | if(font['enc']) | |||
|
394 | if !font['diff'].nil? | |||
|
395 | out('/Encoding '+(nf+font['diff'])+' 0 R') | |||
|
396 | else | |||
|
397 | out('/Encoding /WinAnsiEncoding') | |||
|
398 | end | |||
|
399 | end | |||
|
400 | end | |||
|
401 | out('>>') | |||
|
402 | out('endobj') | |||
|
403 | if(font['type']!='core') | |||
|
404 | #Widths | |||
|
405 | newobj() | |||
|
406 | cw=font['cw'] | |||
|
407 | s='[' | |||
|
408 | 32.upto(255) do |i| | |||
|
409 | s+=cw[i.chr]+' ' | |||
|
410 | end | |||
|
411 | out(s+']') | |||
|
412 | out('endobj') | |||
|
413 | #Descriptor | |||
|
414 | newobj() | |||
|
415 | s='<</Type /FontDescriptor /FontName /'+name | |||
|
416 | font['desc'].each_pair do |k, v| | |||
|
417 | s+=' /'+k+' '+v | |||
|
418 | end | |||
|
419 | file=font['file'] | |||
|
420 | if(file) | |||
|
421 | s+=' /FontFile'+(font['type']=='Type1' ? '' : '2')+' '+@FontFiles[file]['n']+' 0 R' | |||
|
422 | end | |||
|
423 | out(s+'>>') | |||
|
424 | out('endobj') | |||
|
425 | end | |||
|
426 | end | |||
|
427 | end | |||
|
428 | end | |||
|
429 | ||||
|
430 | def putType0(font) | |||
|
431 | #Type0 | |||
|
432 | out('/Subtype /Type0') | |||
|
433 | out('/BaseFont /'+font['name']+'-'+font['CMap']) | |||
|
434 | out('/Encoding /'+font['CMap']) | |||
|
435 | out('/DescendantFonts ['+(@n+1).to_s+' 0 R]') | |||
|
436 | out('>>') | |||
|
437 | out('endobj') | |||
|
438 | #CIDFont | |||
|
439 | newobj() | |||
|
440 | out('<</Type /Font') | |||
|
441 | out('/Subtype /CIDFontType0') | |||
|
442 | out('/BaseFont /'+font['name']) | |||
|
443 | out('/CIDSystemInfo <</Registry (Adobe) /Ordering ('+font['registry']['ordering']+') /Supplement '+font['registry']['supplement'].to_s+'>>') | |||
|
444 | out('/FontDescriptor '+(@n+1).to_s+' 0 R') | |||
|
445 | w='/W [1 [' | |||
|
446 | font['cw'].keys.sort.each {|key| | |||
|
447 | w+=font['cw'][key].to_s + " " | |||
|
448 | # ActionController::Base::logger.debug key.to_s | |||
|
449 | # ActionController::Base::logger.debug font['cw'][key].to_s | |||
|
450 | } | |||
|
451 | out(w+'] 231 325 500 631 [500] 326 389 500]') | |||
|
452 | out('>>') | |||
|
453 | out('endobj') | |||
|
454 | #Font descriptor | |||
|
455 | newobj() | |||
|
456 | out('<</Type /FontDescriptor') | |||
|
457 | out('/FontName /'+font['name']) | |||
|
458 | out('/Flags 6') | |||
|
459 | out('/FontBBox [0 -200 1000 900]') | |||
|
460 | out('/ItalicAngle 0') | |||
|
461 | out('/Ascent 800') | |||
|
462 | out('/Descent -200') | |||
|
463 | out('/CapHeight 800') | |||
|
464 | out('/StemV 60') | |||
|
465 | out('>>') | |||
|
466 | out('endobj') | |||
|
467 | end | |||
|
468 | end |
@@ -0,0 +1,436 | |||||
|
1 | # Copyright (c) 2006 4ssoM LLC <www.4ssoM.com> | |||
|
2 | # 1.12 contributed by Ed Moss. | |||
|
3 | # | |||
|
4 | # The MIT License | |||
|
5 | # | |||
|
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
|
7 | # of this software and associated documentation files (the "Software"), to deal | |||
|
8 | # in the Software without restriction, including without limitation the rights | |||
|
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||
|
10 | # copies of the Software, and to permit persons to whom the Software is | |||
|
11 | # furnished to do so, subject to the following conditions: | |||
|
12 | # | |||
|
13 | # The above copyright notice and this permission notice shall be included in | |||
|
14 | # all copies or substantial portions of the Software. | |||
|
15 | # | |||
|
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
|
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
|
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
|
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
|
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||
|
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |||
|
22 | # THE SOFTWARE. | |||
|
23 | # | |||
|
24 | # This is direct port of korean.php | |||
|
25 | # | |||
|
26 | # Korean PDF support. | |||
|
27 | # | |||
|
28 | # Usage is as follows: | |||
|
29 | # | |||
|
30 | # require 'fpdf' | |||
|
31 | # require 'chinese' | |||
|
32 | # pdf = FPDF.new | |||
|
33 | # pdf.extend(PDF_Korean) | |||
|
34 | # | |||
|
35 | # This allows it to be combined with other extensions, such as the bookmark | |||
|
36 | # module. | |||
|
37 | ||||
|
38 | module PDF_Korean | |||
|
39 | ||||
|
40 | UHC_widths={' ' => 333, '!' => 416, '"' => 416, '#' => 833, '$' => 625, '%' => 916, '&' => 833, '\'' => 250, | |||
|
41 | '(' => 500, ')' => 500, '*' => 500, '+' => 833, ',' => 291, '-' => 833, '.' => 291, '/' => 375, '0' => 625, '1' => 625, | |||
|
42 | '2' => 625, '3' => 625, '4' => 625, '5' => 625, '6' => 625, '7' => 625, '8' => 625, '9' => 625, ':' => 333, ';' => 333, | |||
|
43 | '<' => 833, '=' => 833, '>' => 916, '?' => 500, '@' => 1000, 'A' => 791, 'B' => 708, 'C' => 708, 'D' => 750, 'E' => 708, | |||
|
44 | 'F' => 666, 'G' => 750, 'H' => 791, 'I' => 375, 'J' => 500, 'K' => 791, 'L' => 666, 'M' => 916, 'N' => 791, 'O' => 750, | |||
|
45 | 'P' => 666, 'Q' => 750, 'R' => 708, 'S' => 666, 'T' => 791, 'U' => 791, 'V' => 750, 'W' => 1000, 'X' => 708, 'Y' => 708, | |||
|
46 | 'Z' => 666, '[' => 500, '\\' => 375, ']' => 500, '^' => 500, '_' => 500, '`' => 333, 'a' => 541, 'b' => 583, 'c' => 541, | |||
|
47 | 'd' => 583, 'e' => 583, 'f' => 375, 'g' => 583, 'h' => 583, 'i' => 291, 'j' => 333, 'k' => 583, 'l' => 291, 'm' => 875, | |||
|
48 | 'n' => 583, 'o' => 583, 'p' => 583, 'q' => 583, 'r' => 458, 's' => 541, 't' => 375, 'u' => 583, 'v' => 583, 'w' => 833, | |||
|
49 | 'x' => 625, 'y' => 625, 'z' => 500, '{' => 583, '|' => 583, '}' => 583, '~' => 750} | |||
|
50 | ||||
|
51 | def AddCIDFont(family,style,name,cw,cMap,registry) | |||
|
52 | fontkey=family.downcase+style.upcase | |||
|
53 | unless @fonts[fontkey].nil? | |||
|
54 | Error("Font already added: family style") | |||
|
55 | end | |||
|
56 | i=@fonts.length+1 | |||
|
57 | name=name.gsub(' ','') | |||
|
58 | @fonts[fontkey]={'i'=>i,'type'=>'Type0','name'=>name,'up'=>-130,'ut'=>40,'cw'=>cw, | |||
|
59 | 'CMap'=>cMap,'registry'=>registry} | |||
|
60 | end | |||
|
61 | ||||
|
62 | def AddCIDFonts(family,name,cw,cMap,registry) | |||
|
63 | AddCIDFont(family,'',name,cw,cMap,registry) | |||
|
64 | AddCIDFont(family,'B',name+',Bold',cw,cMap,registry) | |||
|
65 | AddCIDFont(family,'I',name+',Italic',cw,cMap,registry) | |||
|
66 | AddCIDFont(family,'BI',name+',BoldItalic',cw,cMap,registry) | |||
|
67 | end | |||
|
68 | ||||
|
69 | def AddUHCFont(family='UHC',name='HYSMyeongJoStd-Medium-Acro') | |||
|
70 | #Add UHC font with proportional Latin | |||
|
71 | cw=UHC_widths | |||
|
72 | cMap='KSCms-UHC-H' | |||
|
73 | registry={'ordering'=>'Korea1','supplement'=>1} | |||
|
74 | AddCIDFonts(family,name,cw,cMap,registry) | |||
|
75 | end | |||
|
76 | ||||
|
77 | def AddUHChwFont(family='UHC-hw',name='HYSMyeongJoStd-Medium-Acro') | |||
|
78 | #Add UHC font with half-witdh Latin | |||
|
79 | 32.upto(126) do |i| | |||
|
80 | cw[i.chr]=500 | |||
|
81 | end | |||
|
82 | cMap='KSCms-UHC-HW-H' | |||
|
83 | registry={'ordering'=>'Korea1','supplement'=>1} | |||
|
84 | AddCIDFonts(family,name,cw,cMap,registry) | |||
|
85 | end | |||
|
86 | ||||
|
87 | def GetStringWidth(s) | |||
|
88 | if(@CurrentFont['type']=='Type0') | |||
|
89 | return GetMBStringWidth(s) | |||
|
90 | else | |||
|
91 | return super(s) | |||
|
92 | end | |||
|
93 | end | |||
|
94 | ||||
|
95 | def GetMBStringWidth(s) | |||
|
96 | #Multi-byte version of GetStringWidth() | |||
|
97 | l=0 | |||
|
98 | cw=@CurrentFont['cw'] | |||
|
99 | nb=s.length | |||
|
100 | i=0 | |||
|
101 | while(i<nb) | |||
|
102 | c=s[i] | |||
|
103 | if(c<128) | |||
|
104 | l+=cw[c.chr] | |||
|
105 | i+=1 | |||
|
106 | else | |||
|
107 | l+=1000 | |||
|
108 | i+=2 | |||
|
109 | end | |||
|
110 | end | |||
|
111 | return l*@FontSize/1000 | |||
|
112 | end | |||
|
113 | ||||
|
114 | def MultiCell(w,h,txt,border=0,align='L',fill=0) | |||
|
115 | if(@CurrentFont['type']=='Type0') | |||
|
116 | MBMultiCell(w,h,txt,border,align,fill) | |||
|
117 | else | |||
|
118 | super(w,h,txt,border,align,fill) | |||
|
119 | end | |||
|
120 | end | |||
|
121 | ||||
|
122 | def MBMultiCell(w,h,txt,border=0,align='L',fill=0) | |||
|
123 | #Multi-byte version of MultiCell() | |||
|
124 | cw=@CurrentFont['cw'] | |||
|
125 | if(w==0) | |||
|
126 | w=@w-@rMargin-@x | |||
|
127 | end | |||
|
128 | wmax=(w-2*@cMargin)*1000/@FontSize | |||
|
129 | s=txt.gsub("\r",'') | |||
|
130 | nb=s.length | |||
|
131 | if(nb>0 and s[nb-1]=="\n") | |||
|
132 | nb-=1 | |||
|
133 | end | |||
|
134 | b=0 | |||
|
135 | if(border) | |||
|
136 | if(border==1) | |||
|
137 | border='LTRB' | |||
|
138 | b='LRT' | |||
|
139 | b2='LR' | |||
|
140 | else | |||
|
141 | b2='' | |||
|
142 | if(border.index('L').nil?) | |||
|
143 | b2+='L' | |||
|
144 | end | |||
|
145 | if(border.index('R').nil?) | |||
|
146 | b2+='R' | |||
|
147 | end | |||
|
148 | b=border.index('T').nil? ? b2+'T' : b2 | |||
|
149 | end | |||
|
150 | end | |||
|
151 | sep=-1 | |||
|
152 | i=0 | |||
|
153 | j=0 | |||
|
154 | l=0 | |||
|
155 | nl=1 | |||
|
156 | while(i<nb) | |||
|
157 | #Get next character | |||
|
158 | c=s[i] | |||
|
159 | #Check if ASCII or MB | |||
|
160 | ascii=(c<128) | |||
|
161 | if(c=="\n") | |||
|
162 | #Explicit line break | |||
|
163 | Cell(w,h,s[j,i-j],b,2,align,fill) | |||
|
164 | i+=1 | |||
|
165 | sep=-1 | |||
|
166 | j=i | |||
|
167 | l=0 | |||
|
168 | nl+=1 | |||
|
169 | if(border and nl==2) | |||
|
170 | b=b2 | |||
|
171 | end | |||
|
172 | next | |||
|
173 | end | |||
|
174 | if(!ascii) | |||
|
175 | sep=i | |||
|
176 | ls=l | |||
|
177 | elsif(c==' ') | |||
|
178 | sep=i | |||
|
179 | ls=l | |||
|
180 | end | |||
|
181 | l+=ascii ? cw[c.chr] : 1000 | |||
|
182 | if(l>wmax) | |||
|
183 | #Automatic line break | |||
|
184 | if(sep==-1 or i==j) | |||
|
185 | if(i==j) | |||
|
186 | i+=ascii ? 1 : 2 | |||
|
187 | end | |||
|
188 | Cell(w,h,s[j,i-j],b,2,align,fill) | |||
|
189 | else | |||
|
190 | Cell(w,h,s[j,sep-j],b,2,align,fill) | |||
|
191 | i=(s[sep]==' ') ? sep+1 : sep | |||
|
192 | end | |||
|
193 | sep=-1 | |||
|
194 | j=i | |||
|
195 | l=0 | |||
|
196 | nl+=1 | |||
|
197 | if(border and nl==2) | |||
|
198 | b=b2 | |||
|
199 | end | |||
|
200 | else | |||
|
201 | i+=ascii ? 1 : 2 | |||
|
202 | end | |||
|
203 | end | |||
|
204 | #Last chunk | |||
|
205 | if(border and not border.index('B').nil?) | |||
|
206 | b+='B' | |||
|
207 | end | |||
|
208 | Cell(w,h,s[j,i-j],b,2,align,fill) | |||
|
209 | @x=@lMargin | |||
|
210 | end | |||
|
211 | ||||
|
212 | def Write(h,txt,link='') | |||
|
213 | if(@CurrentFont['type']=='Type0') | |||
|
214 | MBWrite(h,txt,link) | |||
|
215 | else | |||
|
216 | super(h,txt,link) | |||
|
217 | end | |||
|
218 | end | |||
|
219 | ||||
|
220 | def MBWrite(h,txt,link) | |||
|
221 | #Multi-byte version of Write() | |||
|
222 | cw=@CurrentFont['cw'] | |||
|
223 | w=@w-@rMargin-@x | |||
|
224 | wmax=(w-2*@cMargin)*1000/@FontSize | |||
|
225 | s=txt.gsub("\r",'') | |||
|
226 | nb=s.length | |||
|
227 | sep=-1 | |||
|
228 | i=0 | |||
|
229 | j=0 | |||
|
230 | l=0 | |||
|
231 | nl=1 | |||
|
232 | while(i<nb) | |||
|
233 | #Get next character | |||
|
234 | c=s[i] | |||
|
235 | #Check if ASCII or MB | |||
|
236 | ascii=(c<128) | |||
|
237 | if(c=="\n") | |||
|
238 | #Explicit line break | |||
|
239 | Cell(w,h,s[j,i-j],0,2,'',0,link) | |||
|
240 | i+=1 | |||
|
241 | sep=-1 | |||
|
242 | j=i | |||
|
243 | l=0 | |||
|
244 | if(nl==1) | |||
|
245 | @x=@lMargin | |||
|
246 | w=@w-@rMargin-@x | |||
|
247 | wmax=(w-2*@cMargin)*1000/@FontSize | |||
|
248 | end | |||
|
249 | nl+=1 | |||
|
250 | next | |||
|
251 | end | |||
|
252 | if(!ascii or c==' ') | |||
|
253 | sep=i | |||
|
254 | end | |||
|
255 | l+=ascii ? cw[c.chr] : 1000 | |||
|
256 | if(l>wmax) | |||
|
257 | #Automatic line break | |||
|
258 | if(sep==-1 or i==j) | |||
|
259 | if(@x>@lMargin) | |||
|
260 | #Move to next line | |||
|
261 | @x=@lMargin | |||
|
262 | @y+=h | |||
|
263 | w=@w-@rMargin-@x | |||
|
264 | wmax=(w-2*@cMargin)*1000/@FontSize | |||
|
265 | i+=1 | |||
|
266 | nl+=1 | |||
|
267 | next | |||
|
268 | end | |||
|
269 | if(i==j) | |||
|
270 | i+=ascii ? 1 : 2 | |||
|
271 | end | |||
|
272 | Cell(w,h,s[j,i-j],0,2,'',0,link) | |||
|
273 | else | |||
|
274 | Cell(w,h,s[j,sep-j],0,2,'',0,link) | |||
|
275 | i=(s[sep]==' ') ? sep+1 : sep | |||
|
276 | end | |||
|
277 | sep=-1 | |||
|
278 | j=i | |||
|
279 | l=0 | |||
|
280 | if(nl==1) | |||
|
281 | @x=@lMargin | |||
|
282 | w=@w-@rMargin-@x | |||
|
283 | wmax=(w-2*@cMargin)*1000/@FontSize | |||
|
284 | end | |||
|
285 | nl+=1 | |||
|
286 | else | |||
|
287 | i+=ascii ? 1 : 2 | |||
|
288 | end | |||
|
289 | end | |||
|
290 | #Last chunk | |||
|
291 | if(i!=j) | |||
|
292 | Cell(l/1000*@FontSize,h,s[j,i-j],0,0,'',0,link) | |||
|
293 | end | |||
|
294 | end | |||
|
295 | ||||
|
296 | private | |||
|
297 | ||||
|
298 | def putfonts() | |||
|
299 | nf=@n | |||
|
300 | @diffs.each do |diff| | |||
|
301 | #Encodings | |||
|
302 | newobj() | |||
|
303 | out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['+diff+']>>') | |||
|
304 | out('endobj') | |||
|
305 | end | |||
|
306 | # mqr=get_magic_quotes_runtime() | |||
|
307 | # set_magic_quotes_runtime(0) | |||
|
308 | @FontFiles.each_pair do |file, info| | |||
|
309 | #Font file embedding | |||
|
310 | newobj() | |||
|
311 | @FontFiles[file]['n']=@n | |||
|
312 | if(defined('FPDF_FONTPATH')) | |||
|
313 | file=FPDF_FONTPATH+file | |||
|
314 | end | |||
|
315 | size=filesize(file) | |||
|
316 | if(!size) | |||
|
317 | Error('Font file not found') | |||
|
318 | end | |||
|
319 | out('<</Length '+size) | |||
|
320 | if(file[-2]=='.z') | |||
|
321 | out('/Filter /FlateDecode') | |||
|
322 | end | |||
|
323 | out('/Length1 '+info['length1']) | |||
|
324 | if(not info['length2'].nil?) | |||
|
325 | out('/Length2 '+info['length2']+' /Length3 0') | |||
|
326 | end | |||
|
327 | out('>>') | |||
|
328 | f=fopen(file,'rb') | |||
|
329 | putstream(fread(f,size)) | |||
|
330 | fclose(f) | |||
|
331 | out('endobj') | |||
|
332 | end | |||
|
333 | # set_magic_quotes_runtime(mqr) | |||
|
334 | @fonts.each_pair do |k, font| | |||
|
335 | #Font objects | |||
|
336 | newobj() | |||
|
337 | @fonts[k]['n']=@n | |||
|
338 | out('<</Type /Font') | |||
|
339 | if(font['type']=='Type0') | |||
|
340 | putType0(font) | |||
|
341 | else | |||
|
342 | name=font['name'] | |||
|
343 | out('/BaseFont /'+name) | |||
|
344 | if(font['type']=='core') | |||
|
345 | #Standard font | |||
|
346 | out('/Subtype /Type1') | |||
|
347 | if(name!='Symbol' and name!='ZapfDingbats') | |||
|
348 | out('/Encoding /WinAnsiEncoding') | |||
|
349 | end | |||
|
350 | else | |||
|
351 | #Additional font | |||
|
352 | out('/Subtype /'+font['type']) | |||
|
353 | out('/FirstChar 32') | |||
|
354 | out('/LastChar 255') | |||
|
355 | out('/Widths '+(@n+1)+' 0 R') | |||
|
356 | out('/FontDescriptor '+(@n+2)+' 0 R') | |||
|
357 | if(font['enc']) | |||
|
358 | if(not font['diff'].nil?) | |||
|
359 | out('/Encoding '+(nf+font['diff'])+' 0 R') | |||
|
360 | else | |||
|
361 | out('/Encoding /WinAnsiEncoding') | |||
|
362 | end | |||
|
363 | end | |||
|
364 | end | |||
|
365 | out('>>') | |||
|
366 | out('endobj') | |||
|
367 | if(font['type']!='core') | |||
|
368 | #Widths | |||
|
369 | newobj() | |||
|
370 | cw=font['cw'] | |||
|
371 | s='[' | |||
|
372 | 32.upto(255) do |i| | |||
|
373 | s+=cw[i.chr]+' ' | |||
|
374 | end | |||
|
375 | out(s+']') | |||
|
376 | out('endobj') | |||
|
377 | #Descriptor | |||
|
378 | newobj() | |||
|
379 | s='<</Type /FontDescriptor /FontName /'+name | |||
|
380 | font['desc'].each_pair do |k, v| | |||
|
381 | s+=' /'+k+' '+v | |||
|
382 | end | |||
|
383 | file=font['file'] | |||
|
384 | if(file) | |||
|
385 | s+=' /FontFile'+(font['type']=='Type1' ? '' : '2')+' '+@FontFiles[file]['n']+' 0 R' | |||
|
386 | end | |||
|
387 | out(s+'>>') | |||
|
388 | out('endobj') | |||
|
389 | end | |||
|
390 | end | |||
|
391 | end | |||
|
392 | end | |||
|
393 | ||||
|
394 | def putType0(font) | |||
|
395 | #Type0 | |||
|
396 | out('/Subtype /Type0') | |||
|
397 | out('/BaseFont /'+font['name']+'-'+font['CMap']) | |||
|
398 | out('/Encoding /'+font['CMap']) | |||
|
399 | out('/DescendantFonts ['+(@n+1).to_s+' 0 R]') | |||
|
400 | out('>>') | |||
|
401 | out('endobj') | |||
|
402 | #CIDFont | |||
|
403 | newobj() | |||
|
404 | out('<</Type /Font') | |||
|
405 | out('/Subtype /CIDFontType0') | |||
|
406 | out('/BaseFont /'+font['name']) | |||
|
407 | out('/CIDSystemInfo <</Registry (Adobe) /Ordering ('+font['registry']['ordering']+') /Supplement '+font['registry']['supplement'].to_s+'>>') | |||
|
408 | out('/FontDescriptor '+(@n+1).to_s+' 0 R') | |||
|
409 | if(font['CMap']=='KSCms-UHC-HW-H') | |||
|
410 | w='8094 8190 500' | |||
|
411 | else | |||
|
412 | w='1 [' | |||
|
413 | font['cw'].keys.sort.each {|key| | |||
|
414 | w+=font['cw'][key].to_s + " " | |||
|
415 | # ActionController::Base::logger.debug key.to_s | |||
|
416 | # ActionController::Base::logger.debug font['cw'][key].to_s | |||
|
417 | } | |||
|
418 | w +=']' | |||
|
419 | end | |||
|
420 | out('/W ['+w+']>>') | |||
|
421 | out('endobj') | |||
|
422 | #Font descriptor | |||
|
423 | newobj() | |||
|
424 | out('<</Type /FontDescriptor') | |||
|
425 | out('/FontName /'+font['name']) | |||
|
426 | out('/Flags 6') | |||
|
427 | out('/FontBBox [0 -200 1000 900]') | |||
|
428 | out('/ItalicAngle 0') | |||
|
429 | out('/Ascent 800') | |||
|
430 | out('/Descent -200') | |||
|
431 | out('/CapHeight 800') | |||
|
432 | out('/StemV 50') | |||
|
433 | out('>>') | |||
|
434 | out('endobj') | |||
|
435 | end | |||
|
436 | end |
This diff has been collapsed as it changes many lines, (1787 lines changed) Show them Hide them | |||||
@@ -0,0 +1,1787 | |||||
|
1 | #!/usr/bin/env ruby | |||
|
2 | # | |||
|
3 | # Utility to generate font definition files | |||
|
4 | # Version: 1.1 | |||
|
5 | # Date: 2006-07-19 | |||
|
6 | # | |||
|
7 | # Changelog: | |||
|
8 | # Version 1.1 - Brian Ollenberger | |||
|
9 | # - Fixed a very small bug in MakeFont for generating FontDef.diff. | |||
|
10 | ||||
|
11 | Charencodings = { | |||
|
12 | # Central Europe | |||
|
13 | 'cp1250' => [ | |||
|
14 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
15 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
16 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
17 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
18 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
19 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
20 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
21 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
22 | 'space', 'exclam', 'quotedbl', 'numbersign', | |||
|
23 | 'dollar', 'percent', 'ampersand', 'quotesingle', | |||
|
24 | 'parenleft', 'parenright', 'asterisk', 'plus', | |||
|
25 | 'comma', 'hyphen', 'period', 'slash', | |||
|
26 | 'zero', 'one', 'two', 'three', | |||
|
27 | 'four', 'five', 'six', 'seven', | |||
|
28 | 'eight', 'nine', 'colon', 'semicolon', | |||
|
29 | 'less', 'equal', 'greater', 'question', | |||
|
30 | 'at', 'A', 'B', 'C', | |||
|
31 | 'D', 'E', 'F', 'G', | |||
|
32 | 'H', 'I', 'J', 'K', | |||
|
33 | 'L', 'M', 'N', 'O', | |||
|
34 | 'P', 'Q', 'R', 'S', | |||
|
35 | 'T', 'U', 'V', 'W', | |||
|
36 | 'X', 'Y', 'Z', 'bracketleft', | |||
|
37 | 'backslash', 'bracketright', 'asciicircum', 'underscore', | |||
|
38 | 'grave', 'a', 'b', 'c', | |||
|
39 | 'd', 'e', 'f', 'g', | |||
|
40 | 'h', 'i', 'j', 'k', | |||
|
41 | 'l', 'm', 'n', 'o', | |||
|
42 | 'p', 'q', 'r', 's', | |||
|
43 | 't', 'u', 'v', 'w', | |||
|
44 | 'x', 'y', 'z', 'braceleft', | |||
|
45 | 'bar', 'braceright', 'asciitilde', '.notdef', | |||
|
46 | 'Euro', '.notdef', 'quotesinglbase', '.notdef', | |||
|
47 | 'quotedblbase', 'ellipsis', 'dagger', 'daggerdbl', | |||
|
48 | '.notdef', 'perthousand', 'Scaron', 'guilsinglleft', | |||
|
49 | 'Sacute', 'Tcaron', 'Zcaron', 'Zacute', | |||
|
50 | '.notdef', 'quoteleft', 'quoteright', 'quotedblleft', | |||
|
51 | 'quotedblright', 'bullet', 'endash', 'emdash', | |||
|
52 | '.notdef', 'trademark', 'scaron', 'guilsinglright', | |||
|
53 | 'sacute', 'tcaron', 'zcaron', 'zacute', | |||
|
54 | 'space', 'caron', 'breve', 'Lslash', | |||
|
55 | 'currency', 'Aogonek', 'brokenbar', 'section', | |||
|
56 | 'dieresis', 'copyright', 'Scedilla', 'guillemotleft', | |||
|
57 | 'logicalnot', 'hyphen', 'registered', 'Zdotaccent', | |||
|
58 | 'degree', 'plusminus', 'ogonek', 'lslash', | |||
|
59 | 'acute', 'mu', 'paragraph', 'periodcentered', | |||
|
60 | 'cedilla', 'aogonek', 'scedilla', 'guillemotright', | |||
|
61 | 'Lcaron', 'hungarumlaut', 'lcaron', 'zdotaccent', | |||
|
62 | 'Racute', 'Aacute', 'Acircumflex', 'Abreve', | |||
|
63 | 'Adieresis', 'Lacute', 'Cacute', 'Ccedilla', | |||
|
64 | 'Ccaron', 'Eacute', 'Eogonek', 'Edieresis', | |||
|
65 | 'Ecaron', 'Iacute', 'Icircumflex', 'Dcaron', | |||
|
66 | 'Dcroat', 'Nacute', 'Ncaron', 'Oacute', | |||
|
67 | 'Ocircumflex', 'Ohungarumlaut', 'Odieresis', 'multiply', | |||
|
68 | 'Rcaron', 'Uring', 'Uacute', 'Uhungarumlaut', | |||
|
69 | 'Udieresis', 'Yacute', 'Tcommaaccent', 'germandbls', | |||
|
70 | 'racute', 'aacute', 'acircumflex', 'abreve', | |||
|
71 | 'adieresis', 'lacute', 'cacute', 'ccedilla', | |||
|
72 | 'ccaron', 'eacute', 'eogonek', 'edieresis', | |||
|
73 | 'ecaron', 'iacute', 'icircumflex', 'dcaron', | |||
|
74 | 'dcroat', 'nacute', 'ncaron', 'oacute', | |||
|
75 | 'ocircumflex', 'ohungarumlaut', 'odieresis', 'divide', | |||
|
76 | 'rcaron', 'uring', 'uacute', 'uhungarumlaut', | |||
|
77 | 'udieresis', 'yacute', 'tcommaaccent', 'dotaccent' | |||
|
78 | ], | |||
|
79 | # Cyrillic | |||
|
80 | 'cp1251' => [ | |||
|
81 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
82 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
83 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
84 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
85 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
86 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
87 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
88 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
89 | 'space', 'exclam', 'quotedbl', 'numbersign', | |||
|
90 | 'dollar', 'percent', 'ampersand', 'quotesingle', | |||
|
91 | 'parenleft', 'parenright', 'asterisk', 'plus', | |||
|
92 | 'comma', 'hyphen', 'period', 'slash', | |||
|
93 | 'zero', 'one', 'two', 'three', | |||
|
94 | 'four', 'five', 'six', 'seven', | |||
|
95 | 'eight', 'nine', 'colon', 'semicolon', | |||
|
96 | 'less', 'equal', 'greater', 'question', | |||
|
97 | 'at', 'A', 'B', 'C', | |||
|
98 | 'D', 'E', 'F', 'G', | |||
|
99 | 'H', 'I', 'J', 'K', | |||
|
100 | 'L', 'M', 'N', 'O', | |||
|
101 | 'P', 'Q', 'R', 'S', | |||
|
102 | 'T', 'U', 'V', 'W', | |||
|
103 | 'X', 'Y', 'Z', 'bracketleft', | |||
|
104 | 'backslash', 'bracketright', 'asciicircum', 'underscore', | |||
|
105 | 'grave', 'a', 'b', 'c', | |||
|
106 | 'd', 'e', 'f', 'g', | |||
|
107 | 'h', 'i', 'j', 'k', | |||
|
108 | 'l', 'm', 'n', 'o', | |||
|
109 | 'p', 'q', 'r', 's', | |||
|
110 | 't', 'u', 'v', 'w', | |||
|
111 | 'x', 'y', 'z', 'braceleft', | |||
|
112 | 'bar', 'braceright', 'asciitilde', '.notdef', | |||
|
113 | 'afii10051', 'afii10052', 'quotesinglbase', 'afii10100', | |||
|
114 | 'quotedblbase', 'ellipsis', 'dagger', 'daggerdbl', | |||
|
115 | 'Euro', 'perthousand', 'afii10058', 'guilsinglleft', | |||
|
116 | 'afii10059', 'afii10061', 'afii10060', 'afii10145', | |||
|
117 | 'afii10099', 'quoteleft', 'quoteright', 'quotedblleft', | |||
|
118 | 'quotedblright', 'bullet', 'endash', 'emdash', | |||
|
119 | '.notdef', 'trademark', 'afii10106', 'guilsinglright', | |||
|
120 | 'afii10107', 'afii10109', 'afii10108', 'afii10193', | |||
|
121 | 'space', 'afii10062', 'afii10110', 'afii10057', | |||
|
122 | 'currency', 'afii10050', 'brokenbar', 'section', | |||
|
123 | 'afii10023', 'copyright', 'afii10053', 'guillemotleft', | |||
|
124 | 'logicalnot', 'hyphen', 'registered', 'afii10056', | |||
|
125 | 'degree', 'plusminus', 'afii10055', 'afii10103', | |||
|
126 | 'afii10098', 'mu', 'paragraph', 'periodcentered', | |||
|
127 | 'afii10071', 'afii61352', 'afii10101', 'guillemotright', | |||
|
128 | 'afii10105', 'afii10054', 'afii10102', 'afii10104', | |||
|
129 | 'afii10017', 'afii10018', 'afii10019', 'afii10020', | |||
|
130 | 'afii10021', 'afii10022', 'afii10024', 'afii10025', | |||
|
131 | 'afii10026', 'afii10027', 'afii10028', 'afii10029', | |||
|
132 | 'afii10030', 'afii10031', 'afii10032', 'afii10033', | |||
|
133 | 'afii10034', 'afii10035', 'afii10036', 'afii10037', | |||
|
134 | 'afii10038', 'afii10039', 'afii10040', 'afii10041', | |||
|
135 | 'afii10042', 'afii10043', 'afii10044', 'afii10045', | |||
|
136 | 'afii10046', 'afii10047', 'afii10048', 'afii10049', | |||
|
137 | 'afii10065', 'afii10066', 'afii10067', 'afii10068', | |||
|
138 | 'afii10069', 'afii10070', 'afii10072', 'afii10073', | |||
|
139 | 'afii10074', 'afii10075', 'afii10076', 'afii10077', | |||
|
140 | 'afii10078', 'afii10079', 'afii10080', 'afii10081', | |||
|
141 | 'afii10082', 'afii10083', 'afii10084', 'afii10085', | |||
|
142 | 'afii10086', 'afii10087', 'afii10088', 'afii10089', | |||
|
143 | 'afii10090', 'afii10091', 'afii10092', 'afii10093', | |||
|
144 | 'afii10094', 'afii10095', 'afii10096', 'afii10097' | |||
|
145 | ], | |||
|
146 | # Western Europe | |||
|
147 | 'cp1252' => [ | |||
|
148 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
149 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
150 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
151 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
152 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
153 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
154 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
155 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
156 | 'space', 'exclam', 'quotedbl', 'numbersign', | |||
|
157 | 'dollar', 'percent', 'ampersand', 'quotesingle', | |||
|
158 | 'parenleft', 'parenright', 'asterisk', 'plus', | |||
|
159 | 'comma', 'hyphen', 'period', 'slash', | |||
|
160 | 'zero', 'one', 'two', 'three', | |||
|
161 | 'four', 'five', 'six', 'seven', | |||
|
162 | 'eight', 'nine', 'colon', 'semicolon', | |||
|
163 | 'less', 'equal', 'greater', 'question', | |||
|
164 | 'at', 'A', 'B', 'C', | |||
|
165 | 'D', 'E', 'F', 'G', | |||
|
166 | 'H', 'I', 'J', 'K', | |||
|
167 | 'L', 'M', 'N', 'O', | |||
|
168 | 'P', 'Q', 'R', 'S', | |||
|
169 | 'T', 'U', 'V', 'W', | |||
|
170 | 'X', 'Y', 'Z', 'bracketleft', | |||
|
171 | 'backslash', 'bracketright', 'asciicircum', 'underscore', | |||
|
172 | 'grave', 'a', 'b', 'c', | |||
|
173 | 'd', 'e', 'f', 'g', | |||
|
174 | 'h', 'i', 'j', 'k', | |||
|
175 | 'l', 'm', 'n', 'o', | |||
|
176 | 'p', 'q', 'r', 's', | |||
|
177 | 't', 'u', 'v', 'w', | |||
|
178 | 'x', 'y', 'z', 'braceleft', | |||
|
179 | 'bar', 'braceright', 'asciitilde', '.notdef', | |||
|
180 | 'Euro', '.notdef', 'quotesinglbase', 'florin', | |||
|
181 | 'quotedblbase', 'ellipsis', 'dagger', 'daggerdbl', | |||
|
182 | 'circumflex', 'perthousand', 'Scaron', 'guilsinglleft', | |||
|
183 | 'OE', '.notdef', 'Zcaron', '.notdef', | |||
|
184 | '.notdef', 'quoteleft', 'quoteright', 'quotedblleft', | |||
|
185 | 'quotedblright', 'bullet', 'endash', 'emdash', | |||
|
186 | 'tilde', 'trademark', 'scaron', 'guilsinglright', | |||
|
187 | 'oe', '.notdef', 'zcaron', 'Ydieresis', | |||
|
188 | 'space', 'exclamdown', 'cent', 'sterling', | |||
|
189 | 'currency', 'yen', 'brokenbar', 'section', | |||
|
190 | 'dieresis', 'copyright', 'ordfeminine', 'guillemotleft', | |||
|
191 | 'logicalnot', 'hyphen', 'registered', 'macron', | |||
|
192 | 'degree', 'plusminus', 'twosuperior', 'threesuperior', | |||
|
193 | 'acute', 'mu', 'paragraph', 'periodcentered', | |||
|
194 | 'cedilla', 'onesuperior', 'ordmasculine', 'guillemotright', | |||
|
195 | 'onequarter', 'onehalf', 'threequarters', 'questiondown', | |||
|
196 | 'Agrave', 'Aacute', 'Acircumflex', 'Atilde', | |||
|
197 | 'Adieresis', 'Aring', 'AE', 'Ccedilla', | |||
|
198 | 'Egrave', 'Eacute', 'Ecircumflex', 'Edieresis', | |||
|
199 | 'Igrave', 'Iacute', 'Icircumflex', 'Idieresis', | |||
|
200 | 'Eth', 'Ntilde', 'Ograve', 'Oacute', | |||
|
201 | 'Ocircumflex', 'Otilde', 'Odieresis', 'multiply', | |||
|
202 | 'Oslash', 'Ugrave', 'Uacute', 'Ucircumflex', | |||
|
203 | 'Udieresis', 'Yacute', 'Thorn', 'germandbls', | |||
|
204 | 'agrave', 'aacute', 'acircumflex', 'atilde', | |||
|
205 | 'adieresis', 'aring', 'ae', 'ccedilla', | |||
|
206 | 'egrave', 'eacute', 'ecircumflex', 'edieresis', | |||
|
207 | 'igrave', 'iacute', 'icircumflex', 'idieresis', | |||
|
208 | 'eth', 'ntilde', 'ograve', 'oacute', | |||
|
209 | 'ocircumflex', 'otilde', 'odieresis', 'divide', | |||
|
210 | 'oslash', 'ugrave', 'uacute', 'ucircumflex', | |||
|
211 | 'udieresis', 'yacute', 'thorn', 'ydieresis' | |||
|
212 | ], | |||
|
213 | # Greek | |||
|
214 | 'cp1253' => [ | |||
|
215 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
216 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
217 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
218 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
219 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
220 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
221 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
222 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
223 | 'space', 'exclam', 'quotedbl', 'numbersign', | |||
|
224 | 'dollar', 'percent', 'ampersand', 'quotesingle', | |||
|
225 | 'parenleft', 'parenright', 'asterisk', 'plus', | |||
|
226 | 'comma', 'hyphen', 'period', 'slash', | |||
|
227 | 'zero', 'one', 'two', 'three', | |||
|
228 | 'four', 'five', 'six', 'seven', | |||
|
229 | 'eight', 'nine', 'colon', 'semicolon', | |||
|
230 | 'less', 'equal', 'greater', 'question', | |||
|
231 | 'at', 'A', 'B', 'C', | |||
|
232 | 'D', 'E', 'F', 'G', | |||
|
233 | 'H', 'I', 'J', 'K', | |||
|
234 | 'L', 'M', 'N', 'O', | |||
|
235 | 'P', 'Q', 'R', 'S', | |||
|
236 | 'T', 'U', 'V', 'W', | |||
|
237 | 'X', 'Y', 'Z', 'bracketleft', | |||
|
238 | 'backslash', 'bracketright', 'asciicircum', 'underscore', | |||
|
239 | 'grave', 'a', 'b', 'c', | |||
|
240 | 'd', 'e', 'f', 'g', | |||
|
241 | 'h', 'i', 'j', 'k', | |||
|
242 | 'l', 'm', 'n', 'o', | |||
|
243 | 'p', 'q', 'r', 's', | |||
|
244 | 't', 'u', 'v', 'w', | |||
|
245 | 'x', 'y', 'z', 'braceleft', | |||
|
246 | 'bar', 'braceright', 'asciitilde', '.notdef', | |||
|
247 | 'Euro', '.notdef', 'quotesinglbase', 'florin', | |||
|
248 | 'quotedblbase', 'ellipsis', 'dagger', 'daggerdbl', | |||
|
249 | '.notdef', 'perthousand', '.notdef', 'guilsinglleft', | |||
|
250 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
251 | '.notdef', 'quoteleft', 'quoteright', 'quotedblleft', | |||
|
252 | 'quotedblright', 'bullet', 'endash', 'emdash', | |||
|
253 | '.notdef', 'trademark', '.notdef', 'guilsinglright', | |||
|
254 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
255 | 'space', 'dieresistonos', 'Alphatonos', 'sterling', | |||
|
256 | 'currency', 'yen', 'brokenbar', 'section', | |||
|
257 | 'dieresis', 'copyright', '.notdef', 'guillemotleft', | |||
|
258 | 'logicalnot', 'hyphen', 'registered', 'afii00208', | |||
|
259 | 'degree', 'plusminus', 'twosuperior', 'threesuperior', | |||
|
260 | 'tonos', 'mu', 'paragraph', 'periodcentered', | |||
|
261 | 'Epsilontonos', 'Etatonos', 'Iotatonos', 'guillemotright', | |||
|
262 | 'Omicrontonos', 'onehalf', 'Upsilontonos', 'Omegatonos', | |||
|
263 | 'iotadieresistonos','Alpha', 'Beta', 'Gamma', | |||
|
264 | 'Delta', 'Epsilon', 'Zeta', 'Eta', | |||
|
265 | 'Theta', 'Iota', 'Kappa', 'Lambda', | |||
|
266 | 'Mu', 'Nu', 'Xi', 'Omicron', | |||
|
267 | 'Pi', 'Rho', '.notdef', 'Sigma', | |||
|
268 | 'Tau', 'Upsilon', 'Phi', 'Chi', | |||
|
269 | 'Psi', 'Omega', 'Iotadieresis', 'Upsilondieresis', | |||
|
270 | 'alphatonos', 'epsilontonos', 'etatonos', 'iotatonos', | |||
|
271 | 'upsilondieresistonos','alpha', 'beta', 'gamma', | |||
|
272 | 'delta', 'epsilon', 'zeta', 'eta', | |||
|
273 | 'theta', 'iota', 'kappa', 'lambda', | |||
|
274 | 'mu', 'nu', 'xi', 'omicron', | |||
|
275 | 'pi', 'rho', 'sigma1', 'sigma', | |||
|
276 | 'tau', 'upsilon', 'phi', 'chi', | |||
|
277 | 'psi', 'omega', 'iotadieresis', 'upsilondieresis', | |||
|
278 | 'omicrontonos', 'upsilontonos', 'omegatonos', '.notdef' | |||
|
279 | ], | |||
|
280 | # Turkish | |||
|
281 | 'cp1254' => [ | |||
|
282 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
283 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
284 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
285 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
286 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
287 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
288 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
289 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
290 | 'space', 'exclam', 'quotedbl', 'numbersign', | |||
|
291 | 'dollar', 'percent', 'ampersand', 'quotesingle', | |||
|
292 | 'parenleft', 'parenright', 'asterisk', 'plus', | |||
|
293 | 'comma', 'hyphen', 'period', 'slash', | |||
|
294 | 'zero', 'one', 'two', 'three', | |||
|
295 | 'four', 'five', 'six', 'seven', | |||
|
296 | 'eight', 'nine', 'colon', 'semicolon', | |||
|
297 | 'less', 'equal', 'greater', 'question', | |||
|
298 | 'at', 'A', 'B', 'C', | |||
|
299 | 'D', 'E', 'F', 'G', | |||
|
300 | 'H', 'I', 'J', 'K', | |||
|
301 | 'L', 'M', 'N', 'O', | |||
|
302 | 'P', 'Q', 'R', 'S', | |||
|
303 | 'T', 'U', 'V', 'W', | |||
|
304 | 'X', 'Y', 'Z', 'bracketleft', | |||
|
305 | 'backslash', 'bracketright', 'asciicircum', 'underscore', | |||
|
306 | 'grave', 'a', 'b', 'c', | |||
|
307 | 'd', 'e', 'f', 'g', | |||
|
308 | 'h', 'i', 'j', 'k', | |||
|
309 | 'l', 'm', 'n', 'o', | |||
|
310 | 'p', 'q', 'r', 's', | |||
|
311 | 't', 'u', 'v', 'w', | |||
|
312 | 'x', 'y', 'z', 'braceleft', | |||
|
313 | 'bar', 'braceright', 'asciitilde', '.notdef', | |||
|
314 | 'Euro', '.notdef', 'quotesinglbase', 'florin', | |||
|
315 | 'quotedblbase', 'ellipsis', 'dagger', 'daggerdbl', | |||
|
316 | 'circumflex', 'perthousand', 'Scaron', 'guilsinglleft', | |||
|
317 | 'OE', '.notdef', '.notdef', '.notdef', | |||
|
318 | '.notdef', 'quoteleft', 'quoteright', 'quotedblleft', | |||
|
319 | 'quotedblright', 'bullet', 'endash', 'emdash', | |||
|
320 | 'tilde', 'trademark', 'scaron', 'guilsinglright', | |||
|
321 | 'oe', '.notdef', '.notdef', 'Ydieresis', | |||
|
322 | 'space', 'exclamdown', 'cent', 'sterling', | |||
|
323 | 'currency', 'yen', 'brokenbar', 'section', | |||
|
324 | 'dieresis', 'copyright', 'ordfeminine', 'guillemotleft', | |||
|
325 | 'logicalnot', 'hyphen', 'registered', 'macron', | |||
|
326 | 'degree', 'plusminus', 'twosuperior', 'threesuperior', | |||
|
327 | 'acute', 'mu', 'paragraph', 'periodcentered', | |||
|
328 | 'cedilla', 'onesuperior', 'ordmasculine', 'guillemotright', | |||
|
329 | 'onequarter', 'onehalf', 'threequarters', 'questiondown', | |||
|
330 | 'Agrave', 'Aacute', 'Acircumflex', 'Atilde', | |||
|
331 | 'Adieresis', 'Aring', 'AE', 'Ccedilla', | |||
|
332 | 'Egrave', 'Eacute', 'Ecircumflex', 'Edieresis', | |||
|
333 | 'Igrave', 'Iacute', 'Icircumflex', 'Idieresis', | |||
|
334 | 'Gbreve', 'Ntilde', 'Ograve', 'Oacute', | |||
|
335 | 'Ocircumflex', 'Otilde', 'Odieresis', 'multiply', | |||
|
336 | 'Oslash', 'Ugrave', 'Uacute', 'Ucircumflex', | |||
|
337 | 'Udieresis', 'Idotaccent', 'Scedilla', 'germandbls', | |||
|
338 | 'agrave', 'aacute', 'acircumflex', 'atilde', | |||
|
339 | 'adieresis', 'aring', 'ae', 'ccedilla', | |||
|
340 | 'egrave', 'eacute', 'ecircumflex', 'edieresis', | |||
|
341 | 'igrave', 'iacute', 'icircumflex', 'idieresis', | |||
|
342 | 'gbreve', 'ntilde', 'ograve', 'oacute', | |||
|
343 | 'ocircumflex', 'otilde', 'odieresis', 'divide', | |||
|
344 | 'oslash', 'ugrave', 'uacute', 'ucircumflex', | |||
|
345 | 'udieresis', 'dotlessi', 'scedilla', 'ydieresis' | |||
|
346 | ], | |||
|
347 | # Hebrew | |||
|
348 | 'cp1255' => [ | |||
|
349 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
350 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
351 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
352 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
353 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
354 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
355 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
356 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
357 | 'space', 'exclam', 'quotedbl', 'numbersign', | |||
|
358 | 'dollar', 'percent', 'ampersand', 'quotesingle', | |||
|
359 | 'parenleft', 'parenright', 'asterisk', 'plus', | |||
|
360 | 'comma', 'hyphen', 'period', 'slash', | |||
|
361 | 'zero', 'one', 'two', 'three', | |||
|
362 | 'four', 'five', 'six', 'seven', | |||
|
363 | 'eight', 'nine', 'colon', 'semicolon', | |||
|
364 | 'less', 'equal', 'greater', 'question', | |||
|
365 | 'at', 'A', 'B', 'C', | |||
|
366 | 'D', 'E', 'F', 'G', | |||
|
367 | 'H', 'I', 'J', 'K', | |||
|
368 | 'L', 'M', 'N', 'O', | |||
|
369 | 'P', 'Q', 'R', 'S', | |||
|
370 | 'T', 'U', 'V', 'W', | |||
|
371 | 'X', 'Y', 'Z', 'bracketleft', | |||
|
372 | 'backslash', 'bracketright', 'asciicircum', 'underscore', | |||
|
373 | 'grave', 'a', 'b', 'c', | |||
|
374 | 'd', 'e', 'f', 'g', | |||
|
375 | 'h', 'i', 'j', 'k', | |||
|
376 | 'l', 'm', 'n', 'o', | |||
|
377 | 'p', 'q', 'r', 's', | |||
|
378 | 't', 'u', 'v', 'w', | |||
|
379 | 'x', 'y', 'z', 'braceleft', | |||
|
380 | 'bar', 'braceright', 'asciitilde', '.notdef', | |||
|
381 | 'Euro', '.notdef', 'quotesinglbase', 'florin', | |||
|
382 | 'quotedblbase', 'ellipsis', 'dagger', 'daggerdbl', | |||
|
383 | 'circumflex', 'perthousand', '.notdef', 'guilsinglleft', | |||
|
384 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
385 | '.notdef', 'quoteleft', 'quoteright', 'quotedblleft', | |||
|
386 | 'quotedblright', 'bullet', 'endash', 'emdash', | |||
|
387 | 'tilde', 'trademark', '.notdef', 'guilsinglright', | |||
|
388 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
389 | 'space', 'exclamdown', 'cent', 'sterling', | |||
|
390 | 'afii57636', 'yen', 'brokenbar', 'section', | |||
|
391 | 'dieresis', 'copyright', 'multiply', 'guillemotleft', | |||
|
392 | 'logicalnot', 'sfthyphen', 'registered', 'macron', | |||
|
393 | 'degree', 'plusminus', 'twosuperior', 'threesuperior', | |||
|
394 | 'acute', 'mu', 'paragraph', 'middot', | |||
|
395 | 'cedilla', 'onesuperior', 'divide', 'guillemotright', | |||
|
396 | 'onequarter', 'onehalf', 'threequarters', 'questiondown', | |||
|
397 | 'afii57799', 'afii57801', 'afii57800', 'afii57802', | |||
|
398 | 'afii57793', 'afii57794', 'afii57795', 'afii57798', | |||
|
399 | 'afii57797', 'afii57806', '.notdef', 'afii57796', | |||
|
400 | 'afii57807', 'afii57839', 'afii57645', 'afii57841', | |||
|
401 | 'afii57842', 'afii57804', 'afii57803', 'afii57658', | |||
|
402 | 'afii57716', 'afii57717', 'afii57718', 'gereshhebrew', | |||
|
403 | 'gershayimhebrew','.notdef', '.notdef', '.notdef', | |||
|
404 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
405 | 'afii57664', 'afii57665', 'afii57666', 'afii57667', | |||
|
406 | 'afii57668', 'afii57669', 'afii57670', 'afii57671', | |||
|
407 | 'afii57672', 'afii57673', 'afii57674', 'afii57675', | |||
|
408 | 'afii57676', 'afii57677', 'afii57678', 'afii57679', | |||
|
409 | 'afii57680', 'afii57681', 'afii57682', 'afii57683', | |||
|
410 | 'afii57684', 'afii57685', 'afii57686', 'afii57687', | |||
|
411 | 'afii57688', 'afii57689', 'afii57690', '.notdef', | |||
|
412 | '.notdef', 'afii299', 'afii300', '.notdef' | |||
|
413 | ], | |||
|
414 | # Baltic | |||
|
415 | 'cp1257' => [ | |||
|
416 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
417 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
418 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
419 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
420 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
421 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
422 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
423 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
424 | 'space', 'exclam', 'quotedbl', 'numbersign', | |||
|
425 | 'dollar', 'percent', 'ampersand', 'quotesingle', | |||
|
426 | 'parenleft', 'parenright', 'asterisk', 'plus', | |||
|
427 | 'comma', 'hyphen', 'period', 'slash', | |||
|
428 | 'zero', 'one', 'two', 'three', | |||
|
429 | 'four', 'five', 'six', 'seven', | |||
|
430 | 'eight', 'nine', 'colon', 'semicolon', | |||
|
431 | 'less', 'equal', 'greater', 'question', | |||
|
432 | 'at', 'A', 'B', 'C', | |||
|
433 | 'D', 'E', 'F', 'G', | |||
|
434 | 'H', 'I', 'J', 'K', | |||
|
435 | 'L', 'M', 'N', 'O', | |||
|
436 | 'P', 'Q', 'R', 'S', | |||
|
437 | 'T', 'U', 'V', 'W', | |||
|
438 | 'X', 'Y', 'Z', 'bracketleft', | |||
|
439 | 'backslash', 'bracketright', 'asciicircum', 'underscore', | |||
|
440 | 'grave', 'a', 'b', 'c', | |||
|
441 | 'd', 'e', 'f', 'g', | |||
|
442 | 'h', 'i', 'j', 'k', | |||
|
443 | 'l', 'm', 'n', 'o', | |||
|
444 | 'p', 'q', 'r', 's', | |||
|
445 | 't', 'u', 'v', 'w', | |||
|
446 | 'x', 'y', 'z', 'braceleft', | |||
|
447 | 'bar', 'braceright', 'asciitilde', '.notdef', | |||
|
448 | 'Euro', '.notdef', 'quotesinglbase', '.notdef', | |||
|
449 | 'quotedblbase', 'ellipsis', 'dagger', 'daggerdbl', | |||
|
450 | '.notdef', 'perthousand', '.notdef', 'guilsinglleft', | |||
|
451 | '.notdef', 'dieresis', 'caron', 'cedilla', | |||
|
452 | '.notdef', 'quoteleft', 'quoteright', 'quotedblleft', | |||
|
453 | 'quotedblright', 'bullet', 'endash', 'emdash', | |||
|
454 | '.notdef', 'trademark', '.notdef', 'guilsinglright', | |||
|
455 | '.notdef', 'macron', 'ogonek', '.notdef', | |||
|
456 | 'space', '.notdef', 'cent', 'sterling', | |||
|
457 | 'currency', '.notdef', 'brokenbar', 'section', | |||
|
458 | 'Oslash', 'copyright', 'Rcommaaccent', 'guillemotleft', | |||
|
459 | 'logicalnot', 'hyphen', 'registered', 'AE', | |||
|
460 | 'degree', 'plusminus', 'twosuperior', 'threesuperior', | |||
|
461 | 'acute', 'mu', 'paragraph', 'periodcentered', | |||
|
462 | 'oslash', 'onesuperior', 'rcommaaccent', 'guillemotright', | |||
|
463 | 'onequarter', 'onehalf', 'threequarters', 'ae', | |||
|
464 | 'Aogonek', 'Iogonek', 'Amacron', 'Cacute', | |||
|
465 | 'Adieresis', 'Aring', 'Eogonek', 'Emacron', | |||
|
466 | 'Ccaron', 'Eacute', 'Zacute', 'Edotaccent', | |||
|
467 | 'Gcommaaccent', 'Kcommaaccent', 'Imacron', 'Lcommaaccent', | |||
|
468 | 'Scaron', 'Nacute', 'Ncommaaccent', 'Oacute', | |||
|
469 | 'Omacron', 'Otilde', 'Odieresis', 'multiply', | |||
|
470 | 'Uogonek', 'Lslash', 'Sacute', 'Umacron', | |||
|
471 | 'Udieresis', 'Zdotaccent', 'Zcaron', 'germandbls', | |||
|
472 | 'aogonek', 'iogonek', 'amacron', 'cacute', | |||
|
473 | 'adieresis', 'aring', 'eogonek', 'emacron', | |||
|
474 | 'ccaron', 'eacute', 'zacute', 'edotaccent', | |||
|
475 | 'gcommaaccent', 'kcommaaccent', 'imacron', 'lcommaaccent', | |||
|
476 | 'scaron', 'nacute', 'ncommaaccent', 'oacute', | |||
|
477 | 'omacron', 'otilde', 'odieresis', 'divide', | |||
|
478 | 'uogonek', 'lslash', 'sacute', 'umacron', | |||
|
479 | 'udieresis', 'zdotaccent', 'zcaron', 'dotaccent' | |||
|
480 | ], | |||
|
481 | # Vietnamese | |||
|
482 | 'cp1258' => [ | |||
|
483 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
484 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
485 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
486 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
487 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
488 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
489 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
490 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
491 | 'space', 'exclam', 'quotedbl', 'numbersign', | |||
|
492 | 'dollar', 'percent', 'ampersand', 'quotesingle', | |||
|
493 | 'parenleft', 'parenright', 'asterisk', 'plus', | |||
|
494 | 'comma', 'hyphen', 'period', 'slash', | |||
|
495 | 'zero', 'one', 'two', 'three', | |||
|
496 | 'four', 'five', 'six', 'seven', | |||
|
497 | 'eight', 'nine', 'colon', 'semicolon', | |||
|
498 | 'less', 'equal', 'greater', 'question', | |||
|
499 | 'at', 'A', 'B', 'C', | |||
|
500 | 'D', 'E', 'F', 'G', | |||
|
501 | 'H', 'I', 'J', 'K', | |||
|
502 | 'L', 'M', 'N', 'O', | |||
|
503 | 'P', 'Q', 'R', 'S', | |||
|
504 | 'T', 'U', 'V', 'W', | |||
|
505 | 'X', 'Y', 'Z', 'bracketleft', | |||
|
506 | 'backslash', 'bracketright', 'asciicircum', 'underscore', | |||
|
507 | 'grave', 'a', 'b', 'c', | |||
|
508 | 'd', 'e', 'f', 'g', | |||
|
509 | 'h', 'i', 'j', 'k', | |||
|
510 | 'l', 'm', 'n', 'o', | |||
|
511 | 'p', 'q', 'r', 's', | |||
|
512 | 't', 'u', 'v', 'w', | |||
|
513 | 'x', 'y', 'z', 'braceleft', | |||
|
514 | 'bar', 'braceright', 'asciitilde', '.notdef', | |||
|
515 | 'Euro', '.notdef', 'quotesinglbase', 'florin', | |||
|
516 | 'quotedblbase', 'ellipsis', 'dagger', 'daggerdbl', | |||
|
517 | 'circumflex', 'perthousand', '.notdef', 'guilsinglleft', | |||
|
518 | 'OE', '.notdef', '.notdef', '.notdef', | |||
|
519 | '.notdef', 'quoteleft', 'quoteright', 'quotedblleft', | |||
|
520 | 'quotedblright', 'bullet', 'endash', 'emdash', | |||
|
521 | 'tilde', 'trademark', '.notdef', 'guilsinglright', | |||
|
522 | 'oe', '.notdef', '.notdef', 'Ydieresis', | |||
|
523 | 'space', 'exclamdown', 'cent', 'sterling', | |||
|
524 | 'currency', 'yen', 'brokenbar', 'section', | |||
|
525 | 'dieresis', 'copyright', 'ordfeminine', 'guillemotleft', | |||
|
526 | 'logicalnot', 'hyphen', 'registered', 'macron', | |||
|
527 | 'degree', 'plusminus', 'twosuperior', 'threesuperior', | |||
|
528 | 'acute', 'mu', 'paragraph', 'periodcentered', | |||
|
529 | 'cedilla', 'onesuperior', 'ordmasculine', 'guillemotright', | |||
|
530 | 'onequarter', 'onehalf', 'threequarters', 'questiondown', | |||
|
531 | 'Agrave', 'Aacute', 'Acircumflex', 'Abreve', | |||
|
532 | 'Adieresis', 'Aring', 'AE', 'Ccedilla', | |||
|
533 | 'Egrave', 'Eacute', 'Ecircumflex', 'Edieresis', | |||
|
534 | 'gravecomb', 'Iacute', 'Icircumflex', 'Idieresis', | |||
|
535 | 'Dcroat', 'Ntilde', 'hookabovecomb', 'Oacute', | |||
|
536 | 'Ocircumflex', 'Ohorn', 'Odieresis', 'multiply', | |||
|
537 | 'Oslash', 'Ugrave', 'Uacute', 'Ucircumflex', | |||
|
538 | 'Udieresis', 'Uhorn', 'tildecomb', 'germandbls', | |||
|
539 | 'agrave', 'aacute', 'acircumflex', 'abreve', | |||
|
540 | 'adieresis', 'aring', 'ae', 'ccedilla', | |||
|
541 | 'egrave', 'eacute', 'ecircumflex', 'edieresis', | |||
|
542 | 'acutecomb', 'iacute', 'icircumflex', 'idieresis', | |||
|
543 | 'dcroat', 'ntilde', 'dotbelowcomb', 'oacute', | |||
|
544 | 'ocircumflex', 'ohorn', 'odieresis', 'divide', | |||
|
545 | 'oslash', 'ugrave', 'uacute', 'ucircumflex', | |||
|
546 | 'udieresis', 'uhorn', 'dong', 'ydieresis' | |||
|
547 | ], | |||
|
548 | # Thai | |||
|
549 | 'cp874' => [ | |||
|
550 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
551 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
552 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
553 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
554 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
555 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
556 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
557 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
558 | 'space', 'exclam', 'quotedbl', 'numbersign', | |||
|
559 | 'dollar', 'percent', 'ampersand', 'quotesingle', | |||
|
560 | 'parenleft', 'parenright', 'asterisk', 'plus', | |||
|
561 | 'comma', 'hyphen', 'period', 'slash', | |||
|
562 | 'zero', 'one', 'two', 'three', | |||
|
563 | 'four', 'five', 'six', 'seven', | |||
|
564 | 'eight', 'nine', 'colon', 'semicolon', | |||
|
565 | 'less', 'equal', 'greater', 'question', | |||
|
566 | 'at', 'A', 'B', 'C', | |||
|
567 | 'D', 'E', 'F', 'G', | |||
|
568 | 'H', 'I', 'J', 'K', | |||
|
569 | 'L', 'M', 'N', 'O', | |||
|
570 | 'P', 'Q', 'R', 'S', | |||
|
571 | 'T', 'U', 'V', 'W', | |||
|
572 | 'X', 'Y', 'Z', 'bracketleft', | |||
|
573 | 'backslash', 'bracketright', 'asciicircum', 'underscore', | |||
|
574 | 'grave', 'a', 'b', 'c', | |||
|
575 | 'd', 'e', 'f', 'g', | |||
|
576 | 'h', 'i', 'j', 'k', | |||
|
577 | 'l', 'm', 'n', 'o', | |||
|
578 | 'p', 'q', 'r', 's', | |||
|
579 | 't', 'u', 'v', 'w', | |||
|
580 | 'x', 'y', 'z', 'braceleft', | |||
|
581 | 'bar', 'braceright', 'asciitilde', '.notdef', | |||
|
582 | 'Euro', '.notdef', '.notdef', '.notdef', | |||
|
583 | '.notdef', 'ellipsis', '.notdef', '.notdef', | |||
|
584 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
585 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
586 | '.notdef', 'quoteleft', 'quoteright', 'quotedblleft', | |||
|
587 | 'quotedblright', 'bullet', 'endash', 'emdash', | |||
|
588 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
589 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
590 | 'space', 'kokaithai', 'khokhaithai', 'khokhuatthai', | |||
|
591 | 'khokhwaithai', 'khokhonthai', 'khorakhangthai', 'ngonguthai', | |||
|
592 | 'chochanthai', 'chochingthai', 'chochangthai', 'sosothai', | |||
|
593 | 'chochoethai', 'yoyingthai', 'dochadathai', 'topatakthai', | |||
|
594 | 'thothanthai', 'thonangmonthothai', 'thophuthaothai', 'nonenthai', | |||
|
595 | 'dodekthai', 'totaothai', 'thothungthai', 'thothahanthai', | |||
|
596 | 'thothongthai', 'nonuthai', 'bobaimaithai', 'poplathai', | |||
|
597 | 'phophungthai', 'fofathai', 'phophanthai', 'fofanthai', | |||
|
598 | 'phosamphaothai', 'momathai', 'yoyakthai', 'roruathai', | |||
|
599 | 'ruthai', 'lolingthai', 'luthai', 'wowaenthai', | |||
|
600 | 'sosalathai', 'sorusithai', 'sosuathai', 'hohipthai', | |||
|
601 | 'lochulathai', 'oangthai', 'honokhukthai', 'paiyannoithai', | |||
|
602 | 'saraathai', 'maihanakatthai', 'saraaathai', 'saraamthai', | |||
|
603 | 'saraithai', 'saraiithai', 'sarauethai', 'saraueethai', | |||
|
604 | 'sarauthai', 'sarauuthai', 'phinthuthai', '.notdef', | |||
|
605 | '.notdef', '.notdef', '.notdef', 'bahtthai', | |||
|
606 | 'saraethai', 'saraaethai', 'saraothai', 'saraaimaimuanthai', | |||
|
607 | 'saraaimaimalaithai', 'lakkhangyaothai', 'maiyamokthai', 'maitaikhuthai', | |||
|
608 | 'maiekthai', 'maithothai', 'maitrithai', 'maichattawathai', | |||
|
609 | 'thanthakhatthai', 'nikhahitthai', 'yamakkanthai', 'fongmanthai', | |||
|
610 | 'zerothai', 'onethai', 'twothai', 'threethai', | |||
|
611 | 'fourthai', 'fivethai', 'sixthai', 'seventhai', | |||
|
612 | 'eightthai', 'ninethai', 'angkhankhuthai', 'khomutthai', | |||
|
613 | '.notdef', '.notdef', '.notdef', '.notdef' | |||
|
614 | ], | |||
|
615 | # Western Europe | |||
|
616 | 'ISO-8859-1' => [ | |||
|
617 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
618 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
619 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
620 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
621 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
622 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
623 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
624 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
625 | 'space', 'exclam', 'quotedbl', 'numbersign', | |||
|
626 | 'dollar', 'percent', 'ampersand', 'quotesingle', | |||
|
627 | 'parenleft', 'parenright', 'asterisk', 'plus', | |||
|
628 | 'comma', 'hyphen', 'period', 'slash', | |||
|
629 | 'zero', 'one', 'two', 'three', | |||
|
630 | 'four', 'five', 'six', 'seven', | |||
|
631 | 'eight', 'nine', 'colon', 'semicolon', | |||
|
632 | 'less', 'equal', 'greater', 'question', | |||
|
633 | 'at', 'A', 'B', 'C', | |||
|
634 | 'D', 'E', 'F', 'G', | |||
|
635 | 'H', 'I', 'J', 'K', | |||
|
636 | 'L', 'M', 'N', 'O', | |||
|
637 | 'P', 'Q', 'R', 'S', | |||
|
638 | 'T', 'U', 'V', 'W', | |||
|
639 | 'X', 'Y', 'Z', 'bracketleft', | |||
|
640 | 'backslash', 'bracketright', 'asciicircum', 'underscore', | |||
|
641 | 'grave', 'a', 'b', 'c', | |||
|
642 | 'd', 'e', 'f', 'g', | |||
|
643 | 'h', 'i', 'j', 'k', | |||
|
644 | 'l', 'm', 'n', 'o', | |||
|
645 | 'p', 'q', 'r', 's', | |||
|
646 | 't', 'u', 'v', 'w', | |||
|
647 | 'x', 'y', 'z', 'braceleft', | |||
|
648 | 'bar', 'braceright', 'asciitilde', '.notdef', | |||
|
649 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
650 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
651 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
652 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
653 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
654 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
655 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
656 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
657 | 'space', 'exclamdown', 'cent', 'sterling', | |||
|
658 | 'currency', 'yen', 'brokenbar', 'section', | |||
|
659 | 'dieresis', 'copyright', 'ordfeminine', 'guillemotleft', | |||
|
660 | 'logicalnot', 'hyphen', 'registered', 'macron', | |||
|
661 | 'degree', 'plusminus', 'twosuperior', 'threesuperior', | |||
|
662 | 'acute', 'mu', 'paragraph', 'periodcentered', | |||
|
663 | 'cedilla', 'onesuperior', 'ordmasculine', 'guillemotright', | |||
|
664 | 'onequarter', 'onehalf', 'threequarters', 'questiondown', | |||
|
665 | 'Agrave', 'Aacute', 'Acircumflex', 'Atilde', | |||
|
666 | 'Adieresis', 'Aring', 'AE', 'Ccedilla', | |||
|
667 | 'Egrave', 'Eacute', 'Ecircumflex', 'Edieresis', | |||
|
668 | 'Igrave', 'Iacute', 'Icircumflex', 'Idieresis', | |||
|
669 | 'Eth', 'Ntilde', 'Ograve', 'Oacute', | |||
|
670 | 'Ocircumflex', 'Otilde', 'Odieresis', 'multiply', | |||
|
671 | 'Oslash', 'Ugrave', 'Uacute', 'Ucircumflex', | |||
|
672 | 'Udieresis', 'Yacute', 'Thorn', 'germandbls', | |||
|
673 | 'agrave', 'aacute', 'acircumflex', 'atilde', | |||
|
674 | 'adieresis', 'aring', 'ae', 'ccedilla', | |||
|
675 | 'egrave', 'eacute', 'ecircumflex', 'edieresis', | |||
|
676 | 'igrave', 'iacute', 'icircumflex', 'idieresis', | |||
|
677 | 'eth', 'ntilde', 'ograve', 'oacute', | |||
|
678 | 'ocircumflex', 'otilde', 'odieresis', 'divide', | |||
|
679 | 'oslash', 'ugrave', 'uacute', 'ucircumflex', | |||
|
680 | 'udieresis', 'yacute', 'thorn', 'ydieresis' | |||
|
681 | ], | |||
|
682 | # Central Europe | |||
|
683 | 'ISO-8859-2' => [ | |||
|
684 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
685 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
686 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
687 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
688 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
689 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
690 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
691 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
692 | 'space', 'exclam', 'quotedbl', 'numbersign', | |||
|
693 | 'dollar', 'percent', 'ampersand', 'quotesingle', | |||
|
694 | 'parenleft', 'parenright', 'asterisk', 'plus', | |||
|
695 | 'comma', 'hyphen', 'period', 'slash', | |||
|
696 | 'zero', 'one', 'two', 'three', | |||
|
697 | 'four', 'five', 'six', 'seven', | |||
|
698 | 'eight', 'nine', 'colon', 'semicolon', | |||
|
699 | 'less', 'equal', 'greater', 'question', | |||
|
700 | 'at', 'A', 'B', 'C', | |||
|
701 | 'D', 'E', 'F', 'G', | |||
|
702 | 'H', 'I', 'J', 'K', | |||
|
703 | 'L', 'M', 'N', 'O', | |||
|
704 | 'P', 'Q', 'R', 'S', | |||
|
705 | 'T', 'U', 'V', 'W', | |||
|
706 | 'X', 'Y', 'Z', 'bracketleft', | |||
|
707 | 'backslash', 'bracketright', 'asciicircum', 'underscore', | |||
|
708 | 'grave', 'a', 'b', 'c', | |||
|
709 | 'd', 'e', 'f', 'g', | |||
|
710 | 'h', 'i', 'j', 'k', | |||
|
711 | 'l', 'm', 'n', 'o', | |||
|
712 | 'p', 'q', 'r', 's', | |||
|
713 | 't', 'u', 'v', 'w', | |||
|
714 | 'x', 'y', 'z', 'braceleft', | |||
|
715 | 'bar', 'braceright', 'asciitilde', '.notdef', | |||
|
716 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
717 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
718 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
719 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
720 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
721 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
722 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
723 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
724 | 'space', 'Aogonek', 'breve', 'Lslash', | |||
|
725 | 'currency', 'Lcaron', 'Sacute', 'section', | |||
|
726 | 'dieresis', 'Scaron', 'Scedilla', 'Tcaron', | |||
|
727 | 'Zacute', 'hyphen', 'Zcaron', 'Zdotaccent', | |||
|
728 | 'degree', 'aogonek', 'ogonek', 'lslash', | |||
|
729 | 'acute', 'lcaron', 'sacute', 'caron', | |||
|
730 | 'cedilla', 'scaron', 'scedilla', 'tcaron', | |||
|
731 | 'zacute', 'hungarumlaut', 'zcaron', 'zdotaccent', | |||
|
732 | 'Racute', 'Aacute', 'Acircumflex', 'Abreve', | |||
|
733 | 'Adieresis', 'Lacute', 'Cacute', 'Ccedilla', | |||
|
734 | 'Ccaron', 'Eacute', 'Eogonek', 'Edieresis', | |||
|
735 | 'Ecaron', 'Iacute', 'Icircumflex', 'Dcaron', | |||
|
736 | 'Dcroat', 'Nacute', 'Ncaron', 'Oacute', | |||
|
737 | 'Ocircumflex', 'Ohungarumlaut', 'Odieresis', 'multiply', | |||
|
738 | 'Rcaron', 'Uring', 'Uacute', 'Uhungarumlaut', | |||
|
739 | 'Udieresis', 'Yacute', 'Tcommaaccent', 'germandbls', | |||
|
740 | 'racute', 'aacute', 'acircumflex', 'abreve', | |||
|
741 | 'adieresis', 'lacute', 'cacute', 'ccedilla', | |||
|
742 | 'ccaron', 'eacute', 'eogonek', 'edieresis', | |||
|
743 | 'ecaron', 'iacute', 'icircumflex', 'dcaron', | |||
|
744 | 'dcroat', 'nacute', 'ncaron', 'oacute', | |||
|
745 | 'ocircumflex', 'ohungarumlaut', 'odieresis', 'divide', | |||
|
746 | 'rcaron', 'uring', 'uacute', 'uhungarumlaut', | |||
|
747 | 'udieresis', 'yacute', 'tcommaaccent', 'dotaccent' | |||
|
748 | ], | |||
|
749 | # Baltic | |||
|
750 | 'ISO-8859-4' => [ | |||
|
751 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
752 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
753 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
754 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
755 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
756 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
757 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
758 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
759 | 'space', 'exclam', 'quotedbl', 'numbersign', | |||
|
760 | 'dollar', 'percent', 'ampersand', 'quotesingle', | |||
|
761 | 'parenleft', 'parenright', 'asterisk', 'plus', | |||
|
762 | 'comma', 'hyphen', 'period', 'slash', | |||
|
763 | 'zero', 'one', 'two', 'three', | |||
|
764 | 'four', 'five', 'six', 'seven', | |||
|
765 | 'eight', 'nine', 'colon', 'semicolon', | |||
|
766 | 'less', 'equal', 'greater', 'question', | |||
|
767 | 'at', 'A', 'B', 'C', | |||
|
768 | 'D', 'E', 'F', 'G', | |||
|
769 | 'H', 'I', 'J', 'K', | |||
|
770 | 'L', 'M', 'N', 'O', | |||
|
771 | 'P', 'Q', 'R', 'S', | |||
|
772 | 'T', 'U', 'V', 'W', | |||
|
773 | 'X', 'Y', 'Z', 'bracketleft', | |||
|
774 | 'backslash', 'bracketright', 'asciicircum', 'underscore', | |||
|
775 | 'grave', 'a', 'b', 'c', | |||
|
776 | 'd', 'e', 'f', 'g', | |||
|
777 | 'h', 'i', 'j', 'k', | |||
|
778 | 'l', 'm', 'n', 'o', | |||
|
779 | 'p', 'q', 'r', 's', | |||
|
780 | 't', 'u', 'v', 'w', | |||
|
781 | 'x', 'y', 'z', 'braceleft', | |||
|
782 | 'bar', 'braceright', 'asciitilde', '.notdef', | |||
|
783 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
784 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
785 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
786 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
787 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
788 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
789 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
790 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
791 | 'space', 'Aogonek', 'kgreenlandic', 'Rcommaaccent', | |||
|
792 | 'currency', 'Itilde', 'Lcommaaccent', 'section', | |||
|
793 | 'dieresis', 'Scaron', 'Emacron', 'Gcommaaccent', | |||
|
794 | 'Tbar', 'hyphen', 'Zcaron', 'macron', | |||
|
795 | 'degree', 'aogonek', 'ogonek', 'rcommaaccent', | |||
|
796 | 'acute', 'itilde', 'lcommaaccent', 'caron', | |||
|
797 | 'cedilla', 'scaron', 'emacron', 'gcommaaccent', | |||
|
798 | 'tbar', 'Eng', 'zcaron', 'eng', | |||
|
799 | 'Amacron', 'Aacute', 'Acircumflex', 'Atilde', | |||
|
800 | 'Adieresis', 'Aring', 'AE', 'Iogonek', | |||
|
801 | 'Ccaron', 'Eacute', 'Eogonek', 'Edieresis', | |||
|
802 | 'Edotaccent', 'Iacute', 'Icircumflex', 'Imacron', | |||
|
803 | 'Dcroat', 'Ncommaaccent', 'Omacron', 'Kcommaaccent', | |||
|
804 | 'Ocircumflex', 'Otilde', 'Odieresis', 'multiply', | |||
|
805 | 'Oslash', 'Uogonek', 'Uacute', 'Ucircumflex', | |||
|
806 | 'Udieresis', 'Utilde', 'Umacron', 'germandbls', | |||
|
807 | 'amacron', 'aacute', 'acircumflex', 'atilde', | |||
|
808 | 'adieresis', 'aring', 'ae', 'iogonek', | |||
|
809 | 'ccaron', 'eacute', 'eogonek', 'edieresis', | |||
|
810 | 'edotaccent', 'iacute', 'icircumflex', 'imacron', | |||
|
811 | 'dcroat', 'ncommaaccent', 'omacron', 'kcommaaccent', | |||
|
812 | 'ocircumflex', 'otilde', 'odieresis', 'divide', | |||
|
813 | 'oslash', 'uogonek', 'uacute', 'ucircumflex', | |||
|
814 | 'udieresis', 'utilde', 'umacron', 'dotaccent' | |||
|
815 | ], | |||
|
816 | # Cyrillic | |||
|
817 | 'ISO-8859-5' => [ | |||
|
818 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
819 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
820 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
821 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
822 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
823 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
824 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
825 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
826 | 'space', 'exclam', 'quotedbl', 'numbersign', | |||
|
827 | 'dollar', 'percent', 'ampersand', 'quotesingle', | |||
|
828 | 'parenleft', 'parenright', 'asterisk', 'plus', | |||
|
829 | 'comma', 'hyphen', 'period', 'slash', | |||
|
830 | 'zero', 'one', 'two', 'three', | |||
|
831 | 'four', 'five', 'six', 'seven', | |||
|
832 | 'eight', 'nine', 'colon', 'semicolon', | |||
|
833 | 'less', 'equal', 'greater', 'question', | |||
|
834 | 'at', 'A', 'B', 'C', | |||
|
835 | 'D', 'E', 'F', 'G', | |||
|
836 | 'H', 'I', 'J', 'K', | |||
|
837 | 'L', 'M', 'N', 'O', | |||
|
838 | 'P', 'Q', 'R', 'S', | |||
|
839 | 'T', 'U', 'V', 'W', | |||
|
840 | 'X', 'Y', 'Z', 'bracketleft', | |||
|
841 | 'backslash', 'bracketright', 'asciicircum', 'underscore', | |||
|
842 | 'grave', 'a', 'b', 'c', | |||
|
843 | 'd', 'e', 'f', 'g', | |||
|
844 | 'h', 'i', 'j', 'k', | |||
|
845 | 'l', 'm', 'n', 'o', | |||
|
846 | 'p', 'q', 'r', 's', | |||
|
847 | 't', 'u', 'v', 'w', | |||
|
848 | 'x', 'y', 'z', 'braceleft', | |||
|
849 | 'bar', 'braceright', 'asciitilde', '.notdef', | |||
|
850 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
851 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
852 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
853 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
854 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
855 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
856 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
857 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
858 | 'space', 'afii10023', 'afii10051', 'afii10052', | |||
|
859 | 'afii10053', 'afii10054', 'afii10055', 'afii10056', | |||
|
860 | 'afii10057', 'afii10058', 'afii10059', 'afii10060', | |||
|
861 | 'afii10061', 'hyphen', 'afii10062', 'afii10145', | |||
|
862 | 'afii10017', 'afii10018', 'afii10019', 'afii10020', | |||
|
863 | 'afii10021', 'afii10022', 'afii10024', 'afii10025', | |||
|
864 | 'afii10026', 'afii10027', 'afii10028', 'afii10029', | |||
|
865 | 'afii10030', 'afii10031', 'afii10032', 'afii10033', | |||
|
866 | 'afii10034', 'afii10035', 'afii10036', 'afii10037', | |||
|
867 | 'afii10038', 'afii10039', 'afii10040', 'afii10041', | |||
|
868 | 'afii10042', 'afii10043', 'afii10044', 'afii10045', | |||
|
869 | 'afii10046', 'afii10047', 'afii10048', 'afii10049', | |||
|
870 | 'afii10065', 'afii10066', 'afii10067', 'afii10068', | |||
|
871 | 'afii10069', 'afii10070', 'afii10072', 'afii10073', | |||
|
872 | 'afii10074', 'afii10075', 'afii10076', 'afii10077', | |||
|
873 | 'afii10078', 'afii10079', 'afii10080', 'afii10081', | |||
|
874 | 'afii10082', 'afii10083', 'afii10084', 'afii10085', | |||
|
875 | 'afii10086', 'afii10087', 'afii10088', 'afii10089', | |||
|
876 | 'afii10090', 'afii10091', 'afii10092', 'afii10093', | |||
|
877 | 'afii10094', 'afii10095', 'afii10096', 'afii10097', | |||
|
878 | 'afii61352', 'afii10071', 'afii10099', 'afii10100', | |||
|
879 | 'afii10101', 'afii10102', 'afii10103', 'afii10104', | |||
|
880 | 'afii10105', 'afii10106', 'afii10107', 'afii10108', | |||
|
881 | 'afii10109', 'section', 'afii10110', 'afii10193' | |||
|
882 | ], | |||
|
883 | # Greek | |||
|
884 | 'ISO-8859-7' => [ | |||
|
885 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
886 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
887 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
888 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
889 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
890 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
891 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
892 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
893 | 'space', 'exclam', 'quotedbl', 'numbersign', | |||
|
894 | 'dollar', 'percent', 'ampersand', 'quotesingle', | |||
|
895 | 'parenleft', 'parenright', 'asterisk', 'plus', | |||
|
896 | 'comma', 'hyphen', 'period', 'slash', | |||
|
897 | 'zero', 'one', 'two', 'three', | |||
|
898 | 'four', 'five', 'six', 'seven', | |||
|
899 | 'eight', 'nine', 'colon', 'semicolon', | |||
|
900 | 'less', 'equal', 'greater', 'question', | |||
|
901 | 'at', 'A', 'B', 'C', | |||
|
902 | 'D', 'E', 'F', 'G', | |||
|
903 | 'H', 'I', 'J', 'K', | |||
|
904 | 'L', 'M', 'N', 'O', | |||
|
905 | 'P', 'Q', 'R', 'S', | |||
|
906 | 'T', 'U', 'V', 'W', | |||
|
907 | 'X', 'Y', 'Z', 'bracketleft', | |||
|
908 | 'backslash', 'bracketright', 'asciicircum', 'underscore', | |||
|
909 | 'grave', 'a', 'b', 'c', | |||
|
910 | 'd', 'e', 'f', 'g', | |||
|
911 | 'h', 'i', 'j', 'k', | |||
|
912 | 'l', 'm', 'n', 'o', | |||
|
913 | 'p', 'q', 'r', 's', | |||
|
914 | 't', 'u', 'v', 'w', | |||
|
915 | 'x', 'y', 'z', 'braceleft', | |||
|
916 | 'bar', 'braceright', 'asciitilde', '.notdef', | |||
|
917 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
918 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
919 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
920 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
921 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
922 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
923 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
924 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
925 | 'space', 'quoteleft', 'quoteright', 'sterling', | |||
|
926 | '.notdef', '.notdef', 'brokenbar', 'section', | |||
|
927 | 'dieresis', 'copyright', '.notdef', 'guillemotleft', | |||
|
928 | 'logicalnot', 'hyphen', '.notdef', 'afii00208', | |||
|
929 | 'degree', 'plusminus', 'twosuperior', 'threesuperior', | |||
|
930 | 'tonos', 'dieresistonos', 'Alphatonos', 'periodcentered', | |||
|
931 | 'Epsilontonos', 'Etatonos', 'Iotatonos', 'guillemotright', | |||
|
932 | 'Omicrontonos', 'onehalf', 'Upsilontonos', 'Omegatonos', | |||
|
933 | 'iotadieresistonos','Alpha', 'Beta', 'Gamma', | |||
|
934 | 'Delta', 'Epsilon', 'Zeta', 'Eta', | |||
|
935 | 'Theta', 'Iota', 'Kappa', 'Lambda', | |||
|
936 | 'Mu', 'Nu', 'Xi', 'Omicron', | |||
|
937 | 'Pi', 'Rho', '.notdef', 'Sigma', | |||
|
938 | 'Tau', 'Upsilon', 'Phi', 'Chi', | |||
|
939 | 'Psi', 'Omega', 'Iotadieresis', 'Upsilondieresis', | |||
|
940 | 'alphatonos', 'epsilontonos', 'etatonos', 'iotatonos', | |||
|
941 | 'upsilondieresistonos','alpha', 'beta', 'gamma', | |||
|
942 | 'delta', 'epsilon', 'zeta', 'eta', | |||
|
943 | 'theta', 'iota', 'kappa', 'lambda', | |||
|
944 | 'mu', 'nu', 'xi', 'omicron', | |||
|
945 | 'pi', 'rho', 'sigma1', 'sigma', | |||
|
946 | 'tau', 'upsilon', 'phi', 'chi', | |||
|
947 | 'psi', 'omega', 'iotadieresis', 'upsilondieresis', | |||
|
948 | 'omicrontonos', 'upsilontonos', 'omegatonos', '.notdef' | |||
|
949 | ], | |||
|
950 | # Turkish | |||
|
951 | 'ISO-8859-9' => [ | |||
|
952 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
953 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
954 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
955 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
956 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
957 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
958 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
959 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
960 | 'space', 'exclam', 'quotedbl', 'numbersign', | |||
|
961 | 'dollar', 'percent', 'ampersand', 'quotesingle', | |||
|
962 | 'parenleft', 'parenright', 'asterisk', 'plus', | |||
|
963 | 'comma', 'hyphen', 'period', 'slash', | |||
|
964 | 'zero', 'one', 'two', 'three', | |||
|
965 | 'four', 'five', 'six', 'seven', | |||
|
966 | 'eight', 'nine', 'colon', 'semicolon', | |||
|
967 | 'less', 'equal', 'greater', 'question', | |||
|
968 | 'at', 'A', 'B', 'C', | |||
|
969 | 'D', 'E', 'F', 'G', | |||
|
970 | 'H', 'I', 'J', 'K', | |||
|
971 | 'L', 'M', 'N', 'O', | |||
|
972 | 'P', 'Q', 'R', 'S', | |||
|
973 | 'T', 'U', 'V', 'W', | |||
|
974 | 'X', 'Y', 'Z', 'bracketleft', | |||
|
975 | 'backslash', 'bracketright', 'asciicircum', 'underscore', | |||
|
976 | 'grave', 'a', 'b', 'c', | |||
|
977 | 'd', 'e', 'f', 'g', | |||
|
978 | 'h', 'i', 'j', 'k', | |||
|
979 | 'l', 'm', 'n', 'o', | |||
|
980 | 'p', 'q', 'r', 's', | |||
|
981 | 't', 'u', 'v', 'w', | |||
|
982 | 'x', 'y', 'z', 'braceleft', | |||
|
983 | 'bar', 'braceright', 'asciitilde', '.notdef', | |||
|
984 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
985 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
986 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
987 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
988 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
989 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
990 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
991 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
992 | 'space', 'exclamdown', 'cent', 'sterling', | |||
|
993 | 'currency', 'yen', 'brokenbar', 'section', | |||
|
994 | 'dieresis', 'copyright', 'ordfeminine', 'guillemotleft', | |||
|
995 | 'logicalnot', 'hyphen', 'registered', 'macron', | |||
|
996 | 'degree', 'plusminus', 'twosuperior', 'threesuperior', | |||
|
997 | 'acute', 'mu', 'paragraph', 'periodcentered', | |||
|
998 | 'cedilla', 'onesuperior', 'ordmasculine', 'guillemotright', | |||
|
999 | 'onequarter', 'onehalf', 'threequarters', 'questiondown', | |||
|
1000 | 'Agrave', 'Aacute', 'Acircumflex', 'Atilde', | |||
|
1001 | 'Adieresis', 'Aring', 'AE', 'Ccedilla', | |||
|
1002 | 'Egrave', 'Eacute', 'Ecircumflex', 'Edieresis', | |||
|
1003 | 'Igrave', 'Iacute', 'Icircumflex', 'Idieresis', | |||
|
1004 | 'Gbreve', 'Ntilde', 'Ograve', 'Oacute', | |||
|
1005 | 'Ocircumflex', 'Otilde', 'Odieresis', 'multiply', | |||
|
1006 | 'Oslash', 'Ugrave', 'Uacute', 'Ucircumflex', | |||
|
1007 | 'Udieresis', 'Idotaccent', 'Scedilla', 'germandbls', | |||
|
1008 | 'agrave', 'aacute', 'acircumflex', 'atilde', | |||
|
1009 | 'adieresis', 'aring', 'ae', 'ccedilla', | |||
|
1010 | 'egrave', 'eacute', 'ecircumflex', 'edieresis', | |||
|
1011 | 'igrave', 'iacute', 'icircumflex', 'idieresis', | |||
|
1012 | 'gbreve', 'ntilde', 'ograve', 'oacute', | |||
|
1013 | 'ocircumflex', 'otilde', 'odieresis', 'divide', | |||
|
1014 | 'oslash', 'ugrave', 'uacute', 'ucircumflex', | |||
|
1015 | 'udieresis', 'dotlessi', 'scedilla', 'ydieresis' | |||
|
1016 | ], | |||
|
1017 | # Thai | |||
|
1018 | 'ISO-8859-11' => [ | |||
|
1019 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1020 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1021 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1022 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1023 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1024 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1025 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1026 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1027 | 'space', 'exclam', 'quotedbl', 'numbersign', | |||
|
1028 | 'dollar', 'percent', 'ampersand', 'quotesingle', | |||
|
1029 | 'parenleft', 'parenright', 'asterisk', 'plus', | |||
|
1030 | 'comma', 'hyphen', 'period', 'slash', | |||
|
1031 | 'zero', 'one', 'two', 'three', | |||
|
1032 | 'four', 'five', 'six', 'seven', | |||
|
1033 | 'eight', 'nine', 'colon', 'semicolon', | |||
|
1034 | 'less', 'equal', 'greater', 'question', | |||
|
1035 | 'at', 'A', 'B', 'C', | |||
|
1036 | 'D', 'E', 'F', 'G', | |||
|
1037 | 'H', 'I', 'J', 'K', | |||
|
1038 | 'L', 'M', 'N', 'O', | |||
|
1039 | 'P', 'Q', 'R', 'S', | |||
|
1040 | 'T', 'U', 'V', 'W', | |||
|
1041 | 'X', 'Y', 'Z', 'bracketleft', | |||
|
1042 | 'backslash', 'bracketright', 'asciicircum', 'underscore', | |||
|
1043 | 'grave', 'a', 'b', 'c', | |||
|
1044 | 'd', 'e', 'f', 'g', | |||
|
1045 | 'h', 'i', 'j', 'k', | |||
|
1046 | 'l', 'm', 'n', 'o', | |||
|
1047 | 'p', 'q', 'r', 's', | |||
|
1048 | 't', 'u', 'v', 'w', | |||
|
1049 | 'x', 'y', 'z', 'braceleft', | |||
|
1050 | 'bar', 'braceright', 'asciitilde', '.notdef', | |||
|
1051 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1052 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1053 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1054 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1055 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1056 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1057 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1058 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1059 | 'space', 'kokaithai', 'khokhaithai', 'khokhuatthai', | |||
|
1060 | 'khokhwaithai', 'khokhonthai', 'khorakhangthai', 'ngonguthai', | |||
|
1061 | 'chochanthai', 'chochingthai', 'chochangthai', 'sosothai', | |||
|
1062 | 'chochoethai', 'yoyingthai', 'dochadathai', 'topatakthai', | |||
|
1063 | 'thothanthai', 'thonangmonthothai','thophuthaothai', 'nonenthai', | |||
|
1064 | 'dodekthai', 'totaothai', 'thothungthai', 'thothahanthai', | |||
|
1065 | 'thothongthai', 'nonuthai', 'bobaimaithai', 'poplathai', | |||
|
1066 | 'phophungthai', 'fofathai', 'phophanthai', 'fofanthai', | |||
|
1067 | 'phosamphaothai', 'momathai', 'yoyakthai', 'roruathai', | |||
|
1068 | 'ruthai', 'lolingthai', 'luthai', 'wowaenthai', | |||
|
1069 | 'sosalathai', 'sorusithai', 'sosuathai', 'hohipthai', | |||
|
1070 | 'lochulathai', 'oangthai', 'honokhukthai', 'paiyannoithai', | |||
|
1071 | 'saraathai', 'maihanakatthai', 'saraaathai', 'saraamthai', | |||
|
1072 | 'saraithai', 'saraiithai', 'sarauethai', 'saraueethai', | |||
|
1073 | 'sarauthai', 'sarauuthai', 'phinthuthai', '.notdef', | |||
|
1074 | '.notdef', '.notdef', '.notdef', 'bahtthai', | |||
|
1075 | 'saraethai', 'saraaethai', 'saraothai', 'saraaimaimuanthai', | |||
|
1076 | 'saraaimaimalaithai','lakkhangyaothai','maiyamokthai', 'maitaikhuthai', | |||
|
1077 | 'maiekthai', 'maithothai', 'maitrithai', 'maichattawathai', | |||
|
1078 | 'thanthakhatthai','nikhahitthai', 'yamakkanthai', 'fongmanthai', | |||
|
1079 | 'zerothai', 'onethai', 'twothai', 'threethai', | |||
|
1080 | 'fourthai', 'fivethai', 'sixthai', 'seventhai', | |||
|
1081 | 'eightthai', 'ninethai', 'angkhankhuthai', 'khomutthai', | |||
|
1082 | '.notdef', '.notdef', '.notdef', '.notdef' | |||
|
1083 | ], | |||
|
1084 | # Western Europe | |||
|
1085 | 'ISO-8859-15' => [ | |||
|
1086 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1087 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1088 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1089 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1090 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1091 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1092 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1093 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1094 | 'space', 'exclam', 'quotedbl', 'numbersign', | |||
|
1095 | 'dollar', 'percent', 'ampersand', 'quotesingle', | |||
|
1096 | 'parenleft', 'parenright', 'asterisk', 'plus', | |||
|
1097 | 'comma', 'hyphen', 'period', 'slash', | |||
|
1098 | 'zero', 'one', 'two', 'three', | |||
|
1099 | 'four', 'five', 'six', 'seven', | |||
|
1100 | 'eight', 'nine', 'colon', 'semicolon', | |||
|
1101 | 'less', 'equal', 'greater', 'question', | |||
|
1102 | 'at', 'A', 'B', 'C', | |||
|
1103 | 'D', 'E', 'F', 'G', | |||
|
1104 | 'H', 'I', 'J', 'K', | |||
|
1105 | 'L', 'M', 'N', 'O', | |||
|
1106 | 'P', 'Q', 'R', 'S', | |||
|
1107 | 'T', 'U', 'V', 'W', | |||
|
1108 | 'X', 'Y', 'Z', 'bracketleft', | |||
|
1109 | 'backslash', 'bracketright', 'asciicircum', 'underscore', | |||
|
1110 | 'grave', 'a', 'b', 'c', | |||
|
1111 | 'd', 'e', 'f', 'g', | |||
|
1112 | 'h', 'i', 'j', 'k', | |||
|
1113 | 'l', 'm', 'n', 'o', | |||
|
1114 | 'p', 'q', 'r', 's', | |||
|
1115 | 't', 'u', 'v', 'w', | |||
|
1116 | 'x', 'y', 'z', 'braceleft', | |||
|
1117 | 'bar', 'braceright', 'asciitilde', '.notdef', | |||
|
1118 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1119 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1120 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1121 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1122 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1123 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1124 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1125 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1126 | 'space', 'exclamdown', 'cent', 'sterling', | |||
|
1127 | 'Euro', 'yen', 'Scaron', 'section', | |||
|
1128 | 'scaron', 'copyright', 'ordfeminine', 'guillemotleft', | |||
|
1129 | 'logicalnot', 'hyphen', 'registered', 'macron', | |||
|
1130 | 'degree', 'plusminus', 'twosuperior', 'threesuperior', | |||
|
1131 | 'Zcaron', 'mu', 'paragraph', 'periodcentered', | |||
|
1132 | 'zcaron', 'onesuperior', 'ordmasculine', 'guillemotright', | |||
|
1133 | 'OE', 'oe', 'Ydieresis', 'questiondown', | |||
|
1134 | 'Agrave', 'Aacute', 'Acircumflex', 'Atilde', | |||
|
1135 | 'Adieresis', 'Aring', 'AE', 'Ccedilla', | |||
|
1136 | 'Egrave', 'Eacute', 'Ecircumflex', 'Edieresis', | |||
|
1137 | 'Igrave', 'Iacute', 'Icircumflex', 'Idieresis', | |||
|
1138 | 'Eth', 'Ntilde', 'Ograve', 'Oacute', | |||
|
1139 | 'Ocircumflex', 'Otilde', 'Odieresis', 'multiply', | |||
|
1140 | 'Oslash', 'Ugrave', 'Uacute', 'Ucircumflex', | |||
|
1141 | 'Udieresis', 'Yacute', 'Thorn', 'germandbls', | |||
|
1142 | 'agrave', 'aacute', 'acircumflex', 'atilde', | |||
|
1143 | 'adieresis', 'aring', 'ae', 'ccedilla', | |||
|
1144 | 'egrave', 'eacute', 'ecircumflex', 'edieresis', | |||
|
1145 | 'igrave', 'iacute', 'icircumflex', 'idieresis', | |||
|
1146 | 'eth', 'ntilde', 'ograve', 'oacute', | |||
|
1147 | 'ocircumflex', 'otilde', 'odieresis', 'divide', | |||
|
1148 | 'oslash', 'ugrave', 'uacute', 'ucircumflex', | |||
|
1149 | 'udieresis', 'yacute', 'thorn', 'ydieresis' | |||
|
1150 | ], | |||
|
1151 | # Central Europe | |||
|
1152 | 'ISO-8859-16' => [ | |||
|
1153 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1154 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1155 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1156 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1157 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1158 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1159 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1160 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1161 | 'space', 'exclam', 'quotedbl', 'numbersign', | |||
|
1162 | 'dollar', 'percent', 'ampersand', 'quotesingle', | |||
|
1163 | 'parenleft', 'parenright', 'asterisk', 'plus', | |||
|
1164 | 'comma', 'hyphen', 'period', 'slash', | |||
|
1165 | 'zero', 'one', 'two', 'three', | |||
|
1166 | 'four', 'five', 'six', 'seven', | |||
|
1167 | 'eight', 'nine', 'colon', 'semicolon', | |||
|
1168 | 'less', 'equal', 'greater', 'question', | |||
|
1169 | 'at', 'A', 'B', 'C', | |||
|
1170 | 'D', 'E', 'F', 'G', | |||
|
1171 | 'H', 'I', 'J', 'K', | |||
|
1172 | 'L', 'M', 'N', 'O', | |||
|
1173 | 'P', 'Q', 'R', 'S', | |||
|
1174 | 'T', 'U', 'V', 'W', | |||
|
1175 | 'X', 'Y', 'Z', 'bracketleft', | |||
|
1176 | 'backslash', 'bracketright', 'asciicircum', 'underscore', | |||
|
1177 | 'grave', 'a', 'b', 'c', | |||
|
1178 | 'd', 'e', 'f', 'g', | |||
|
1179 | 'h', 'i', 'j', 'k', | |||
|
1180 | 'l', 'm', 'n', 'o', | |||
|
1181 | 'p', 'q', 'r', 's', | |||
|
1182 | 't', 'u', 'v', 'w', | |||
|
1183 | 'x', 'y', 'z', 'braceleft', | |||
|
1184 | 'bar', 'braceright', 'asciitilde', '.notdef', | |||
|
1185 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1186 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1187 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1188 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1189 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1190 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1191 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1192 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1193 | 'space', 'Aogonek', 'aogonek', 'Lslash', | |||
|
1194 | 'Euro', 'quotedblbase', 'Scaron', 'section', | |||
|
1195 | 'scaron', 'copyright', 'Scommaaccent', 'guillemotleft', | |||
|
1196 | 'Zacute', 'hyphen', 'zacute', 'Zdotaccent', | |||
|
1197 | 'degree', 'plusminus', 'Ccaron', 'lslash', | |||
|
1198 | 'Zcaron', 'quotedblright', 'paragraph', 'periodcentered', | |||
|
1199 | 'zcaron', 'ccaron', 'scommaaccent', 'guillemotright', | |||
|
1200 | 'OE', 'oe', 'Ydieresis', 'zdotaccent', | |||
|
1201 | 'Agrave', 'Aacute', 'Acircumflex', 'Abreve', | |||
|
1202 | 'Adieresis', 'Cacute', 'AE', 'Ccedilla', | |||
|
1203 | 'Egrave', 'Eacute', 'Ecircumflex', 'Edieresis', | |||
|
1204 | 'Igrave', 'Iacute', 'Icircumflex', 'Idieresis', | |||
|
1205 | 'Dcroat', 'Nacute', 'Ograve', 'Oacute', | |||
|
1206 | 'Ocircumflex', 'Ohungarumlaut', 'Odieresis', 'Sacute', | |||
|
1207 | 'Uhungarumlaut', 'Ugrave', 'Uacute', 'Ucircumflex', | |||
|
1208 | 'Udieresis', 'Eogonek', 'Tcommaaccent', 'germandbls', | |||
|
1209 | 'agrave', 'aacute', 'acircumflex', 'abreve', | |||
|
1210 | 'adieresis', 'cacute', 'ae', 'ccedilla', | |||
|
1211 | 'egrave', 'eacute', 'ecircumflex', 'edieresis', | |||
|
1212 | 'igrave', 'iacute', 'icircumflex', 'idieresis', | |||
|
1213 | 'dcroat', 'nacute', 'ograve', 'oacute', | |||
|
1214 | 'ocircumflex', 'ohungarumlaut', 'odieresis', 'sacute', | |||
|
1215 | 'uhungarumlaut', 'ugrave', 'uacute', 'ucircumflex', | |||
|
1216 | 'udieresis', 'eogonek', 'tcommaaccent', 'ydieresis' | |||
|
1217 | ], | |||
|
1218 | # Russian | |||
|
1219 | 'KOI8-R' => [ | |||
|
1220 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1221 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1222 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1223 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1224 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1225 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1226 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1227 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1228 | 'space', 'exclam', 'quotedbl', 'numbersign', | |||
|
1229 | 'dollar', 'percent', 'ampersand', 'quotesingle', | |||
|
1230 | 'parenleft', 'parenright', 'asterisk', 'plus', | |||
|
1231 | 'comma', 'hyphen', 'period', 'slash', | |||
|
1232 | 'zero', 'one', 'two', 'three', | |||
|
1233 | 'four', 'five', 'six', 'seven', | |||
|
1234 | 'eight', 'nine', 'colon', 'semicolon', | |||
|
1235 | 'less', 'equal', 'greater', 'question', | |||
|
1236 | 'at', 'A', 'B', 'C', | |||
|
1237 | 'D', 'E', 'F', 'G', | |||
|
1238 | 'H', 'I', 'J', 'K', | |||
|
1239 | 'L', 'M', 'N', 'O', | |||
|
1240 | 'P', 'Q', 'R', 'S', | |||
|
1241 | 'T', 'U', 'V', 'W', | |||
|
1242 | 'X', 'Y', 'Z', 'bracketleft', | |||
|
1243 | 'backslash', 'bracketright', 'asciicircum', 'underscore', | |||
|
1244 | 'grave', 'a', 'b', 'c', | |||
|
1245 | 'd', 'e', 'f', 'g', | |||
|
1246 | 'h', 'i', 'j', 'k', | |||
|
1247 | 'l', 'm', 'n', 'o', | |||
|
1248 | 'p', 'q', 'r', 's', | |||
|
1249 | 't', 'u', 'v', 'w', | |||
|
1250 | 'x', 'y', 'z', 'braceleft', | |||
|
1251 | 'bar', 'braceright', 'asciitilde', '.notdef', | |||
|
1252 | 'SF100000', 'SF110000', 'SF010000', 'SF030000', | |||
|
1253 | 'SF020000', 'SF040000', 'SF080000', 'SF090000', | |||
|
1254 | 'SF060000', 'SF070000', 'SF050000', 'upblock', | |||
|
1255 | 'dnblock', 'block', 'lfblock', 'rtblock', | |||
|
1256 | 'ltshade', 'shade', 'dkshade', 'integraltp', | |||
|
1257 | 'filledbox', 'periodcentered', 'radical', 'approxequal', | |||
|
1258 | 'lessequal', 'greaterequal', 'space', 'integralbt', | |||
|
1259 | 'degree', 'twosuperior', 'periodcentered', 'divide', | |||
|
1260 | 'SF430000', 'SF240000', 'SF510000', 'afii10071', | |||
|
1261 | 'SF520000', 'SF390000', 'SF220000', 'SF210000', | |||
|
1262 | 'SF250000', 'SF500000', 'SF490000', 'SF380000', | |||
|
1263 | 'SF280000', 'SF270000', 'SF260000', 'SF360000', | |||
|
1264 | 'SF370000', 'SF420000', 'SF190000', 'afii10023', | |||
|
1265 | 'SF200000', 'SF230000', 'SF470000', 'SF480000', | |||
|
1266 | 'SF410000', 'SF450000', 'SF460000', 'SF400000', | |||
|
1267 | 'SF540000', 'SF530000', 'SF440000', 'copyright', | |||
|
1268 | 'afii10096', 'afii10065', 'afii10066', 'afii10088', | |||
|
1269 | 'afii10069', 'afii10070', 'afii10086', 'afii10068', | |||
|
1270 | 'afii10087', 'afii10074', 'afii10075', 'afii10076', | |||
|
1271 | 'afii10077', 'afii10078', 'afii10079', 'afii10080', | |||
|
1272 | 'afii10081', 'afii10097', 'afii10082', 'afii10083', | |||
|
1273 | 'afii10084', 'afii10085', 'afii10072', 'afii10067', | |||
|
1274 | 'afii10094', 'afii10093', 'afii10073', 'afii10090', | |||
|
1275 | 'afii10095', 'afii10091', 'afii10089', 'afii10092', | |||
|
1276 | 'afii10048', 'afii10017', 'afii10018', 'afii10040', | |||
|
1277 | 'afii10021', 'afii10022', 'afii10038', 'afii10020', | |||
|
1278 | 'afii10039', 'afii10026', 'afii10027', 'afii10028', | |||
|
1279 | 'afii10029', 'afii10030', 'afii10031', 'afii10032', | |||
|
1280 | 'afii10033', 'afii10049', 'afii10034', 'afii10035', | |||
|
1281 | 'afii10036', 'afii10037', 'afii10024', 'afii10019', | |||
|
1282 | 'afii10046', 'afii10045', 'afii10025', 'afii10042', | |||
|
1283 | 'afii10047', 'afii10043', 'afii10041', 'afii10044' | |||
|
1284 | ], | |||
|
1285 | # Ukrainian | |||
|
1286 | 'KOI8-U' => [ | |||
|
1287 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1288 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1289 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1290 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1291 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1292 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1293 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1294 | '.notdef', '.notdef', '.notdef', '.notdef', | |||
|
1295 | 'space', 'exclam', 'quotedbl', 'numbersign', | |||
|
1296 | 'dollar', 'percent', 'ampersand', 'quotesingle', | |||
|
1297 | 'parenleft', 'parenright', 'asterisk', 'plus', | |||
|
1298 | 'comma', 'hyphen', 'period', 'slash', | |||
|
1299 | 'zero', 'one', 'two', 'three', | |||
|
1300 | 'four', 'five', 'six', 'seven', | |||
|
1301 | 'eight', 'nine', 'colon', 'semicolon', | |||
|
1302 | 'less', 'equal', 'greater', 'question', | |||
|
1303 | 'at', 'A', 'B', 'C', | |||
|
1304 | 'D', 'E', 'F', 'G', | |||
|
1305 | 'H', 'I', 'J', 'K', | |||
|
1306 | 'L', 'M', 'N', 'O', | |||
|
1307 | 'P', 'Q', 'R', 'S', | |||
|
1308 | 'T', 'U', 'V', 'W', | |||
|
1309 | 'X', 'Y', 'Z', 'bracketleft', | |||
|
1310 | 'backslash', 'bracketright', 'asciicircum', 'underscore', | |||
|
1311 | 'grave', 'a', 'b', 'c', | |||
|
1312 | 'd', 'e', 'f', 'g', | |||
|
1313 | 'h', 'i', 'j', 'k', | |||
|
1314 | 'l', 'm', 'n', 'o', | |||
|
1315 | 'p', 'q', 'r', 's', | |||
|
1316 | 't', 'u', 'v', 'w', | |||
|
1317 | 'x', 'y', 'z', 'braceleft', | |||
|
1318 | 'bar', 'braceright', 'asciitilde', '.notdef', | |||
|
1319 | 'SF100000', 'SF110000', 'SF010000', 'SF030000', | |||
|
1320 | 'SF020000', 'SF040000', 'SF080000', 'SF090000', | |||
|
1321 | 'SF060000', 'SF070000', 'SF050000', 'upblock', | |||
|
1322 | 'dnblock', 'block', 'lfblock', 'rtblock', | |||
|
1323 | 'ltshade', 'shade', 'dkshade', 'integraltp', | |||
|
1324 | 'filledbox', 'bullet', 'radical', 'approxequal', | |||
|
1325 | 'lessequal', 'greaterequal', 'space', 'integralbt', | |||
|
1326 | 'degree', 'twosuperior', 'periodcentered', 'divide', | |||
|
1327 | 'SF430000', 'SF240000', 'SF510000', 'afii10071', | |||
|
1328 | 'afii10101', 'SF390000', 'afii10103', 'afii10104', | |||
|
1329 | 'SF250000', 'SF500000', 'SF490000', 'SF380000', | |||
|
1330 | 'SF280000', 'afii10098', 'SF260000', 'SF360000', | |||
|
1331 | 'SF370000', 'SF420000', 'SF190000', 'afii10023', | |||
|
1332 | 'afii10053', 'SF230000', 'afii10055', 'afii10056', | |||
|
1333 | 'SF410000', 'SF450000', 'SF460000', 'SF400000', | |||
|
1334 | 'SF540000', 'afii10050', 'SF440000', 'copyright', | |||
|
1335 | 'afii10096', 'afii10065', 'afii10066', 'afii10088', | |||
|
1336 | 'afii10069', 'afii10070', 'afii10086', 'afii10068', | |||
|
1337 | 'afii10087', 'afii10074', 'afii10075', 'afii10076', | |||
|
1338 | 'afii10077', 'afii10078', 'afii10079', 'afii10080', | |||
|
1339 | 'afii10081', 'afii10097', 'afii10082', 'afii10083', | |||
|
1340 | 'afii10084', 'afii10085', 'afii10072', 'afii10067', | |||
|
1341 | 'afii10094', 'afii10093', 'afii10073', 'afii10090', | |||
|
1342 | 'afii10095', 'afii10091', 'afii10089', 'afii10092', | |||
|
1343 | 'afii10048', 'afii10017', 'afii10018', 'afii10040', | |||
|
1344 | 'afii10021', 'afii10022', 'afii10038', 'afii10020', | |||
|
1345 | 'afii10039', 'afii10026', 'afii10027', 'afii10028', | |||
|
1346 | 'afii10029', 'afii10030', 'afii10031', 'afii10032', | |||
|
1347 | 'afii10033', 'afii10049', 'afii10034', 'afii10035', | |||
|
1348 | 'afii10036', 'afii10037', 'afii10024', 'afii10019', | |||
|
1349 | 'afii10046', 'afii10045', 'afii10025', 'afii10042', | |||
|
1350 | 'afii10047', 'afii10043', 'afii10041', 'afii10044' | |||
|
1351 | ] | |||
|
1352 | } | |||
|
1353 | ||||
|
1354 | def ReadAFM(file, map) | |||
|
1355 | ||||
|
1356 | # Read a font metric file | |||
|
1357 | a = IO.readlines(file) | |||
|
1358 | ||||
|
1359 | raise "File no found: #{file}" if a.size == 0 | |||
|
1360 | ||||
|
1361 | widths = {} | |||
|
1362 | fm = {} | |||
|
1363 | fix = { 'Edot' => 'Edotaccent', 'edot' => 'edotaccent', | |||
|
1364 | 'Idot' => 'Idotaccent', | |||
|
1365 | 'Zdot' => 'Zdotaccent', 'zdot' => 'zdotaccent', | |||
|
1366 | 'Odblacute' => 'Ohungarumlaut', 'odblacute' => 'ohungarumlaut', | |||
|
1367 | 'Udblacute' => 'Uhungarumlaut', 'udblacute' => 'uhungarumlaut', | |||
|
1368 | 'Gcedilla' => 'Gcommaaccent', 'gcedilla' => 'gcommaaccent', | |||
|
1369 | 'Kcedilla' => 'Kcommaaccent', 'kcedilla' => 'kcommaaccent', | |||
|
1370 | 'Lcedilla' => 'Lcommaaccent', 'lcedilla' => 'lcommaaccent', | |||
|
1371 | 'Ncedilla' => 'Ncommaaccent', 'ncedilla' => 'ncommaaccent', | |||
|
1372 | 'Rcedilla' => 'Rcommaaccent', 'rcedilla' => 'rcommaaccent', | |||
|
1373 | 'Scedilla' => 'Scommaaccent',' scedilla' => 'scommaaccent', | |||
|
1374 | 'Tcedilla' => 'Tcommaaccent',' tcedilla' => 'tcommaaccent', | |||
|
1375 | 'Dslash' => 'Dcroat', 'dslash' => 'dcroat', | |||
|
1376 | 'Dmacron' => 'Dcroat', 'dmacron' => 'dcroat', | |||
|
1377 | 'combininggraveaccent' => 'gravecomb', | |||
|
1378 | 'combininghookabove' => 'hookabovecomb', | |||
|
1379 | 'combiningtildeaccent' => 'tildecomb', | |||
|
1380 | 'combiningacuteaccent' => 'acutecomb', | |||
|
1381 | 'combiningdotbelow' => 'dotbelowcomb', | |||
|
1382 | 'dongsign' => 'dong' | |||
|
1383 | } | |||
|
1384 | ||||
|
1385 | a.each do |line| | |||
|
1386 | ||||
|
1387 | e = line.rstrip.split(' ') | |||
|
1388 | next if e.size < 2 | |||
|
1389 | ||||
|
1390 | code = e[0] | |||
|
1391 | param = e[1] | |||
|
1392 | ||||
|
1393 | if code == 'C' then | |||
|
1394 | ||||
|
1395 | # Character metrics | |||
|
1396 | cc = e[1].to_i | |||
|
1397 | w = e[4] | |||
|
1398 | gn = e[7] | |||
|
1399 | ||||
|
1400 | gn = 'Euro' if gn[-4, 4] == '20AC' | |||
|
1401 | ||||
|
1402 | if fix[gn] then | |||
|
1403 | ||||
|
1404 | # Fix incorrect glyph name | |||
|
1405 | 0.upto(map.size - 1) do |i| | |||
|
1406 | if map[i] == fix[gn] then | |||
|
1407 | map[i] = gn | |||
|
1408 | end | |||
|
1409 | end | |||
|
1410 | end | |||
|
1411 | ||||
|
1412 | if map.size == 0 then | |||
|
1413 | # Symbolic font: use built-in encoding | |||
|
1414 | widths[cc] = w | |||
|
1415 | else | |||
|
1416 | widths[gn] = w | |||
|
1417 | fm['CapXHeight'] = e[13].to_i if gn == 'X' | |||
|
1418 | end | |||
|
1419 | ||||
|
1420 | fm['MissingWidth'] = w if gn == '.notdef' | |||
|
1421 | ||||
|
1422 | elsif code == 'FontName' then | |||
|
1423 | fm['FontName'] = param | |||
|
1424 | elsif code == 'Weight' then | |||
|
1425 | fm['Weight'] = param | |||
|
1426 | elsif code == 'ItalicAngle' then | |||
|
1427 | fm['ItalicAngle'] = param.to_f | |||
|
1428 | elsif code == 'Ascender' then | |||
|
1429 | fm['Ascender'] = param.to_i | |||
|
1430 | elsif code == 'Descender' then | |||
|
1431 | fm['Descender'] = param.to_i | |||
|
1432 | elsif code == 'UnderlineThickness' then | |||
|
1433 | fm['UnderlineThickness'] = param.to_i | |||
|
1434 | elsif code == 'UnderlinePosition' then | |||
|
1435 | fm['UnderlinePosition'] = param.to_i | |||
|
1436 | elsif code == 'IsFixedPitch' then | |||
|
1437 | fm['IsFixedPitch'] = (param == 'true') | |||
|
1438 | elsif code == 'FontBBox' then | |||
|
1439 | fm['FontBBox'] = "[#{e[1]},#{e[2]},#{e[3]},#{e[4]}]" | |||
|
1440 | elsif code == 'CapHeight' then | |||
|
1441 | fm['CapHeight'] = param.to_i | |||
|
1442 | elsif code == 'StdVW' then | |||
|
1443 | fm['StdVW'] = param.to_i | |||
|
1444 | end | |||
|
1445 | end | |||
|
1446 | ||||
|
1447 | raise 'FontName not found' unless fm['FontName'] | |||
|
1448 | ||||
|
1449 | if map.size > 0 then | |||
|
1450 | widths['.notdef'] = 600 unless widths['.notdef'] | |||
|
1451 | ||||
|
1452 | if (widths['Delta'] == nil) && widths['increment'] then | |||
|
1453 | widths['Delta'] = widths['increment'] | |||
|
1454 | end | |||
|
1455 | ||||
|
1456 | # Order widths according to map | |||
|
1457 | 0.upto(255) do |i| | |||
|
1458 | if widths[map[i]] == nil | |||
|
1459 | puts "Warning: character #{map[i]} is missing" | |||
|
1460 | widths[i] = widths['.notdef'] | |||
|
1461 | else | |||
|
1462 | widths[i] = widths[map[i]] | |||
|
1463 | end | |||
|
1464 | end | |||
|
1465 | end | |||
|
1466 | ||||
|
1467 | fm['Widths'] = widths | |||
|
1468 | ||||
|
1469 | return fm | |||
|
1470 | end | |||
|
1471 | ||||
|
1472 | def MakeFontDescriptor(fm, symbolic) | |||
|
1473 | ||||
|
1474 | # Ascent | |||
|
1475 | asc = fm['Ascender'] ? fm['Ascender'] : 1000 | |||
|
1476 | fd = "{\n 'Ascent' => '#{asc}'" | |||
|
1477 | ||||
|
1478 | # Descent | |||
|
1479 | desc = fm['Descender'] ? fm['Descender'] : -200 | |||
|
1480 | fd += ", 'Descent' => '#{desc}'" | |||
|
1481 | ||||
|
1482 | # CapHeight | |||
|
1483 | if fm['CapHeight'] then | |||
|
1484 | ch = fm['CapHeight'] | |||
|
1485 | elsif fm['CapXHeight'] | |||
|
1486 | ch = fm['CapXHeight'] | |||
|
1487 | else | |||
|
1488 | ch = asc | |||
|
1489 | end | |||
|
1490 | fd += ", 'CapHeight' => '#{ch}'" | |||
|
1491 | ||||
|
1492 | # Flags | |||
|
1493 | flags = 0 | |||
|
1494 | ||||
|
1495 | if fm['IsFixedPitch'] then | |||
|
1496 | flags += 1 << 0 | |||
|
1497 | end | |||
|
1498 | ||||
|
1499 | if symbolic then | |||
|
1500 | flags += 1 << 2 | |||
|
1501 | else | |||
|
1502 | flags += 1 << 5 | |||
|
1503 | end | |||
|
1504 | ||||
|
1505 | if fm['ItalicAngle'] && (fm['ItalicAngle'] != 0) then | |||
|
1506 | flags += 1 << 6 | |||
|
1507 | end | |||
|
1508 | ||||
|
1509 | fd += ",\n 'Flags' => '#{flags}'" | |||
|
1510 | ||||
|
1511 | # FontBBox | |||
|
1512 | if fm['FontBBox'] then | |||
|
1513 | fbb = fm['FontBBox'].gsub(/,/, ' ') | |||
|
1514 | else | |||
|
1515 | fbb = "[0 #{desc - 100} 1000 #{asc + 100}]" | |||
|
1516 | end | |||
|
1517 | ||||
|
1518 | fd += ", 'FontBBox' => '#{fbb}'" | |||
|
1519 | ||||
|
1520 | # ItalicAngle | |||
|
1521 | ia = fm['ItalicAngle'] ? fm['ItalicAngle'] : 0 | |||
|
1522 | fd += ",\n 'ItalicAngle' => '#{ia}'" | |||
|
1523 | ||||
|
1524 | # StemV | |||
|
1525 | if fm['StdVW'] then | |||
|
1526 | stemv = fm['StdVW'] | |||
|
1527 | elsif fm['Weight'] && (/bold|black/i =~ fm['Weight']) | |||
|
1528 | stemv = 120 | |||
|
1529 | else | |||
|
1530 | stemv = 70 | |||
|
1531 | end | |||
|
1532 | ||||
|
1533 | fd += ", 'StemV' => '#{stemv}'" | |||
|
1534 | ||||
|
1535 | # MissingWidth | |||
|
1536 | if fm['MissingWidth'] then | |||
|
1537 | fd += ", 'MissingWidth' => '#{fm['MissingWidth']}'" | |||
|
1538 | end | |||
|
1539 | ||||
|
1540 | fd += "\n }" | |||
|
1541 | return fd | |||
|
1542 | end | |||
|
1543 | ||||
|
1544 | def MakeWidthArray(fm) | |||
|
1545 | ||||
|
1546 | # Make character width array | |||
|
1547 | s = " [\n " | |||
|
1548 | ||||
|
1549 | cw = fm['Widths'] | |||
|
1550 | ||||
|
1551 | 0.upto(255) do |i| | |||
|
1552 | s += "%5d" % cw[i] | |||
|
1553 | s += "," if i != 255 | |||
|
1554 | s += "\n " if (i % 8) == 7 | |||
|
1555 | end | |||
|
1556 | ||||
|
1557 | s += ']' | |||
|
1558 | ||||
|
1559 | return s | |||
|
1560 | end | |||
|
1561 | ||||
|
1562 | def MakeFontEncoding(map) | |||
|
1563 | ||||
|
1564 | # Build differences from reference encoding | |||
|
1565 | ref = Charencodings['cp1252'] | |||
|
1566 | s = '' | |||
|
1567 | last = 0 | |||
|
1568 | 32.upto(255) do |i| | |||
|
1569 | if map[i] != ref[i] then | |||
|
1570 | if i != last + 1 then | |||
|
1571 | s += i.to_s + ' ' | |||
|
1572 | end | |||
|
1573 | last = i | |||
|
1574 | s += '/' + map[i] + ' ' | |||
|
1575 | end | |||
|
1576 | end | |||
|
1577 | return s.rstrip | |||
|
1578 | end | |||
|
1579 | ||||
|
1580 | def ReadShort(f) | |||
|
1581 | a = f.read(2).unpack('n') | |||
|
1582 | return a[0] | |||
|
1583 | end | |||
|
1584 | ||||
|
1585 | def ReadLong(f) | |||
|
1586 | a = f.read(4).unpack('N') | |||
|
1587 | return a[0] | |||
|
1588 | end | |||
|
1589 | ||||
|
1590 | def CheckTTF(file) | |||
|
1591 | ||||
|
1592 | rl = false | |||
|
1593 | pp = false | |||
|
1594 | e = false | |||
|
1595 | ||||
|
1596 | # Check if font license allows embedding | |||
|
1597 | File.open(file, 'rb') do |f| | |||
|
1598 | ||||
|
1599 | # Extract number of tables | |||
|
1600 | f.seek(4, IO::SEEK_CUR) | |||
|
1601 | nb = ReadShort(f) | |||
|
1602 | f.seek(6, IO::SEEK_CUR) | |||
|
1603 | ||||
|
1604 | # Seek OS/2 table | |||
|
1605 | found = false | |||
|
1606 | 0.upto(nb - 1) do |i| | |||
|
1607 | if f.read(4) == 'OS/2' then | |||
|
1608 | found = true | |||
|
1609 | break | |||
|
1610 | end | |||
|
1611 | ||||
|
1612 | f.seek(12, IO::SEEK_CUR) | |||
|
1613 | end | |||
|
1614 | ||||
|
1615 | if ! found then | |||
|
1616 | return | |||
|
1617 | end | |||
|
1618 | ||||
|
1619 | f.seek(4, IO::SEEK_CUR) | |||
|
1620 | offset = ReadLong(f) | |||
|
1621 | f.seek(offset, IO::SEEK_SET) | |||
|
1622 | ||||
|
1623 | # Extract fsType flags | |||
|
1624 | f.seek(8, IO::SEEK_CUR) | |||
|
1625 | fsType = ReadShort(f) | |||
|
1626 | ||||
|
1627 | rl = (fsType & 0x02) != 0 | |||
|
1628 | pp = (fsType & 0x04) != 0 | |||
|
1629 | e = (fsType & 0x08) != 0 | |||
|
1630 | end | |||
|
1631 | ||||
|
1632 | if rl && ( ! pp) && ( ! e) then | |||
|
1633 | puts 'Warning: font license does not allow embedding' | |||
|
1634 | end | |||
|
1635 | end | |||
|
1636 | ||||
|
1637 | # | |||
|
1638 | # fontfile: path to TTF file (or empty string if not to be embedded) | |||
|
1639 | # afmfile: path to AFM file | |||
|
1640 | # enc: font encoding (or empty string for symbolic fonts) | |||
|
1641 | # patch: optional patch for encoding | |||
|
1642 | # type : font type if $fontfile is empty | |||
|
1643 | # | |||
|
1644 | def MakeFont(fontfile, afmfile, enc = 'cp1252', patch = {}, type = 'TrueType') | |||
|
1645 | # Generate a font definition file | |||
|
1646 | if (enc != nil) && (enc != '') then | |||
|
1647 | map = Charencodings[enc] | |||
|
1648 | patch.each { |cc, gn| map[cc] = gn } | |||
|
1649 | else | |||
|
1650 | map = [] | |||
|
1651 | end | |||
|
1652 | ||||
|
1653 | raise "Error: AFM file not found: #{afmfile}" unless File.exists?(afmfile) | |||
|
1654 | ||||
|
1655 | fm = ReadAFM(afmfile, map) | |||
|
1656 | ||||
|
1657 | if (enc != nil) && (enc != '') then | |||
|
1658 | diff = MakeFontEncoding(map) | |||
|
1659 | else | |||
|
1660 | diff = '' | |||
|
1661 | end | |||
|
1662 | ||||
|
1663 | fd = MakeFontDescriptor(fm, (map.size == 0)) | |||
|
1664 | ||||
|
1665 | # Find font type | |||
|
1666 | if fontfile then | |||
|
1667 | ext = File.extname(fontfile).downcase.sub(/^\./, '') | |||
|
1668 | ||||
|
1669 | if ext == 'ttf' then | |||
|
1670 | type = 'TrueType' | |||
|
1671 | elsif ext == 'pfb' | |||
|
1672 | type = 'Type1' | |||
|
1673 | else | |||
|
1674 | raise "Error: unrecognized font file extension: #{ext}" | |||
|
1675 | end | |||
|
1676 | else | |||
|
1677 | raise "Error: incorrect font type: #{type}" if (type != 'TrueType') && (type != 'Type1') | |||
|
1678 | end | |||
|
1679 | printf "type = #{type}\n" | |||
|
1680 | # Start generation | |||
|
1681 | s = "# #{fm['FontName']} font definition\n\n" | |||
|
1682 | s += "module FontDef\n" | |||
|
1683 | s += " def FontDef.type\n '#{type}'\n end\n" | |||
|
1684 | s += " def FontDef.name\n '#{fm['FontName']}'\n end\n" | |||
|
1685 | s += " def FontDef.desc\n #{fd}\n end\n" | |||
|
1686 | ||||
|
1687 | if fm['UnderlinePosition'] == nil then | |||
|
1688 | fm['UnderlinePosition'] = -100 | |||
|
1689 | end | |||
|
1690 | ||||
|
1691 | if fm['UnderlineThickness'] == nil then | |||
|
1692 | fm['UnderlineThickness'] = 50 | |||
|
1693 | end | |||
|
1694 | ||||
|
1695 | s += " def FontDef.up\n #{fm['UnderlinePosition']}\n end\n" | |||
|
1696 | s += " def FontDef.ut\n #{fm['UnderlineThickness']}\n end\n" | |||
|
1697 | ||||
|
1698 | w = MakeWidthArray(fm) | |||
|
1699 | s += " def FontDef.cw\n#{w}\n end\n" | |||
|
1700 | ||||
|
1701 | s += " def FontDef.enc\n '#{enc}'\n end\n" | |||
|
1702 | s += " def FontDef.diff\n #{(diff == nil) || (diff == '') ? 'nil' : '\'' + diff '\''}\n end\n" | |||
|
1703 | ||||
|
1704 | basename = File.basename(afmfile, '.*') | |||
|
1705 | ||||
|
1706 | if fontfile then | |||
|
1707 | # Embedded font | |||
|
1708 | if ! File.exist?(fontfile) then | |||
|
1709 | raise "Error: font file not found: #{fontfile}" | |||
|
1710 | end | |||
|
1711 | ||||
|
1712 | if type == 'TrueType' then | |||
|
1713 | CheckTTF(fontfile) | |||
|
1714 | end | |||
|
1715 | ||||
|
1716 | file = '' | |||
|
1717 | File.open(fontfile, 'rb') do |f| | |||
|
1718 | file = f.read() | |||
|
1719 | end | |||
|
1720 | ||||
|
1721 | if type == 'Type1' then | |||
|
1722 | # Find first two sections and discard third one | |||
|
1723 | header = file[0] == 128 | |||
|
1724 | file = file[6, file.length - 6] if header | |||
|
1725 | ||||
|
1726 | pos = file.index('eexec') | |||
|
1727 | raise 'Error: font file does not seem to be valid Type1' if pos == nil | |||
|
1728 | ||||
|
1729 | size1 = pos + 6 | |||
|
1730 | ||||
|
1731 | file = file[0, size1] + file[size1 + 6, file.length - (size1 + 6)] if header && file[size1] == 128 | |||
|
1732 | ||||
|
1733 | pos = file.index('00000000') | |||
|
1734 | raise 'Error: font file does not seem to be valid Type1' if pos == nil | |||
|
1735 | ||||
|
1736 | size2 = pos - size1 | |||
|
1737 | file = file[0, size1 + size2] | |||
|
1738 | end | |||
|
1739 | ||||
|
1740 | if require 'zlib' then | |||
|
1741 | File.open(basename + '.z', 'wb') { |f| f.write(Zlib::Deflate.deflate(file)) } | |||
|
1742 | s += " def FontDef.file\n '#{basename}.z'\n end\n" | |||
|
1743 | puts "Font file compressed ('#{basename}.z')" | |||
|
1744 | else | |||
|
1745 | s += " def FontDef.file\n '#{File.basename(fontfile)}'\n end\n" | |||
|
1746 | puts 'Notice: font file could not be compressed (zlib not available)' | |||
|
1747 | end | |||
|
1748 | ||||
|
1749 | if type == 'Type1' then | |||
|
1750 | s += " def FontDef.size1\n '#{size1}'\n end\n" | |||
|
1751 | s += " def FontDef.size2\n '#{size2}'\n end\n" | |||
|
1752 | else | |||
|
1753 | s += " def FontDef.originalsize\n '#{File.size(fontfile)}'\n end\n" | |||
|
1754 | end | |||
|
1755 | ||||
|
1756 | else | |||
|
1757 | # Not embedded font | |||
|
1758 | s += " def FontDef.file\n ''\n end\n" | |||
|
1759 | end | |||
|
1760 | ||||
|
1761 | s += "end\n" | |||
|
1762 | File.open(basename + '.rb', 'w') { |file| file.write(s)} | |||
|
1763 | puts "Font definition file generated (#{basename}.rb)" | |||
|
1764 | end | |||
|
1765 | ||||
|
1766 | ||||
|
1767 | if $0 == __FILE__ then | |||
|
1768 | if ARGV.length >= 3 then | |||
|
1769 | enc = ARGV[2] | |||
|
1770 | else | |||
|
1771 | enc = 'cp1252' | |||
|
1772 | end | |||
|
1773 | ||||
|
1774 | if ARGV.length >= 4 then | |||
|
1775 | patch = ARGV[3] | |||
|
1776 | else | |||
|
1777 | patch = {} | |||
|
1778 | end | |||
|
1779 | ||||
|
1780 | if ARGV.length >= 5 then | |||
|
1781 | type = ARGV[4] | |||
|
1782 | else | |||
|
1783 | type = 'TrueType' | |||
|
1784 | end | |||
|
1785 | ||||
|
1786 | MakeFont(ARGV[0], ARGV[1], enc, patch, type) | |||
|
1787 | end |
@@ -0,0 +1,346 | |||||
|
1 | module RFPDF | |||
|
2 | COLOR_PALETTE = { | |||
|
3 | :black => [0x00, 0x00, 0x00], | |||
|
4 | :white => [0xff, 0xff, 0xff], | |||
|
5 | }.freeze | |||
|
6 | ||||
|
7 | # Draw a line from (<tt>x1, y1</tt>) to (<tt>x2, y2</tt>). | |||
|
8 | # | |||
|
9 | # Options are: | |||
|
10 | # * <tt>:line_color</tt> - Default value is <tt>COLOR_PALETTE[:black]</tt>. | |||
|
11 | # * <tt>:line_width</tt> - Default value is <tt>0.5</tt>. | |||
|
12 | # | |||
|
13 | # Example: | |||
|
14 | # | |||
|
15 | # draw_line(x1, y1, x1, y1+h, :line_color => ReportHelper::COLOR_PALETTE[:dark_blue], :line_width => 1) | |||
|
16 | # | |||
|
17 | def draw_line(x1, y1, x2, y2, options = {}) | |||
|
18 | options[:line_color] ||= COLOR_PALETTE[:black] | |||
|
19 | options[:line_width] ||= 0.5 | |||
|
20 | set_draw_color(options[:line_color]) | |||
|
21 | SetLineWidth(options[:line_width]) | |||
|
22 | Line(x1, y1, x2, y2) | |||
|
23 | end | |||
|
24 | ||||
|
25 | # Draw a string of <tt>text</tt> at (<tt>x, y</tt>). | |||
|
26 | # | |||
|
27 | # Options are: | |||
|
28 | # * <tt>:font_color</tt> - Default value is <tt>COLOR_PALETTE[:black]</tt>. | |||
|
29 | # * <tt>:font_size</tt> - Default value is <tt>10</tt>. | |||
|
30 | # * <tt>:font_style</tt> - Default value is nothing or <tt>''</tt>. | |||
|
31 | # | |||
|
32 | # Example: | |||
|
33 | # | |||
|
34 | # draw_text(x, y, header_left, :font_size => 10) | |||
|
35 | # | |||
|
36 | def draw_text(x, y, text, options = {}) | |||
|
37 | options[:font_color] ||= COLOR_PALETTE[:black] | |||
|
38 | options[:font_size] ||= 10 | |||
|
39 | options[:font_style] ||= '' | |||
|
40 | set_text_color(options[:font_color]) | |||
|
41 | SetFont('Arial', options[:font_style], options[:font_size]) | |||
|
42 | SetXY(x, y) | |||
|
43 | Write(options[:font_size] + 4, text) | |||
|
44 | end | |||
|
45 | ||||
|
46 | # Draw a block of <tt>text</tt> at (<tt>x, y</tt>) bounded by <tt>left_margin</tt> and <tt>right_margin</tt>. Both | |||
|
47 | # margins are measured from their corresponding edge. | |||
|
48 | # | |||
|
49 | # Options are: | |||
|
50 | # * <tt>:font_color</tt> - Default value is <tt>COLOR_PALETTE[:black]</tt>. | |||
|
51 | # * <tt>:font_size</tt> - Default value is <tt>10</tt>. | |||
|
52 | # * <tt>:font_style</tt> - Default value is nothing or <tt>''</tt>. | |||
|
53 | # | |||
|
54 | # Example: | |||
|
55 | # | |||
|
56 | # draw_text_block(left_margin, 85, "question", left_margin, 280, | |||
|
57 | # :font_color => ReportHelper::COLOR_PALETTE[:dark_blue], | |||
|
58 | # :font_size => 12, | |||
|
59 | # :font_style => 'I') | |||
|
60 | # | |||
|
61 | def draw_text_block(x, y, text, left_margin, right_margin, options = {}) | |||
|
62 | options[:font_color] ||= COLOR_PALETTE[:black] | |||
|
63 | options[:font_size] ||= 10 | |||
|
64 | options[:font_style] ||= '' | |||
|
65 | set_text_color(options[:font_color]) | |||
|
66 | SetFont('Arial', options[:font_style], options[:font_size]) | |||
|
67 | SetXY(x, y) | |||
|
68 | SetLeftMargin(left_margin) | |||
|
69 | SetRightMargin(right_margin) | |||
|
70 | Write(options[:font_size] + 4, text) | |||
|
71 | SetMargins(0,0,0) | |||
|
72 | end | |||
|
73 | ||||
|
74 | # Draw a box at (<tt>x, y</tt>), <tt>w</tt> wide and <tt>h</tt> high. | |||
|
75 | # | |||
|
76 | # Options are: | |||
|
77 | # * <tt>:border</tt> - Draw a border, 0 = no, 1 = yes? Default value is <tt>1</tt>. | |||
|
78 | # * <tt>:border_color</tt> - Default value is <tt>COLOR_PALETTE[:black]</tt>. | |||
|
79 | # * <tt>:border_width</tt> - Default value is <tt>0.5</tt>. | |||
|
80 | # * <tt>:fill</tt> - Fill the box, 0 = no, 1 = yes? Default value is <tt>1</tt>. | |||
|
81 | # * <tt>:fill_color</tt> - Default value is nothing or <tt>COLOR_PALETTE[:white]</tt>. | |||
|
82 | # | |||
|
83 | # Example: | |||
|
84 | # | |||
|
85 | # draw_box(x, y - 1, 38, 22) | |||
|
86 | # | |||
|
87 | def draw_box(x, y, w, h, options = {}) | |||
|
88 | options[:border] ||= 1 | |||
|
89 | options[:border_color] ||= COLOR_PALETTE[:black] | |||
|
90 | options[:border_width] ||= 0.5 | |||
|
91 | options[:fill] ||= 1 | |||
|
92 | options[:fill_color] ||= COLOR_PALETTE[:white] | |||
|
93 | SetLineWidth(options[:border_width]) | |||
|
94 | set_draw_color(options[:border_color]) | |||
|
95 | set_fill_color(options[:fill_color]) | |||
|
96 | fd = "" | |||
|
97 | fd = "D" if options[:border] == 1 | |||
|
98 | fd += "F" if options[:fill] == 1 | |||
|
99 | Rect(x, y, w, h, fd) | |||
|
100 | end | |||
|
101 | ||||
|
102 | # Draw a string of <tt>text</tt> at (<tt>x, y</tt>) in a box <tt>w</tt> wide and <tt>h</tt> high. | |||
|
103 | # | |||
|
104 | # Options are: | |||
|
105 | # * <tt>:align</tt> - Vertical alignment 'C' = center, 'L' = left, 'R' = right. Default value is <tt>'C'</tt>. | |||
|
106 | # * <tt>:border</tt> - Draw a border, 0 = no, 1 = yes? Default value is <tt>0</tt>. | |||
|
107 | # * <tt>:border_color</tt> - Default value is <tt>COLOR_PALETTE[:black]</tt>. | |||
|
108 | # * <tt>:border_width</tt> - Default value is <tt>0.5</tt>. | |||
|
109 | # * <tt>:fill</tt> - Fill the box, 0 = no, 1 = yes? Default value is <tt>1</tt>. | |||
|
110 | # * <tt>:fill_color</tt> - Default value is nothing or <tt>COLOR_PALETTE[:white]</tt>. | |||
|
111 | # * <tt>:font_color</tt> - Default value is <tt>COLOR_PALETTE[:black]</tt>. | |||
|
112 | # * <tt>:font_size</tt> - Default value is nothing or <tt>8</tt>. | |||
|
113 | # * <tt>:font_style</tt> - 'B' = bold, 'I' = italic, 'U' = underline. Default value is nothing <tt>''</tt>. | |||
|
114 | # * <tt>:padding</tt> - Default value is nothing or <tt>2</tt>. | |||
|
115 | # * <tt>:valign</tt> - 'M' = middle, 'T' = top, 'B' = bottom. Default value is nothing or <tt>'M'</tt>. | |||
|
116 | # | |||
|
117 | # Example: | |||
|
118 | # | |||
|
119 | # draw_text_box(x, y - 1, 38, 22, | |||
|
120 | # "your_score_title", | |||
|
121 | # :fill => 0, | |||
|
122 | # :font_color => ReportHelper::COLOR_PALETTE[:blue], | |||
|
123 | # :font_line_spacing => 0, | |||
|
124 | # :font_style => "B", | |||
|
125 | # :valign => "M") | |||
|
126 | # | |||
|
127 | def draw_text_box(x, y, w, h, text, options = {}) | |||
|
128 | options[:align] ||= 'C' | |||
|
129 | options[:border] ||= 0 | |||
|
130 | options[:border_color] ||= COLOR_PALETTE[:black] | |||
|
131 | options[:border_width] ||= 0.5 | |||
|
132 | options[:fill] ||= 1 | |||
|
133 | options[:fill_color] ||= COLOR_PALETTE[:white] | |||
|
134 | options[:font_color] ||= COLOR_PALETTE[:black] | |||
|
135 | options[:font_size] ||= 8 | |||
|
136 | options[:font_line_spacing] ||= options[:font_size] * 0.3 | |||
|
137 | options[:font_style] ||= '' | |||
|
138 | options[:padding] ||= 2 | |||
|
139 | options[:valign] ||= "M" | |||
|
140 | if options[:fill] == 1 or options[:border] == 1 | |||
|
141 | draw_box(x, y, w, h, options) | |||
|
142 | end | |||
|
143 | SetMargins(0,0,0) | |||
|
144 | set_text_color(options[:font_color]) | |||
|
145 | font_size = options[:font_size] | |||
|
146 | SetFont('Arial', options[:font_style], font_size) | |||
|
147 | font_size += options[:font_line_spacing] | |||
|
148 | case options[:valign] | |||
|
149 | when "B" | |||
|
150 | y -= options[:padding] | |||
|
151 | text = "\n" + text if text["\n"].nil? | |||
|
152 | when "T" | |||
|
153 | y += options[:padding] | |||
|
154 | end | |||
|
155 | SetXY(x, y) | |||
|
156 | if GetStringWidth(text) > w or not text["\n"].nil? or options[:valign] == "T" | |||
|
157 | font_size += options[:font_size] * 0.1 | |||
|
158 | #TODO 2006-07-21 Level=1 - this is assuming a 2 line text | |||
|
159 | SetXY(x, y + ((h - (font_size * 2)) / 2)) if options[:valign] == "M" | |||
|
160 | MultiCell(w, font_size, text, 0, options[:align]) | |||
|
161 | else | |||
|
162 | Cell(w, h, text, 0, 0, options[:align]) | |||
|
163 | end | |||
|
164 | end | |||
|
165 | ||||
|
166 | # Draw a string of <tt>text</tt> at (<tt>x, y</tt>) as a title. | |||
|
167 | # | |||
|
168 | # Options are: | |||
|
169 | # * <tt>:font_color</tt> - Default value is <tt>COLOR_PALETTE[:black]</tt>. | |||
|
170 | # * <tt>:font_size</tt> - Default value is <tt>18</tt>. | |||
|
171 | # * <tt>:font_style</tt> - Default value is nothing or <tt>''</tt>. | |||
|
172 | # | |||
|
173 | # Example: | |||
|
174 | # | |||
|
175 | # draw_title(left_margin, 60, | |||
|
176 | # "title:", | |||
|
177 | # :font_color => ReportHelper::COLOR_PALETTE[:dark_blue]) | |||
|
178 | # | |||
|
179 | def draw_title(x, y, title, options = {}) | |||
|
180 | options[:font_color] ||= COLOR_PALETTE[:black] | |||
|
181 | options[:font_size] ||= 18 | |||
|
182 | options[:font_style] ||= '' | |||
|
183 | set_text_color(options[:font_color]) | |||
|
184 | SetFont('Arial', options[:font_style], options[:font_size]) | |||
|
185 | SetXY(x, y) | |||
|
186 | Write(options[:font_size] + 2, title) | |||
|
187 | end | |||
|
188 | ||||
|
189 | # Set the draw color. Default value is <tt>COLOR_PALETTE[:black]</tt>. | |||
|
190 | # | |||
|
191 | # Example: | |||
|
192 | # | |||
|
193 | # set_draw_color(ReportHelper::COLOR_PALETTE[:dark_blue]) | |||
|
194 | # | |||
|
195 | def set_draw_color(color = COLOR_PALETTE[:black]) | |||
|
196 | SetDrawColor(color[0], color[1], color[2]) | |||
|
197 | end | |||
|
198 | ||||
|
199 | # Set the fill color. Default value is <tt>COLOR_PALETTE[:white]</tt>. | |||
|
200 | # | |||
|
201 | # Example: | |||
|
202 | # | |||
|
203 | # set_fill_color(ReportHelper::COLOR_PALETTE[:dark_blue]) | |||
|
204 | # | |||
|
205 | def set_fill_color(color = COLOR_PALETTE[:white]) | |||
|
206 | SetFillColor(color[0], color[1], color[2]) | |||
|
207 | end | |||
|
208 | ||||
|
209 | # Set the text color. Default value is <tt>COLOR_PALETTE[:white]</tt>. | |||
|
210 | # | |||
|
211 | # Example: | |||
|
212 | # | |||
|
213 | # set_text_color(ReportHelper::COLOR_PALETTE[:dark_blue]) | |||
|
214 | # | |||
|
215 | def set_text_color(color = COLOR_PALETTE[:black]) | |||
|
216 | SetTextColor(color[0], color[1], color[2]) | |||
|
217 | end | |||
|
218 | ||||
|
219 | # Write a string containing html characters. Default value is <tt>COLOR_PALETTE[:white]</tt>. | |||
|
220 | # | |||
|
221 | # Options are: | |||
|
222 | # * <tt>:height</tt> - Line height. Default value is <tt>20</tt>. | |||
|
223 | # | |||
|
224 | # Example: | |||
|
225 | # | |||
|
226 | # write_html(html, :height => 12) | |||
|
227 | # | |||
|
228 | def write_html(html, options = {}) | |||
|
229 | options[:height] ||= 20 | |||
|
230 | #HTML parser | |||
|
231 | @href = nil | |||
|
232 | @style = {} | |||
|
233 | html.gsub!("\n",' ') | |||
|
234 | re = %r{ ( <!--.*?--> | | |||
|
235 | < (?: | |||
|
236 | [^<>"] + | |||
|
237 | | | |||
|
238 | " (?: \\. | [^\\"]+ ) * " | |||
|
239 | ) * | |||
|
240 | > | |||
|
241 | ) }xm | |||
|
242 | ||||
|
243 | html.split(re).each do |value| | |||
|
244 | if "<" == value[0,1] | |||
|
245 | #Tag | |||
|
246 | if (value[1, 1] == '/') | |||
|
247 | close_tag(value[2..-2], options) | |||
|
248 | else | |||
|
249 | tag = value[1..-2] | |||
|
250 | open_tag(tag, options) | |||
|
251 | end | |||
|
252 | else | |||
|
253 | #Text | |||
|
254 | if @href | |||
|
255 | put_link(@href,value) | |||
|
256 | else | |||
|
257 | Write(options[:height], value) | |||
|
258 | end | |||
|
259 | end | |||
|
260 | end | |||
|
261 | end | |||
|
262 | ||||
|
263 | def open_tag(tag, options = {}) #:nodoc: | |||
|
264 | #Opening tag | |||
|
265 | tag = tag.to_s.upcase | |||
|
266 | set_style(tag, true) if tag == 'B' or tag == 'I' or tag == 'U' | |||
|
267 | @href = options['HREF'] if tag == 'A' | |||
|
268 | Ln(options[:height]) if tag == 'BR' | |||
|
269 | end | |||
|
270 | ||||
|
271 | def close_tag(tag, options = {}) #:nodoc: | |||
|
272 | #Closing tag | |||
|
273 | tag = tag.to_s.upcase | |||
|
274 | set_style(tag, false) if tag == 'B' or tag == 'I' or tag == 'U' | |||
|
275 | @href = '' if $tag == 'A' | |||
|
276 | end | |||
|
277 | ||||
|
278 | def set_style(tag, enable = true) #:nodoc: | |||
|
279 | #Modify style and select corresponding font | |||
|
280 | style = "" | |||
|
281 | @style[tag] = enable | |||
|
282 | ['B','I','U'].each do |s| | |||
|
283 | style += s if not @style[s].nil? and @style[s] | |||
|
284 | end | |||
|
285 | SetFont('', style) | |||
|
286 | end | |||
|
287 | ||||
|
288 | def put_link(url, txt) #:nodoc: | |||
|
289 | #Put a hyperlink | |||
|
290 | SetTextColor(0,0,255) | |||
|
291 | set_style('U',true) | |||
|
292 | Write(5, txt, url) | |||
|
293 | set_style('U',false) | |||
|
294 | SetTextColor(0) | |||
|
295 | end | |||
|
296 | end | |||
|
297 | ||||
|
298 | # class FPDF | |||
|
299 | # alias_method :set_margins , :SetMargins | |||
|
300 | # alias_method :set_left_margin , :SetLeftMargin | |||
|
301 | # alias_method :set_top_margin , :SetTopMargin | |||
|
302 | # alias_method :set_right_margin , :SetRightMargin | |||
|
303 | # alias_method :set_auto_pagebreak , :SetAutoPageBreak | |||
|
304 | # alias_method :set_display_mode , :SetDisplayMode | |||
|
305 | # alias_method :set_compression , :SetCompression | |||
|
306 | # alias_method :set_title , :SetTitle | |||
|
307 | # alias_method :set_subject , :SetSubject | |||
|
308 | # alias_method :set_author , :SetAuthor | |||
|
309 | # alias_method :set_keywords , :SetKeywords | |||
|
310 | # alias_method :set_creator , :SetCreator | |||
|
311 | # alias_method :set_draw_color , :SetDrawColor | |||
|
312 | # alias_method :set_fill_color , :SetFillColor | |||
|
313 | # alias_method :set_text_color , :SetTextColor | |||
|
314 | # alias_method :set_line_width , :SetLineWidth | |||
|
315 | # alias_method :set_font , :SetFont | |||
|
316 | # alias_method :set_font_size , :SetFontSize | |||
|
317 | # alias_method :set_link , :SetLink | |||
|
318 | # alias_method :set_y , :SetY | |||
|
319 | # alias_method :set_xy , :SetXY | |||
|
320 | # alias_method :get_string_width , :GetStringWidth | |||
|
321 | # alias_method :get_x , :GetX | |||
|
322 | # alias_method :set_x , :SetX | |||
|
323 | # alias_method :get_y , :GetY | |||
|
324 | # alias_method :accept_pagev_break , :AcceptPageBreak | |||
|
325 | # alias_method :add_font , :AddFont | |||
|
326 | # alias_method :add_link , :AddLink | |||
|
327 | # alias_method :add_page , :AddPage | |||
|
328 | # alias_method :alias_nb_pages , :AliasNbPages | |||
|
329 | # alias_method :cell , :Cell | |||
|
330 | # alias_method :close , :Close | |||
|
331 | # alias_method :error , :Error | |||
|
332 | # alias_method :footer , :Footer | |||
|
333 | # alias_method :header , :Header | |||
|
334 | # alias_method :image , :Image | |||
|
335 | # alias_method :line , :Line | |||
|
336 | # alias_method :link , :Link | |||
|
337 | # alias_method :ln , :Ln | |||
|
338 | # alias_method :multi_cell , :MultiCell | |||
|
339 | # alias_method :open , :Open | |||
|
340 | # alias_method :Open , :open | |||
|
341 | # alias_method :output , :Output | |||
|
342 | # alias_method :page_no , :PageNo | |||
|
343 | # alias_method :rect , :Rect | |||
|
344 | # alias_method :text , :Text | |||
|
345 | # alias_method :write , :Write | |||
|
346 | # end |
@@ -0,0 +1,75 | |||||
|
1 | # Copyright (c) 2006 4ssoM LLC <www.4ssoM.com> | |||
|
2 | # | |||
|
3 | # The MIT License | |||
|
4 | # | |||
|
5 | # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
|
6 | # of this software and associated documentation files (the "Software"), to deal | |||
|
7 | # in the Software without restriction, including without limitation the rights | |||
|
8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||
|
9 | # copies of the Software, and to permit persons to whom the Software is | |||
|
10 | # furnished to do so, subject to the following conditions: | |||
|
11 | # | |||
|
12 | # The above copyright notice and this permission notice shall be included in | |||
|
13 | # all copies or substantial portions of the Software. | |||
|
14 | # | |||
|
15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
|
16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
|
17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
|
18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
|
19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||
|
20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |||
|
21 | # THE SOFTWARE. | |||
|
22 | # | |||
|
23 | # Thanks go out to Bruce Williams of codefluency who created RTex. This | |||
|
24 | # template handler is modification of his work. | |||
|
25 | # | |||
|
26 | # Example Registration | |||
|
27 | # | |||
|
28 | # ActionView::Base::register_template_handler 'rfpdf', RFpdfView | |||
|
29 | ||||
|
30 | module RFPDF | |||
|
31 | ||||
|
32 | class View | |||
|
33 | ||||
|
34 | def initialize(action_view) | |||
|
35 | @action_view = action_view | |||
|
36 | # Override with @options_for_rfpdf Hash in your controller | |||
|
37 | @options = { | |||
|
38 | # Run through latex first? (for table of contents, etc) | |||
|
39 | :pre_process => false, | |||
|
40 | # Debugging mode; raises exception | |||
|
41 | :debug => false, | |||
|
42 | # Filename of pdf to generate | |||
|
43 | :file_name => "#{@action_view.controller.action_name}.pdf", | |||
|
44 | # Temporary Directory | |||
|
45 | :temp_dir => "#{File.expand_path(RAILS_ROOT)}/tmp" | |||
|
46 | }.merge(@action_view.controller.instance_eval{ @options_for_rfpdf } || {}).with_indifferent_access | |||
|
47 | end | |||
|
48 | ||||
|
49 | def render(template, local_assigns = {}) | |||
|
50 | @pdf_name = "Default.pdf" if @pdf_name.nil? | |||
|
51 | unless @action_view.controller.headers["Content-Type"] == 'application/pdf' | |||
|
52 | @generate = true | |||
|
53 | @action_view.controller.headers["Content-Type"] = 'application/pdf' | |||
|
54 | @action_view.controller.headers["Content-disposition:"] = "inline; filename=\"#{@options[:file_name]}\"" | |||
|
55 | end | |||
|
56 | assigns = @action_view.assigns.dup | |||
|
57 | ||||
|
58 | if content_for_layout = @action_view.instance_variable_get("@content_for_layout") | |||
|
59 | assigns['content_for_layout'] = content_for_layout | |||
|
60 | end | |||
|
61 | ||||
|
62 | result = @action_view.instance_eval do | |||
|
63 | assigns.each do |key,val| | |||
|
64 | instance_variable_set "@#{key}", val | |||
|
65 | end | |||
|
66 | local_assigns.each do |key,val| | |||
|
67 | class << self; self; end.send(:define_method,key){ val } | |||
|
68 | end | |||
|
69 | ERB.new(template).result(binding) | |||
|
70 | end | |||
|
71 | end | |||
|
72 | ||||
|
73 | end | |||
|
74 | ||||
|
75 | end No newline at end of file |
@@ -0,0 +1,1 | |||||
|
1 | #!/usr/bin/env ruby No newline at end of file |
General Comments 0
You need to be logged in to leave comments.
Login now