To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / .svn / pristine / 34 / 34ce52464aaba9c361d4d597bfc1e5b07bef8911.svn-base @ 1298:4f746d8966dd

History | View | Annotate | Download (11.7 KB)

1
# Copyright (c) 2006 4ssoM LLC <www.4ssoM.com>
2
# 1.12 contributed by Ed Moss.
3
#
4
# The MIT License
5
#
6
# Permission is hereby granted, free of charge, to any person obtaining a copy
7
# of this software and associated documentation files (the "Software"), to deal
8
# in the Software without restriction, including without limitation the rights
9
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
# copies of the Software, and to permit persons to whom the Software is
11
# furnished to do so, subject to the following conditions:
12
#
13
# The above copyright notice and this permission notice shall be included in
14
# all copies or substantial portions of the Software.
15
#
16
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
19
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
# THE SOFTWARE.
23
#
24
# This is direct port of korean.php
25
#
26
# Korean PDF support.
27
#
28
# Usage is as follows:
29
#
30
# require 'fpdf'
31
# require 'chinese'
32
# pdf = FPDF.new
33
# pdf.extend(PDF_Korean)
34
#
35
# This allows it to be combined with other extensions, such as the bookmark
36
# module.
37

    
38
module PDF_Korean
39

    
40
UHC_widths={' ' => 333, '!' => 416, '"' => 416, '#' => 833, '$' => 625, '%' => 916, '&' => 833, '\'' => 250, 
41
	'(' => 500, ')' => 500, '*' => 500, '+' => 833, ',' => 291, '-' => 833, '.' => 291, '/' => 375, '0' => 625, '1' => 625, 
42
	'2' => 625, '3' => 625, '4' => 625, '5' => 625, '6' => 625, '7' => 625, '8' => 625, '9' => 625, ':' => 333, ';' => 333, 
43
	'<' => 833, '=' => 833, '>' => 916, '?' => 500, '@' => 1000, 'A' => 791, 'B' => 708, 'C' => 708, 'D' => 750, 'E' => 708, 
44
	'F' => 666, 'G' => 750, 'H' => 791, 'I' => 375, 'J' => 500, 'K' => 791, 'L' => 666, 'M' => 916, 'N' => 791, 'O' => 750, 
45
	'P' => 666, 'Q' => 750, 'R' => 708, 'S' => 666, 'T' => 791, 'U' => 791, 'V' => 750, 'W' => 1000, 'X' => 708, 'Y' => 708, 
46
	'Z' => 666, '[' => 500, '\\' => 375, ']' => 500, '^' => 500, '_' => 500, '`' => 333, 'a' => 541, 'b' => 583, 'c' => 541, 
47
	'd' => 583, 'e' => 583, 'f' => 375, 'g' => 583, 'h' => 583, 'i' => 291, 'j' => 333, 'k' => 583, 'l' => 291, 'm' => 875, 
48
	'n' => 583, 'o' => 583, 'p' => 583, 'q' => 583, 'r' => 458, 's' => 541, 't' => 375, 'u' => 583, 'v' => 583, 'w' => 833, 
49
	'x' => 625, 'y' => 625, 'z' => 500, '{' => 583, '|' => 583, '}' => 583, '~' => 750}
50

    
51
  def AddCIDFont(family,style,name,cw,cMap,registry)
52
    fontkey=family.downcase+style.upcase
53
    unless @fonts[fontkey].nil?
54
  		Error("Font already added: family style")
55
    end
56
  	i=@fonts.length+1
57
  	name=name.gsub(' ','')
58
  	@fonts[fontkey]={'i'=>i,'type'=>'Type0','name'=>name,'up'=>-130,'ut'=>40,'cw'=>cw,
59
  	  'CMap'=>cMap,'registry'=>registry}
60
  end
61

    
62
  def AddCIDFonts(family,name,cw,cMap,registry)
63
  	AddCIDFont(family,'',name,cw,cMap,registry)
64
  	AddCIDFont(family,'B',name+',Bold',cw,cMap,registry)
65
  	AddCIDFont(family,'I',name+',Italic',cw,cMap,registry)
66
  	AddCIDFont(family,'BI',name+',BoldItalic',cw,cMap,registry)
67
  end
68

    
69
  def AddUHCFont(family='UHC',name='HYSMyeongJoStd-Medium-Acro')
70
  	#Add UHC font with proportional Latin
71
  	cw=UHC_widths
