##// END OF EJS Templates
PDF: import Chinese rfpdf patch for textilized PDF (#69)....
Toshi MARUYAMA -
r6013:e9cdaf0d4bc7
parent child
Show More
@@ -1,469 +1,486
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)
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,ln)
148 else
148 else
149 super(w,h,txt,border,align,fill)
149 super(w,h,txt,border,align,fill,ln)
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,ln=1)
154
155 # save current position
156 prevx = @x;
157 prevy = @y;
158
154 #Multi-byte version of MultiCell()
159 #Multi-byte version of MultiCell()
155 cw=@current_font['cw']
160 cw=@current_font['cw']
156 if(w==0)
161 if(w==0)
157 w=@w-@r_margin-@x
162 w=@w-@r_margin-@x
158 end
163 end
159 wmax=(w-2*@c_margin)*1000/@font_size
164 wmax=(w-2*@c_margin)*1000/@font_size
160 s=txt.gsub("\r",'')
165 s=txt.gsub("\r",'')
161 nb=s.length
166 nb=s.length
162 if(nb>0 and s[nb-1]=="\n")
167 if(nb>0 and s[nb-1]=="\n")
163 nb-=1
168 nb-=1
164 end
169 end
165 b=0
170 b=0
166 if(border)
171 if(border)
167 if(border==1)
172 if(border==1)
168 border='LTRB'
173 border='LTRB'
169 b='LRT'
174 b='LRT'
170 b2='LR'
175 b2='LR'
171 else
176 else
172 b2=''
177 b2=''
173 b2='L' unless border.to_s.index('L').nil?
178 b2='L' unless border.to_s.index('L').nil?
174 b2=b2+'R' unless border.to_s.index('R').nil?
179 b2=b2+'R' unless border.to_s.index('R').nil?
175 b=(border.to_s.index('T')) ? (b2+'T') : b2
180 b=(border.to_s.index('T')) ? (b2+'T') : b2
176 end
181 end
177 end
182 end
178 sep=-1
183 sep=-1
179 i=0
184 i=0
180 j=0
185 j=0
181 l=0
186 l=0
182 nl=1
187 nl=1
183 while(i<nb)
188 while(i<nb)
184 #Get next character
189 #Get next character
185 c = s[i].is_a?(String) ? s[i].ord : s[i]
190 c = s[i].is_a?(String) ? s[i].ord : s[i]
186 #Check if ASCII or MB
191 #Check if ASCII or MB
187 ascii=(c<128)
192 ascii=(c<128)
188 if(c.chr=="\n")
193 if(c.chr=="\n")
189 #Explicit line break
194 #Explicit line break
190 Cell(w,h,s[j,i-j],b,2,align,fill)
195 Cell(w,h,s[j,i-j],b,2,align,fill)
191 i+=1
196 i+=1
192 sep=-1
197 sep=-1
193 j=i
198 j=i
194 l=0
199 l=0
195 nl+=1
200 nl+=1
196 if(border and nl==2)
201 if(border and nl==2)
197 b=b2
202 b=b2
198 end
203 end
199 next
204 next
200 end
205 end
201 if(!ascii)
206 if(!ascii)
202 sep=i
207 sep=i
203 ls=l
208 ls=l
204 elsif(c.chr==' ')
209 elsif(c.chr==' ')
205 sep=i
210 sep=i
206 ls=l
211 ls=l
207 end
212 end
208 l+=(ascii ? cw[c.chr] : 1000) || 0
213 l+=(ascii ? cw[c.chr] : 1000) || 0
209 if(l>wmax)
214 if(l>wmax)
210 #Automatic line break
215 #Automatic line break
211 if(sep==-1 or i==j)
216 if(sep==-1 or i==j)
212 if(i==j)
217 if(i==j)
213 i+=ascii ? 1 : 2
218 i+=ascii ? 1 : 2
214 end
219 end
215 Cell(w,h,s[j,i-j],b,2,align,fill)
220 Cell(w,h,s[j,i-j],b,2,align,fill)
216 else
221 else
217 Cell(w,h,s[j,sep-j],b,2,align,fill)
222 Cell(w,h,s[j,sep-j],b,2,align,fill)
218 i=(s[sep].chr==' ') ? sep+1 : sep
223 i=(s[sep].chr==' ') ? sep+1 : sep
219 end
224 end
220 sep=-1
225 sep=-1
221 j=i
226 j=i
222 l=0
227 l=0
223 nl+=1
228 nl+=1
224 if(border and nl==2)
229 if(border and nl==2)
225 b=b2
230 b=b2
226 end
231 end
227 else
232 else
228 i+=ascii ? 1 : 2
233 i+=ascii ? 1 : 2
229 end
234 end
230 end
235 end
231 #Last chunk
236 #Last chunk
232 if(border and not border.to_s.index('B').nil?)
237 if(border and not border.to_s.index('B').nil?)
233 b+='B'
238 b+='B'
234 end
239 end
235 Cell(w,h,s[j,i-j],b,2,align,fill)
240 Cell(w,h,s[j,i-j],b,2,align,fill)
236 @x=@l_margin
241
242 # move cursor to specified position
243 if (ln == 1)
244 # go to the beginning of the next line
245 @x=@l_margin
246 elsif (ln == 0)
247 # go to the top-right of the cell
248 @y = prevy;
249 @x = prevx + w;
250 elsif (ln == 2)
251 # go to the bottom-left of the cell
252 @x = prevx;
253 end
237 end
254 end
238
255
239 def Write(h,txt,link='')
256 def Write(h,txt,link='',fill=0)
240 if(@current_font['type']=='Type0')
257 if(@current_font['type']=='Type0')
241 MBWrite(h,txt,link)
258 MBWrite(h,txt,link,fill)
242 else
259 else
243 super(h,txt,link)
260 super(h,txt,link,fill)
244 end
261 end
245 end
262 end
246
263
247 def MBWrite(h,txt,link)
264 def MBWrite(h,txt,link,fill=0)
248 #Multi-byte version of Write()
265 #Multi-byte version of Write()
249 cw=@current_font['cw']
266 cw=@current_font['cw']
250 w=@w-@r_margin-@x
267 w=@w-@r_margin-@x
251 wmax=(w-2*@c_margin)*1000/@font_size
268 wmax=(w-2*@c_margin)*1000/@font_size
252 s=txt.gsub("\r",'')
269 s=txt.gsub("\r",'')
253 nb=s.length
270 nb=s.length
254 sep=-1
271 sep=-1
255 i=0
272 i=0
256 j=0
273 j=0
257 l=0
274 l=0
258 nl=1
275 nl=1
259 while(i<nb)
276 while(i<nb)
260 #Get next character
277 #Get next character
261 c = s[i].is_a?(String) ? s[i].ord : s[i]
278 c = s[i].is_a?(String) ? s[i].ord : s[i]
262 #Check if ASCII or MB
279 #Check if ASCII or MB
263 ascii=(c<128)
280 ascii=(c<128)
264 if(c.chr=="\n")
281 if(c.chr=="\n")
265 #Explicit line break
282 #Explicit line break
266 Cell(w,h,s[j,i-j],0,2,'',0,link)
283 Cell(w,h,s[j,i-j],0,2,'',fill,link)
267 i+=1
284 i+=1
268 sep=-1
285 sep=-1
269 j=i
286 j=i
270 l=0
287 l=0
271 if(nl==1)
288 if(nl==1)
272 @x=@l_margin
289 @x=@l_margin
273 w=@w-@r_margin-@x
290 w=@w-@r_margin-@x
274 wmax=(w-2*@c_margin)*1000/@font_size
291 wmax=(w-2*@c_margin)*1000/@font_size
275 end
292 end
276 nl+=1
293 nl+=1
277 next
294 next
278 end
295 end
279 if(!ascii or c.chr==' ')
296 if(!ascii or c.chr==' ')
280 sep=i
297 sep=i
281 end
298 end
282 l+=(ascii ? cw[c.chr] : 1000) || 0
299 l+=(ascii ? cw[c.chr] : 1000) || 0
283 if(l>wmax)
300 if(l>wmax)
284 #Automatic line break
301 #Automatic line break
285 if(sep==-1 or i==j)
302 if(sep==-1 or i==j)
286 if(@x>@l_margin)
303 if(@x>@l_margin)
287 #Move to next line
304 #Move to next line
288 @x=@l_margin
305 @x=@l_margin
289 @y+=h
306 @y+=h
290 w=@w-@r_margin-@x
307 w=@w-@r_margin-@x
291 wmax=(w-2*@c_margin)*1000/@font_size
308 wmax=(w-2*@c_margin)*1000/@font_size
292 i+=1
309 i+=1
293 nl+=1
310 nl+=1
294 next
311 next
295 end
312 end
296 if(i==j)
313 if(i==j)
297 i+=ascii ? 1 : 2
314 i+=ascii ? 1 : 2
298 end
315 end
299 Cell(w,h,s[j,i-j],0,2,'',0,link)
316 Cell(w,h,s[j,i-j],0,2,'',fill,link)
300 else
317 else
301 Cell(w,h,s[j,sep-j],0,2,'',0,link)
318 Cell(w,h,s[j,sep-j],0,2,'',fill,link)
302 i=(s[sep].chr==' ') ? sep+1 : sep
319 i=(s[sep].chr==' ') ? sep+1 : sep
303 end
320 end
304 sep=-1
321 sep=-1
305 j=i
322 j=i
306 l=0
323 l=0
307 if(nl==1)
324 if(nl==1)
308 @x=@l_margin
325 @x=@l_margin
309 w=@w-@r_margin-@x
326 w=@w-@r_margin-@x
310 wmax=(w-2*@c_margin)*1000/@font_size
327 wmax=(w-2*@c_margin)*1000/@font_size
311 end
328 end
312 nl+=1
329 nl+=1
313 else
330 else
314 i+=ascii ? 1 : 2
331 i+=ascii ? 1 : 2
315 end
332 end
316 end
333 end
317 #Last chunk
334 #Last chunk
318 if(i!=j)
335 if(i!=j)
319 Cell(l/1000*@font_size,h,s[j,i-j],0,0,'',0,link)
336 Cell(l*@font_size/1000.0,h,s[j,i-j],0,0,'',fill,link)
320 end
337 end
321 end
338 end
322
339
323 private
340 private
324
341
325 def putfonts()
342 def putfonts()
326 nf=@n
343 nf=@n
327 @diffs.each do |diff|
344 @diffs.each do |diff|
328 #Encodings
345 #Encodings
329 newobj()
346 newobj()
330 out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['+diff+']>>')
347 out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['+diff+']>>')
331 out('endobj')
348 out('endobj')
332 end
349 end
333 # mqr=get_magic_quotes_runtime()
350 # mqr=get_magic_quotes_runtime()
334 # set_magic_quotes_runtime(0)
351 # set_magic_quotes_runtime(0)
335 @font_files.each_pair do |file, info|
352 @font_files.each_pair do |file, info|
336 #Font file embedding
353 #Font file embedding
337 newobj()
354 newobj()
338 @font_files[file]['n']=@n
355 @font_files[file]['n']=@n
339 if(defined('FPDF_FONTPATH'))
356 if(defined('FPDF_FONTPATH'))
340 file=FPDF_FONTPATH+file
357 file=FPDF_FONTPATH+file
341 end
358 end
342 size=filesize(file)
359 size=filesize(file)
343 if(!size)
360 if(!size)
344 Error('Font file not found')
361 Error('Font file not found')
345 end
362 end
346 out('<</Length '+size)
363 out('<</Length '+size)
347 if(file[-2]=='.z')
364 if(file[-2]=='.z')
348 out('/Filter /FlateDecode')
365 out('/Filter /FlateDecode')
349 end
366 end
350 out('/Length1 '+info['length1'])
367 out('/Length1 '+info['length1'])
351 unless info['length2'].nil?
368 unless info['length2'].nil?
352 out('/Length2 '+info['length2']+' /Length3 0')
369 out('/Length2 '+info['length2']+' /Length3 0')
353 end
370 end
354 out('>>')
371 out('>>')
355 f=fopen(file,'rb')
372 f=fopen(file,'rb')
356 putstream(fread(f,size))
373 putstream(fread(f,size))
357 fclose(f)
374 fclose(f)
358 out('endobj')
375 out('endobj')
359 end
376 end
360 #
377 #
361 # set_magic_quotes_runtime(mqr)
378 # set_magic_quotes_runtime(mqr)
362 #
379 #
363 @fonts.each_pair do |k, font|
380 @fonts.each_pair do |k, font|
364 #Font objects
381 #Font objects
365 newobj()
382 newobj()
366 @fonts[k]['n']=@n
383 @fonts[k]['n']=@n
367 out('<</Type /Font')
384 out('<</Type /Font')
368 if(font['type']=='Type0')
385 if(font['type']=='Type0')
369 putType0(font)
386 putType0(font)
370 else
387 else
371 name=font['name']
388 name=font['name']
372 out('/BaseFont /'+name)
389 out('/BaseFont /'+name)
373 if(font['type']=='core')
390 if(font['type']=='core')
374 #Standard font
391 #Standard font
375 out('/Subtype /Type1')
392 out('/Subtype /Type1')
376 if(name!='Symbol' and name!='ZapfDingbats')
393 if(name!='Symbol' and name!='ZapfDingbats')
377 out('/Encoding /WinAnsiEncoding')
394 out('/Encoding /WinAnsiEncoding')
378 end
395 end
379 else
396 else
380 #Additional font
397 #Additional font
381 out('/Subtype /'+font['type'])
398 out('/Subtype /'+font['type'])
382 out('/FirstChar 32')
399 out('/FirstChar 32')
383 out('/LastChar 255')
400 out('/LastChar 255')
384 out('/Widths '+(@n+1)+' 0 R')
401 out('/Widths '+(@n+1)+' 0 R')
385 out('/FontDescriptor '+(@n+2)+' 0 R')
402 out('/FontDescriptor '+(@n+2)+' 0 R')
386 if(font['enc'])
403 if(font['enc'])
387 if !font['diff'].nil?
404 if !font['diff'].nil?
388 out('/Encoding '+(nf+font['diff'])+' 0 R')
405 out('/Encoding '+(nf+font['diff'])+' 0 R')
389 else
406 else
390 out('/Encoding /WinAnsiEncoding')
407 out('/Encoding /WinAnsiEncoding')
391 end
408 end
392 end
409 end
393 end
410 end
394 out('>>')
411 out('>>')
395 out('endobj')
412 out('endobj')
396 if(font['type']!='core')
413 if(font['type']!='core')
397 #Widths
414 #Widths
398 newobj()
415 newobj()
399 cw=font['cw']
416 cw=font['cw']
400 s='['
417 s='['
401 32.upto(255) do |i|
418 32.upto(255) do |i|
402 s+=cw[i.chr]+' '
419 s+=cw[i.chr]+' '
403 end
420 end
404 out(s+']')
421 out(s+']')
405 out('endobj')
422 out('endobj')
406 #Descriptor
423 #Descriptor
407 newobj()
424 newobj()
408 s='<</Type /FontDescriptor /FontName /'+name
425 s='<</Type /FontDescriptor /FontName /'+name
409 font['desc'].each_pair do |k, v|
426 font['desc'].each_pair do |k, v|
410 s+=' /'+k+' '+v
427 s+=' /'+k+' '+v
411 end
428 end
412 file=font['file']
429 file=font['file']
413 if(file)
430 if(file)
414 s+=' /FontFile'+(font['type']=='Type1' ? '' : '2')+' '+@font_files[file]['n']+' 0 R'
431 s+=' /FontFile'+(font['type']=='Type1' ? '' : '2')+' '+@font_files[file]['n']+' 0 R'
415 end
432 end
416 out(s+'>>')
433 out(s+'>>')
417 out('endobj')
434 out('endobj')
418 end
435 end
419 end
436 end
420 end
437 end
421 end
438 end
422
439
423 def putType0(font)
440 def putType0(font)
424 #Type0
441 #Type0
425 out('/Subtype /Type0')
442 out('/Subtype /Type0')
426 out('/BaseFont /'+font['name']+'-'+font['CMap'])
443 out('/BaseFont /'+font['name']+'-'+font['CMap'])
427 out('/Encoding /'+font['CMap'])
444 out('/Encoding /'+font['CMap'])
428 out('/DescendantFonts ['+(@n+1).to_s+' 0 R]')
445 out('/DescendantFonts ['+(@n+1).to_s+' 0 R]')
429 out('>>')
446 out('>>')
430 out('endobj')
447 out('endobj')
431 #CIDFont
448 #CIDFont
432 newobj()
449 newobj()
433 out('<</Type /Font')
450 out('<</Type /Font')
434 out('/Subtype /CIDFontType0')
451 out('/Subtype /CIDFontType0')
435 out('/BaseFont /'+font['name'])
452 out('/BaseFont /'+font['name'])
436 out('/CIDSystemInfo <</Registry '+textstring('Adobe')+' /Ordering '+textstring(font['registry']['ordering'])+' /Supplement '+font['registry']['supplement'].to_s+'>>')
453 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')
454 out('/FontDescriptor '+(@n+1).to_s+' 0 R')
438 if(font['CMap']=='ETen-B5-H')
455 if(font['CMap']=='ETen-B5-H')
439 w='13648 13742 500'
456 w='13648 13742 500'
440 elsif(font['CMap']=='GBK-EUC-H')
457 elsif(font['CMap']=='GBK-EUC-H')
441 w='814 907 500 7716 [500]'
458 w='814 907 500 7716 [500]'
442 else
459 else
443 # ActionController::Base::logger.debug font['cw'].keys.sort.join(' ').to_s
460 # ActionController::Base::logger.debug font['cw'].keys.sort.join(' ').to_s
444 # ActionController::Base::logger.debug font['cw'].values.join(' ').to_s
461 # ActionController::Base::logger.debug font['cw'].values.join(' ').to_s
445 w='1 ['
462 w='1 ['
446 font['cw'].keys.sort.each {|key|
463 font['cw'].keys.sort.each {|key|
447 w+=font['cw'][key].to_s + " "
464 w+=font['cw'][key].to_s + " "
448 # ActionController::Base::logger.debug key.to_s
465 # ActionController::Base::logger.debug key.to_s
449 # ActionController::Base::logger.debug font['cw'][key].to_s
466 # ActionController::Base::logger.debug font['cw'][key].to_s
450 }
467 }
451 w +=']'
468 w +=']'
452 end
469 end
453 out('/W ['+w+']>>')
470 out('/W ['+w+']>>')
454 out('endobj')
471 out('endobj')
455 #Font descriptor
472 #Font descriptor
456 newobj()
473 newobj()
457 out('<</Type /FontDescriptor')
474 out('<</Type /FontDescriptor')
458 out('/FontName /'+font['name'])
475 out('/FontName /'+font['name'])
459 out('/Flags 6')
476 out('/Flags 6')
460 out('/FontBBox [0 -200 1000 900]')
477 out('/FontBBox [0 -200 1000 900]')
461 out('/ItalicAngle 0')
478 out('/ItalicAngle 0')
462 out('/Ascent 800')
479 out('/Ascent 800')
463 out('/Descent -200')
480 out('/Descent -200')
464 out('/CapHeight 800')
481 out('/CapHeight 800')
465 out('/StemV 50')
482 out('/StemV 50')
466 out('>>')
483 out('>>')
467 out('endobj')
484 out('endobj')
468 end
485 end
469 end
486 end
General Comments 0
You need to be logged in to leave comments. Login now