##// END OF EJS Templates
PDF: fix automatic line break in Chinese PDF (#5629)....
Toshi MARUYAMA -
r5485:46bd78aa2106
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(@CurrentFont['type']=='Type0')
119 if(@CurrentFont['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=@CurrentFont['cw']
129 cw=@CurrentFont['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*@FontSize/1000
142 return l*@FontSize/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)
146 if(@CurrentFont['type']=='Type0')
146 if(@CurrentFont['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=@CurrentFont['cw']
155 cw=@CurrentFont['cw']
156 if(w==0)
156 if(w==0)
157 w=@w-@rMargin-@x
157 w=@w-@rMargin-@x
158 end
158 end
159 wmax=(w-2*@cMargin)*1000/@FontSize
159 wmax=(w-2*@cMargin)*1000/@FontSize
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=@lMargin
236 @x=@lMargin
237 end
237 end
238
238
239 def Write(h,txt,link='')
239 def Write(h,txt,link='')
240 if(@CurrentFont['type']=='Type0')
240 if(@CurrentFont['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=@CurrentFont['cw']
249 cw=@CurrentFont['cw']
250 w=@w-@rMargin-@x
250 w=@w-@rMargin-@x
251 wmax=(w-2*@cMargin)*1000/@FontSize
251 wmax=(w-2*@cMargin)*1000/@FontSize
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=@lMargin
272 @x=@lMargin
273 w=@w-@rMargin-@x
273 w=@w-@rMargin-@x
274 wmax=(w-2*@cMargin)*1000/@FontSize
274 wmax=(w-2*@cMargin)*1000/@FontSize
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>@lMargin)
286 if(@x>@lMargin)
287 #Move to next line
287 #Move to next line
288 @x=@lMargin
288 @x=@lMargin
289 @y+=h
289 @y+=h
290 w=@w-@rMargin-@x
290 w=@w-@rMargin-@x
291 wmax=(w-2*@cMargin)*1000/@FontSize
291 wmax=(w-2*@cMargin)*1000/@FontSize
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=@lMargin
308 @x=@lMargin
309 w=@w-@rMargin-@x
309 w=@w-@rMargin-@x
310 wmax=(w-2*@cMargin)*1000/@FontSize
310 wmax=(w-2*@cMargin)*1000/@FontSize
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*@FontSize,h,s[j,i-j],0,0,'',0,link)
319 Cell(l/1000*@FontSize,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 @FontFiles.each_pair do |file, info|
335 @FontFiles.each_pair do |file, info|
336 #Font file embedding
336 #Font file embedding
337 newobj()
337 newobj()
338 @FontFiles[file]['n']=@n
338 @FontFiles[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')+' '+@FontFiles[file]['n']+' 0 R'
414 s+=' /FontFile'+(font['type']=='Type1' ? '' : '2')+' '+@FontFiles[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
General Comments 0
You need to be logged in to leave comments. Login now