72
  	cMap='KSCms-UHC-H'
73
  	registry={'ordering'=>'Korea1','supplement'=>1}
74
  	AddCIDFonts(family,name,cw,cMap,registry)
75
  end
76

    
77
  def AddUHChwFont(family='UHC-hw',name='HYSMyeongJoStd-Medium-Acro')
78
  	#Add UHC font with half-witdh Latin
79
    32.upto(126) do |i|
80
  		cw[i.chr]=500
81
    end
82
  	cMap='KSCms-UHC-HW-H'
83
  	registry={'ordering'=>'Korea1','supplement'=>1}
84
  	AddCIDFonts(family,name,cw,cMap,registry)
85
  end
86

    
87
  def GetStringWidth(s)
88
  	if(@current_font['type']=='Type0')
89
  		return GetMBStringWidth(s)
90
  	else
91
  		return super(s)
92
    end
93
  end
94

    
95
  def GetMBStringWidth(s)
96
  	#Multi-byte version of GetStringWidth()
97
  	l=0
98
  	cw=@current_font['cw']
99
  	nb=s.length
100
  	i=0
101
  	while(i<nb)
102
  		c = s[i].is_a?(String) ? s[i].ord : s[i]
103
  		if(c<128)
104
  			l+=cw[c.chr] if cw[c.chr]
105
  			i+=1
106
  		else
107
  			l+=1000
108
  			i+=2
109
  		end
110
  	end
111
  	return l*@font_size/1000
112
  end
113

    
114
  def MultiCell(w,h,txt,border=0,align='L',fill=0,ln=1)
115
  	if(@current_font['type']=='Type0')
116
  		MBMultiCell(w,h,txt,border,align,fill,ln)
117
  	else
118
  		super(w,h,txt,border,align,fill,ln)
119
    end
120
  end
121

    
122
  def MBMultiCell(w,h,txt,border=0,align='L',fill=0,ln=1)
123

    
124
  	# save current position
125
  	prevx = @x;
126
  	prevy = @y;
127

    
128
  	#Multi-byte version of MultiCell()
129
  	cw=@current_font['cw']
130
  	if(w==0)
131
  		w=@w-@r_margin-@x
132
    end
133
  	wmax=(w-2*@c_margin)*1000/@font_size
134
  	s=txt.gsub("\r",'')
135
  	nb=s.length
136
  	if(nb>0 and s[nb-1]=="\n")
137
  		nb-=1
138
    end
139
  	b=0
140
  	if(border)
141
  		if(border==1)
142
  			border='LTRB'
143
  			b='LRT'
144
  			b2='LR'
145
  		else
146
  			b2=''
147
  			b2='L' unless border.to_s.index('L').nil?
148
  			b2=b2+'R' unless border.to_s.index('R').nil?
149
  			b=(border.to_s.index('T')) ? (b2+'T') : b2
150
  		end
151
  	end
152
  	sep=-1
153
  	i=0
154
  	j=0
155
  	l=0
156
  	nl=1
157
  	while(i<nb)
158
  		#Get next character
159
  		c = s[i].is_a?(String) ? s[i].ord : s[i]
160
  		#Check if ASCII or MB
161
  		ascii=(c<128)
162
  		if(c.chr=="\n")
163
  			#Explicit line break
164
  			Cell(w,h,s[j,i-j],b,2,align,fill)
165
  			i+=1
166
  			sep=-1
167
  			j=i
168
  			l=0
169
  			nl+=1
170
  			if(border and nl==2)
171
  				b=b2
172
        end
173
  			next
174
  		end
175
  		if(!ascii)
176
  			sep=i
177
  			ls=l
178
  		elsif(c.chr==' ')
179
  			sep=i
180
  			ls=l
181
  		end
182
  		l+=(ascii ? cw[c.chr] : 1000) || 0
183
  		if(l>wmax)
184
  			#Automatic line break
185
  			if(sep==-1 or i==j)
186
  				if(i==j)
187
  					i+=ascii ? 1 : 2
188
          end
189
  				Cell(w,h,s[j,i-j],b,2,align,fill)
190
  			else
191
  				Cell(w,h,s[j,sep-j],b,2,align,fill)
192
  				i=(s[sep].chr==' ') ? sep+1 : sep
193
  			end
194
  			sep=-1
195
  			j=i
196
  			l=0
197
  			nl+=1
198
  			if(border and nl==2)
199
  				b=b2
200
        end
201
  		else
