Coverage C0 Coverage Information - RCov

lib/plugins/rfpdf/lib/fpdf/japanese.rb

Name Total Lines Lines of Code Total Coverage Code Coverage
lib/plugins/rfpdf/lib/fpdf/japanese.rb 481 383
48.44%
40.99%

Key

Code reported as executed by Ruby looks like this...and this: this line is also marked as covered.Lines considered as run by rcov, but not reported by Ruby, look like this,and this: these lines were inferred by rcov (using simple heuristics).Finally, here's a line marked as not executed.

Coverage Details

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

Generated on Sat Aug 16 04:10:26 +0200 2014 with rcov 1.0.0