##// END OF EJS Templates
PDF: add dummy 'fill' parameter at rfpdf CJK Write method (#8737)....
Toshi MARUYAMA -
r6036:edc4f6d54b99
parent child
Show More
@@ -1,469 +1,469
1 # Copyright (c) 2006 4ssoM LLC <www.4ssoM.com>
1 # Copyright (c) 2006 4ssoM LLC <www.4ssoM.com>
2 # 1.12 contributed by Ed Moss.
2 # 1.12 contributed by Ed Moss.
3 #
3 #
4 # The MIT License
4 # The MIT License
5 #
5 #
6 # Permission is hereby granted, free of charge, to any person obtaining a copy
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
7 # of this software and associated documentation files (the "Software"), to deal
8 # in the Software without restriction, including without limitation the rights
8 # in the Software without restriction, including without limitation the rights
9 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
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
10 # copies of the Software, and to permit persons to whom the Software is
11 # furnished to do so, subject to the following conditions:
11 # furnished to do so, subject to the following conditions:
12 #
12 #
13 # The above copyright notice and this permission notice shall be included in
13 # The above copyright notice and this permission notice shall be included in
14 # all copies or substantial portions of the Software.
14 # all copies or substantial portions of the Software.
15 #
15 #
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
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,
17 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
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
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,
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
21 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 # THE SOFTWARE.
22 # THE SOFTWARE.
23 #
23 #
24 # This is direct port of chinese.php
24 # This is direct port of chinese.php
25 #
25 #
26 # Chinese PDF support.
26 # Chinese PDF support.
27 #
27 #
28 # Usage is as follows:
28 # Usage is as follows:
29 #
29 #
30 # require 'fpdf'
30 # require 'fpdf'
31 # require 'chinese'
31 # require 'chinese'
32 # pdf = FPDF.new
32 # pdf = FPDF.new
33 # pdf.extend(PDF_Chinese)
33 # pdf.extend(PDF_Chinese)
34 #
34 #
35 # This allows it to be combined with other extensions, such as the bookmark
35 # This allows it to be combined with other extensions, such as the bookmark
36 # module.
36 # module.
37
37
38 module PDF_Chinese
38 module PDF_Chinese
39
39
40 Big5_widths={' '=>250,'!'=>250,'"'=>408,'#'=>668,'$'=>490,'%'=>875,'&'=>698,'\''=>250,
40 Big5_widths={' '=>250,'!'=>250,'"'=>408,'#'=>668,'$'=>490,'%'=>875,'&'=>698,'\''=>250,
41 '('=>240,')'=>240,'*'=>417,'+'=>667,','=>250,'-'=>313,'.'=>250,'/'=>520,'0'=>500,'1'=>500,
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,
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,
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,
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,
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,
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,
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,
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,'}'=>480,'~'=>667}
49 'x'=>479,'y'=>458,'z'=>427,'{'=>480,'|'=>496,'}'=>480,'~'=>667}
50
50
51 GB_widths={' '=>207,'!'=>270,'"'=>342,'#'=>467,'$'=>462,'%'=>797,'&'=>710,'\''=>239,
51 GB_widths={' '=>207,'!'=>270,'"'=>342,'#'=>467,'$'=>462,'%'=>797,'&'=>710,'\''=>239,
52 '('=>374,')'=>374,'*'=>423,'+'=>605,','=>238,'-'=>375,'.'=>238,'/'=>334,'0'=>462,'1'=>462,
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,
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,
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,
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,
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,
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,
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,
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,'}'=>370,'~'=>605}
60 'x'=>466,'y'=>452,'z'=>407,'{'=>370,'|'=>258,'}'=>370,'~'=>605}
61
61
62 def AddCIDFont(family,style,name,cw,cMap,registry)
62 def AddCIDFont(family,style,name,cw,cMap,registry)
63 #ActionController::Base::logger.debug registry.to_a.join(":").to_s
63 #ActionController::Base::logger.debug registry.to_a.join(":").to_s
64 fontkey=family.downcase+style.upcase
64 fontkey=family.downcase+style.upcase
65 unless @fonts[fontkey].nil?
65 unless @fonts[fontkey].nil?
66 Error("Font already added: family style")
66 Error("Font already added: family style")
67 end
67 end
68 i=@fonts.length+1
68 i=@fonts.length+1
69 name=name.gsub(' ','')
69 name=name.gsub(' ','')
70 @fonts[fontkey]={'i'=>i,'type'=>'Type0','name'=>name,'up'=>-130,'ut'=>40,'cw'=>cw, 'CMap'=>cMap,'registry'=>registry}
70 @fonts[fontkey]={'i'=>i,'type'=>'Type0','name'=>name,'up'=>-130,'ut'=>40,'cw'=>cw, 'CMap'=>cMap,'registry'=>registry}
71 end
71 end
72
72
73 def AddCIDFonts(family,name,cw,cMap,registry)
73 def AddCIDFonts(family,name,cw,cMap,registry)
74 AddCIDFont(family,'',name,cw,cMap,registry)
74 AddCIDFont(family,'',name,cw,cMap,registry)
75 AddCIDFont(family,'B',name+',Bold',cw,cMap,registry)
75 AddCIDFont(family,'B',name+',Bold',cw,cMap,registry)
76 AddCIDFont(family,'I',name+',Italic',cw,cMap,registry)
76 AddCIDFont(family,'I',name+',Italic',cw,cMap,registry)
77 AddCIDFont(family,'BI',name+',BoldItalic',cw,cMap,registry)
77 AddCIDFont(family,'BI',name+',BoldItalic',cw,cMap,registry)
78 end
78 end
79
79
80 def AddBig5Font(family='Big5',name='MSungStd-Light-Acro')
80 def AddBig5Font(family='Big5',name='MSungStd-Light-Acro')
81 #Add Big5 font with proportional Latin
81 #Add Big5 font with proportional Latin
82 cw=Big5_widths
82 cw=Big5_widths
83 cMap='ETenms-B5-H'
83 cMap='ETenms-B5-H'
84 registry={'ordering'=>'CNS1','supplement'=>0}
84 registry={'ordering'=>'CNS1','supplement'=>0}
85 #ActionController::Base::logger.debug registry.to_a.join(":").to_s
85 #ActionController::Base::logger.debug registry.to_a.join(":").to_s
86 AddCIDFonts(family,name,cw,cMap,registry)
86 AddCIDFonts(family,name,cw,cMap,registry)
87 end
87 end
88
88
89 def AddBig5hwFont(family='Big5-hw',name='MSungStd-Light-Acro')
89 def AddBig5hwFont(family='Big5-hw',name='MSungStd-Light-Acro')
90 #Add Big5 font with half-witdh Latin
90 #Add Big5 font with half-witdh Latin
91 cw = {}
91 cw = {}
92 32.upto(126) do |i|
92 32.upto(126) do |i|
93 cw[i.chr]=500
93 cw[i.chr]=500
94 end
94 end
95 cMap='ETen-B5-H'
95 cMap='ETen-B5-H'
96 registry={'ordering'=>'CNS1','supplement'=>0}
96 registry={'ordering'=>'CNS1','supplement'=>0}
97 AddCIDFonts(family,name,cw,cMap,registry)
97 AddCIDFonts(family,name,cw,cMap,registry)
98 end
98 end
99
99
100 def AddGBFont(family='GB',name='STSongStd-Light-Acro')
100 def AddGBFont(family='GB',name='STSongStd-Light-Acro')
101 #Add GB font with proportional Latin
101 #Add GB font with proportional Latin
102 cw=GB_widths
102 cw=GB_widths
103 cMap='GBKp-EUC-H'
103 cMap='GBKp-EUC-H'
104 registry={'ordering'=>'GB1','supplement'=>2}
104 registry={'ordering'=>'GB1','supplement'=>2}
105 AddCIDFonts(family,name,cw,cMap,registry)
105 AddCIDFonts(family,name,cw,cMap,registry)
106 end
106 end
107
107
108 def AddGBhwFont(family='GB-hw',name='STSongStd-Light-Acro')
108 def AddGBhwFont(family='GB-hw',name='STSongStd-Light-Acro')
109 #Add GB font with half-width Latin
109 #Add GB font with half-width Latin
110 32.upto(126) do |i|
110 32.upto(126) do |i|
111 cw[i.chr]=500
111 cw[i.chr]=500
112 end
112 end
113 cMap='GBK-EUC-H'
113 cMap='GBK-EUC-H'
114 registry={'ordering'=>'GB1','supplement'=>2}
114 registry={'ordering'=>'GB1','supplement'=>2}
115 AddCIDFonts(family,name,cw,cMap,registry)
115 AddCIDFonts(family,name,cw,cMap,registry)
116 end
116 end
117
117
118 def GetStringWidth(s)
118 def GetStringWidth(s)
119 if(@current_font['type']=='Type0')
119 if(@current_font['type']=='Type0')
120 return GetMBStringWidth(s)
120 return GetMBStringWidth(s)
121 else
121 else
122 return super(s)
122 return super(s)
123 end
123 end
124 end
124 end
125
125
126 def GetMBStringWidth(s)
126 def GetMBStringWidth(s)
127 #Multi-byte version of GetStringWidth()
127 #Multi-byte version of GetStringWidth()
128 l=0
128 l=0
129 cw=@current_font['cw']
129 cw=@current_font['cw']
130 nb=s.length
130 nb=s.length
131 i=0
131 i=0
132 while(i<nb)
132 while(i<nb)
133 c = s[i].is_a?(String) ? s[i].ord : s[i]
133 c = s[i].is_a?(String) ? s[i].ord : s[i]
134 if(c<128)
134 if(c<128)
135 l+=cw[c.chr] if cw[c.chr]
135 l+=cw[c.chr] if cw[c.chr]
136 i+=1
136 i+=1
137 else
137 else
138 l+=1000
138 l+=1000
139 i+=2
139 i+=2
140 end
140 end
141 end
141 end
142 return l*@font_size/1000
142 return l*@font_size/1000
143 end
143 end
144
144
145 def MultiCell(w,h,txt,border=0,align='L',fill=0,ln=1)
145 def MultiCell(w,h,txt,border=0,align='L',fill=0,ln=1)
146 if(@current_font['type']=='Type0')
146 if(@current_font['type']=='Type0')
147 MBMultiCell(w,h,txt,border,align,fill)
147 MBMultiCell(w,h,txt,border,align,fill)
148 else
148 else
149 super(w,h,txt,border,align,fill)
149 super(w,h,txt,border,align,fill)
150 end
150 end
151 end
151 end
152
152
153 def MBMultiCell(w,h,txt,border=0,align='L',fill=0)
153 def MBMultiCell(w,h,txt,border=0,align='L',fill=0)
154 #Multi-byte version of MultiCell()
154 #Multi-byte version of MultiCell()
155 cw=@current_font['cw']
155 cw=@current_font['cw']
156 if(w==0)
156 if(w==0)
157 w=@w-@r_margin-@x
157 w=@w-@r_margin-@x
158 end
158 end
159 wmax=(w-2*@c_margin)*1000/@font_size
159 wmax=(w-2*@c_margin)*1000/@font_size
160 s=txt.gsub("\r",'')
160 s=txt.gsub("\r",'')
161 nb=s.length
161 nb=s.length
162 if(nb>0 and s[nb-1]=="\n")
162 if(nb>0 and s[nb-1]=="\n")
163 nb-=1
163 nb-=1
164 end
164 end
165 b=0
165 b=0
166 if(border)
166 if(border)
167 if(border==1)
167 if(border==1)
168 border='LTRB'
168 border='LTRB'
169 b='LRT'
169 b='LRT'
170 b2='LR'
170 b2='LR'
171 else
171 else
172 b2=''
172 b2=''
173 b2='L' unless border.to_s.index('L').nil?
173 b2='L' unless border.to_s.index('L').nil?
174 b2=b2+'R' unless border.to_s.index('R').nil?
174 b2=b2+'R' unless border.to_s.index('R').nil?
175 b=(border.to_s.index('T')) ? (b2+'T') : b2
175 b=(border.to_s.index('T')) ? (b2+'T') : b2
176 end
176 end
177 end
177 end
178 sep=-1
178 sep=-1
179 i=0
179 i=0
180 j=0
180 j=0
181 l=0
181 l=0
182 nl=1
182 nl=1
183 while(i<nb)
183 while(i<nb)
184 #Get next character
184 #Get next character
185 c = s[i].is_a?(String) ? s[i].ord : s[i]
185 c = s[i].is_a?(String) ? s[i].ord : s[i]
186 #Check if ASCII or MB
186 #Check if ASCII or MB
187 ascii=(c<128)
187 ascii=(c<128)
188 if(c.chr=="\n")
188 if(c.chr=="\n")
189 #Explicit line break
189 #Explicit line break
190 Cell(w,h,s[j,i-j],b,2,align,fill)
190 Cell(w,h,s[j,i-j],b,2,align,fill)
191 i+=1
191 i+=1
192 sep=-1
192 sep=-1
193 j=i
193 j=i
194 l=0
194 l=0
195 nl+=1
195 nl+=1
196 if(border and nl==2)
196 if(border and nl==2)
197 b=b2
197 b=b2
198 end
198 end
199 next
199 next
200 end
200 end
201 if(!ascii)
201 if(!ascii)
202 sep=i
202 sep=i
203 ls=l
203 ls=l
204 elsif(c.chr==' ')
204 elsif(c.chr==' ')
205 sep=i
205 sep=i
206 ls=l
206 ls=l
207 end
207 end
208 l+=(ascii ? cw[c.chr] : 1000) || 0
208 l+=(ascii ? cw[c.chr] : 1000) || 0
209 if(l>wmax)
209 if(l>wmax)
210 #Automatic line break
210 #Automatic line break
211 if(sep==-1 or i==j)
211 if(sep==-1 or i==j)
212 if(i==j)
212 if(i==j)
213 i+=ascii ? 1 : 2
213 i+=ascii ? 1 : 2
214 end
214 end
215 Cell(w,h,s[j,i-j],b,2,align,fill)
215 Cell(w,h,s[j,i-j],b,2,align,fill)
216 else
216 else
217 Cell(w,h,s[j,sep-j],b,2,align,fill)
217 Cell(w,h,s[j,sep-j],b,2,align,fill)
218 i=(s[sep].chr==' ') ? sep+1 : sep
218 i=(s[sep].chr==' ') ? sep+1 : sep
219 end
219 end
220 sep=-1
220 sep=-1
221 j=i
221 j=i
222 l=0
222 l=0
223 nl+=1
223 nl+=1
224 if(border and nl==2)
224 if(border and nl==2)
225 b=b2
225 b=b2
226 end
226 end
227 else
227 else
228 i+=ascii ? 1 : 2
228 i+=ascii ? 1 : 2
229 end
229 end
230 end
230 end
231 #Last chunk
231 #Last chunk
232 if(border and not border.to_s.index('B').nil?)
232 if(border and not border.to_s.index('B').nil?)
233 b+='B'
233 b+='B'
234 end
234 end
235 Cell(w,h,s[j,i-j],b,2,align,fill)
235 Cell(w,h,s[j,i-j],b,2,align,fill)
236 @x=@l_margin
236 @x=@l_margin
237 end
237 end
238
238
239 def Write(h,txt,link='')
239 def Write(h,txt,link='',fill=0)
240 if(@current_font['type']=='Type0')
240 if(@current_font['type']=='Type0')
241 MBWrite(h,txt,link)
241 MBWrite(h,txt,link)
242 else
242 else
243 super(h,txt,link)
243 super(h,txt,link)
244 end
244 end
245 end
245 end
246
246
247 def MBWrite(h,txt,link)
247 def MBWrite(h,txt,link)
248 #Multi-byte version of Write()
248 #Multi-byte version of Write()
249 cw=@current_font['cw']
249 cw=@current_font['cw']
250 w=@w-@r_margin-@x
250 w=@w-@r_margin-@x
251 wmax=(w-2*@c_margin)*1000/@font_size
251 wmax=(w-2*@c_margin)*1000/@font_size
252 s=txt.gsub("\r",'')
252 s=txt.gsub("\r",'')
253 nb=s.length
253 nb=s.length
254 sep=-1
254 sep=-1
255 i=0
255 i=0
256 j=0
256 j=0
257 l=0
257 l=0
258 nl=1
258 nl=1
259 while(i<nb)
259 while(i<nb)
260 #Get next character
260 #Get next character
261 c = s[i].is_a?(String) ? s[i].ord : s[i]
261 c = s[i].is_a?(String) ? s[i].ord : s[i]
262 #Check if ASCII or MB
262 #Check if ASCII or MB
263 ascii=(c<128)
263 ascii=(c<128)
264 if(c.chr=="\n")
264 if(c.chr=="\n")
265 #Explicit line break
265 #Explicit line break
266 Cell(w,h,s[j,i-j],0,2,'',0,link)
266 Cell(w,h,s[j,i-j],0,2,'',0,link)
267 i+=1
267 i+=1
268 sep=-1
268 sep=-1
269 j=i
269 j=i
270 l=0
270 l=0
271 if(nl==1)
271 if(nl==1)
272 @x=@l_margin
272 @x=@l_margin
273 w=@w-@r_margin-@x
273 w=@w-@r_margin-@x
274 wmax=(w-2*@c_margin)*1000/@font_size
274 wmax=(w-2*@c_margin)*1000/@font_size
275 end
275 end
276 nl+=1
276 nl+=1
277 next
277 next
278 end
278 end
279 if(!ascii or c.chr==' ')
279 if(!ascii or c.chr==' ')
280 sep=i
280 sep=i
281 end
281 end
282 l+=(ascii ? cw[c.chr] : 1000) || 0
282 l+=(ascii ? cw[c.chr] : 1000) || 0
283 if(l>wmax)
283 if(l>wmax)
284 #Automatic line break
284 #Automatic line break
285 if(sep==-1 or i==j)
285 if(sep==-1 or i==j)
286 if(@x>@l_margin)
286 if(@x>@l_margin)
287 #Move to next line
287 #Move to next line
288 @x=@l_margin
288 @x=@l_margin
289 @y+=h
289 @y+=h
290 w=@w-@r_margin-@x
290 w=@w-@r_margin-@x
291 wmax=(w-2*@c_margin)*1000/@font_size
291 wmax=(w-2*@c_margin)*1000/@font_size
292 i+=1
292 i+=1
293 nl+=1
293 nl+=1
294 next
294 next
295 end
295 end
296 if(i==j)
296 if(i==j)
297 i+=ascii ? 1 : 2
297 i+=ascii ? 1 : 2
298 end
298 end
299 Cell(w,h,s[j,i-j],0,2,'',0,link)
299 Cell(w,h,s[j,i-j],0,2,'',0,link)
300 else
300 else
301 Cell(w,h,s[j,sep-j],0,2,'',0,link)
301 Cell(w,h,s[j,sep-j],0,2,'',0,link)
302 i=(s[sep].chr==' ') ? sep+1 : sep
302 i=(s[sep].chr==' ') ? sep+1 : sep
303 end
303 end
304 sep=-1
304 sep=-1
305 j=i
305 j=i
306 l=0
306 l=0
307 if(nl==1)
307 if(nl==1)
308 @x=@l_margin
308 @x=@l_margin
309 w=@w-@r_margin-@x
309 w=@w-@r_margin-@x
310 wmax=(w-2*@c_margin)*1000/@font_size
310 wmax=(w-2*@c_margin)*1000/@font_size
311 end
311 end
312 nl+=1
312 nl+=1
313 else
313 else
314 i+=ascii ? 1 : 2
314 i+=ascii ? 1 : 2
315 end
315 end
316 end
316 end
317 #Last chunk
317 #Last chunk
318 if(i!=j)
318 if(i!=j)
319 Cell(l/1000*@font_size,h,s[j,i-j],0,0,'',0,link)
319 Cell(l/1000*@font_size,h,s[j,i-j],0,0,'',0,link)
320 end
320 end
321 end
321 end
322
322
323 private
323 private
324
324
325 def putfonts()
325 def putfonts()
326 nf=@n
326 nf=@n
327 @diffs.each do |diff|
327 @diffs.each do |diff|
328 #Encodings
328 #Encodings
329 newobj()
329 newobj()
330 out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['+diff+']>>')
330 out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['+diff+']>>')
331 out('endobj')
331 out('endobj')
332 end
332 end
333 # mqr=get_magic_quotes_runtime()
333 # mqr=get_magic_quotes_runtime()
334 # set_magic_quotes_runtime(0)
334 # set_magic_quotes_runtime(0)
335 @font_files.each_pair do |file, info|
335 @font_files.each_pair do |file, info|
336 #Font file embedding
336 #Font file embedding
337 newobj()
337 newobj()
338 @font_files[file]['n']=@n
338 @font_files[file]['n']=@n
339 if(defined('FPDF_FONTPATH'))
339 if(defined('FPDF_FONTPATH'))
340 file=FPDF_FONTPATH+file
340 file=FPDF_FONTPATH+file
341 end
341 end
342 size=filesize(file)
342 size=filesize(file)
343 if(!size)
343 if(!size)
344 Error('Font file not found')
344 Error('Font file not found')
345 end
345 end
346 out('<</Length '+size)
346 out('<</Length '+size)
347 if(file[-2]=='.z')
347 if(file[-2]=='.z')
348 out('/Filter /FlateDecode')
348 out('/Filter /FlateDecode')
349 end
349 end
350 out('/Length1 '+info['length1'])
350 out('/Length1 '+info['length1'])
351 unless info['length2'].nil?
351 unless info['length2'].nil?
352 out('/Length2 '+info['length2']+' /Length3 0')
352 out('/Length2 '+info['length2']+' /Length3 0')
353 end
353 end
354 out('>>')
354 out('>>')
355 f=fopen(file,'rb')
355 f=fopen(file,'rb')
356 putstream(fread(f,size))
356 putstream(fread(f,size))
357 fclose(f)
357 fclose(f)
358 out('endobj')
358 out('endobj')
359 end
359 end
360 #
360 #
361 # set_magic_quotes_runtime(mqr)
361 # set_magic_quotes_runtime(mqr)
362 #
362 #
363 @fonts.each_pair do |k, font|
363 @fonts.each_pair do |k, font|
364 #Font objects
364 #Font objects
365 newobj()
365 newobj()
366 @fonts[k]['n']=@n
366 @fonts[k]['n']=@n
367 out('<</Type /Font')
367 out('<</Type /Font')
368 if(font['type']=='Type0')
368 if(font['type']=='Type0')
369 putType0(font)
369 putType0(font)
370 else
370 else
371 name=font['name']
371 name=font['name']
372 out('/BaseFont /'+name)
372 out('/BaseFont /'+name)
373 if(font['type']=='core')
373 if(font['type']=='core')
374 #Standard font
374 #Standard font
375 out('/Subtype /Type1')
375 out('/Subtype /Type1')
376 if(name!='Symbol' and name!='ZapfDingbats')
376 if(name!='Symbol' and name!='ZapfDingbats')
377 out('/Encoding /WinAnsiEncoding')
377 out('/Encoding /WinAnsiEncoding')
378 end
378 end
379 else
379 else
380 #Additional font
380 #Additional font
381 out('/Subtype /'+font['type'])
381 out('/Subtype /'+font['type'])
382 out('/FirstChar 32')
382 out('/FirstChar 32')
383 out('/LastChar 255')
383 out('/LastChar 255')
384 out('/Widths '+(@n+1)+' 0 R')
384 out('/Widths '+(@n+1)+' 0 R')
385 out('/FontDescriptor '+(@n+2)+' 0 R')
385 out('/FontDescriptor '+(@n+2)+' 0 R')
386 if(font['enc'])
386 if(font['enc'])
387 if !font['diff'].nil?
387 if !font['diff'].nil?
388 out('/Encoding '+(nf+font['diff'])+' 0 R')
388 out('/Encoding '+(nf+font['diff'])+' 0 R')
389 else
389 else
390 out('/Encoding /WinAnsiEncoding')
390 out('/Encoding /WinAnsiEncoding')
391 end
391 end
392 end
392 end
393 end
393 end
394 out('>>')
394 out('>>')
395 out('endobj')
395 out('endobj')
396 if(font['type']!='core')
396 if(font['type']!='core')
397 #Widths
397 #Widths
398 newobj()
398 newobj()
399 cw=font['cw']
399 cw=font['cw']
400 s='['
400 s='['
401 32.upto(255) do |i|
401 32.upto(255) do |i|
402 s+=cw[i.chr]+' '
402 s+=cw[i.chr]+' '
403 end
403 end
404 out(s+']')
404 out(s+']')
405 out('endobj')
405 out('endobj')
406 #Descriptor
406 #Descriptor
407 newobj()
407 newobj()
408 s='<</Type /FontDescriptor /FontName /'+name
408 s='<</Type /FontDescriptor /FontName /'+name
409 font['desc'].each_pair do |k, v|
409 font['desc'].each_pair do |k, v|
410 s+=' /'+k+' '+v
410 s+=' /'+k+' '+v
411 end
411 end
412 file=font['file']
412 file=font['file']
413 if(file)
413 if(file)
414 s+=' /FontFile'+(font['type']=='Type1' ? '' : '2')+' '+@font_files[file]['n']+' 0 R'
414 s+=' /FontFile'+(font['type']=='Type1' ? '' : '2')+' '+@font_files[file]['n']+' 0 R'
415 end
415 end
416 out(s+'>>')
416 out(s+'>>')
417 out('endobj')
417 out('endobj')
418 end
418 end
419 end
419 end
420 end
420 end
421 end
421 end
422
422
423 def putType0(font)
423 def putType0(font)
424 #Type0
424 #Type0
425 out('/Subtype /Type0')
425 out('/Subtype /Type0')
426 out('/BaseFont /'+font['name']+'-'+font['CMap'])
426 out('/BaseFont /'+font['name']+'-'+font['CMap'])
427 out('/Encoding /'+font['CMap'])
427 out('/Encoding /'+font['CMap'])
428 out('/DescendantFonts ['+(@n+1).to_s+' 0 R]')
428 out('/DescendantFonts ['+(@n+1).to_s+' 0 R]')
429 out('>>')
429 out('>>')
430 out('endobj')
430 out('endobj')
431 #CIDFont
431 #CIDFont
432 newobj()
432 newobj()
433 out('<</Type /Font')
433 out('<</Type /Font')
434 out('/Subtype /CIDFontType0')
434 out('/Subtype /CIDFontType0')
435 out('/BaseFont /'+font['name'])
435 out('/BaseFont /'+font['name'])
436 out('/CIDSystemInfo <</Registry '+textstring('Adobe')+' /Ordering '+textstring(font['registry']['ordering'])+' /Supplement '+font['registry']['supplement'].to_s+'>>')
436 out('/CIDSystemInfo <</Registry '+textstring('Adobe')+' /Ordering '+textstring(font['registry']['ordering'])+' /Supplement '+font['registry']['supplement'].to_s+'>>')
437 out('/FontDescriptor '+(@n+1).to_s+' 0 R')
437 out('/FontDescriptor '+(@n+1).to_s+' 0 R')
438 if(font['CMap']=='ETen-B5-H')
438 if(font['CMap']=='ETen-B5-H')
439 w='13648 13742 500'
439 w='13648 13742 500'
440 elsif(font['CMap']=='GBK-EUC-H')
440 elsif(font['CMap']=='GBK-EUC-H')
441 w='814 907 500 7716 [500]'
441 w='814 907 500 7716 [500]'
442 else
442 else
443 # ActionController::Base::logger.debug font['cw'].keys.sort.join(' ').to_s
443 # ActionController::Base::logger.debug font['cw'].keys.sort.join(' ').to_s
444 # ActionController::Base::logger.debug font['cw'].values.join(' ').to_s
444 # ActionController::Base::logger.debug font['cw'].values.join(' ').to_s
445 w='1 ['
445 w='1 ['
446 font['cw'].keys.sort.each {|key|
446 font['cw'].keys.sort.each {|key|
447 w+=font['cw'][key].to_s + " "
447 w+=font['cw'][key].to_s + " "
448 # ActionController::Base::logger.debug key.to_s
448 # ActionController::Base::logger.debug key.to_s
449 # ActionController::Base::logger.debug font['cw'][key].to_s
449 # ActionController::Base::logger.debug font['cw'][key].to_s
450 }
450 }
451 w +=']'
451 w +=']'
452 end
452 end
453 out('/W ['+w+']>>')
453 out('/W ['+w+']>>')
454 out('endobj')
454 out('endobj')
455 #Font descriptor
455 #Font descriptor
456 newobj()
456 newobj()
457 out('<</Type /FontDescriptor')
457 out('<</Type /FontDescriptor')
458 out('/FontName /'+font['name'])
458 out('/FontName /'+font['name'])
459 out('/Flags 6')
459 out('/Flags 6')
460 out('/FontBBox [0 -200 1000 900]')
460 out('/FontBBox [0 -200 1000 900]')
461 out('/ItalicAngle 0')
461 out('/ItalicAngle 0')
462 out('/Ascent 800')
462 out('/Ascent 800')
463 out('/Descent -200')
463 out('/Descent -200')
464 out('/CapHeight 800')
464 out('/CapHeight 800')
465 out('/StemV 50')
465 out('/StemV 50')
466 out('>>')
466 out('>>')
467 out('endobj')
467 out('endobj')
468 end
468 end
469 end
469 end
@@ -1,464 +1,464
1 # Copyright (c) 2006 4ssoM LLC <www.4ssoM.com>
1 # Copyright (c) 2006 4ssoM LLC <www.4ssoM.com>
2 # 1.12 contributed by Ed Moss.
2 # 1.12 contributed by Ed Moss.
3 #
3 #
4 # The MIT License
4 # The MIT License
5 #
5 #
6 # Permission is hereby granted, free of charge, to any person obtaining a copy
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
7 # of this software and associated documentation files (the "Software"), to deal
8 # in the Software without restriction, including without limitation the rights
8 # in the Software without restriction, including without limitation the rights
9 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
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
10 # copies of the Software, and to permit persons to whom the Software is
11 # furnished to do so, subject to the following conditions:
11 # furnished to do so, subject to the following conditions:
12 #
12 #
13 # The above copyright notice and this permission notice shall be included in
13 # The above copyright notice and this permission notice shall be included in
14 # all copies or substantial portions of the Software.
14 # all copies or substantial portions of the Software.
15 #
15 #
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
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,
17 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
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
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,
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
21 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 # THE SOFTWARE.
22 # THE SOFTWARE.
23 #
23 #
24 # This is direct port of japanese.php
24 # This is direct port of japanese.php
25 #
25 #
26 # Japanese PDF support.
26 # Japanese PDF support.
27 #
27 #
28 # Usage is as follows:
28 # Usage is as follows:
29 #
29 #
30 # require 'fpdf'
30 # require 'fpdf'
31 # require 'chinese'
31 # require 'chinese'
32 # pdf = FPDF.new
32 # pdf = FPDF.new
33 # pdf.extend(PDF_Japanese)
33 # pdf.extend(PDF_Japanese)
34 #
34 #
35 # This allows it to be combined with other extensions, such as the bookmark
35 # This allows it to be combined with other extensions, such as the bookmark
36 # module.
36 # module.
37
37
38 module PDF_Japanese
38 module PDF_Japanese
39
39
40 SJIS_widths={' ' => 278, '!' => 299, '"' => 353, '#' => 614, '$' => 614, '%' => 721, '&' => 735, '\'' => 216,
40 SJIS_widths={' ' => 278, '!' => 299, '"' => 353, '#' => 614, '$' => 614, '%' => 721, '&' => 735, '\'' => 216,
41 '(' => 323, ')' => 323, '*' => 449, '+' => 529, ',' => 219, '-' => 306, '.' => 219, '/' => 453, '0' => 614, '1' => 614,
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,
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,
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,
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,
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,
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,
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,
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}
49 'x' => 503, 'y' => 529, 'z' => 453, '{' => 326, '|' => 380, '}' => 326, '~' => 387}
50
50
51 def AddCIDFont(family,style,name,cw,cMap,registry)
51 def AddCIDFont(family,style,name,cw,cMap,registry)
52 fontkey=family.downcase+style.upcase
52 fontkey=family.downcase+style.upcase
53 unless @fonts[fontkey].nil?
53 unless @fonts[fontkey].nil?
54 Error("CID font already added: family style")
54 Error("CID font already added: family style")
55 end
55 end
56 i=@fonts.length+1
56 i=@fonts.length+1
57 @fonts[fontkey]={'i'=>i,'type'=>'Type0','name'=>name,'up'=>-120,'ut'=>40,'cw'=>cw,
57 @fonts[fontkey]={'i'=>i,'type'=>'Type0','name'=>name,'up'=>-120,'ut'=>40,'cw'=>cw,
58 'CMap'=>cMap,'registry'=>registry}
58 'CMap'=>cMap,'registry'=>registry}
59 end
59 end
60
60
61 def AddCIDFonts(family,name,cw,cMap,registry)
61 def AddCIDFonts(family,name,cw,cMap,registry)
62 AddCIDFont(family,'',name,cw,cMap,registry)
62 AddCIDFont(family,'',name,cw,cMap,registry)
63 AddCIDFont(family,'B',name+',Bold',cw,cMap,registry)
63 AddCIDFont(family,'B',name+',Bold',cw,cMap,registry)
64 AddCIDFont(family,'I',name+',Italic',cw,cMap,registry)
64 AddCIDFont(family,'I',name+',Italic',cw,cMap,registry)
65 AddCIDFont(family,'BI',name+',BoldItalic',cw,cMap,registry)
65 AddCIDFont(family,'BI',name+',BoldItalic',cw,cMap,registry)
66 end
66 end
67
67
68 def AddSJISFont(family='SJIS')
68 def AddSJISFont(family='SJIS')
69 #Add SJIS font with proportional Latin
69 #Add SJIS font with proportional Latin
70 name='KozMinPro-Regular-Acro'
70 name='KozMinPro-Regular-Acro'
71 cw=SJIS_widths
71 cw=SJIS_widths
72 cMap='90msp-RKSJ-H'
72 cMap='90msp-RKSJ-H'
73 registry={'ordering'=>'Japan1','supplement'=>2}
73 registry={'ordering'=>'Japan1','supplement'=>2}
74 AddCIDFonts(family,name,cw,cMap,registry)
74 AddCIDFonts(family,name,cw,cMap,registry)
75 end
75 end
76
76
77 def AddSJIShwFont(family='SJIS-hw')
77 def AddSJIShwFont(family='SJIS-hw')
78 #Add SJIS font with half-width Latin
78 #Add SJIS font with half-width Latin
79 name='KozMinPro-Regular-Acro'
79 name='KozMinPro-Regular-Acro'
80 32.upto(126) do |i|
80 32.upto(126) do |i|
81 cw[i.chr]=500
81 cw[i.chr]=500
82 end
82 end
83 cMap='90ms-RKSJ-H'
83 cMap='90ms-RKSJ-H'
84 registry={'ordering'=>'Japan1','supplement'=>2}
84 registry={'ordering'=>'Japan1','supplement'=>2}
85 AddCIDFonts(family,name,cw,cMap,registry)
85 AddCIDFonts(family,name,cw,cMap,registry)
86 end
86 end
87
87
88 def GetStringWidth(s)
88 def GetStringWidth(s)
89 if(@current_font['type']=='Type0')
89 if(@current_font['type']=='Type0')
90 return GetSJISStringWidth(s)
90 return GetSJISStringWidth(s)
91 else
91 else
92 return super(s)
92 return super(s)
93 end
93 end
94 end
94 end
95
95
96 def GetSJISStringWidth(s)
96 def GetSJISStringWidth(s)
97 #SJIS version of GetStringWidth()
97 #SJIS version of GetStringWidth()
98 l=0
98 l=0
99 cw=@current_font['cw']
99 cw=@current_font['cw']
100 nb=s.length
100 nb=s.length
101 i=0
101 i=0
102 while(i<nb)
102 while(i<nb)
103 o = s[i].is_a?(String) ? s[i].ord : s[i]
103 o = s[i].is_a?(String) ? s[i].ord : s[i]
104 if(o<128)
104 if(o<128)
105 #ASCII
105 #ASCII
106 l+=cw[o.chr] if cw[o.chr]
106 l+=cw[o.chr] if cw[o.chr]
107 i+=1
107 i+=1
108 elsif(o>=161 and o<=223)
108 elsif(o>=161 and o<=223)
109 #Half-width katakana
109 #Half-width katakana
110 l+=500
110 l+=500
111 i+=1
111 i+=1
112 else
112 else
113 #Full-width character
113 #Full-width character
114 l+=1000
114 l+=1000
115 i+=2
115 i+=2
116 end
116 end
117 end
117 end
118 return l*@font_size/1000
118 return l*@font_size/1000
119 end
119 end
120
120
121 def MultiCell(w,h,txt,border=0,align='L',fill=0,ln=1)
121 def MultiCell(w,h,txt,border=0,align='L',fill=0,ln=1)
122 if(@current_font['type']=='Type0')
122 if(@current_font['type']=='Type0')
123 SJISMultiCell(w,h,txt,border,align,fill)
123 SJISMultiCell(w,h,txt,border,align,fill)
124 else
124 else
125 super(w,h,txt,border,align,fill)
125 super(w,h,txt,border,align,fill)
126 end
126 end
127 end
127 end
128
128
129 def SJISMultiCell(w,h,txt,border=0,align='L',fill=0)
129 def SJISMultiCell(w,h,txt,border=0,align='L',fill=0)
130 #Output text with automatic or explicit line breaks
130 #Output text with automatic or explicit line breaks
131 cw=@current_font['cw']
131 cw=@current_font['cw']
132 if(w==0)
132 if(w==0)
133 w=@w-@r_margin-@x
133 w=@w-@r_margin-@x
134 end
134 end
135 wmax=(w-2*@c_margin)*1000/@font_size
135 wmax=(w-2*@c_margin)*1000/@font_size
136 s=txt.gsub("\r",'')
136 s=txt.gsub("\r",'')
137 nb=s.length
137 nb=s.length
138 if(nb>0 and s[nb-1]=="\n")
138 if(nb>0 and s[nb-1]=="\n")
139 nb-=1
139 nb-=1
140 end
140 end
141 b=0
141 b=0
142 if(border)
142 if(border)
143 if(border==1)
143 if(border==1)
144 border='LTRB'
144 border='LTRB'
145 b='LRT'
145 b='LRT'
146 b2='LR'
146 b2='LR'
147 else
147 else
148 b2=''
148 b2=''
149 b2='L' unless border.to_s.index('L').nil?
149 b2='L' unless border.to_s.index('L').nil?
150 b2=b2+'R' unless border.to_s.index('R').nil?
150 b2=b2+'R' unless border.to_s.index('R').nil?
151 b=(border.to_s.index('T')) ? (b2+'T') : b2
151 b=(border.to_s.index('T')) ? (b2+'T') : b2
152 end
152 end
153 end
153 end
154 sep=-1
154 sep=-1
155 i=0
155 i=0
156 j=0
156 j=0
157 l=0
157 l=0
158 nl=1
158 nl=1
159 while(i<nb)
159 while(i<nb)
160 #Get next character
160 #Get next character
161 c = s[i].is_a?(String) ? s[i].ord : s[i]
161 c = s[i].is_a?(String) ? s[i].ord : s[i]
162 o=c #o=ord(c)
162 o=c #o=ord(c)
163 if(o==10)
163 if(o==10)
164 #Explicit line break
164 #Explicit line break
165 Cell(w,h,s[j,i-j],b,2,align,fill)
165 Cell(w,h,s[j,i-j],b,2,align,fill)
166 i+=1
166 i+=1
167 sep=-1
167 sep=-1
168 j=i
168 j=i
169 l=0
169 l=0
170 nl+=1
170 nl+=1
171 if(border and nl==2)
171 if(border and nl==2)
172 b=b2
172 b=b2
173 end
173 end
174 next
174 next
175 end
175 end
176 if(o<128)
176 if(o<128)
177 #ASCII
177 #ASCII
178 l+=cw[c.chr] || 0
178 l+=cw[c.chr] || 0
179 n=1
179 n=1
180 if(o==32)
180 if(o==32)
181 sep=i
181 sep=i
182 end
182 end
183 elsif(o>=161 and o<=223)
183 elsif(o>=161 and o<=223)
184 #Half-width katakana
184 #Half-width katakana
185 l+=500
185 l+=500
186 n=1
186 n=1
187 sep=i
187 sep=i
188 else
188 else
189 #Full-width character
189 #Full-width character
190 l+=1000
190 l+=1000
191 n=2
191 n=2
192 sep=i
192 sep=i
193 end
193 end
194 if(l>wmax)
194 if(l>wmax)
195 #Automatic line break
195 #Automatic line break
196 if(sep==-1 or i==j)
196 if(sep==-1 or i==j)
197 if(i==j)
197 if(i==j)
198 i+=n
198 i+=n
199 end
199 end
200 Cell(w,h,s[j,i-j],b,2,align,fill)
200 Cell(w,h,s[j,i-j],b,2,align,fill)
201 else
201 else
202 Cell(w,h,s[j,sep-j],b,2,align,fill)
202 Cell(w,h,s[j,sep-j],b,2,align,fill)
203 i=(s[sep].chr==' ') ? sep+1 : sep
203 i=(s[sep].chr==' ') ? sep+1 : sep
204 end
204 end
205 sep=-1
205 sep=-1
206 j=i
206 j=i
207 l=0
207 l=0
208 nl+=1
208 nl+=1
209 if(border and nl==2)
209 if(border and nl==2)
210 b=b2
210 b=b2
211 end
211 end
212 else
212 else
213 i+=n
213 i+=n
214 if(o>=128)
214 if(o>=128)
215 sep=i
215 sep=i
216 end
216 end
217 end
217 end
218 end
218 end
219 #Last chunk
219 #Last chunk
220 if(border and not border.to_s.index('B').nil?)
220 if(border and not border.to_s.index('B').nil?)
221 b+='B'
221 b+='B'
222 end
222 end
223 Cell(w,h,s[j,i-j],b,2,align,fill)
223 Cell(w,h,s[j,i-j],b,2,align,fill)
224 @x=@l_margin
224 @x=@l_margin
225 end
225 end
226
226
227 def Write(h,txt,link='')
227 def Write(h,txt,link='',fill=0)
228 if(@current_font['type']=='Type0')
228 if(@current_font['type']=='Type0')
229 SJISWrite(h,txt,link)
229 SJISWrite(h,txt,link)
230 else
230 else
231 super(h,txt,link)
231 super(h,txt,link)
232 end
232 end
233 end
233 end
234
234
235 def SJISWrite(h,txt,link)
235 def SJISWrite(h,txt,link)
236 #SJIS version of Write()
236 #SJIS version of Write()
237 cw=@current_font['cw']
237 cw=@current_font['cw']
238 w=@w-@r_margin-@x
238 w=@w-@r_margin-@x
239 wmax=(w-2*@c_margin)*1000/@font_size
239 wmax=(w-2*@c_margin)*1000/@font_size
240 s=txt.gsub("\r",'')
240 s=txt.gsub("\r",'')
241 nb=s.length
241 nb=s.length
242 sep=-1
242 sep=-1
243 i=0
243 i=0
244 j=0
244 j=0
245 l=0
245 l=0
246 nl=1
246 nl=1
247 while(i<nb)
247 while(i<nb)
248 #Get next character
248 #Get next character
249 c = s[i].is_a?(String) ? s[i].ord : s[i]
249 c = s[i].is_a?(String) ? s[i].ord : s[i]
250 o=c
250 o=c
251 if(o==10)
251 if(o==10)
252 #Explicit line break
252 #Explicit line break
253 Cell(w,h,s[j,i-j],0,2,'',0,link)
253 Cell(w,h,s[j,i-j],0,2,'',0,link)
254 i+=1
254 i+=1
255 sep=-1
255 sep=-1
256 j=i
256 j=i
257 l=0
257 l=0
258 if(nl==1)
258 if(nl==1)
259 #Go to left margin
259 #Go to left margin
260 @x=@l_margin
260 @x=@l_margin
261 w=@w-@r_margin-@x
261 w=@w-@r_margin-@x
262 wmax=(w-2*@c_margin)*1000/@font_size
262 wmax=(w-2*@c_margin)*1000/@font_size
263 end
263 end
264 nl+=1
264 nl+=1
265 next
265 next
266 end
266 end
267 if(o<128)
267 if(o<128)
268 #ASCII
268 #ASCII
269 l+=cw[c.chr] || 0
269 l+=cw[c.chr] || 0
270 n=1
270 n=1
271 if(o==32)
271 if(o==32)
272 sep=i
272 sep=i
273 end
273 end
274 elsif(o>=161 and o<=223)
274 elsif(o>=161 and o<=223)
275 #Half-width katakana
275 #Half-width katakana
276 l+=500
276 l+=500
277 n=1
277 n=1
278 sep=i
278 sep=i
279 else
279 else
280 #Full-width character
280 #Full-width character
281 l+=1000
281 l+=1000
282 n=2
282 n=2
283 sep=i
283 sep=i
284 end
284 end
285 if(l>wmax)
285 if(l>wmax)
286 #Automatic line break
286 #Automatic line break
287 if(sep==-1 or i==j)
287 if(sep==-1 or i==j)
288 if(@x>@l_margin)
288 if(@x>@l_margin)
289 #Move to next line
289 #Move to next line
290 @x=@l_margin
290 @x=@l_margin
291 @y+=h
291 @y+=h
292 w=@w-@r_margin-@x
292 w=@w-@r_margin-@x
293 wmax=(w-2*@c_margin)*1000/@font_size
293 wmax=(w-2*@c_margin)*1000/@font_size
294 i+=n
294 i+=n
295 nl+=1
295 nl+=1
296 next
296 next
297 end
297 end
298 if(i==j)
298 if(i==j)
299 i+=n
299 i+=n
300 end
300 end
301 Cell(w,h,s[j,i-j],0,2,'',0,link)
301 Cell(w,h,s[j,i-j],0,2,'',0,link)
302 else
302 else
303 Cell(w,h,s[j,sep-j],0,2,'',0,link)
303 Cell(w,h,s[j,sep-j],0,2,'',0,link)
304 i=(s[sep].chr==' ') ? sep+1 : sep
304 i=(s[sep].chr==' ') ? sep+1 : sep
305 end
305 end
306 sep=-1
306 sep=-1
307 j=i
307 j=i
308 l=0
308 l=0
309 if(nl==1)
309 if(nl==1)
310 @x=@l_margin
310 @x=@l_margin
311 w=@w-@r_margin-@x
311 w=@w-@r_margin-@x
312 wmax=(w-2*@c_margin)*1000/@font_size
312 wmax=(w-2*@c_margin)*1000/@font_size
313 end
313 end
314 nl+=1
314 nl+=1
315 else
315 else
316 i+=n
316 i+=n
317 if(o>=128)
317 if(o>=128)
318 sep=i
318 sep=i
319 end
319 end
320 end
320 end
321 end
321 end
322 #Last chunk
322 #Last chunk
323 if(i!=j)
323 if(i!=j)
324 Cell(l/1000*@font_size,h,s[j,i-j],0,0,'',0,link)
324 Cell(l/1000*@font_size,h,s[j,i-j],0,0,'',0,link)
325 end
325 end
326 end
326 end
327
327
328 private
328 private
329
329
330 def putfonts()
330 def putfonts()
331 nf=@n
331 nf=@n
332 @diffs.each do |diff|
332 @diffs.each do |diff|
333 #Encodings
333 #Encodings
334 newobj()
334 newobj()
335 out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['+diff+']>>')
335 out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['+diff+']>>')
336 out('endobj')
336 out('endobj')
337 end
337 end
338 # mqr=get_magic_quotes_runtime()
338 # mqr=get_magic_quotes_runtime()
339 # set_magic_quotes_runtime(0)
339 # set_magic_quotes_runtime(0)
340 @font_files.each_pair do |file, info|
340 @font_files.each_pair do |file, info|
341 #Font file embedding
341 #Font file embedding
342 newobj()
342 newobj()
343 @font_files[file]['n']=@n
343 @font_files[file]['n']=@n
344 if(defined('FPDF_FONTPATH'))
344 if(defined('FPDF_FONTPATH'))
345 file=FPDF_FONTPATH+file
345 file=FPDF_FONTPATH+file
346 end
346 end
347 size=filesize(file)
347 size=filesize(file)
348 if(!size)
348 if(!size)
349 Error('Font file not found')
349 Error('Font file not found')
350 end
350 end
351 out('<</Length '+size)
351 out('<</Length '+size)
352 if(file[-2]=='.z')
352 if(file[-2]=='.z')
353 out('/Filter /FlateDecode')
353 out('/Filter /FlateDecode')
354 end
354 end
355 out('/Length1 '+info['length1'])
355 out('/Length1 '+info['length1'])
356 unless info['length2'].nil?
356 unless info['length2'].nil?
357 out('/Length2 '+info['length2']+' /Length3 0')
357 out('/Length2 '+info['length2']+' /Length3 0')
358 end
358 end
359 out('>>')
359 out('>>')
360 f=fopen(file,'rb')
360 f=fopen(file,'rb')
361 putstream(fread(f,size))
361 putstream(fread(f,size))
362 fclose(f)
362 fclose(f)
363 out('endobj')
363 out('endobj')
364 end
364 end
365 # set_magic_quotes_runtime(mqr)
365 # set_magic_quotes_runtime(mqr)
366 @fonts.each_pair do |k, font|
366 @fonts.each_pair do |k, font|
367 #Font objects
367 #Font objects
368 newobj()
368 newobj()
369 @fonts[k]['n']=@n
369 @fonts[k]['n']=@n
370 out('<</Type /Font')
370 out('<</Type /Font')
371 if(font['type']=='Type0')
371 if(font['type']=='Type0')
372 putType0(font)
372 putType0(font)
373 else
373 else
374 name=font['name']
374 name=font['name']
375 out('/BaseFont /'+name)
375 out('/BaseFont /'+name)
376 if(font['type']=='core')
376 if(font['type']=='core')
377 #Standard font
377 #Standard font
378 out('/Subtype /Type1')
378 out('/Subtype /Type1')
379 if(name!='Symbol' and name!='ZapfDingbats')
379 if(name!='Symbol' and name!='ZapfDingbats')
380 out('/Encoding /WinAnsiEncoding')
380 out('/Encoding /WinAnsiEncoding')
381 end
381 end
382 else
382 else
383 #Additional font
383 #Additional font
384 out('/Subtype /'+font['type'])
384 out('/Subtype /'+font['type'])
385 out('/FirstChar 32')
385 out('/FirstChar 32')
386 out('/LastChar 255')
386 out('/LastChar 255')
387 out('/Widths '+(@n+1)+' 0 R')
387 out('/Widths '+(@n+1)+' 0 R')
388 out('/FontDescriptor '+(@n+2)+' 0 R')
388 out('/FontDescriptor '+(@n+2)+' 0 R')
389 if(font['enc'])
389 if(font['enc'])
390 if !font['diff'].nil?
390 if !font['diff'].nil?
391 out('/Encoding '+(nf+font['diff'])+' 0 R')
391 out('/Encoding '+(nf+font['diff'])+' 0 R')
392 else
392 else
393 out('/Encoding /WinAnsiEncoding')
393 out('/Encoding /WinAnsiEncoding')
394 end
394 end
395 end
395 end
396 end
396 end
397 out('>>')
397 out('>>')
398 out('endobj')
398 out('endobj')
399 if(font['type']!='core')
399 if(font['type']!='core')
400 #Widths
400 #Widths
401 newobj()
401 newobj()
402 cw=font['cw']
402 cw=font['cw']
403 s='['
403 s='['
404 32.upto(255) do |i|
404 32.upto(255) do |i|
405 s+=cw[i.chr]+' '
405 s+=cw[i.chr]+' '
406 end
406 end
407 out(s+']')
407 out(s+']')
408 out('endobj')
408 out('endobj')
409 #Descriptor
409 #Descriptor
410 newobj()
410 newobj()
411 s='<</Type /FontDescriptor /FontName /'+name
411 s='<</Type /FontDescriptor /FontName /'+name
412 font['desc'].each_pair do |k, v|
412 font['desc'].each_pair do |k, v|
413 s+=' /'+k+' '+v
413 s+=' /'+k+' '+v
414 end
414 end
415 file=font['file']
415 file=font['file']
416 if(file)
416 if(file)
417 s+=' /FontFile'+(font['type']=='Type1' ? '' : '2')+' '+@font_files[file]['n']+' 0 R'
417 s+=' /FontFile'+(font['type']=='Type1' ? '' : '2')+' '+@font_files[file]['n']+' 0 R'
418 end
418 end
419 out(s+'>>')
419 out(s+'>>')
420 out('endobj')
420 out('endobj')
421 end
421 end
422 end
422 end
423 end
423 end
424 end
424 end
425
425
426 def putType0(font)
426 def putType0(font)
427 #Type0
427 #Type0
428 out('/Subtype /Type0')
428 out('/Subtype /Type0')
429 out('/BaseFont /'+font['name']+'-'+font['CMap'])
429 out('/BaseFont /'+font['name']+'-'+font['CMap'])
430 out('/Encoding /'+font['CMap'])
430 out('/Encoding /'+font['CMap'])
431 out('/DescendantFonts ['+(@n+1).to_s+' 0 R]')
431 out('/DescendantFonts ['+(@n+1).to_s+' 0 R]')
432 out('>>')
432 out('>>')
433 out('endobj')
433 out('endobj')
434 #CIDFont
434 #CIDFont
435 newobj()
435 newobj()
436 out('<</Type /Font')
436 out('<</Type /Font')
437 out('/Subtype /CIDFontType0')
437 out('/Subtype /CIDFontType0')
438 out('/BaseFont /'+font['name'])
438 out('/BaseFont /'+font['name'])
439 out('/CIDSystemInfo <</Registry (Adobe) /Ordering ('+font['registry']['ordering']+') /Supplement '+font['registry']['supplement'].to_s+'>>')
439 out('/CIDSystemInfo <</Registry (Adobe) /Ordering ('+font['registry']['ordering']+') /Supplement '+font['registry']['supplement'].to_s+'>>')
440 out('/FontDescriptor '+(@n+1).to_s+' 0 R')
440 out('/FontDescriptor '+(@n+1).to_s+' 0 R')
441 w='/W [1 ['
441 w='/W [1 ['
442 font['cw'].keys.sort.each {|key|
442 font['cw'].keys.sort.each {|key|
443 w+=font['cw'][key].to_s + " "
443 w+=font['cw'][key].to_s + " "
444 # ActionController::Base::logger.debug key.to_s
444 # ActionController::Base::logger.debug key.to_s
445 # ActionController::Base::logger.debug font['cw'][key].to_s
445 # ActionController::Base::logger.debug font['cw'][key].to_s
446 }
446 }
447 out(w+'] 231 325 500 631 [500] 326 389 500]')
447 out(w+'] 231 325 500 631 [500] 326 389 500]')
448 out('>>')
448 out('>>')
449 out('endobj')
449 out('endobj')
450 #Font descriptor
450 #Font descriptor
451 newobj()
451 newobj()
452 out('<</Type /FontDescriptor')
452 out('<</Type /FontDescriptor')
453 out('/FontName /'+font['name'])
453 out('/FontName /'+font['name'])
454 out('/Flags 6')
454 out('/Flags 6')
455 out('/FontBBox [0 -200 1000 900]')
455 out('/FontBBox [0 -200 1000 900]')
456 out('/ItalicAngle 0')
456 out('/ItalicAngle 0')
457 out('/Ascent 800')
457 out('/Ascent 800')
458 out('/Descent -200')
458 out('/Descent -200')
459 out('/CapHeight 800')
459 out('/CapHeight 800')
460 out('/StemV 60')
460 out('/StemV 60')
461 out('>>')
461 out('>>')
462 out('endobj')
462 out('endobj')
463 end
463 end
464 end
464 end
@@ -1,432 +1,432
1 # Copyright (c) 2006 4ssoM LLC <www.4ssoM.com>
1 # Copyright (c) 2006 4ssoM LLC <www.4ssoM.com>
2 # 1.12 contributed by Ed Moss.
2 # 1.12 contributed by Ed Moss.
3 #
3 #
4 # The MIT License
4 # The MIT License
5 #
5 #
6 # Permission is hereby granted, free of charge, to any person obtaining a copy
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
7 # of this software and associated documentation files (the "Software"), to deal
8 # in the Software without restriction, including without limitation the rights
8 # in the Software without restriction, including without limitation the rights
9 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
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
10 # copies of the Software, and to permit persons to whom the Software is
11 # furnished to do so, subject to the following conditions:
11 # furnished to do so, subject to the following conditions:
12 #
12 #
13 # The above copyright notice and this permission notice shall be included in
13 # The above copyright notice and this permission notice shall be included in
14 # all copies or substantial portions of the Software.
14 # all copies or substantial portions of the Software.
15 #
15 #
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
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,
17 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
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
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,
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
21 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 # THE SOFTWARE.
22 # THE SOFTWARE.
23 #
23 #
24 # This is direct port of korean.php
24 # This is direct port of korean.php
25 #
25 #
26 # Korean PDF support.
26 # Korean PDF support.
27 #
27 #
28 # Usage is as follows:
28 # Usage is as follows:
29 #
29 #
30 # require 'fpdf'
30 # require 'fpdf'
31 # require 'chinese'
31 # require 'chinese'
32 # pdf = FPDF.new
32 # pdf = FPDF.new
33 # pdf.extend(PDF_Korean)
33 # pdf.extend(PDF_Korean)
34 #
34 #
35 # This allows it to be combined with other extensions, such as the bookmark
35 # This allows it to be combined with other extensions, such as the bookmark
36 # module.
36 # module.
37
37
38 module PDF_Korean
38 module PDF_Korean
39
39
40 UHC_widths={' ' => 333, '!' => 416, '"' => 416, '#' => 833, '$' => 625, '%' => 916, '&' => 833, '\'' => 250,
40 UHC_widths={' ' => 333, '!' => 416, '"' => 416, '#' => 833, '$' => 625, '%' => 916, '&' => 833, '\'' => 250,
41 '(' => 500, ')' => 500, '*' => 500, '+' => 833, ',' => 291, '-' => 833, '.' => 291, '/' => 375, '0' => 625, '1' => 625,
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,
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,
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,
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,
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,
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,
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,
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}
49 'x' => 625, 'y' => 625, 'z' => 500, '{' => 583, '|' => 583, '}' => 583, '~' => 750}
50
50
51 def AddCIDFont(family,style,name,cw,cMap,registry)
51 def AddCIDFont(family,style,name,cw,cMap,registry)
52 fontkey=family.downcase+style.upcase
52 fontkey=family.downcase+style.upcase
53 unless @fonts[fontkey].nil?
53 unless @fonts[fontkey].nil?
54 Error("Font already added: family style")
54 Error("Font already added: family style")
55 end
55 end
56 i=@fonts.length+1
56 i=@fonts.length+1
57 name=name.gsub(' ','')
57 name=name.gsub(' ','')
58 @fonts[fontkey]={'i'=>i,'type'=>'Type0','name'=>name,'up'=>-130,'ut'=>40,'cw'=>cw,
58 @fonts[fontkey]={'i'=>i,'type'=>'Type0','name'=>name,'up'=>-130,'ut'=>40,'cw'=>cw,
59 'CMap'=>cMap,'registry'=>registry}
59 'CMap'=>cMap,'registry'=>registry}
60 end
60 end
61
61
62 def AddCIDFonts(family,name,cw,cMap,registry)
62 def AddCIDFonts(family,name,cw,cMap,registry)
63 AddCIDFont(family,'',name,cw,cMap,registry)
63 AddCIDFont(family,'',name,cw,cMap,registry)
64 AddCIDFont(family,'B',name+',Bold',cw,cMap,registry)
64 AddCIDFont(family,'B',name+',Bold',cw,cMap,registry)
65 AddCIDFont(family,'I',name+',Italic',cw,cMap,registry)
65 AddCIDFont(family,'I',name+',Italic',cw,cMap,registry)
66 AddCIDFont(family,'BI',name+',BoldItalic',cw,cMap,registry)
66 AddCIDFont(family,'BI',name+',BoldItalic',cw,cMap,registry)
67 end
67 end
68
68
69 def AddUHCFont(family='UHC',name='HYSMyeongJoStd-Medium-Acro')
69 def AddUHCFont(family='UHC',name='HYSMyeongJoStd-Medium-Acro')
70 #Add UHC font with proportional Latin
70 #Add UHC font with proportional Latin
71 cw=UHC_widths
71 cw=UHC_widths
72 cMap='KSCms-UHC-H'
72 cMap='KSCms-UHC-H'
73 registry={'ordering'=>'Korea1','supplement'=>1}
73 registry={'ordering'=>'Korea1','supplement'=>1}
74 AddCIDFonts(family,name,cw,cMap,registry)
74 AddCIDFonts(family,name,cw,cMap,registry)
75 end
75 end
76
76
77 def AddUHChwFont(family='UHC-hw',name='HYSMyeongJoStd-Medium-Acro')
77 def AddUHChwFont(family='UHC-hw',name='HYSMyeongJoStd-Medium-Acro')
78 #Add UHC font with half-witdh Latin
78 #Add UHC font with half-witdh Latin
79 32.upto(126) do |i|
79 32.upto(126) do |i|
80 cw[i.chr]=500
80 cw[i.chr]=500
81 end
81 end
82 cMap='KSCms-UHC-HW-H'
82 cMap='KSCms-UHC-HW-H'
83 registry={'ordering'=>'Korea1','supplement'=>1}
83 registry={'ordering'=>'Korea1','supplement'=>1}
84 AddCIDFonts(family,name,cw,cMap,registry)
84 AddCIDFonts(family,name,cw,cMap,registry)
85 end
85 end
86
86
87 def GetStringWidth(s)
87 def GetStringWidth(s)
88 if(@current_font['type']=='Type0')
88 if(@current_font['type']=='Type0')
89 return GetMBStringWidth(s)
89 return GetMBStringWidth(s)
90 else
90 else
91 return super(s)
91 return super(s)
92 end
92 end
93 end
93 end
94
94
95 def GetMBStringWidth(s)
95 def GetMBStringWidth(s)
96 #Multi-byte version of GetStringWidth()
96 #Multi-byte version of GetStringWidth()
97 l=0
97 l=0
98 cw=@current_font['cw']
98 cw=@current_font['cw']
99 nb=s.length
99 nb=s.length
100 i=0
100 i=0
101 while(i<nb)
101 while(i<nb)
102 c = s[i].is_a?(String) ? s[i].ord : s[i]
102 c = s[i].is_a?(String) ? s[i].ord : s[i]
103 if(c<128)
103 if(c<128)
104 l+=cw[c.chr] if cw[c.chr]
104 l+=cw[c.chr] if cw[c.chr]
105 i+=1
105 i+=1
106 else
106 else
107 l+=1000
107 l+=1000
108 i+=2
108 i+=2
109 end
109 end
110 end
110 end
111 return l*@font_size/1000
111 return l*@font_size/1000
112 end
112 end
113
113
114 def MultiCell(w,h,txt,border=0,align='L',fill=0,ln=1)
114 def MultiCell(w,h,txt,border=0,align='L',fill=0,ln=1)
115 if(@current_font['type']=='Type0')
115 if(@current_font['type']=='Type0')
116 MBMultiCell(w,h,txt,border,align,fill)
116 MBMultiCell(w,h,txt,border,align,fill)
117 else
117 else
118 super(w,h,txt,border,align,fill)
118 super(w,h,txt,border,align,fill)
119 end
119 end
120 end
120 end
121
121
122 def MBMultiCell(w,h,txt,border=0,align='L',fill=0)
122 def MBMultiCell(w,h,txt,border=0,align='L',fill=0)
123 #Multi-byte version of MultiCell()
123 #Multi-byte version of MultiCell()
124 cw=@current_font['cw']
124 cw=@current_font['cw']
125 if(w==0)
125 if(w==0)
126 w=@w-@r_margin-@x
126 w=@w-@r_margin-@x
127 end
127 end
128 wmax=(w-2*@c_margin)*1000/@font_size
128 wmax=(w-2*@c_margin)*1000/@font_size
129 s=txt.gsub("\r",'')
129 s=txt.gsub("\r",'')
130 nb=s.length
130 nb=s.length
131 if(nb>0 and s[nb-1]=="\n")
131 if(nb>0 and s[nb-1]=="\n")
132 nb-=1
132 nb-=1
133 end
133 end
134 b=0
134 b=0
135 if(border)
135 if(border)
136 if(border==1)
136 if(border==1)
137 border='LTRB'
137 border='LTRB'
138 b='LRT'
138 b='LRT'
139 b2='LR'
139 b2='LR'
140 else
140 else
141 b2=''
141 b2=''
142 b2='L' unless border.to_s.index('L').nil?
142 b2='L' unless border.to_s.index('L').nil?
143 b2=b2+'R' unless border.to_s.index('R').nil?
143 b2=b2+'R' unless border.to_s.index('R').nil?
144 b=(border.to_s.index('T')) ? (b2+'T') : b2
144 b=(border.to_s.index('T')) ? (b2+'T') : b2
145 end
145 end
146 end
146 end
147 sep=-1
147 sep=-1
148 i=0
148 i=0
149 j=0
149 j=0
150 l=0
150 l=0
151 nl=1
151 nl=1
152 while(i<nb)
152 while(i<nb)
153 #Get next character
153 #Get next character
154 c = s[i].is_a?(String) ? s[i].ord : s[i]
154 c = s[i].is_a?(String) ? s[i].ord : s[i]
155 #Check if ASCII or MB
155 #Check if ASCII or MB
156 ascii=(c<128)
156 ascii=(c<128)
157 if(c.chr=="\n")
157 if(c.chr=="\n")
158 #Explicit line break
158 #Explicit line break
159 Cell(w,h,s[j,i-j],b,2,align,fill)
159 Cell(w,h,s[j,i-j],b,2,align,fill)
160 i+=1
160 i+=1
161 sep=-1
161 sep=-1
162 j=i
162 j=i
163 l=0
163 l=0
164 nl+=1
164 nl+=1
165 if(border and nl==2)
165 if(border and nl==2)
166 b=b2
166 b=b2
167 end
167 end
168 next
168 next
169 end
169 end
170 if(!ascii)
170 if(!ascii)
171 sep=i
171 sep=i
172 ls=l
172 ls=l
173 elsif(c.chr==' ')
173 elsif(c.chr==' ')
174 sep=i
174 sep=i
175 ls=l
175 ls=l
176 end
176 end
177 l+=(ascii ? cw[c.chr] : 1000) || 0
177 l+=(ascii ? cw[c.chr] : 1000) || 0
178 if(l>wmax)
178 if(l>wmax)
179 #Automatic line break
179 #Automatic line break
180 if(sep==-1 or i==j)
180 if(sep==-1 or i==j)
181 if(i==j)
181 if(i==j)
182 i+=ascii ? 1 : 2
182 i+=ascii ? 1 : 2
183 end
183 end
184 Cell(w,h,s[j,i-j],b,2,align,fill)
184 Cell(w,h,s[j,i-j],b,2,align,fill)
185 else
185 else
186 Cell(w,h,s[j,sep-j],b,2,align,fill)
186 Cell(w,h,s[j,sep-j],b,2,align,fill)
187 i=(s[sep].chr==' ') ? sep+1 : sep
187 i=(s[sep].chr==' ') ? sep+1 : sep
188 end
188 end
189 sep=-1
189 sep=-1
190 j=i
190 j=i
191 l=0
191 l=0
192 nl+=1
192 nl+=1
193 if(border and nl==2)
193 if(border and nl==2)
194 b=b2
194 b=b2
195 end
195 end
196 else
196 else
197 i+=ascii ? 1 : 2
197 i+=ascii ? 1 : 2
198 end
198 end
199 end
199 end
200 #Last chunk
200 #Last chunk
201 if(border and not border.to_s.index('B').nil?)
201 if(border and not border.to_s.index('B').nil?)
202 b+='B'
202 b+='B'
203 end
203 end
204 Cell(w,h,s[j,i-j],b,2,align,fill)
204 Cell(w,h,s[j,i-j],b,2,align,fill)
205 @x=@l_margin
205 @x=@l_margin
206 end
206 end
207
207
208 def Write(h,txt,link='')
208 def Write(h,txt,link='',fill=0)
209 if(@current_font['type']=='Type0')
209 if(@current_font['type']=='Type0')
210 MBWrite(h,txt,link)
210 MBWrite(h,txt,link)
211 else
211 else
212 super(h,txt,link)
212 super(h,txt,link)
213 end
213 end
214 end
214 end
215
215
216 def MBWrite(h,txt,link)
216 def MBWrite(h,txt,link)
217 #Multi-byte version of Write()
217 #Multi-byte version of Write()
218 cw=@current_font['cw']
218 cw=@current_font['cw']
219 w=@w-@r_margin-@x
219 w=@w-@r_margin-@x
220 wmax=(w-2*@c_margin)*1000/@font_size
220 wmax=(w-2*@c_margin)*1000/@font_size
221 s=txt.gsub("\r",'')
221 s=txt.gsub("\r",'')
222 nb=s.length
222 nb=s.length
223 sep=-1
223 sep=-1
224 i=0
224 i=0
225 j=0
225 j=0
226 l=0
226 l=0
227 nl=1
227 nl=1
228 while(i<nb)
228 while(i<nb)
229 #Get next character
229 #Get next character
230 c = s[i].is_a?(String) ? s[i].ord : s[i]
230 c = s[i].is_a?(String) ? s[i].ord : s[i]
231 #Check if ASCII or MB
231 #Check if ASCII or MB
232 ascii=(c<128)
232 ascii=(c<128)
233 if(c.chr=="\n")
233 if(c.chr=="\n")
234 #Explicit line break
234 #Explicit line break
235 Cell(w,h,s[j,i-j],0,2,'',0,link)
235 Cell(w,h,s[j,i-j],0,2,'',0,link)
236 i+=1
236 i+=1
237 sep=-1
237 sep=-1
238 j=i
238 j=i
239 l=0
239 l=0
240 if(nl==1)
240 if(nl==1)
241 @x=@l_margin
241 @x=@l_margin
242 w=@w-@r_margin-@x
242 w=@w-@r_margin-@x
243 wmax=(w-2*@c_margin)*1000/@font_size
243 wmax=(w-2*@c_margin)*1000/@font_size
244 end
244 end
245 nl+=1
245 nl+=1
246 next
246 next
247 end
247 end
248 if(!ascii or c.chr==' ')
248 if(!ascii or c.chr==' ')
249 sep=i
249 sep=i
250 end
250 end
251 l+=(ascii ? cw[c.chr] : 1000) || 0
251 l+=(ascii ? cw[c.chr] : 1000) || 0
252 if(l>wmax)
252 if(l>wmax)
253 #Automatic line break
253 #Automatic line break
254 if(sep==-1 or i==j)
254 if(sep==-1 or i==j)
255 if(@x>@l_margin)
255 if(@x>@l_margin)
256 #Move to next line
256 #Move to next line
257 @x=@l_margin
257 @x=@l_margin
258 @y+=h
258 @y+=h
259 w=@w-@r_margin-@x
259 w=@w-@r_margin-@x
260 wmax=(w-2*@c_margin)*1000/@font_size
260 wmax=(w-2*@c_margin)*1000/@font_size
261 i+=1
261 i+=1
262 nl+=1
262 nl+=1
263 next
263 next
264 end
264 end
265 if(i==j)
265 if(i==j)
266 i+=ascii ? 1 : 2
266 i+=ascii ? 1 : 2
267 end
267 end
268 Cell(w,h,s[j,i-j],0,2,'',0,link)
268 Cell(w,h,s[j,i-j],0,2,'',0,link)
269 else
269 else
270 Cell(w,h,s[j,sep-j],0,2,'',0,link)
270 Cell(w,h,s[j,sep-j],0,2,'',0,link)
271 i=(s[sep].chr==' ') ? sep+1 : sep
271 i=(s[sep].chr==' ') ? sep+1 : sep
272 end
272 end
273 sep=-1
273 sep=-1
274 j=i
274 j=i
275 l=0
275 l=0
276 if(nl==1)
276 if(nl==1)
277 @x=@l_margin
277 @x=@l_margin
278 w=@w-@r_margin-@x
278 w=@w-@r_margin-@x
279 wmax=(w-2*@c_margin)*1000/@font_size
279 wmax=(w-2*@c_margin)*1000/@font_size
280 end
280 end
281 nl+=1
281 nl+=1
282 else
282 else
283 i+=ascii ? 1 : 2
283 i+=ascii ? 1 : 2
284 end
284 end
285 end
285 end
286 #Last chunk
286 #Last chunk
287 if(i!=j)
287 if(i!=j)
288 Cell(l/1000*@font_size,h,s[j,i-j],0,0,'',0,link)
288 Cell(l/1000*@font_size,h,s[j,i-j],0,0,'',0,link)
289 end
289 end
290 end
290 end
291
291
292 private
292 private
293
293
294 def putfonts()
294 def putfonts()
295 nf=@n
295 nf=@n
296 @diffs.each do |diff|
296 @diffs.each do |diff|
297 #Encodings
297 #Encodings
298 newobj()
298 newobj()
299 out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['+diff+']>>')
299 out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['+diff+']>>')
300 out('endobj')
300 out('endobj')
301 end
301 end
302 # mqr=get_magic_quotes_runtime()
302 # mqr=get_magic_quotes_runtime()
303 # set_magic_quotes_runtime(0)
303 # set_magic_quotes_runtime(0)
304 @font_files.each_pair do |file, info|
304 @font_files.each_pair do |file, info|
305 #Font file embedding
305 #Font file embedding
306 newobj()
306 newobj()
307 @font_files[file]['n']=@n
307 @font_files[file]['n']=@n
308 if(defined('FPDF_FONTPATH'))
308 if(defined('FPDF_FONTPATH'))
309 file=FPDF_FONTPATH+file
309 file=FPDF_FONTPATH+file
310 end
310 end
311 size=filesize(file)
311 size=filesize(file)
312 if(!size)
312 if(!size)
313 Error('Font file not found')
313 Error('Font file not found')
314 end
314 end
315 out('<</Length '+size)
315 out('<</Length '+size)
316 if(file[-2]=='.z')
316 if(file[-2]=='.z')
317 out('/Filter /FlateDecode')
317 out('/Filter /FlateDecode')
318 end
318 end
319 out('/Length1 '+info['length1'])
319 out('/Length1 '+info['length1'])
320 if(not info['length2'].nil?)
320 if(not info['length2'].nil?)
321 out('/Length2 '+info['length2']+' /Length3 0')
321 out('/Length2 '+info['length2']+' /Length3 0')
322 end
322 end
323 out('>>')
323 out('>>')
324 f=fopen(file,'rb')
324 f=fopen(file,'rb')
325 putstream(fread(f,size))
325 putstream(fread(f,size))
326 fclose(f)
326 fclose(f)
327 out('endobj')
327 out('endobj')
328 end
328 end
329 # set_magic_quotes_runtime(mqr)
329 # set_magic_quotes_runtime(mqr)
330 @fonts.each_pair do |k, font|
330 @fonts.each_pair do |k, font|
331 #Font objects
331 #Font objects
332 newobj()
332 newobj()
333 @fonts[k]['n']=@n
333 @fonts[k]['n']=@n
334 out('<</Type /Font')
334 out('<</Type /Font')
335 if(font['type']=='Type0')
335 if(font['type']=='Type0')
336 putType0(font)
336 putType0(font)
337 else
337 else
338 name=font['name']
338 name=font['name']
339 out('/BaseFont /'+name)
339 out('/BaseFont /'+name)
340 if(font['type']=='core')
340 if(font['type']=='core')
341 #Standard font
341 #Standard font
342 out('/Subtype /Type1')
342 out('/Subtype /Type1')
343 if(name!='Symbol' and name!='ZapfDingbats')
343 if(name!='Symbol' and name!='ZapfDingbats')
344 out('/Encoding /WinAnsiEncoding')
344 out('/Encoding /WinAnsiEncoding')
345 end
345 end
346 else
346 else
347 #Additional font
347 #Additional font
348 out('/Subtype /'+font['type'])
348 out('/Subtype /'+font['type'])
349 out('/FirstChar 32')
349 out('/FirstChar 32')
350 out('/LastChar 255')
350 out('/LastChar 255')
351 out('/Widths '+(@n+1)+' 0 R')
351 out('/Widths '+(@n+1)+' 0 R')
352 out('/FontDescriptor '+(@n+2)+' 0 R')
352 out('/FontDescriptor '+(@n+2)+' 0 R')
353 if(font['enc'])
353 if(font['enc'])
354 if(not font['diff'].nil?)
354 if(not font['diff'].nil?)
355 out('/Encoding '+(nf+font['diff'])+' 0 R')
355 out('/Encoding '+(nf+font['diff'])+' 0 R')
356 else
356 else
357 out('/Encoding /WinAnsiEncoding')
357 out('/Encoding /WinAnsiEncoding')
358 end
358 end
359 end
359 end
360 end
360 end
361 out('>>')
361 out('>>')
362 out('endobj')
362 out('endobj')
363 if(font['type']!='core')
363 if(font['type']!='core')
364 #Widths
364 #Widths
365 newobj()
365 newobj()
366 cw=font['cw']
366 cw=font['cw']
367 s='['
367 s='['
368 32.upto(255) do |i|
368 32.upto(255) do |i|
369 s+=cw[i.chr]+' '
369 s+=cw[i.chr]+' '
370 end
370 end
371 out(s+']')
371 out(s+']')
372 out('endobj')
372 out('endobj')
373 #Descriptor
373 #Descriptor
374 newobj()
374 newobj()
375 s='<</Type /FontDescriptor /FontName /'+name
375 s='<</Type /FontDescriptor /FontName /'+name
376 font['desc'].each_pair do |k, v|
376 font['desc'].each_pair do |k, v|
377 s+=' /'+k+' '+v
377 s+=' /'+k+' '+v
378 end
378 end
379 file=font['file']
379 file=font['file']
380 if(file)
380 if(file)
381 s+=' /FontFile'+(font['type']=='Type1' ? '' : '2')+' '+@font_files[file]['n']+' 0 R'
381 s+=' /FontFile'+(font['type']=='Type1' ? '' : '2')+' '+@font_files[file]['n']+' 0 R'
382 end
382 end
383 out(s+'>>')
383 out(s+'>>')
384 out('endobj')
384 out('endobj')
385 end
385 end
386 end
386 end
387 end
387 end
388 end
388 end
389
389
390 def putType0(font)
390 def putType0(font)
391 #Type0
391 #Type0
392 out('/Subtype /Type0')
392 out('/Subtype /Type0')
393 out('/BaseFont /'+font['name']+'-'+font['CMap'])
393 out('/BaseFont /'+font['name']+'-'+font['CMap'])
394 out('/Encoding /'+font['CMap'])
394 out('/Encoding /'+font['CMap'])
395 out('/DescendantFonts ['+(@n+1).to_s+' 0 R]')
395 out('/DescendantFonts ['+(@n+1).to_s+' 0 R]')
396 out('>>')
396 out('>>')
397 out('endobj')
397 out('endobj')
398 #CIDFont
398 #CIDFont
399 newobj()
399 newobj()
400 out('<</Type /Font')
400 out('<</Type /Font')
401 out('/Subtype /CIDFontType0')
401 out('/Subtype /CIDFontType0')
402 out('/BaseFont /'+font['name'])
402 out('/BaseFont /'+font['name'])
403 out('/CIDSystemInfo <</Registry (Adobe) /Ordering ('+font['registry']['ordering']+') /Supplement '+font['registry']['supplement'].to_s+'>>')
403 out('/CIDSystemInfo <</Registry (Adobe) /Ordering ('+font['registry']['ordering']+') /Supplement '+font['registry']['supplement'].to_s+'>>')
404 out('/FontDescriptor '+(@n+1).to_s+' 0 R')
404 out('/FontDescriptor '+(@n+1).to_s+' 0 R')
405 if(font['CMap']=='KSCms-UHC-HW-H')
405 if(font['CMap']=='KSCms-UHC-HW-H')
406 w='8094 8190 500'
406 w='8094 8190 500'
407 else
407 else
408 w='1 ['
408 w='1 ['
409 font['cw'].keys.sort.each {|key|
409 font['cw'].keys.sort.each {|key|
410 w+=font['cw'][key].to_s + " "
410 w+=font['cw'][key].to_s + " "
411 # ActionController::Base::logger.debug key.to_s
411 # ActionController::Base::logger.debug key.to_s
412 # ActionController::Base::logger.debug font['cw'][key].to_s
412 # ActionController::Base::logger.debug font['cw'][key].to_s
413 }
413 }
414 w +=']'
414 w +=']'
415 end
415 end
416 out('/W ['+w+']>>')
416 out('/W ['+w+']>>')
417 out('endobj')
417 out('endobj')
418 #Font descriptor
418 #Font descriptor
419 newobj()
419 newobj()
420 out('<</Type /FontDescriptor')
420 out('<</Type /FontDescriptor')
421 out('/FontName /'+font['name'])
421 out('/FontName /'+font['name'])
422 out('/Flags 6')
422 out('/Flags 6')
423 out('/FontBBox [0 -200 1000 900]')
423 out('/FontBBox [0 -200 1000 900]')
424 out('/ItalicAngle 0')
424 out('/ItalicAngle 0')
425 out('/Ascent 800')
425 out('/Ascent 800')
426 out('/Descent -200')
426 out('/Descent -200')
427 out('/CapHeight 800')
427 out('/CapHeight 800')
428 out('/StemV 50')
428 out('/StemV 50')
429 out('>>')
429 out('>>')
430 out('endobj')
430 out('endobj')
431 end
431 end
432 end
432 end
General Comments 0
You need to be logged in to leave comments. Login now