202
  			i+=ascii ? 1 : 2
203
      end
204
  	end
205
  	#Last chunk
206
  	if(border and not border.to_s.index('B').nil?)
207
  		b+='B'
208
    end
209
  	Cell(w,h,s[j,i-j],b,2,align,fill)
210

    
211
  	# move cursor to specified position
212
  	if (ln == 1)
213
  		# go to the beginning of the next line
214
  		@x=@l_margin
215
  	elsif (ln == 0)
216
  		# go to the top-right of the cell
217
  		@y = prevy;
218
  		@x = prevx + w;
219
  	elsif (ln == 2)
220
  		# go to the bottom-left of the cell
221
  		@x = prevx;
222
    end
223
  end
224

    
225
  def Write(h,txt,link='',fill=0)
226
  	if(@current_font['type']=='Type0')
227
  		MBWrite(h,txt,link,fill)
228
  	else
229
  		super(h,txt,link,fill)
230
    end
231
  end
232

    
233
  def MBWrite(h,txt,link,fill=0)
234
  	#Multi-byte version of Write()
235
  	cw=@current_font['cw']
236
  	w=@w-@r_margin-@x
237
  	wmax=(w-2*@c_margin)*1000/@font_size
238
  	s=txt.gsub("\r",'')
239
  	nb=s.length
240
  	sep=-1
241
  	i=0
242
  	j=0
243
  	l=0
244
  	nl=1
245
  	while(i<nb)
246
  		#Get next character
247
  		c = s[i].is_a?(String) ? s[i].ord : s[i]
248
  		#Check if ASCII or MB
249
  		ascii=(c<128)
250
  		if(c.chr=="\n")
251
  			#Explicit line break
252
  			Cell(w,h,s[j,i-j],0,2,'',fill,link)
253
  			i+=1
254
  			sep=-1
255
  			j=i
256
  			l=0
257
  			if(nl==1)
258
  				@x=@l_margin
259
  				w=@w-@r_margin-@x
260
  				wmax=(w-2*@c_margin)*1000/@font_size
261
  			end
262
  			nl+=1
263
  			next
264
  		end
265
  		if(!ascii or c.chr==' ')
266
  			sep=i
267
      end
268
  		l+=(ascii ? cw[c.chr] : 1000) || 0
269
  		if(l>wmax)
270
  			#Automatic line break
271
  			if(sep==-1 or i==j)
272
  				if(@x>@l_margin)
273
  					#Move to next line
274
  					@x=@l_margin
275
  					@y+=h
276
  					w=@w-@r_margin-@x
277
  					wmax=(w-2*@c_margin)*1000/@font_size
278
  					i+=1
279
  					nl+=1
280
  					next
281
  				end
282
  				if(i==j)
283
  					i+=ascii ? 1 : 2
284
          end
285
  				Cell(w,h,s[j,i-j],0,2,'',fill,link)
286
  			else
287
  				Cell(w,h,s[j,sep-j],0,2,'',fill,link)
288
  				i=(s[sep].chr==' ') ? sep+1 : sep
289
  			end
290
  			sep=-1
291
  			j=i
292
  			l=0
293
  			if(nl==1)
294
  				@x=@l_margin
295
  				w=@w-@r_margin-@x
296
  				wmax=(w-2*@c_margin)*1000/@font_size
297
  			end
298
  			nl+=1
299
  		else
300
  			i+=ascii ? 1 : 2
301
      end
302
  	end
303
  	#Last chunk
304
  	if(i!=j)
305
  		Cell(l*@font_size/1000.0,h,s[j,i-j],0,0,'',fill,link)
306
    end
307
  end
308

    
309
private
310

    
311
  def putfonts()
312
  	nf=@n
313
    @diffs.each do |diff|
314
  		#Encodings
315
  		newobj()
316
  		out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['+diff+']>>')
317
  		out('endobj')
318
  	end
319
  	# mqr=get_magic_quotes_runtime()
320
  	# set_magic_quotes_runtime(0)
321
    @font_files.each_pair do |file, info|
322
  		#Font file embedding
323
  		newobj()
324
  		@font_files[file]['n']=@n
325
  		if(defined('FPDF_FONTPATH'))
326
  			file=FPDF_FONTPATH+file
327
      end
328
  		size=filesize(file)
329
  		if(!size)
330
  			Error('Font file not found')
331
      end
332
  		out('<</Length '+size)
333
  		if(file[-2]=='.z')
334
  			out('/Filter /FlateDecode')
335
      end
336
  		out('/Length1 '+info['length1'])
337
  		if(not info['length2'].nil?)
338
  			out('/Length2 '+info['length2']+' /Length3 0')
339
      end
340
  		out('>>')
341
  		f=fopen(file,'rb')
342
  		putstream(fread(f,size))
343
  		fclose(f)
344
  		out('endobj')
345
  	end
346
  	# set_magic_quotes_runtime(mqr)
347
    @fonts.each_pair do |k, font|
348
  		#Font objects
349
  		newobj()
350
  		@fonts[k]['n']=@n
351
  		out('<</Type /Font')
352
  		if(font['type']=='Type0')
353
  			putType0(font)
354
  		else
355
  			name=font['name']
356
  			out('/BaseFont /'+name)
357
  			if(font['type']=='core')
358
  				#Standard font
359
  				out('/Subtype /Type1')
360
  				if(name!='Symbol' and name!='ZapfDingbats')
361
  					out('/Encoding /WinAnsiEncoding')
362
  				end
363
  			else
364
  				#Additional font
365
  				out('/Subtype /'+font['type'])
366
  				out('/FirstChar 32')
367
  				out('/LastChar 255')
368
  				out('/Widths '+(@n+1)+' 0 R')
369
  				out('/FontDescriptor '+(@n+2)+' 0 R')
370
  				if(font['enc'])
371
  					if(not font['diff'].nil?)
372
  						out('/Encoding '+(nf+font['diff'])+' 0 R')
373
  					else
374
  						out('/Encoding /WinAnsiEncoding')
375
            end
376
  				end
377
  			end
378
  			out('>>')
379
  			out('endobj')
380
  			if(font['type']!='core')
381
  				#Widths
382
  				newobj()
383
  				cw=font['cw']
384
  				s='['
385
          32.upto(255) do |i|
386
  					s+=cw[i.chr]+' '
387
          end
388
  				out(s+']')
389
  				out('endobj')
390
  				#Descriptor
391
  				newobj()
392
  				s='<</Type /FontDescriptor /FontName /'+name
393
  				font['desc'].each_pair do |k, v|  				
394
  					s+=' /'+k+' '+v
395
          end
396
  				file=font['file']
397
  				if(file)
398
  					s+=' /FontFile'+(font['type']=='Type1' ? '' : '2')+' '+@font_files[file]['n']+' 0 R'
399
          end
400
  				out(s+'>>')
401
  				out('endobj')
402
  			end
403
  		end
404
  	end
405
  end
406
  
407
  def putType0(font)
408
  	#Type0
409
  	out('/Subtype /Type0')
410
  	out('/BaseFont /'+font['name']+'-'+font['CMap'])
411
  	out('/Encoding /'+font['CMap'])
412
  	out('/DescendantFonts ['+(@n+1).to_s+' 0 R]')
413
  	out('>>')
414
  	out('endobj')
415
  	#CIDFont
416
  	newobj()
417
  	out('<</Type /Font')
418
  	out('/Subtype /CIDFontType0')
419
  	out('/BaseFont /'+font['name'])
420
  	out('/CIDSystemInfo <</Registry (Adobe) /Ordering ('+font['registry']['ordering']+') /Supplement '+font['registry']['supplement'].to_s+'>>')
421
  	out('/FontDescriptor '+(@n+1).to_s+' 0 R')
422
  	if(font['CMap']=='KSCms-UHC-HW-H')
423
  		w='8094 8190 500'
424
  	else
425
  		w='1 ['
426
  		font['cw'].keys.sort.each {|key|
427
  		  w+=font['cw'][key].to_s + " "
428
  # ActionController::Base::logger.debug key.to_s
429
  # ActionController::Base::logger.debug font['cw'][key].to_s
430
  		}
431
  		w +=']'
432
    end
433
  	out('/W ['+w+']>>')
434
  	out('endobj')
435
  	#Font descriptor
436
  	newobj()
437
  	out('<</Type /FontDescriptor')
438
  	out('/FontName /'+font['name'])
439
  	out('/Flags 6')
440
  	out('/FontBBox [0 -200 1000 900]')
441
  	out('/ItalicAngle 0')
442
  	out('/Ascent 800')
443
  	out('/Descent -200')
444
  	out('/CapHeight 800')
445
  	out('/StemV 50')
446
  	out('>>')
447
  	out('endobj')
448
  end
449
end