summaryrefslogtreecommitdiffstats
path: root/vendor/plugins/rfpdf
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/plugins/rfpdf')
-rw-r--r--vendor/plugins/rfpdf/CHANGELOG13
-rw-r--r--vendor/plugins/rfpdf/MIT-LICENSE20
-rw-r--r--vendor/plugins/rfpdf/README99
-rw-r--r--vendor/plugins/rfpdf/init.rb3
-rw-r--r--vendor/plugins/rfpdf/lib/rfpdf.rb31
-rw-r--r--vendor/plugins/rfpdf/lib/rfpdf/bookmark.rb99
-rw-r--r--vendor/plugins/rfpdf/lib/rfpdf/chinese.rb473
-rw-r--r--vendor/plugins/rfpdf/lib/rfpdf/errors.rb4
-rw-r--r--vendor/plugins/rfpdf/lib/rfpdf/fpdf.rb1550
-rw-r--r--vendor/plugins/rfpdf/lib/rfpdf/fpdf_eps.rb139
-rw-r--r--vendor/plugins/rfpdf/lib/rfpdf/japanese.rb468
-rw-r--r--vendor/plugins/rfpdf/lib/rfpdf/korean.rb436
-rw-r--r--vendor/plugins/rfpdf/lib/rfpdf/makefont.rb1787
-rw-r--r--vendor/plugins/rfpdf/lib/rfpdf/rfpdf.rb346
-rw-r--r--vendor/plugins/rfpdf/lib/rfpdf/view.rb75
-rw-r--r--vendor/plugins/rfpdf/test/test_helper.rb1
16 files changed, 5544 insertions, 0 deletions
diff --git a/vendor/plugins/rfpdf/CHANGELOG b/vendor/plugins/rfpdf/CHANGELOG
new file mode 100644
index 000000000..6822b8364
--- /dev/null
+++ b/vendor/plugins/rfpdf/CHANGELOG
@@ -0,0 +1,13 @@
+1.00 Added view template functionality
+1.10 Added Chinese support
+1.11 Added Japanese support
+1.12 Added Korean support
+1.13 Updated to fpdf.rb 1.53d.
+ Added makefont and fpdf_eps.
+ Handle \n at the beginning of a string in MultiCell.
+ Tried to fix clipping issue in MultiCell - still needs some work.
+1.14 2006-09-26
+* Added support for @options_for_rfpdf hash for configuration:
+ * Added :filename option in this hash
+If you're using the same settings for @options_for_rfpdf often, you might want to
+put your assignment in a before_filter (perhaps overriding :filename, etc in your actions).
diff --git a/vendor/plugins/rfpdf/MIT-LICENSE b/vendor/plugins/rfpdf/MIT-LICENSE
new file mode 100644
index 000000000..f39a79dc0
--- /dev/null
+++ b/vendor/plugins/rfpdf/MIT-LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2006 4ssoM LLC <www.4ssoM.com>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOa AND
+NONINFRINGEMENT. IN NO EVENT SaALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file
diff --git a/vendor/plugins/rfpdf/README b/vendor/plugins/rfpdf/README
new file mode 100644
index 000000000..9db19075b
--- /dev/null
+++ b/vendor/plugins/rfpdf/README
@@ -0,0 +1,99 @@
+= RFPDF Template Plugin
+
+A template plugin allowing the inclusion of ERB-enabled RFPDF template files.
+
+== Example .rb method Usage
+
+In the controller, something like:
+
+ def mypdf
+ pdf = FPDF.new()
+
+ #
+ # Chinese
+ #
+ pdf.extend(PDF_Chinese)
+ pdf.AddPage
+ pdf.AddBig5Font
+ pdf.SetFont('Big5','',18)
+ pdf.Write(5, '²{®É®ð·Å 18 C Àã«× 83 %')
+ icBig5 = Iconv.new('Big5', 'UTF-8')
+ pdf.Write(15, icBig5.iconv("宋体 should be working"))
+ send_data pdf.Output, :filename => "something.pdf", :type => "application/pdf"
+ end
+
+== Example .rfdf Usage
+
+In the controller, something like:
+
+ def mypdf
+ @options_for_rfpdf ||= {}
+ @options_for_rfpdf[:file_name] = "nice_looking.pdf"
+ end
+
+In the layout (make sure this is the only item in the layout):
+<%= @content_for_layout %>
+
+In the view (mypdf.rfpdf):
+
+<%
+ pdf = FPDF.new()
+ #
+ # Chinese
+ #
+ pdf.extend(PDF_Chinese)
+ pdf.AddPage
+ pdf.AddBig5Font
+ pdf.SetFont('Big5','',18)
+ pdf.Write(5, '²{®É®ð·Å 18 C Àã«× 83 %')
+ icBig5 = Iconv.new('Big5', 'UTF-8')
+ pdf.Write(15, icBig5.iconv("宋体 should be working"))
+
+ #
+ # Japanese
+ #
+ pdf.extend(PDF_Japanese)
+ pdf.AddSJISFont();
+ pdf.AddPage();
+ pdf.SetFont('SJIS','',18);
+ pdf.Write(5,'9ÉñåéÇÃåˆäJÉeÉXÉgÇåoǃPHP 3.0ÇÕ1998îN6åéÇ…åˆéÆÇ…ÉäÉäÅ[ÉXÇ≥ÇÍNjǵÇΩÅB');
+ icSJIS = Iconv.new('SJIS', 'UTF-8')
+ pdf.Write(15, icSJIS.iconv("これはテキストである should be working"))
+
+ #
+ # Korean
+ #
+ pdf.extend(PDF_Korean)
+ pdf.AddUHCFont();
+ pdf.AddPage();
+ pdf.SetFont('UHC','',18);
+ pdf.Write(5,'PHP 3.0Àº 1998³â 6¿ù¿¡ °ø½ÄÀûÀ¸·Î ¸±¸®ÁîµÇ¾ú´Ù. °ø°³ÀûÀÎ Å×½ºÆ® ÀÌÈľà 9°³¿ù¸¸À̾ú´Ù.');
+ icUHC = Iconv.new('UHC', 'UTF-8')
+ pdf.Write(15, icUHC.iconv("이것은 원본 이다"))
+
+ #
+ # English
+ #
+ pdf.AddPage();
+ pdf.SetFont('Arial', '', 10)
+ pdf.Write(5, "should be working")
+%>
+<%= pdf.Output() %>
+
+
+== Configuring
+
+You can configure Rfpdf by using an @options_for_rfpdf hash in your controllers.
+
+Here are a few options:
+
+:filename (default: action_name.pdf)
+ Filename of PDF to generate
+
+Note: If you're using the same settings for @options_for_rfpdf often, you might want to
+put your assignment in a before_filter (perhaps overriding :filename, etc in your actions).
+
+== Problems
+
+Layouts and partials are currently not supported; just need
+to wrap the PDF generation differently.
diff --git a/vendor/plugins/rfpdf/init.rb b/vendor/plugins/rfpdf/init.rb
new file mode 100644
index 000000000..7e51d9eba
--- /dev/null
+++ b/vendor/plugins/rfpdf/init.rb
@@ -0,0 +1,3 @@
+require 'rfpdf'
+
+ActionView::Base::register_template_handler 'rfpdf', RFPDF::View \ No newline at end of file
diff --git a/vendor/plugins/rfpdf/lib/rfpdf.rb b/vendor/plugins/rfpdf/lib/rfpdf.rb
new file mode 100644
index 000000000..9fc0683ef
--- /dev/null
+++ b/vendor/plugins/rfpdf/lib/rfpdf.rb
@@ -0,0 +1,31 @@
+# Copyright (c) 2006 4ssoM LLC <www.4ssoM.com>
+#
+# The MIT License
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+$LOAD_PATH.unshift(File.dirname(__FILE__))
+
+require 'rfpdf/errors'
+require 'rfpdf/view'
+require 'rfpdf/fpdf'
+require 'rfpdf/rfpdf'
+require 'rfpdf/chinese'
+require 'rfpdf/japanese'
+require 'rfpdf/korean'
diff --git a/vendor/plugins/rfpdf/lib/rfpdf/bookmark.rb b/vendor/plugins/rfpdf/lib/rfpdf/bookmark.rb
new file mode 100644
index 000000000..a04ccd18d
--- /dev/null
+++ b/vendor/plugins/rfpdf/lib/rfpdf/bookmark.rb
@@ -0,0 +1,99 @@
+# Translation of the bookmark class from the PHP FPDF script from Olivier Plathey
+# Translated by Sylvain Lafleur and ?? with the help of Brian Ollenberger
+#
+# First added in 1.53b
+#
+# Usage is as follows:
+#
+# require 'fpdf'
+# require 'bookmark'
+# pdf = FPDF.new
+# pdf.extend(PDF_Bookmark)
+#
+# This allows it to be combined with other extensions, such as the Chinese
+# module.
+
+module PDF_Bookmark
+ def PDF_Bookmark.extend_object(o)
+ o.instance_eval('@outlines,@OutlineRoot=[],0')
+ super(o)
+ end
+
+ def Bookmark(txt,level=0,y=0)
+ y=self.GetY() if y==-1
+ @outlines.push({'t'=>txt,'l'=>level,'y'=>y,'p'=>self.PageNo()})
+ end
+
+ def putbookmarks
+ @nb=@outlines.size
+ return if @nb==0
+ lru=[]
+ level=0
+ @outlines.each_index do |i|
+ o=@outlines[i]
+ if o['l']>0
+ parent=lru[o['l']-1]
+ # Set parent and last pointers
+ @outlines[i]['parent']=parent
+ @outlines[parent]['last']=i
+ if o['l']>level
+ # Level increasing: set first pointer
+ @outlines[parent]['first']=i
+ end
+ else
+ @outlines[i]['parent']=@nb
+ end
+ if o['l']<=level and i>0
+ # Set prev and next pointers
+ prev=lru[o['l']]
+ @outlines[prev]['next']=i
+ @outlines[i]['prev']=prev
+ end
+ lru[o['l']]=i
+ level=o['l']
+ end
+ # Outline items
+ n=@n+1
+ @outlines.each_index do |i|
+ o=@outlines[i]
+ newobj
+ out('<</Title '+(textstring(o['t'])))
+ out('/Parent '+(n+o['parent']).to_s+' 0 R')
+ if o['prev']
+ out('/Prev '+(n+o['prev']).to_s+' 0 R')
+ end
+ if o['next']
+ out('/Next '+(n+o['next']).to_s+' 0 R')
+ end
+ if o['first']
+ out('/First '+(n+o['first']).to_s+' 0 R')
+ end
+ if o['last']
+ out('/Last '+(n+o['last']).to_s+' 0 R')
+ end
+ out(sprintf('/Dest [%d 0 R /XYZ 0 %.2f
+null]',1+2*o['p'],(@h-o['y'])*@k))
+ out('/Count 0>>')
+ out('endobj')
+ end
+ # Outline root
+ newobj
+ @OutlineRoot=@n
+ out('<</Type /Outlines /First '+n.to_s+' 0 R')
+ out('/Last '+(n+lru[0]).to_s+' 0 R>>')
+ out('endobj')
+ end
+
+ def putresources
+ super
+ putbookmarks
+ end
+
+ def putcatalog
+ super
+ if not @outlines.empty?
+ out('/Outlines '+@OutlineRoot.to_s+' 0 R')
+ out('/PageMode /UseOutlines')
+ end
+ end
+end
diff --git a/vendor/plugins/rfpdf/lib/rfpdf/chinese.rb b/vendor/plugins/rfpdf/lib/rfpdf/chinese.rb
new file mode 100644
index 000000000..731d582a2
--- /dev/null
+++ b/vendor/plugins/rfpdf/lib/rfpdf/chinese.rb
@@ -0,0 +1,473 @@
+# Copyright (c) 2006 4ssoM LLC <www.4ssoM.com>
+# 1.12 contributed by Ed Moss.
+#
+# The MIT License
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# This is direct port of chinese.php
+#
+# Chinese PDF support.
+#
+# Usage is as follows:
+#
+# require 'fpdf'
+# require 'chinese'
+# pdf = FPDF.new
+# pdf.extend(PDF_Chinese)
+#
+# This allows it to be combined with other extensions, such as the bookmark
+# module.
+
+module PDF_Chinese
+
+ Big5_widths={' '=>250,'!'=>250,'"'=>408,'#'=>668,''=>490,'%'=>875,'&'=>698,'\''=>250,
+ '('=>240,')'=>240,'*'=>417,'+'=>667,','=>250,'-'=>313,'.'=>250,'/'=>520,'0'=>500,'1'=>500,
+ '2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>250,''=>250,
+ '<'=>667,'='=>667,'>'=>667,'?'=>396,'@'=>921,'A'=>677,'B'=>615,'C'=>719,'D'=>760,'E'=>625,
+ 'F'=>552,'G'=>771,'H'=>802,'I'=>354,'J'=>354,'K'=>781,'L'=>604,'M'=>927,'N'=>750,'O'=>823,
+ 'P'=>563,'Q'=>823,'R'=>729,'S'=>542,'T'=>698,'U'=>771,'V'=>729,'W'=>948,'X'=>771,'Y'=>677,
+ 'Z'=>635,'['=>344,'\\'=>520,']'=>344,'^'=>469,'_'=>500,'`'=>250,'a'=>469,'b'=>521,'c'=>427,
+ 'd'=>521,'e'=>438,'f'=>271,'g'=>469,'h'=>531,'i'=>250,'j'=>250,'k'=>458,'l'=>240,'m'=>802,
+ 'n'=>531,'o'=>500,'p'=>521,'q'=>521,'r'=>365,'s'=>333,'t'=>292,'u'=>521,'v'=>458,'w'=>677,
+ 'x'=>479,'y'=>458,'z'=>427,'{'=>480,'|'=>496,'end'=>480,'~'=>667}
+
+ GB_widths={' '=>207,'!'=>270,'"'=>342,'#'=>467,''=>462,'%'=>797,'&'=>710,'\''=>239,
+ '('=>374,')'=>374,'*'=>423,'+'=>605,','=>238,'-'=>375,'.'=>238,'/'=>334,'0'=>462,'1'=>462,
+ '2'=>462,'3'=>462,'4'=>462,'5'=>462,'6'=>462,'7'=>462,'8'=>462,'9'=>462,':'=>238,''=>238,
+ '<'=>605,'='=>605,'>'=>605,'?'=>344,'@'=>748,'A'=>684,'B'=>560,'C'=>695,'D'=>739,'E'=>563,
+ 'F'=>511,'G'=>729,'H'=>793,'I'=>318,'J'=>312,'K'=>666,'L'=>526,'M'=>896,'N'=>758,'O'=>772,
+ 'P'=>544,'Q'=>772,'R'=>628,'S'=>465,'T'=>607,'U'=>753,'V'=>711,'W'=>972,'X'=>647,'Y'=>620,
+ 'Z'=>607,'['=>374,'\\'=>333,']'=>374,'^'=>606,'_'=>500,'`'=>239,'a'=>417,'b'=>503,'c'=>427,
+ 'd'=>529,'e'=>415,'f'=>264,'g'=>444,'h'=>518,'i'=>241,'j'=>230,'k'=>495,'l'=>228,'m'=>793,
+ 'n'=>527,'o'=>524,'p'=>524,'q'=>504,'r'=>338,'s'=>336,'t'=>277,'u'=>517,'v'=>450,'w'=>652,
+ 'x'=>466,'y'=>452,'z'=>407,'{'=>370,'|'=>258,'end'=>370,'~'=>605}
+
+ def AddCIDFont(family,style,name,cw,cMap,registry)
+#ActionController::Base::logger.debug registry.to_a.join(":").to_s
+ fontkey=family.downcase+style.upcase
+ unless @fonts[fontkey].nil?
+ Error("Font already added: family style")
+ end
+ i=@fonts.length+1
+ name=name.gsub(' ','')
+ @fonts[fontkey]={'i'=>i,'type'=>'Type0','name'=>name,'up'=>-130,'ut'=>40,'cw'=>cw, 'CMap'=>cMap,'registry'=>registry}
+ end
+
+ def AddCIDFonts(family,name,cw,cMap,registry)
+ AddCIDFont(family,'',name,cw,cMap,registry)
+ AddCIDFont(family,'B',name+',Bold',cw,cMap,registry)
+ AddCIDFont(family,'I',name+',Italic',cw,cMap,registry)
+ AddCIDFont(family,'BI',name+',BoldItalic',cw,cMap,registry)
+ end
+
+ def AddBig5Font(family='Big5',name='MSungStd-Light-Acro')
+ #Add Big5 font with proportional Latin
+ cw=Big5_widths
+ cMap='ETenms-B5-H'
+ registry={'ordering'=>'CNS1','supplement'=>0}
+#ActionController::Base::logger.debug registry.to_a.join(":").to_s
+ AddCIDFonts(family,name,cw,cMap,registry)
+ end
+
+ def AddBig5hwFont(family='Big5-hw',name='MSungStd-Light-Acro')
+ #Add Big5 font with half-witdh Latin
+ cw = {}
+ 32.upto(126) do |i|
+ cw[i.chr]=500
+ end
+ cMap='ETen-B5-H'
+ registry={'ordering'=>'CNS1','supplement'=>0}
+ AddCIDFonts(family,name,cw,cMap,registry)
+ end
+
+ def AddGBFont(family='GB',name='STSongStd-Light-Acro')
+ #Add GB font with proportional Latin
+ cw=GB_widths
+ cMap='GBKp-EUC-H'
+ registry={'ordering'=>'GB1','supplement'=>2}
+ AddCIDFonts(family,name,cw,cMap,registry)
+ end
+
+ def AddGBhwFont(family='GB-hw',name='STSongStd-Light-Acro')
+ #Add GB font with half-width Latin
+ 32.upto(126) do |i|
+ cw[i.chr]=500
+ end
+ cMap='GBK-EUC-H'
+ registry={'ordering'=>'GB1','supplement'=>2}
+ AddCIDFonts(family,name,cw,cMap,registry)
+ end
+
+ def GetStringWidth(s)
+ if(@CurrentFont['type']=='Type0')
+ return GetMBStringWidth(s)
+ else
+ return super(s)
+ end
+ end
+
+ def GetMBStringWidth(s)
+ #Multi-byte version of GetStringWidth()
+ l=0
+ cw=@CurrentFont['cw']
+ nb=s.length
+ i=0
+ while(i<nb)
+ c=s[i]
+ if(c<128)
+ l+=cw[c.chr]
+ i+=1
+ else
+ l+=1000
+ i+=2
+ end
+ end
+ return l*@FontSize/1000
+ end
+
+ def MultiCell(w,h,txt,border=0,align='L',fill=0)
+ if(@CurrentFont['type']=='Type0')
+ MBMultiCell(w,h,txt,border,align,fill)
+ else
+ super(w,h,txt,border,align,fill)
+ end
+ end
+
+ def MBMultiCell(w,h,txt,border=0,align='L',fill=0)
+ #Multi-byte version of MultiCell()
+ cw=@CurrentFont['cw']
+ if(w==0)
+ w=@w-@rMargin-@x
+ end
+ wmax=(w-2*@cMargin)*1000/@FontSize
+ s=txt.gsub("\r",'')
+ nb=s.length
+ if(nb>0 and s[nb-1]=="\n")
+ nb-=1
+ end
+ b=0
+ if(border)
+ if(border==1)
+ border='LTRB'
+ b='LRT'
+ b2='LR'
+ else
+ b2=''
+ if(border.index('L').nil?)
+ b2+='L'
+ end
+ if(border.index('R').nil?)
+ b2+='R'
+ end
+ b=border.index('T').nil? ? b2+'T' : b2
+ end
+ end
+ sep=-1
+ i=0
+ j=0
+ l=0
+ nl=1
+ while(i<nb)
+ #Get next character
+ c=s[i]
+ #Check if ASCII or MB
+ ascii=(c<128)
+ if(c=="\n")
+ #Explicit line break
+ Cell(w,h,s[j,i-j],b,2,align,fill)
+ i+=1
+ sep=-1
+ j=i
+ l=0
+ nl+=1
+ if(border and nl==2)
+ b=b2
+ end
+ next
+ end
+ if(!ascii)
+ sep=i
+ ls=l
+ elsif(c==' ')
+ sep=i
+ ls=l
+ end
+ l+=ascii ? cw[c.chr] : 1000
+ if(l>wmax)
+ #Automatic line break
+ if(sep==-1 or i==j)
+ if(i==j)
+ i+=ascii ? 1 : 2
+ end
+ Cell(w,h,s[j,i-j],b,2,align,fill)
+ else
+ Cell(w,h,s[j,sep-j],b,2,align,fill)
+ i=(s[sep]==' ') ? sep+1 : sep
+ end
+ sep=-1
+ j=i
+ l=0
+# nl+=1
+ if(border and nl==2)
+ b=b2
+ end
+ else
+ i+=ascii ? 1 : 2
+ end
+ end
+ #Last chunk
+ if(border and not border.index('B').nil?)
+ b+='B'
+ end
+ Cell(w,h,s[j,i-j],b,2,align,fill)
+ @x=@lMargin
+ end
+
+ def Write(h,txt,link='')
+ if(@CurrentFont['type']=='Type0')
+ MBWrite(h,txt,link)
+ else
+ super(h,txt,link)
+ end
+ end
+
+ def MBWrite(h,txt,link)
+ #Multi-byte version of Write()
+ cw=@CurrentFont['cw']
+ w=@w-@rMargin-@x
+ wmax=(w-2*@cMargin)*1000/@FontSize
+ s=txt.gsub("\r",'')
+ nb=s.length
+ sep=-1
+ i=0
+ j=0
+ l=0
+ nl=1
+ while(i<nb)
+ #Get next character
+ c=s[i]
+ #Check if ASCII or MB
+ ascii=(c<128)
+ if(c=="\n")
+ #Explicit line break
+ Cell(w,h,s[j,i-j],0,2,'',0,link)
+ i+=1
+ sep=-1
+ j=i
+ l=0
+ if(nl==1)
+ @x=@lMargin
+ w=@w-@rMargin-@x
+ wmax=(w-2*@cMargin)*1000/@FontSize
+ end
+ nl+=1
+ next
+ end
+ if(!ascii or c==' ')
+ sep=i
+ end
+ l+=ascii ? cw[c.chr] : 1000
+ if(l>wmax)
+ #Automatic line break
+ if(sep==-1 or i==j)
+ if(@x>@lMargin)
+ #Move to next line
+ @x=@lMargin
+ @y+=h
+ w=@w-@rMargin-@x
+ wmax=(w-2*@cMargin)*1000/@FontSize
+ i+=1
+ nl+=1
+ next
+ end
+ if(i==j)
+ i+=ascii ? 1 : 2
+ end
+ Cell(w,h,s[j,i-j],0,2,'',0,link)
+ else
+ Cell(w,h,s[j,sep-j],0,2,'',0,link)
+ i=(s[sep]==' ') ? sep+1 : sep
+ end
+ sep=-1
+ j=i
+ l=0
+ if(nl==1)
+ @x=@lMargin
+ w=@w-@rMargin-@x
+ wmax=(w-2*@cMargin)*1000/@FontSize
+ end
+ nl+=1
+ else
+ i+=ascii ? 1 : 2
+ end
+ end
+ #Last chunk
+ if(i!=j)
+ Cell(l/1000*@FontSize,h,s[j,i-j],0,0,'',0,link)
+ end
+ end
+
+private
+
+ def putfonts()
+ nf=@n
+ @diffs.each do |diff|
+ #Encodings
+ newobj()
+ out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['+diff+']>>')
+ out('endobj')
+ end
+ # mqr=get_magic_quotes_runtime()
+ # set_magic_quotes_runtime(0)
+ @FontFiles.each_pair do |file, info|
+ #Font file embedding
+ newobj()
+ @FontFiles[file]['n']=@n
+ if(defined('FPDF_FONTPATH'))
+ file=FPDF_FONTPATH+file
+ end
+ size=filesize(file)
+ if(!size)
+ Error('Font file not found')
+ end
+ out('<</Length '+size)
+ if(file[-2]=='.z')
+ out('/Filter /FlateDecode')
+ end
+ out('/Length1 '+info['length1'])
+ unless info['length2'].nil?
+ out('/Length2 '+info['length2']+' /Length3 0')
+ end
+ out('>>')
+ f=fopen(file,'rb')
+ putstream(fread(f,size))
+ fclose(f)
+ out('endobj')
+ end
+#
+ # set_magic_quotes_runtime(mqr)
+#
+ @fonts.each_pair do |k, font|
+ #Font objects
+ newobj()
+ @fonts[k]['n']=@n
+ out('<</Type /Font')
+ if(font['type']=='Type0')
+ putType0(font)
+ else
+ name=font['name']
+ out('/BaseFont /'+name)
+ if(font['type']=='core')
+ #Standard font
+ out('/Subtype /Type1')
+ if(name!='Symbol' and name!='ZapfDingbats')
+ out('/Encoding /WinAnsiEncoding')
+ end
+ else
+ #Additional font
+ out('/Subtype /'+font['type'])
+ out('/FirstChar 32')
+ out('/LastChar 255')
+ out('/Widths '+(@n+1)+' 0 R')
+ out('/FontDescriptor '+(@n+2)+' 0 R')
+ if(font['enc'])
+ if !font['diff'].nil?
+ out('/Encoding '+(nf+font['diff'])+' 0 R')
+ else
+ out('/Encoding /WinAnsiEncoding')
+ end
+ end
+ end
+ out('>>')
+ out('endobj')
+ if(font['type']!='core')
+ #Widths
+ newobj()
+ cw=font['cw']
+ s='['
+ 32.upto(255) do |i|
+ s+=cw[i.chr]+' '
+ end
+ out(s+']')
+ out('endobj')
+ #Descriptor
+ newobj()
+ s='<</Type /FontDescriptor /FontName /'+name
+ font['desc'].each_pair do |k, v|
+ s+=' /'+k+' '+v
+ end
+ file=font['file']
+ if(file)
+ s+=' /FontFile'+(font['type']=='Type1' ? '' : '2')+' '+@FontFiles[file]['n']+' 0 R'
+ end
+ out(s+'>>')
+ out('endobj')
+ end
+ end
+ end
+ end
+
+ def putType0(font)
+ #Type0
+ out('/Subtype /Type0')
+ out('/BaseFont /'+font['name']+'-'+font['CMap'])
+ out('/Encoding /'+font['CMap'])
+ out('/DescendantFonts ['+(@n+1).to_s+' 0 R]')
+ out('>>')
+ out('endobj')
+ #CIDFont
+ newobj()
+ out('<</Type /Font')
+ out('/Subtype /CIDFontType0')
+ out('/BaseFont /'+font['name'])
+ out('/CIDSystemInfo <</Registry '+textstring('Adobe')+' /Ordering '+textstring(font['registry']['ordering'])+' /Supplement '+font['registry']['supplement'].to_s+'>>')
+ out('/FontDescriptor '+(@n+1).to_s+' 0 R')
+ if(font['CMap']=='ETen-B5-H')
+ w='13648 13742 500'
+ elsif(font['CMap']=='GBK-EUC-H')
+ w='814 907 500 7716 [500]'
+ else
+ # ActionController::Base::logger.debug font['cw'].keys.sort.join(' ').to_s
+ # ActionController::Base::logger.debug font['cw'].values.join(' ').to_s
+ w='1 ['
+ font['cw'].keys.sort.each {|key|
+ w+=font['cw'][key].to_s + " "
+# ActionController::Base::logger.debug key.to_s
+# ActionController::Base::logger.debug font['cw'][key].to_s
+ }
+ w +=']'
+ end
+ out('/W ['+w+']>>')
+ out('endobj')
+ #Font descriptor
+ newobj()
+ out('<</Type /FontDescriptor')
+ out('/FontName /'+font['name'])
+ out('/Flags 6')
+ out('/FontBBox [0 -200 1000 900]')
+ out('/ItalicAngle 0')
+ out('/Ascent 800')
+ out('/Descent -200')
+ out('/CapHeight 800')
+ out('/StemV 50')
+ out('>>')
+ out('endobj')
+ end
+end
diff --git a/vendor/plugins/rfpdf/lib/rfpdf/errors.rb b/vendor/plugins/rfpdf/lib/rfpdf/errors.rb
new file mode 100644
index 000000000..2be2dae16
--- /dev/null
+++ b/vendor/plugins/rfpdf/lib/rfpdf/errors.rb
@@ -0,0 +1,4 @@
+module RFPDF
+ class GenerationError < StandardError #:nodoc:
+ end
+end \ No newline at end of file
diff --git a/vendor/plugins/rfpdf/lib/rfpdf/fpdf.rb b/vendor/plugins/rfpdf/lib/rfpdf/fpdf.rb
new file mode 100644
index 000000000..ad52e9e62
--- /dev/null
+++ b/vendor/plugins/rfpdf/lib/rfpdf/fpdf.rb
@@ -0,0 +1,1550 @@
+# Ruby FPDF 1.53d
+# FPDF 1.53 by Olivier Plathey ported to Ruby by Brian Ollenberger
+# Copyright 2005 Brian Ollenberger
+# Please retain this entire copyright notice. If you distribute any
+# modifications, place an additional comment here that clearly indicates
+# that it was modified. You may (but are not send any useful modifications that you make
+# back to me at http://zeropluszero.com/software/fpdf/
+
+# Bug fixes, examples, external fonts, JPEG support, and upgrade to version
+# 1.53 contributed by Kim Shrier.
+#
+# Bookmark support contributed by Sylvain Lafleur.
+#
+# EPS support contributed by Thiago Jackiw, ported from the PHP version by Valentin Schmidt.
+#
+# Bookmarks contributed by Sylvain Lafleur.
+#
+# 1.53 contributed by Ed Moss
+# Handle '\n' at the beginning of a string
+# Bookmarks contributed by Sylvain Lafleur.
+
+require 'date'
+require 'zlib'
+
+class FPDF
+ FPDF_VERSION = '1.53d'
+
+ Charwidths = {
+ 'courier'=>[600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600],
+
+ 'courierB'=>[600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600],
+
+ 'courierI'=>[600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600],
+
+ 'courierBI'=>[600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600],
+
+ 'helvetica'=>[278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 355, 556, 556, 889, 667, 191, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 278, 278, 584, 584, 584, 556, 1015, 667, 667, 722, 722, 667, 611, 778, 722, 278, 500, 667, 556, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 278, 278, 278, 469, 556, 333, 556, 556, 500, 556, 556, 278, 556, 556, 222, 222, 500, 222, 833, 556, 556, 556, 556, 333, 500, 278, 556, 500, 722, 500, 500, 500, 334, 260, 334, 584, 350, 556, 350, 222, 556, 333, 1000, 556, 556, 333, 1000, 667, 333, 1000, 350, 611, 350, 350, 222, 222, 333, 333, 350, 556, 1000, 333, 1000, 500, 333, 944, 350, 500, 667, 278, 333, 556, 556, 556, 556, 260, 556, 333, 737, 370, 556, 584, 333, 737, 333, 400, 584, 333, 333, 333, 556, 537, 278, 333, 333, 365, 556, 834, 834, 834, 611, 667, 667, 667, 667, 667, 667, 1000, 722, 667, 667, 667, 667, 278, 278, 278, 278, 722, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611, 556, 556, 556, 556, 556, 556, 889, 500, 556, 556, 556, 556, 278, 278, 278, 278, 556, 556, 556, 556, 556, 556, 556, 584, 611, 556, 556, 556, 556, 500, 556, 500],
+
+ 'helveticaB'=>[278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 333, 474, 556, 556, 889, 722, 238, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 333, 333, 584, 584, 584, 611, 975, 722, 722, 722, 722, 667, 611, 778, 722, 278, 556, 722, 611, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 333, 278, 333, 584, 556, 333, 556, 611, 556, 611, 556, 333, 611, 611, 278, 278, 556, 278, 889, 611, 611, 611, 611, 389, 556, 333, 611, 556, 778, 556, 556, 500, 389, 280, 389, 584, 350, 556, 350, 278, 556, 500, 1000, 556, 556, 333, 1000, 667, 333, 1000, 350, 611, 350, 350, 278, 278, 500, 500, 350, 556, 1000, 333, 1000, 556, 333, 944, 350, 500, 667, 278, 333, 556, 556, 556, 556, 280, 556, 333, 737, 370, 556, 584, 333, 737, 333, 400, 584, 333, 333, 333, 611, 556, 278, 333, 333, 365, 556, 834, 834, 834, 611, 722, 722, 722, 722, 722, 722, 1000, 722, 667, 667, 667, 667, 278, 278, 278, 278, 722, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611, 556, 556, 556, 556, 556, 556, 889, 556, 556, 556, 556, 556, 278, 278, 278, 278, 611, 611, 611, 611, 611, 611, 611, 584, 611, 611, 611, 611, 611, 556, 611, 556],
+
+ 'helveticaI'=>[278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 355, 556, 556, 889, 667, 191, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 278, 278, 584, 584, 584, 556, 1015, 667, 667, 722, 722, 667, 611, 778, 722, 278, 500, 667, 556, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 278, 278, 278, 469, 556, 333, 556, 556, 500, 556, 556, 278, 556, 556, 222, 222, 500, 222, 833, 556, 556, 556, 556, 333, 500, 278, 556, 500, 722, 500, 500, 500, 334, 260, 334, 584, 350, 556, 350, 222, 556, 333, 1000, 556, 556, 333, 1000, 667, 333, 1000, 350, 611, 350, 350, 222, 222, 333, 333, 350, 556, 1000, 333, 1000, 500, 333, 944, 350, 500, 667, 278, 333, 556, 556, 556, 556, 260, 556, 333, 737, 370, 556, 584, 333, 737, 333, 400, 584, 333, 333, 333, 556, 537, 278, 333, 333, 365, 556, 834, 834, 834, 611, 667, 667, 667, 667, 667, 667, 1000, 722, 667, 667, 667, 667, 278, 278, 278, 278, 722, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611, 556, 556, 556, 556, 556, 556, 889, 500, 556, 556, 556, 556, 278, 278, 278, 278, 556, 556, 556, 556, 556, 556, 556, 584, 611, 556, 556, 556, 556, 500, 556, 500],
+
+ 'helveticaBI'=>[278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 333, 474, 556, 556, 889, 722, 238, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 333, 333, 584, 584, 584, 611, 975, 722, 722, 722, 722, 667, 611, 778, 722, 278, 556, 722, 611, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 333, 278, 333, 584, 556, 333, 556, 611, 556, 611, 556, 333, 611, 611, 278, 278, 556, 278, 889, 611, 611, 611, 611, 389, 556, 333, 611, 556, 778, 556, 556, 500, 389, 280, 389, 584, 350, 556, 350, 278, 556, 500, 1000, 556, 556, 333, 1000, 667, 333, 1000, 350, 611, 350, 350, 278, 278, 500, 500, 350, 556, 1000, 333, 1000, 556, 333, 944, 350, 500, 667, 278, 333, 556, 556, 556, 556, 280, 556, 333, 737, 370, 556, 584, 333, 737, 333, 400, 584, 333, 333, 333, 611, 556, 278, 333, 333, 365, 556, 834, 834, 834, 611, 722, 722, 722, 722, 722, 722, 1000, 722, 667, 667, 667, 667, 278, 278, 278, 278, 722, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611, 556, 556, 556, 556, 556, 556, 889, 556, 556, 556, 556, 556, 278, 278, 278, 278, 611, 611, 611, 611, 611, 611, 611, 584, 611, 611, 611, 611, 611, 556, 611, 556],
+
+ 'times'=>[250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 333, 408, 500, 500, 833, 778, 180, 333, 333, 500, 564, 250, 333, 250, 278, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 278, 564, 564, 564, 444, 921, 722, 667, 667, 722, 611, 556, 722, 722, 333, 389, 722, 611, 889, 722, 722, 556, 722, 667, 556, 611, 722, 722, 944, 722, 722, 611, 333, 278, 333, 469, 500, 333, 444, 500, 444, 500, 444, 333, 500, 500, 278, 278, 500, 278, 778, 500, 500, 500, 500, 333, 389, 278, 500, 500, 722, 500, 500, 444, 480, 200, 480, 541, 350, 500, 350, 333, 500, 444, 1000, 500, 500, 333, 1000, 556, 333, 889, 350, 611, 350, 350, 333, 333, 444, 444, 350, 500, 1000, 333, 980, 389, 333, 722, 350, 444, 722, 250, 333, 500, 500, 500, 500, 200, 500, 333, 760, 276, 500, 564, 333, 760, 333, 400, 564, 300, 300, 333, 500, 453, 250, 333, 300, 310, 500, 750, 750, 750, 444, 722, 722, 722, 722, 722, 722, 889, 667, 611, 611, 611, 611, 333, 333, 333, 333, 722, 722, 722, 722, 722, 722, 722, 564, 722, 722, 722, 722, 722, 722, 556, 500, 444, 444, 444, 444, 444, 444, 667, 444, 444, 444, 444, 444, 278, 278, 278, 278, 500, 500, 500, 500, 500, 500, 500, 564, 500, 500, 500, 500, 500, 500, 500, 500],
+
+ 'timesB'=>[250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 333, 555, 500, 500, 1000, 833, 278, 333, 333, 500, 570, 250, 333, 250, 278, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 333, 570, 570, 570, 500, 930, 722, 667, 722, 722, 667, 611, 778, 778, 389, 500, 778, 667, 944, 722, 778, 611, 778, 722, 556, 667, 722, 722, 1000, 722, 722, 667, 333, 278, 333, 581, 500, 333, 500, 556, 444, 556, 444, 333, 500, 556, 278, 333, 556, 278, 833, 556, 500, 556, 556, 444, 389, 333, 556, 500, 722, 500, 500, 444, 394, 220, 394, 520, 350, 500, 350, 333, 500, 500, 1000, 500, 500, 333, 1000, 556, 333, 1000, 350, 667, 350, 350, 333, 333, 500, 500, 350, 500, 1000, 333, 1000, 389, 333, 722, 350, 444, 722, 250, 333, 500, 500, 500, 500, 220, 500, 333, 747, 300, 500, 570, 333, 747, 333, 400, 570, 300, 300, 333, 556, 540, 250, 333, 300, 330, 500, 750, 750, 750, 500, 722, 722, 722, 722, 722, 722, 1000, 722, 667, 667, 667, 667, 389, 389, 389, 389, 722, 722, 778, 778, 778, 778, 778, 570, 778, 722, 722, 722, 722, 722, 611, 556, 500, 500, 500, 500, 500, 500, 722, 444, 444, 444, 444, 444, 278, 278, 278, 278, 500, 556, 500, 500, 500, 500, 500, 570, 500, 556, 556, 556, 556, 500, 556, 500],
+
+ 'timesI'=>[250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 333, 420, 500, 500, 833, 778, 214, 333, 333, 500, 675, 250, 333, 250, 278, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 333, 675, 675, 675, 500, 920, 611, 611, 667, 722, 611, 611, 722, 722, 333, 444, 667, 556, 833, 667, 722, 611, 722, 611, 500, 556, 722, 611, 833, 611, 556, 556, 389, 278, 389, 422, 500, 333, 500, 500, 444, 500, 444, 278, 500, 500, 278, 278, 444, 278, 722, 500, 500, 500, 500, 389, 389, 278, 500, 444, 667, 444, 444, 389, 400, 275, 400, 541, 350, 500, 350, 333, 500, 556, 889, 500, 500, 333, 1000, 500, 333, 944, 350, 556, 350, 350, 333, 333, 556, 556, 350, 500, 889, 333, 980, 389, 333, 667, 350, 389, 556, 250, 389, 500, 500, 500, 500, 275, 500, 333, 760, 276, 500, 675, 333, 760, 333, 400, 675, 300, 300, 333, 500, 523, 250, 333, 300, 310, 500, 750, 750, 750, 500, 611, 611, 611, 611, 611, 611, 889, 667, 611, 611, 611, 611, 333, 333, 333, 333, 722, 667, 722, 722, 722, 722, 722, 675, 722, 722, 722, 722, 722, 556, 611, 500, 500, 500, 500, 500, 500, 500, 667, 444, 444, 444, 444, 444, 278, 278, 278, 278, 500, 500, 500, 500, 500, 500, 500, 675, 500, 500, 500, 500, 500, 444, 500, 444],
+
+ 'timesBI'=>[250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 389, 555, 500, 500, 833, 778, 278, 333, 333, 500, 570, 250, 333, 250, 278, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 333, 570, 570, 570, 500, 832, 667, 667, 667, 722, 667, 667, 722, 778, 389, 500, 667, 611, 889, 722, 722, 611, 722, 667, 556, 611, 722, 667, 889, 667, 611, 611, 333, 278, 333, 570, 500, 333, 500, 500, 444, 500, 444, 333, 500, 556, 278, 278, 500, 278, 778, 556, 500, 500, 500, 389, 389, 278, 556, 444, 667, 500, 444, 389, 348, 220, 348, 570, 350, 500, 350, 333, 500, 500, 1000, 500, 500, 333, 1000, 556, 333, 944, 350, 611, 350, 350, 333, 333, 500, 500, 350, 500, 1000, 333, 1000, 389, 333, 722, 350, 389, 611, 250, 389, 500, 500, 500, 500, 220, 500, 333, 747, 266, 500, 606, 333, 747, 333, 400, 570, 300, 300, 333, 576, 500, 250, 333, 300, 300, 500, 750, 750, 750, 500, 667, 667, 667, 667, 667, 667, 944, 667, 667, 667, 667, 667, 389, 389, 389, 389, 722, 722, 722, 722, 722, 722, 722, 570, 722, 722, 722, 722, 722, 611, 611, 500, 500, 500, 500, 500, 500, 500, 722, 444, 444, 444, 444, 444, 278, 278, 278, 278, 500, 556, 500, 500, 500, 500, 500, 570, 500, 556, 556, 556, 556, 444, 500, 444],
+
+ 'symbol'=>[250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 333, 713, 500, 549, 833, 778, 439, 333, 333, 500, 549, 250, 549, 250, 278, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 278, 549, 549, 549, 444, 549, 722, 667, 722, 612, 611, 763, 603, 722, 333, 631, 722, 686, 889, 722, 722, 768, 741, 556, 592, 611, 690, 439, 768, 645, 795, 611, 333, 863, 333, 658, 500, 500, 631, 549, 549, 494, 439, 521, 411, 603, 329, 603, 549, 549, 576, 521, 549, 549, 521, 549, 603, 439, 576, 713, 686, 493, 686, 494, 480, 200, 480, 549, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 750, 620, 247, 549, 167, 713, 500, 753, 753, 753, 753, 1042, 987, 603, 987, 603, 400, 549, 411, 549, 549, 713, 494, 460, 549, 549, 549, 549, 1000, 603, 1000, 658, 823, 686, 795, 987, 768, 768, 823, 768, 768, 713, 713, 713, 713, 713, 713, 713, 768, 713, 790, 790, 890, 823, 549, 250, 713, 603, 603, 1042, 987, 603, 987, 603, 494, 329, 790, 790, 786, 713, 384, 384, 384, 384, 384, 384, 494, 494, 494, 494, 0, 329, 274, 686, 686, 686, 384, 384, 384, 384, 384, 384, 494, 494, 494, 0],
+
+ 'zapfdingbats'=>[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 278, 974, 961, 974, 980, 719, 789, 790, 791, 690, 960, 939, 549, 855, 911, 933, 911, 945, 974, 755, 846, 762, 761, 571, 677, 763, 760, 759, 754, 494, 552, 537, 577, 692, 786, 788, 788, 790, 793, 794, 816, 823, 789, 841, 823, 833, 816, 831, 923, 744, 723, 749, 790, 792, 695, 776, 768, 792, 759, 707, 708, 682, 701, 826, 815, 789, 789, 707, 687, 696, 689, 786, 787, 713, 791, 785, 791, 873, 761, 762, 762, 759, 759, 892, 892, 788, 784, 438, 138, 277, 415, 392, 392, 668, 668, 0, 390, 390, 317, 317, 276, 276, 509, 509, 410, 410, 234, 234, 334, 334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 732, 544, 544, 910, 667, 760, 760, 776, 595, 694, 626, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 894, 838, 1016, 458, 748, 924, 748, 918, 927, 928, 928, 834, 873, 828, 924, 924, 917, 930, 931, 463, 883, 836, 836, 867, 867, 696, 696, 874, 0, 874, 760, 946, 771, 865, 771, 888, 967, 888, 831, 873, 927, 970, 918, 0]
+ }
+
+ def initialize(orientation='P', unit='mm', format='A4')
+ # Initialization of properties
+ @page=0
+ @n=2
+ @buffer=''
+ @pages=[]
+ @OrientationChanges=[]
+ @state=0
+ @fonts={}
+ @FontFiles={}
+ @diffs=[]
+ @images={}
+ @links=[]
+ @PageLinks={}
+ @InFooter=false
+ @FontFamily=''
+ @FontStyle=''
+ @FontSizePt=12
+ @underline= false
+ @DrawColor='0 G'
+ @FillColor='0 g'
+ @TextColor='0 g'
+ @ColorFlag=false
+ @ws=0
+ @offsets=[]
+
+ # Standard fonts
+ @CoreFonts={}
+ @CoreFonts['courier']='Courier'
+ @CoreFonts['courierB']='Courier-Bold'
+ @CoreFonts['courierI']='Courier-Oblique'
+ @CoreFonts['courierBI']='Courier-BoldOblique'
+ @CoreFonts['helvetica']='Helvetica'
+ @CoreFonts['helveticaB']='Helvetica-Bold'
+ @CoreFonts['helveticaI']='Helvetica-Oblique'
+ @CoreFonts['helveticaBI']='Helvetica-BoldOblique'
+ @CoreFonts['times']='Times-Roman'
+ @CoreFonts['timesB']='Times-Bold'
+ @CoreFonts['timesI']='Times-Italic'
+ @CoreFonts['timesBI']='Times-BoldItalic'
+ @CoreFonts['symbol']='Symbol'
+ @CoreFonts['zapfdingbats']='ZapfDingbats'
+
+ # Scale factor
+ if unit=='pt'
+ @k=1
+ elsif unit=='mm'
+ @k=72/25.4
+ elsif unit=='cm'
+ @k=72/2.54;
+ elsif unit=='in'
+ @k=72
+ else
+ raise 'Incorrect unit: '+unit
+ end
+
+ # Page format
+ if format.is_a? String
+ format.downcase!
+ if format=='a3'
+ format=[841.89,1190.55]
+ elsif format=='a4'
+ format=[595.28,841.89]
+ elsif format=='a5'
+ format=[420.94,595.28]
+ elsif format=='letter'
+ format=[612,792]
+ elsif format=='legal'
+ format=[612,1008]
+ else
+ raise 'Unknown page format: '+format
+ end
+ @fwPt,@fhPt=format
+ else
+ @fwPt=format[0]*@k
+ @fhPt=format[1]*@k
+ end
+ @fw=@fwPt/@k;
+ @fh=@fhPt/@k;
+
+ # Page orientation
+ orientation.downcase!
+ if orientation=='p' or orientation=='portrait'
+ @DefOrientation='P'
+ @wPt=@fwPt
+ @hPt=@fhPt
+ elsif orientation=='l' or orientation=='landscape'
+ @DefOrientation='L'
+ @wPt=@fhPt
+ @hPt=@fwPt
+ else
+ raise 'Incorrect orientation: '+orientation
+ end
+ @CurOrientation=@DefOrientation
+ @w=@wPt/@k
+ @h=@hPt/@k
+
+ # Page margins (1 cm)
+ margin=28.35/@k
+ SetMargins(margin,margin)
+ # Interior cell margin (1 mm)
+ @cMargin=margin/10
+ # Line width (0.2 mm)
+ @LineWidth=0.567/@k
+ # Automatic page break
+ SetAutoPageBreak(true,2*margin)
+ # Full width display mode
+ SetDisplayMode('fullwidth')
+ # Enable compression
+ SetCompression(true)
+ # Set default PDF version number
+ @PDFVersion='1.3'
+ end
+
+ def SetMargins(left, top, right=-1)
+ # Set left, top and right margins
+ @lMargin=left
+ @tMargin=top
+ right=left if right==-1
+ @rMargin=right
+ end
+
+ def SetLeftMargin(margin)
+ # Set left margin
+ @lMargin=margin
+ @x=margin if @page>0 and @x<margin
+ end
+
+ def SetTopMargin(margin)
+ # Set top margin
+ @tMargin=margin
+ end
+
+ def SetRightMargin(margin)
+ #Set right margin
+ @rMargin=margin
+ end
+
+ def SetAutoPageBreak(auto, margin=0)
+ # Set auto page break mode and triggering margin
+ @AutoPageBreak=auto
+ @bMargin=margin
+ @PageBreakTrigger=@h-margin
+ end
+
+ def SetDisplayMode(zoom, layout='continuous')
+ # Set display mode in viewer
+ if zoom=='fullpage' or zoom=='fullwidth' or zoom=='real' or
+ zoom=='default' or not zoom.kind_of? String
+
+ @ZoomMode=zoom;
+ elsif zoom=='zoom'
+ @ZoomMode=layout
+ else
+ raise 'Incorrect zoom display mode: '+zoom
+ end
+ if layout=='single' or layout=='continuous' or layout=='two' or
+ layout=='default'
+
+ @LayoutMode=layout
+ elsif zoom!='zoom'
+ raise 'Incorrect layout display mode: '+layout
+ end
+ end
+
+ def SetCompression(compress)
+ # Set page compression
+ @compress = compress
+ end
+
+ def SetTitle(title)
+ # Title of document
+ @title=title
+ end
+
+ def SetSubject(subject)
+ # Subject of document
+ @subject=subject
+ end
+
+ def SetAuthor(author)
+ # Author of document
+ @author=author
+ end
+
+ def SetKeywords(keywords)
+ # Keywords of document
+ @keywords=keywords
+ end
+
+ def SetCreator(creator)
+ # Creator of document
+ @creator=creator
+ end
+
+ def AliasNbPages(aliasnb='{nb}')
+ # Define an alias for total number of pages
+ @AliasNbPages=aliasnb
+ end
+
+ def Error(msg)
+ raise 'FPDF error: '+msg
+ end
+
+ def Open
+ # Begin document
+ @state=1
+ end
+
+ def Close
+ # Terminate document
+ return if @state==3
+ self.AddPage if @page==0
+ # Page footer
+ @InFooter=true
+ self.Footer
+ @InFooter=false
+ # Close page
+ endpage
+ # Close document
+ enddoc
+ end
+
+ def AddPage(orientation='')
+ # Start a new page
+ self.Open if @state==0
+ family=@FontFamily
+ style=@FontStyle+(@underline ? 'U' : '')
+ size=@FontSizePt
+ lw=@LineWidth
+ dc=@DrawColor
+ fc=@FillColor
+ tc=@TextColor
+ cf=@ColorFlag
+ if @page>0
+ # Page footer
+ @InFooter=true
+ self.Footer
+ @InFooter=false
+ # Close page
+ endpage
+ end
+ # Start new page
+ beginpage(orientation)
+ # Set line cap style to square
+ out('2 J')
+ # Set line width
+ @LineWidth=lw
+ out(sprintf('%.2f w',lw*@k))
+ # Set font
+ SetFont(family,style,size) if family
+ # Set colors
+ @DrawColor=dc
+ out(dc) if dc!='0 G'
+ @FillColor=fc
+ out(fc) if fc!='0 g'
+ @TextColor=tc
+ @ColorFlag=cf
+ # Page header
+ self.Header
+ # Restore line width
+ if @LineWidth!=lw
+ @LineWidth=lw
+ out(sprintf('%.2f w',lw*@k))
+ end
+ # Restore font
+ self.SetFont(family,style,size) if family
+ # Restore colors
+ if @DrawColor!=dc
+ @DrawColor=dc
+ out(dc)
+ end
+ if @FillColor!=fc
+ @FillColor=fc
+ out(fc)
+ end
+ @TextColor=tc
+ @ColorFlag=cf
+ end
+
+ def Header
+ # To be implemented in your inherited class
+ end
+
+ def Footer
+ # To be implemented in your inherited class
+ end
+
+ def PageNo
+ # Get current page number
+ @page
+ end
+
+ def SetDrawColor(r,g=-1,b=-1)
+ # Set color for all stroking operations
+ if (r==0 and g==0 and b==0) or g==-1
+ @DrawColor=sprintf('%.3f G',r/255.0)
+ else
+ @DrawColor=sprintf('%.3f %.3f %.3f RG',r/255.0,g/255.0,b/255.0)
+ end
+ out(@DrawColor) if(@page>0)
+ end
+
+ def SetFillColor(r,g=-1,b=-1)
+ # Set color for all filling operations
+ if (r==0 and g==0 and b==0) or g==-1
+ @FillColor=sprintf('%.3f g',r/255.0)
+ else
+ @FillColor=sprintf('%.3f %.3f %.3f rg',r/255.0,g/255.0,b/255.0)
+ end
+ @ColorFlag=(@FillColor!=@TextColor)
+ out(@FillColor) if(@page>0)
+ end
+
+ def SetTextColor(r,g=-1,b=-1)
+ # Set color for text
+ if (r==0 and g==0 and b==0) or g==-1
+ @TextColor=sprintf('%.3f g',r/255.0)
+ else
+ @TextColor=sprintf('%.3f %.3f %.3f rg',r/255.0,g/255.0,b/255.0)
+ end
+ @ColorFlag=(@FillColor!=@TextColor)
+ end
+
+ def GetStringWidth(s)
+ # Get width of a string in the current font
+ cw=@CurrentFont['cw']
+ w=0
+ s.each_byte do |c|
+ w=w+cw[c]
+ end
+ w*@FontSize/1000.0
+ end
+
+ def SetLineWidth(width)
+ # Set line width
+ @LineWidth=width
+ out(sprintf('%.2f w',width*@k)) if @page>0
+ end
+
+ def Line(x1, y1, x2, y2)
+ # Draw a line
+ out(sprintf('%.2f %.2f m %.2f %.2f l S',
+ x1*@k,(@h-y1)*@k,x2*@k,(@h-y2)*@k))
+ end
+
+ def Rect(x, y, w, h, style='')
+ # Draw a rectangle
+ if style=='F'
+ op='f'
+ elsif style=='FD' or style=='DF'
+ op='B'
+ else
+ op='S'
+ end
+ out(sprintf('%.2f %.2f %.2f %.2f re %s', x*@k,(@h-y)*@k,w*@k,-h*@k,op))
+ end
+
+ def AddFont(family, style='', file='')
+ # Add a TrueType or Type1 font
+ family = family.downcase
+ family = 'helvetica' if family == 'arial'
+
+ style = style.upcase
+ style = 'BI' if style == 'IB'
+
+ fontkey = family + style
+
+ if @fonts.has_key?(fontkey)
+ self.Error("Font already added: #{family} #{style}")
+ end
+
+ file = family.gsub(' ', '') + style.downcase + '.rb' if file == ''
+
+ if self.class.const_defined? 'FPDF_FONTPATH'
+ if FPDF_FONTPATH[-1,1] == '/'
+ file = FPDF_FONTPATH + file
+ else
+ file = FPDF_FONTPATH + '/' + file
+ end
+ end
+
+ # Changed from "require file" to fix bug reported by Hans Allis.
+ load file
+
+ if FontDef.desc.nil?
+ self.Error("Could not include font definition file #{file}")
+ end
+
+ i = @fonts.length + 1
+
+ @fonts[fontkey] = {'i' => i,
+ 'type' => FontDef.type,
+ 'name' => FontDef.name,
+ 'desc' => FontDef.desc,
+ 'up' => FontDef.up,
+ 'ut' => FontDef.ut,
+ 'cw' => FontDef.cw,
+ 'enc' => FontDef.enc,
+ 'file' => FontDef.file
+ }
+
+ if FontDef.diff
+ # Search existing encodings
+ unless @diffs.include?(FontDef.diff)
+ @diffs.push(FontDef.diff)
+ @fonts[fontkey]['diff'] = @diffs.length - 1
+ end
+ end
+
+ if FontDef.file
+ if FontDef.type == 'TrueType'
+ @FontFiles[FontDef.file] = {'length1' => FontDef.originalsize}
+ else
+ @FontFiles[FontDef.file] = {'length1' => FontDef.size1, 'length2' => FontDef.size2}
+ end
+ end
+
+ return self
+ end
+
+ def SetFont(family, style='', size=0)
+ # Select a font; size given in points
+ family.downcase!
+ family=@FontFamily if family==''
+ if family=='arial'
+ family='helvetica'
+ elsif family=='symbol' or family=='zapfdingbats'
+ style=''
+ end
+ style.upcase!
+ unless style.index('U').nil?
+ @underline=true
+ style.gsub!('U','')
+ else
+ @underline=false;
+ end
+ style='BI' if style=='IB'
+ size=@FontSizePt if size==0
+ # Test if font is already selected
+ return if @FontFamily==family and
+ @FontStyle==style and @FontSizePt==size
+ # Test if used for the first time
+ fontkey=family+style
+ unless @fonts.has_key?(fontkey)
+ if @CoreFonts.has_key?(fontkey)
+ unless Charwidths.has_key?(fontkey)
+ raise 'Font unavailable'
+ end
+ @fonts[fontkey]={
+ 'i'=>@fonts.size,
+ 'type'=>'core',
+ 'name'=>@CoreFonts[fontkey],
+ 'up'=>-100,
+ 'ut'=>50,
+ 'cw'=>Charwidths[fontkey]}
+ else
+ raise 'Font unavailable'
+ end
+ end
+
+ #Select it
+ @FontFamily=family
+ @FontStyle=style;
+ @FontSizePt=size
+ @FontSize=size/@k;
+ @CurrentFont=@fonts[fontkey]
+ if @page>0
+ out(sprintf('BT /F%d %.2f Tf ET', @CurrentFont['i'], @FontSizePt))
+ end
+ end
+
+ def SetFontSize(size)
+ # Set font size in points
+ return if @FontSizePt==size
+ @FontSizePt=size
+ @FontSize=size/@k
+ if @page>0
+ out(sprintf('BT /F%d %.2f Tf ET',@CurrentFont['i'],@FontSizePt))
+ end
+ end
+
+ def AddLink
+ # Create a new internal link
+ @links.push([0, 0])
+ @links.size
+ end
+
+ def SetLink(link, y=0, page=-1)
+ # Set destination of internal link
+ y=@y if y==-1
+ page=@page if page==-1
+ @links[link]=[page, y]
+ end
+
+ def Link(x, y, w, h, link)
+ # Put a link on the page
+ @PageLinks[@page]=Array.new unless @PageLinks.has_key?(@Page)
+ @PageLinks[@page].push([x*@k,@hPt-y*@k,w*@k,h*@k,link])
+ end
+
+ def Text(x, y, txt)
+ # Output a string
+ txt.gsub!(')', '\\)')
+ txt.gsub!('(', '\\(')
+ txt.gsub!('\\', '\\\\')
+ s=sprintf('BT %.2f %.2f Td (%s) Tj ET',x*@k,(@h-y)*@k,txt);
+ s=s+' '+dounderline(x,y,txt) if @underline and txt!=''
+ s='q '+@TextColor+' '+s+' Q' if @ColorFlag
+ out(s)
+ end
+
+ def AcceptPageBreak
+ # Accept automatic page break or not
+ @AutoPageBreak
+ end
+
+ def Cell(w,h=0,txt='',border=0,ln=0,align='',fill=0,link='')
+ # Output a cell
+ if @y+h>@PageBreakTrigger and !@InFooter and self.AcceptPageBreak
+ # Automatic page break
+ x=@x
+ ws=@ws
+ if ws>0
+ @ws=0
+ out('0 Tw')
+ end
+ self.AddPage(@CurOrientation)
+ @x=x
+ if ws>0
+ @ws=ws
+ out(sprintf('%.3f Tw',ws*@k))
+ end
+ end
+ w=@w-@rMargin-@x if w==0
+ s=''
+ if fill==1 or border==1
+ if fill==1
+ op=(border==1) ? 'B' : 'f'
+ else
+ op='S'
+ end
+ s=sprintf('%.2f %.2f %.2f %.2f re %s ',@x*@k,(@h-@y)*@k,w*@k,-h*@k,op)
+ end
+ if border.is_a? String
+ x=@x
+ y=@y
+ unless border.index('L').nil?
+ s=s+sprintf('%.2f %.2f m %.2f %.2f l S ',
+ x*@k,(@h-y)*@k,x*@k,(@h-(y+h))*@k)
+ end
+ unless border.index('T').nil?
+ s=s+sprintf('%.2f %.2f m %.2f %.2f l S ',
+ x*@k,(@h-y)*@k,(x+w)*@k,(@h-y)*@k)
+ end
+ unless border.index('R').nil?
+ s=s+sprintf('%.2f %.2f m %.2f %.2f l S ',
+ (x+w)*@k,(@h-y)*@k,(x+w)*@k,(@h-(y+h))*@k)
+ end
+ unless border.index('B').nil?
+ s=s+sprintf('%.2f %.2f m %.2f %.2f l S ',
+ x*@k,(@h-(y+h))*@k,(x+w)*@k,(@h-(y+h))*@k)
+ end
+ end
+ if txt!=''
+ if align=='R'
+ dx=w-@cMargin-self.GetStringWidth(txt)
+ elsif align=='C'
+ dx=(w-self.GetStringWidth(txt))/2
+ else
+ dx=@cMargin
+ end
+ txt = txt.gsub(')', '\\)')
+ txt.gsub!('(', '\\(')
+ txt.gsub!('\\', '\\\\')
+ if @ColorFlag
+ s=s+'q '+@TextColor+' '
+ end
+ s=s+sprintf('BT %.2f %.2f Td (%s) Tj ET',
+ (@x+dx)*@k,(@h-(@y+0.5*h+0.3*@FontSize))*@k,txt)
+ s=s+' '+dounderline(@x+dx,@y+0.5*h+0.3*@FontSize,txt) if @underline
+ s=s+' Q' if @ColorFlag
+ if link and link != ''
+ Link(@x+dx,@y+0.5*h-0.5*@FontSize,GetStringWidth(txt),@FontSize,link)
+ end
+ end
+ out(s) if s
+ @lasth=h
+ if ln>0
+ # Go to next line
+ @y=@y+h
+ @x=@lMargin if ln==1
+ else
+ @x=@x+w
+ end
+ end
+
+ def MultiCell(w,h,txt,border=0,align='J',fill=0)
+ # Output text with automatic or explicit line breaks
+ cw=@CurrentFont['cw']
+ w=@w-@rMargin-@x if w==0
+ wmax=(w-2*@cMargin)*1000/@FontSize
+ s=txt.gsub('\r','')
+ nb=s.length
+ nb=nb-1 if nb>0 and s[nb-1].chr=='\n'
+ b=0
+ if border!=0
+ if border==1
+ border='LTRB'
+ b='LRT'
+ b2='LR'
+ else
+ b2=''
+ b2='L' unless border.index('L').nil?
+ b2=b2+'R' unless border.index('R').nil?
+ b=(not border.index('T').nil?) ? (b2+'T') : b2
+ end
+ end
+ sep=-1
+ i=0
+ j=0
+ l=0
+ ns=0
+ nl=1
+ while i<nb
+ # Get next character
+ c=s[i].chr
+ if c=="\n"
+ # Explicit line break
+ if @ws>0
+ @ws=0
+ out('0 Tw')
+ end
+#Ed Moss
+# Don't let i go negative
+ end_i = i == 0 ? 0 : i - 1
+ # Changed from s[j..i] to fix bug reported by Hans Allis.
+ self.Cell(w,h,s[j..end_i],b,2,align,fill)
+#
+ i=i+1
+ sep=-1
+ j=i
+ l=0
+ ns=0
+ nl=nl+1
+ b=b2 if border and nl==2
+ else
+ if c==' '
+ sep=i
+ ls=l
+ ns=ns+1
+ end
+ l=l+cw[c[0]]
+ if l>wmax
+ # Automatic line break
+ if sep==-1
+ i=i+1 if i==j
+ if @ws>0
+ @ws=0
+ out('0 Tw')
+ end
+ self.Cell(w,h,s[j..i],b,2,align,fill)
+#Ed Moss
+# Added so that it wouldn't print the last character of the string if it got close
+#FIXME 2006-07-18 Level=0 - but it still puts out an extra new line
+ i += 1
+#
+ else
+ if align=='J'
+ @ws=(ns>1) ? (wmax-ls)/1000.0*@FontSize/(ns-1) : 0
+ out(sprintf('%.3f Tw',@ws*@k))
+ end
+ self.Cell(w,h,s[j..sep],b,2,align,fill)
+ i=sep+1
+ end
+ sep=-1
+ j=i
+ l=0
+ ns=0
+ nl=nl+1
+ b=b2 if border and nl==2
+ else
+ i=i+1
+ end
+ end
+ end
+
+ # Last chunk
+ if @ws>0
+ @ws=0
+ out('0 Tw')
+ end
+ b=b+'B' if border!=0 and not border.index('B').nil?
+ self.Cell(w,h,s[j..i],b,2,align,fill)
+ @x=@lMargin
+ end
+
+ def Write(h,txt,link='')
+ # Output text in flowing mode
+ cw=@CurrentFont['cw']
+ w=@w-@rMargin-@x
+ wmax=(w-2*@cMargin)*1000/@FontSize
+ s=txt.gsub("\r",'')
+ nb=s.length
+ sep=-1
+ i=0
+ j=0
+ l=0
+ nl=1
+ while i<nb
+ # Get next character
+ c=s[i]
+ if c=="\n"[0]
+ # Explicit line break
+ self.Cell(w,h,s[j,i-j],0,2,'',0,link)
+ i=i+1
+ sep=-1
+ j=i
+ l=0
+ if nl==1
+ @x=@lMargin
+ w=@w-@rMargin-@x
+ wmax=(w-2*@cMargin)*1000/@FontSize
+ end
+ nl=nl+1
+ next
+ end
+ if c==' '[0]
+ sep=i
+ ls=l
+ end
+ l=l+cw[c];
+ if l>wmax
+ # Automatic line break
+ if sep==-1
+ if @x>@lMargin
+ # Move to next line
+ @x=@lMargin
+ @y=@y+h
+ w=@w-@rMargin-@x
+ wmax=(w-2*@cMargin)*1000/@FontSize
+ i=i+1
+ nl=nl+1
+ next
+ end
+ i=i+1 if i==j
+ self.Cell(w,h,s[j,i-j],0,2,'',0,link)
+ else
+ self.Cell(w,h,s[j,sep-j],0,2,'',0,link)
+ i=sep+1
+ end
+ sep=-1
+ j=i
+ l=0
+ if nl==1
+ @x=@lMargin
+ w=@w-@rMargin-@x
+ wmax=(w-2*@cMargin)*1000/@FontSize
+ end
+ nl=nl+1
+ else
+ i=i+1
+ end
+ end
+ # Last chunk
+ self.Cell(l/1000.0*@FontSize,h,s[j,i],0,0,'',0,link) if i!=j
+ end
+
+ def Image(file,x,y,w=0,h=0,type='',link='')
+ # Put an image on the page
+ unless @images.has_key?(file)
+ # First use of image, get info
+ if type==''
+ pos=file.rindex('.')
+ if pos.nil?
+ self.Error('Image file has no extension and no type was '+
+ 'specified: '+file)
+ end
+ type=file[pos+1..-1]
+ end
+ type.downcase!
+ if type=='jpg' or type=='jpeg'
+ info=parsejpg(file)
+ elsif type=='png'
+ info=parsepng(file)
+ else
+ self.Error('Unsupported image file type: '+type)
+ end
+ info['i']=@images.length+1
+ @images[file]=info
+ else
+ info=@images[file]
+ end
+#Ed Moss
+ if(w==0 && h==0)
+ #Put image at 72 dpi
+ w=info['w']/@k;
+ h=info['h']/@k;
+ end
+#
+ # Automatic width or height calculation
+ w=h*info['w']/info['h'] if w==0
+ h=w*info['h']/info['w'] if h==0
+ out(sprintf('q %.2f 0 0 %.2f %.2f %.2f cm /I%d Do Q',
+ w*@k,h*@k,x*@k,(@h-(y+h))*@k,info['i']))
+ Link(x,y,w,h,link) if link and link != ''
+ end
+
+ def Ln(h='')
+ # Line feed; default value is last cell height
+ @x=@lMargin
+ if h.kind_of?(String)
+ @y=@y+@lasth
+ else
+ @y=@y+h
+ end
+ end
+
+ def GetX
+ # Get x position
+ @x
+ end
+
+ def SetX(x)
+ # Set x position
+ if x>=0
+ @x=x
+ else
+ @x=@w+x
+ end
+ end
+
+ def GetY
+ # Get y position
+ @y
+ end
+
+ def SetY(y)
+ # Set y position and reset x
+ @x=@lMargin
+ if y>=0
+ @y=y
+ else
+ @y=@h+y
+ end
+ end
+
+ def SetXY(x,y)
+ # Set x and y positions
+ SetY(y)
+ SetX(x)
+ end
+
+ def Output(file=nil)
+ # Output PDF to file or return as a string
+
+ # Finish document if necessary
+ self.Close if(@state<3)
+
+ if file.nil?
+ # Return as a string
+ return @buffer
+ else
+ # Save file locally
+ open(file,'wb') do |f|
+ f.write(@buffer)
+ end
+ end
+ end
+
+ private
+
+ def putpages
+ nb=@page
+ unless @AliasNbPages.nil? or @AliasNbPages==''
+ # Replace number of pages
+ 1.upto(nb) do |n|
+ @pages[n].gsub!(@AliasNbPages,nb.to_s)
+ end
+ end
+ if @DefOrientation=='P'
+ wPt=@fwPt
+ hPt=@fhPt
+ else
+ wPt=@fhPt
+ hPt=@fwPt
+ end
+ filter=(@compress) ? '/Filter /FlateDecode ' : ''
+ 1.upto(nb) do |n|
+ # Page
+ newobj
+ out('<</Type /Page')
+ out('/Parent 1 0 R')
+ unless @OrientationChanges[n].nil?
+ out(sprintf('/MediaBox [0 0 %.2f %.2f]',hPt,wPt))
+ end
+ out('/Resources 2 0 R')
+ if @PageLinks[n]
+ # Links
+ annots='/Annots ['
+ @PageLinks[n].each do |pl|
+ rect=sprintf('%.2f %.2f %.2f %.2f',
+ pl[0],pl[1],pl[0]+pl[2],pl[1]-pl[3])
+ annots=annots+'<</Type /Annot /Subtype /Link /Rect ['+rect+
+ '] /Border [0 0 0] '
+ if pl[4].kind_of?(String)
+ annots=annots+'/A <</S /URI /URI '+textstring(pl[4])+
+ '>>>>'
+ else
+ l=@links[pl[4]]
+ h=@OrientationChanges[l[0]].nil? ? hPt : wPt
+ annots=annots+sprintf(
+ '/Dest [%d 0 R /XYZ 0 %.2f null]>>',
+ 1+2*l[0],h-l[1]*@k)
+ end
+ end
+ out(annots+']')
+ end
+ out('/Contents '+(@n+1).to_s+' 0 R>>')
+ out('endobj')
+ # Page content
+ p=(@compress) ? Zlib::Deflate.deflate(@pages[n]) : @pages[n]
+ newobj
+ out('<<'+filter+'/Length '+p.length.to_s+'>>')
+ putstream(p)
+ out('endobj')
+ end
+ # Pages root
+ @offsets[1]=@buffer.length
+ out('1 0 obj')
+ out('<</Type /Pages')
+ kids='/Kids ['
+ nb.times do |i|
+ kids=kids+(3+2*i).to_s+' 0 R '
+ end
+ out(kids+']')
+ out('/Count '+nb.to_s)
+ out(sprintf('/MediaBox [0 0 %.2f %.2f]',wPt,hPt))
+ out('>>')
+ out('endobj')
+ end
+
+ def putfonts
+ nf=@n
+ @diffs.each do |diff|
+ # Encodings
+ newobj
+ out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences '+
+ '['+diff+']>>')
+ out('endobj')
+ end
+
+ @FontFiles.each do |file, info|
+ # Font file embedding
+ newobj
+ @FontFiles[file]['n'] = @n
+
+ if self.class.const_defined? 'FPDF_FONTPATH' then
+ if FPDF_FONTPATH[-1,1] == '/' then
+ file = FPDF_FONTPATH + file
+ else
+ file = FPDF_FONTPATH + '/' + file
+ end
+ end
+
+ size = File.size(file)
+ unless File.exists?(file)
+ Error('Font file not found')
+ end
+
+ out('<</Length ' + size.to_s)
+
+ if file[-2, 2] == '.z' then
+ out('/Filter /FlateDecode')
+ end
+ out('/Length1 ' + info['length1'])
+ out('/Length2 ' + info['length2'] + ' /Length3 0') if info['length2']
+ out('>>')
+ open(file, 'rb') do |f|
+ putstream(f.read())
+ end
+ out('endobj')
+ end
+
+ file = 0
+ @fonts.each do |k, font|
+ # Font objects
+ @fonts[k]['n']=@n+1
+ type=font['type']
+ name=font['name']
+ if type=='core'
+ # Standard font
+ newobj
+ out('<</Type /Font')
+ out('/BaseFont /'+name)
+ out('/Subtype /Type1')
+ if name!='Symbol' and name!='ZapfDingbats'
+ out('/Encoding /WinAnsiEncoding')
+ end
+ out('>>')
+ out('endobj')
+ elsif type=='Type1' or type=='TrueType'
+ # Additional Type1 or TrueType font
+ newobj
+ out('<</Type /Font')
+ out('/BaseFont /'+name)
+ out('/Subtype /'+type)
+ out('/FirstChar 32 /LastChar 255')
+ out('/Widths '+(@n+1).to_s+' 0 R')
+ out('/FontDescriptor '+(@n+2).to_s+' 0 R')
+ if font['enc'] and font['enc'] != ''
+ unless font['diff'].nil?
+ out('/Encoding '+(nf+font['diff']).to_s+' 0 R')
+ else
+ out('/Encoding /WinAnsiEncoding')
+ end
+ end
+ out('>>')
+ out('endobj')
+ # Widths
+ newobj
+ cw=font['cw']
+ s='['
+ 32.upto(255) do |i|
+ s << cw[i].to_s+' '
+ end
+ out(s+']')
+ out('endobj')
+ # Descriptor
+ newobj
+ s='<</Type /FontDescriptor /FontName /'+name
+ font['desc'].each do |k, v|
+ s << ' /'+k+' '+v
+ end
+ file=font['file']
+ if file
+ s << ' /FontFile'+(type=='Type1' ? '' : '2')+' '+
+ @FontFiles[file]['n'].to_s+' 0 R'
+ end
+ out(s+'>>')
+ out('endobj')
+ else
+ # Allow for additional types
+ mtd='put'+type.downcase
+ unless self.respond_to?(mtd)
+ self.Error('Unsupported font type: '+type)
+ end
+ self.send(mtd, font)
+ end
+ end
+ end
+
+ def putimages
+ filter=(@compress) ? '/Filter /FlateDecode ' : ''
+ @images.each do |file, info|
+ newobj
+ @images[file]['n']=@n
+ out('<</Type /XObject')
+ out('/Subtype /Image')
+ out('/Width '+info['w'].to_s)
+ out('/Height '+info['h'].to_s)
+ if info['cs']=='Indexed'
+ out("/ColorSpace [/Indexed /DeviceRGB #{info['pal'].length/3-1} #{(@n+1)} 0 R]")
+ else
+ out('/ColorSpace /'+info['cs'])
+ if info['cs']=='DeviceCMYK'
+ out('/Decode [1 0 1 0 1 0 1 0]')
+ end
+ end
+ out('/BitsPerComponent '+info['bpc'].to_s)
+ out('/Filter /'+info['f']) if info['f']
+ unless info['parms'].nil?
+ out(info['parms'])
+ end
+ if info['trns'] and info['trns'].kind_of?(Array)
+ trns=''
+ info['trns'].length.times do |i|
+ trns=trns+info['trns'][i].to_s+' '+info['trns'][i].to_s+' '
+ end
+ out('/Mask ['+trns+']')
+ end
+ out('/Length '+info['data'].length.to_s+'>>')
+ putstream(info['data'])
+ @images[file]['data']=nil
+ out('endobj')
+ # Palette
+ if info['cs']=='Indexed'
+ newobj
+ pal=(@compress) ? Zlib::Deflate.deflate(info['pal']) : info['pal']
+ out('<<'+filter+'/Length '+pal.length.to_s+'>>')
+ putstream(pal)
+ out('endobj')
+ end
+ end
+ end
+
+ def putxobjectdict
+ @images.each_value do |image|
+ out('/I'+image['i'].to_s+' '+image['n'].to_s+' 0 R')
+ end
+ end
+
+ def putresourcedict
+ out('/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]')
+ out('/Font <<')
+ @fonts.each_value do |font|
+ out('/F'+font['i'].to_s+' '+font['n'].to_s+' 0 R')
+ end
+ out('>>')
+ out('/XObject <<')
+ putxobjectdict
+ out('>>')
+ end
+
+ def putresources
+ putfonts
+ putimages
+ # Resource dictionary
+ @offsets[2]=@buffer.length
+ out('2 0 obj')
+ out('<<')
+ putresourcedict
+ out('>>')
+ out('endobj')
+ end
+
+ def putinfo
+ out('/Producer '+textstring('Ruby FPDF '+FPDF_VERSION));
+ unless @title.nil?
+ out('/Title '+textstring(@title))
+ end
+ unless @subject.nil?
+ out('/Subject '+textstring(@subject))
+ end
+ unless @author.nil?
+ out('/Author '+textstring(@author))
+ end
+ unless @keywords.nil?
+ out('/Keywords '+textstring(@keywords))
+ end
+ unless @creator.nil?
+ out('/Creator '+textstring(@creator))
+ end
+ out('/CreationDate '+textstring('D: '+DateTime.now.to_s))
+ end
+
+ def putcatalog
+ out('/Type /Catalog')
+ out('/Pages 1 0 R')
+ if @ZoomMode=='fullpage'
+ out('/OpenAction [3 0 R /Fit]')
+ elsif @ZoomMode=='fullwidth'
+ out('/OpenAction [3 0 R /FitH null]')
+ elsif @ZoomMode=='real'
+ out('/OpenAction [3 0 R /XYZ null null 1]')
+ elsif not @ZoomMode.kind_of?(String)
+ out('/OpenAction [3 0 R /XYZ null null '+(@ZoomMode/100)+']')
+ end
+
+ if @LayoutMode=='single'
+ out('/PageLayout /SinglePage')
+ elsif @LayoutMode=='continuous'
+ out('/PageLayout /OneColumn')
+ elsif @LayoutMode=='two'
+ out('/PageLayout /TwoColumnLeft')
+ end
+ end
+
+ def putheader
+ out('%PDF-'+@PDFVersion)
+ end
+
+ def puttrailer
+ out('/Size '+(@n+1).to_s)
+ out('/Root '+@n.to_s+' 0 R')
+ out('/Info '+(@n-1).to_s+' 0 R')
+ end
+
+ def enddoc
+ putheader
+ putpages
+ putresources
+ # Info
+ newobj
+ out('<<')
+ putinfo
+ out('>>')
+ out('endobj')
+ # Catalog
+ newobj
+ out('<<')
+ putcatalog
+ out('>>')
+ out('endobj')
+ # Cross-ref
+ o=@buffer.length
+ out('xref')
+ out('0 '+(@n+1).to_s)
+ out('0000000000 65535 f ')
+ 1.upto(@n) do |i|
+ out(sprintf('%010d 00000 n ',@offsets[i]))
+ end
+ # Trailer
+ out('trailer')
+ out('<<')
+ puttrailer
+ out('>>')
+ out('startxref')
+ out(o)
+ out('%%EOF')
+ state=3
+ end
+
+ def beginpage(orientation)
+ @page=@page+1
+ @pages[@page]=''
+ @state=2
+ @x=@lMargin
+ @y=@tMargin
+ @lasth=0
+ @FontFamily=''
+ # Page orientation
+ if orientation==''
+ orientation=@DefOrientation
+ else
+ orientation=orientation[0].chr.upcase
+ if orientation!=@DefOrientation
+ @OrientationChanges[@page]=true
+ end
+ end
+ if orientation!=@CurOrientation
+ # Change orientation
+ if orientation=='P'
+ @wPt=@fwPt
+ @hPt=@fhPt
+ @w=@fw
+ @h=@fh
+ else
+ @wPt=@fhPt
+ @hPt=@fwPt
+ @w=@fh
+ @h=@fw
+ end
+ @PageBreakTrigger=@h-@bMargin
+ @CurOrientation=orientation
+ end
+ end
+
+ def endpage
+ # End of page contents
+ @state=1
+ end
+
+ def newobj
+ # Begin a new object
+ @n=@n+1
+ @offsets[@n]=@buffer.length
+ out(@n.to_s+' 0 obj')
+ end
+
+ def dounderline(x,y,txt)
+ # Underline text
+ up=@CurrentFont['up']
+ ut=@CurrentFont['ut']
+ w=GetStringWidth(txt)+@ws*txt.count(' ')
+ sprintf('%.2f %.2f %.2f %.2f re f',
+ x*@k,(@h-(y-up/1000.0*@FontSize))*@k,w*@k,-ut/1000.0*@FontSizePt)
+ end
+
+ def parsejpg(file)
+ # Extract info from a JPEG file
+ a=extractjpginfo(file)
+ raise "Missing or incorrect JPEG file: #{file}" if a.nil?
+
+ if a['channels'].nil? || a['channels']==3 then
+ colspace='DeviceRGB'
+ elsif a['channels']==4 then
+ colspace='DeviceCMYK'
+ else
+ colspace='DeviceGray'
+ end
+ bpc= a['bits'] ? a['bits'].to_i : 8
+
+ # Read whole file
+ data = nil
+ open(file, 'rb') do |f|
+ data = f.read
+ end
+ return {'w'=>a['width'],'h'=>a['height'],'cs'=>colspace,'bpc'=>bpc,'f'=>'DCTDecode','data'=>data}
+ end
+
+ def parsepng(file)
+ # Extract info from a PNG file
+ f=open(file,'rb')
+ # Check signature
+ unless f.read(8)==137.chr+'PNG'+13.chr+10.chr+26.chr+10.chr
+ self.Error('Not a PNG file: '+file)
+ end
+ # Read header chunk
+ f.read(4)
+ if f.read(4)!='IHDR'
+ self.Error('Incorrect PNG file: '+file)
+ end
+ w=freadint(f)
+ h=freadint(f)
+ bpc=f.read(1)[0]
+ if bpc>8
+ self.Error('16-bit depth not supported: '+file)
+ end
+ ct=f.read(1)[0]
+ if ct==0
+ colspace='DeviceGray'
+ elsif ct==2
+ colspace='DeviceRGB'
+ elsif ct==3
+ colspace='Indexed'
+ else
+ self.Error('Alpha channel not supported: '+file)
+ end
+ if f.read(1)[0]!=0
+ self.Error('Unknown compression method: '+file)
+ end
+ if f.read(1)[0]!=0
+ self.Error('Unknown filter method: '+file)
+ end
+ if f.read(1)[0]!=0
+ self.Error('Interlacing not supported: '+file)
+ end
+ f.read(4)
+ parms='/DecodeParms <</Predictor 15 /Colors '+(ct==2 ? '3' : '1')+
+ ' /BitsPerComponent '+bpc.to_s+' /Columns '+w.to_s+'>>'
+ # Scan chunks looking for palette, transparency and image data
+ pal=''
+ trns=''
+ data=''
+ begin
+ n=freadint(f)
+ type=f.read(4)
+ if type=='PLTE'
+ # Read palette
+ pal=f.read(n)
+ f.read(4)
+ elsif type=='tRNS'
+ # Read transparency info
+ t=f.read(n)
+ if ct==0
+ trns=[t[1]]
+ elsif ct==2
+ trns=[t[1],t[3],t[5]]
+ else
+ pos=t.index(0)
+ trns=[pos] unless pos.nil?
+ end
+ f.read(4)
+ elsif type=='IDAT'
+ # Read image data block
+ data << f.read(n)
+ f.read(4)
+ elsif type=='IEND'
+ break
+ else
+ f.read(n+4)
+ end
+ end while n
+ if colspace=='Indexed' and pal==''
+ self.Error('Missing palette in '+file)
+ end
+ f.close
+ {'w'=>w,'h'=>h,'cs'=>colspace,'bpc'=>bpc,'f'=>'FlateDecode',
+ 'parms'=>parms,'pal'=>pal,'trns'=>trns,'data'=>data}
+ end
+
+ def freadint(f)
+ # Read a 4-byte integer from file
+ a = f.read(4).unpack('N')
+ return a[0]
+ end
+
+ def freadshort(f)
+ a = f.read(2).unpack('n')
+ return a[0]
+ end
+
+ def freadbyte(f)
+ a = f.read(1).unpack('C')
+ return a[0]
+ end
+
+ def textstring(s)
+ # Format a text string
+ '('+escape(s)+')'
+ end
+
+ def escape(s)
+ # Add \ before \, ( and )
+ s.gsub('\\','\\\\').gsub('(','\\(').gsub(')','\\)')
+ end
+
+ def putstream(s)
+ out('stream')
+ out(s)
+ out('endstream')
+ end
+
+ def out(s)
+ # Add a line to the document
+ if @state==2
+ @pages[@page]=@pages[@page]+s+"\n"
+ else
+ @buffer=@buffer+s.to_s+"\n"
+ end
+ end
+
+ # jpeg marker codes
+
+ M_SOF0 = 0xc0
+ M_SOF1 = 0xc1
+ M_SOF2 = 0xc2
+ M_SOF3 = 0xc3
+
+ M_SOF5 = 0xc5
+ M_SOF6 = 0xc6
+ M_SOF7 = 0xc7
+
+ M_SOF9 = 0xc9
+ M_SOF10 = 0xca
+ M_SOF11 = 0xcb
+
+ M_SOF13 = 0xcd
+ M_SOF14 = 0xce
+ M_SOF15 = 0xcf
+
+ M_SOI = 0xd8
+ M_EOI = 0xd9
+ M_SOS = 0xda
+
+ def extractjpginfo(file)
+ result = nil
+
+ open(file, "rb") do |f|
+ marker = jpegnextmarker(f)
+
+ if marker != M_SOI
+ return nil
+ end
+
+ while true
+ marker = jpegnextmarker(f)
+
+ case marker
+ when M_SOF0, M_SOF1, M_SOF2, M_SOF3,
+ M_SOF5, M_SOF6, M_SOF7, M_SOF9,
+ M_SOF10, M_SOF11, M_SOF13, M_SOF14,
+ M_SOF15 then
+
+ length = freadshort(f)
+
+ if result.nil?
+ result = {}
+
+ result['bits'] = freadbyte(f)
+ result['height'] = freadshort(f)
+ result['width'] = freadshort(f)
+ result['channels'] = freadbyte(f)
+
+ f.seek(length - 8, IO::SEEK_CUR)
+ else
+ f.seek(length - 2, IO::SEEK_CUR)
+ end
+ when M_SOS, M_EOI then
+ return result
+ else
+ length = freadshort(f)
+ f.seek(length - 2, IO::SEEK_CUR)
+ end
+ end
+ end
+ end
+
+ def jpegnextmarker(f)
+ while true
+ # look for 0xff
+ while (c = freadbyte(f)) != 0xff
+ end
+
+ c = freadbyte(f)
+
+ if c != 0
+ return c
+ end
+ end
+ end
+end
diff --git a/vendor/plugins/rfpdf/lib/rfpdf/fpdf_eps.rb b/vendor/plugins/rfpdf/lib/rfpdf/fpdf_eps.rb
new file mode 100644
index 000000000..c6a224310
--- /dev/null
+++ b/vendor/plugins/rfpdf/lib/rfpdf/fpdf_eps.rb
@@ -0,0 +1,139 @@
+# Information
+#
+# PDF_EPS class from Valentin Schmidt ported to ruby by Thiago Jackiw (tjackiw@gmail.com)
+# working for Mingle LLC (www.mingle.com)
+# Release Date: July 13th, 2006
+#
+# Description
+#
+# This script allows to embed vector-based Adobe Illustrator (AI) or AI-compatible EPS files.
+# Only vector drawing is supported, not text or bitmap. Although the script was successfully
+# tested with various AI format versions, best results are probably achieved with files that
+# were exported in the AI3 format (tested with Illustrator CS2, Freehand MX and Photoshop CS2).
+#
+# ImageEps(string file, float x, float y [, float w [, float h [, string link [, boolean useBoundingBox]]]])
+#
+# Same parameters as for regular FPDF::Image() method, with an additional one:
+#
+# useBoundingBox: specifies whether to position the bounding box (true) or the complete canvas (false)
+# at location (x,y). Default value is true.
+#
+# First added to the Ruby FPDF distribution in 1.53c
+#
+# Usage is as follows:
+#
+# require 'fpdf'
+# require 'fpdf_eps'
+# pdf = FPDF.new
+# pdf.extend(PDF_EPS)
+# pdf.ImageEps(...)
+#
+# This allows it to be combined with other extensions, such as the bookmark
+# module.
+
+module PDF_EPS
+ def ImageEps(file, x, y, w=0, h=0, link='', use_bounding_box=true)
+ data = nil
+ if File.exists?(file)
+ File.open(file, 'rb') do |f|
+ data = f.read()
+ end
+ else
+ Error('EPS file not found: '+file)
+ end
+
+ # Find BoundingBox param
+ regs = data.scan(/%%BoundingBox: [^\r\n]*/m)
+ regs << regs[0].gsub(/%%BoundingBox: /, '')
+ if regs.size > 1
+ tmp = regs[1].to_s.split(' ')
+ @x1 = tmp[0].to_i
+ @y1 = tmp[1].to_i
+ @x2 = tmp[2].to_i
+ @y2 = tmp[3].to_i
+ else
+ Error('No BoundingBox found in EPS file: '+file)
+ end
+ f_start = data.index('%%EndSetup')
+ f_start = data.index('%%EndProlog') if f_start === false
+ f_start = data.index('%%BoundingBox') if f_start === false
+
+ data = data.slice(f_start, data.length)
+
+ f_end = data.index('%%PageTrailer')
+ f_end = data.index('showpage') if f_end === false
+ data = data.slice(0, f_end) if f_end
+
+ # save the current graphic state
+ out('q')
+
+ k = @k
+
+ # Translate
+ if use_bounding_box
+ dx = x*k-@x1
+ dy = @hPt-@y2-y*k
+ else
+ dx = x*k
+ dy = -y*k
+ end
+ tm = [1,0,0,1,dx,dy]
+ out(sprintf('%.3f %.3f %.3f %.3f %.3f %.3f cm',
+ tm[0], tm[1], tm[2], tm[3], tm[4], tm[5]))
+
+ if w > 0
+ scale_x = w/((@x2-@x1)/k)
+ if h > 0
+ scale_y = h/((@y2-@y1)/k)
+ else
+ scale_y = scale_x
+ h = (@y2-@y1)/k * scale_y
+ end
+ else
+ if h > 0
+ scale_y = $h/((@y2-@y1)/$k)
+ scale_x = scale_y
+ w = (@x2-@x1)/k * scale_x
+ else
+ w = (@x2-@x1)/k
+ h = (@y2-@y1)/k
+ end
+ end
+
+ if !scale_x.nil?
+ # Scale
+ tm = [scale_x,0,0,scale_y,0,@hPt*(1-scale_y)]
+ out(sprintf('%.3f %.3f %.3f %.3f %.3f %.3f cm',
+ tm[0], tm[1], tm[2], tm[3], tm[4], tm[5]))
+ end
+
+ data.split(/\r\n|[\r\n]/).each do |line|
+ next if line == '' || line[0,1] == '%'
+ len = line.length
+ # next if (len > 2 && line[len-2,len] != ' ')
+ cmd = line[len-2,len].strip
+ case cmd
+ when 'm', 'l', 'v', 'y', 'c', 'k', 'K', 'g', 'G', 's', 'S', 'J', 'j', 'w', 'M', 'd':
+ out(line)
+
+ when 'L':
+ line[len-1,len]='l'
+ out(line)
+
+ when 'C':
+ line[len-1,len]='c'
+ out(line)
+
+ when 'f', 'F':
+ out('f*')
+
+ when 'b', 'B':
+ out(cmd + '*')
+ end
+ end
+
+ # restore previous graphic state
+ out('Q')
+ Link(x,y,w,h,link) if link
+ end
+end
diff --git a/vendor/plugins/rfpdf/lib/rfpdf/japanese.rb b/vendor/plugins/rfpdf/lib/rfpdf/japanese.rb
new file mode 100644
index 000000000..7340936bb
--- /dev/null
+++ b/vendor/plugins/rfpdf/lib/rfpdf/japanese.rb
@@ -0,0 +1,468 @@
+# Copyright (c) 2006 4ssoM LLC <www.4ssoM.com>
+# 1.12 contributed by Ed Moss.
+#
+# The MIT License
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# This is direct port of japanese.php
+#
+# Japanese PDF support.
+#
+# Usage is as follows:
+#
+# require 'fpdf'
+# require 'chinese'
+# pdf = FPDF.new
+# pdf.extend(PDF_Japanese)
+#
+# This allows it to be combined with other extensions, such as the bookmark
+# module.
+
+module PDF_Japanese
+
+ SJIS_widths={' ' => 278, '!' => 299, '"' => 353, '#' => 614, '$' => 614, '%' => 721, '&' => 735, '\'' => 216,
+ '(' => 323, ')' => 323, '*' => 449, '+' => 529, ',' => 219, '-' => 306, '.' => 219, '/' => 453, '0' => 614, '1' => 614,
+ '2' => 614, '3' => 614, '4' => 614, '5' => 614, '6' => 614, '7' => 614, '8' => 614, '9' => 614, ':' => 219, ';' => 219,
+ '<' => 529, '=' => 529, '>' => 529, '?' => 486, '@' => 744, 'A' => 646, 'B' => 604, 'C' => 617, 'D' => 681, 'E' => 567,
+ 'F' => 537, 'G' => 647, 'H' => 738, 'I' => 320, 'J' => 433, 'K' => 637, 'L' => 566, 'M' => 904, 'N' => 710, 'O' => 716,
+ 'P' => 605, 'Q' => 716, 'R' => 623, 'S' => 517, 'T' => 601, 'U' => 690, 'V' => 668, 'W' => 990, 'X' => 681, 'Y' => 634,
+ 'Z' => 578, '[' => 316, '\\' => 614, ']' => 316, '^' => 529, '_' => 500, '`' => 387, 'a' => 509, 'b' => 566, 'c' => 478,
+ 'd' => 565, 'e' => 503, 'f' => 337, 'g' => 549, 'h' => 580, 'i' => 275, 'j' => 266, 'k' => 544, 'l' => 276, 'm' => 854,
+ 'n' => 579, 'o' => 550, 'p' => 578, 'q' => 566, 'r' => 410, 's' => 444, 't' => 340, 'u' => 575, 'v' => 512, 'w' => 760,
+ 'x' => 503, 'y' => 529, 'z' => 453, '{' => 326, '|' => 380, '}' => 326, '~' => 387}
+
+ def AddCIDFont(family,style,name,cw,cMap,registry)
+ fontkey=family.downcase+style.upcase
+ unless @fonts[fontkey].nil?
+ Error("CID font already added: family style")
+ end
+ i=@fonts.length+1
+ @fonts[fontkey]={'i'=>i,'type'=>'Type0','name'=>name,'up'=>-120,'ut'=>40,'cw'=>cw,
+ 'CMap'=>cMap,'registry'=>registry}
+ end
+
+ def AddCIDFonts(family,name,cw,cMap,registry)
+ AddCIDFont(family,'',name,cw,cMap,registry)
+ AddCIDFont(family,'B',name+',Bold',cw,cMap,registry)
+ AddCIDFont(family,'I',name+',Italic',cw,cMap,registry)
+ AddCIDFont(family,'BI',name+',BoldItalic',cw,cMap,registry)
+ end
+
+ def AddSJISFont(family='SJIS')
+ #Add SJIS font with proportional Latin
+ name='KozMinPro-Regular-Acro'
+ cw=SJIS_widths
+ cMap='90msp-RKSJ-H'
+ registry={'ordering'=>'Japan1','supplement'=>2}
+ AddCIDFonts(family,name,cw,cMap,registry)
+ end
+
+ def AddSJIShwFont(family='SJIS-hw')
+ #Add SJIS font with half-width Latin
+ name='KozMinPro-Regular-Acro'
+ 32.upto(126) do |i|
+ cw[i.chr]=500
+ end
+ cMap='90ms-RKSJ-H'
+ registry={'ordering'=>'Japan1','supplement'=>2}
+ AddCIDFonts(family,name,cw,cMap,registry)
+ end
+
+ def GetStringWidth(s)
+ if(@CurrentFont['type']=='Type0')
+ return GetSJISStringWidth(s)
+ else
+ return super(s)
+ end
+ end
+
+ def GetSJISStringWidth(s)
+ #SJIS version of GetStringWidth()
+ l=0
+ cw=@CurrentFont['cw']
+ nb=s.length
+ i=0
+ while(i<nb)
+ o=s[i]
+ if(o<128)
+ #ASCII
+ l+=cw[o.chr]
+ i+=1
+ elsif(o>=161 and o<=223)
+ #Half-width katakana
+ l+=500
+ i+=1
+ else
+ #Full-width character
+ l+=1000
+ i+=2
+ end
+ end
+ return l*@FontSize/1000
+ end
+
+ def MultiCell(w,h,txt,border=0,align='L',fill=0)
+ if(@CurrentFont['type']=='Type0')
+ SJISMultiCell(w,h,txt,border,align,fill)
+ else
+ super(w,h,txt,border,align,fill)
+ end
+ end
+
+ def SJISMultiCell(w,h,txt,border=0,align='L',fill=0)
+ #Output text with automatic or explicit line breaks
+ cw=@CurrentFont['cw']
+ if(w==0)
+ w=@w-@rMargin-@x
+ end
+ wmax=(w-2*@cMargin)*1000/@FontSize
+ s=txt.gsub("\r",'')
+ nb=s.length
+ if(nb>0 and s[nb-1]=="\n")
+ nb-=1
+ end
+ b=0
+ if(border)
+ if(border==1)
+ border='LTRB'
+ b='LRT'
+ b2='LR'
+ else
+ b2=''
+ if(border.index('L').nil?)
+ b2+='L'
+ end
+ if(border.index('R').nil?)
+ b2+='R'
+ end
+ b=border.index('T').nil? ? b2+'T' : b2
+ end
+ end
+ sep=-1
+ i=0
+ j=0
+ l=0
+ nl=1
+ while(i<nb)
+ #Get next character
+ c=s[i]
+ o=ord(c)
+ if(o==10)
+ #Explicit line break
+ Cell(w,h,s[j,i-j],b,2,align,fill)
+ i+=1
+ sep=-1
+ j=i
+ l=0
+ nl+=1
+ if(border and nl==2)
+ b=b2
+ end
+ next
+ end
+ if(o<128)
+ #ASCII
+ l+=cw[c.chr]
+ n=1
+ if(o==32)
+ sep=i
+ end
+ elsif(o>=161 and o<=223)
+ #Half-width katakana
+ l+=500
+ n=1
+ sep=i
+ else
+ #Full-width character
+ l+=1000
+ n=2
+ sep=i
+ end
+ if(l>wmax)
+ #Automatic line break
+ if(sep==-1 or i==j)
+ if(i==j)
+ i+=n
+ end
+ Cell(w,h,s[j,i-j],b,2,align,fill)
+ else
+ Cell(w,h,s[j,sep-j],b,2,align,fill)
+ i=(s[sep]==' ') ? sep+1 : sep
+ end
+ sep=-1
+ j=i
+ l=0
+ nl+=1
+ if(border and nl==2)
+ b=b2
+ end
+ else
+ i+=n
+ if(o>=128)
+ sep=i
+ end
+ end
+ end
+ #Last chunk
+ if(border and not border.index('B').nil?)
+ b+='B'
+ end
+ Cell(w,h,s[j,i-j],b,2,align,fill)
+ @x=@lMargin
+ end
+
+ def Write(h,txt,link='')
+ if(@CurrentFont['type']=='Type0')
+ SJISWrite(h,txt,link)
+ else
+ super(h,txt,link)
+ end
+ end
+
+ def SJISWrite(h,txt,link)
+ #SJIS version of Write()
+ cw=@CurrentFont['cw']
+ w=@w-@rMargin-@x
+ wmax=(w-2*@cMargin)*1000/@FontSize
+ s=txt.gsub("\r",'')
+ nb=s.length
+ sep=-1
+ i=0
+ j=0
+ l=0
+ nl=1
+ while(i<nb)
+ #Get next character
+ c=s[i]
+ o=c
+ if(o==10)
+ #Explicit line break
+ Cell(w,h,s[j,i-j],0,2,'',0,link)
+ i+=1
+ sep=-1
+ j=i
+ l=0
+ if(nl==1)
+ #Go to left margin
+ @x=@lMargin
+ w=@w-@rMargin-@x
+ wmax=(w-2*@cMargin)*1000/@FontSize
+ end
+ nl+=1
+ next
+ end
+ if(o<128)
+ #ASCII
+ l+=cw[c.chr]
+ n=1
+ if(o==32)
+ sep=i
+ end
+ elsif(o>=161 and o<=223)
+ #Half-width katakana
+ l+=500
+ n=1
+ sep=i
+ else
+ #Full-width character
+ l+=1000
+ n=2
+ sep=i
+ end
+ if(l>wmax)
+ #Automatic line break
+ if(sep==-1 or i==j)
+ if(@x>@lMargin)
+ #Move to next line
+ @x=@lMargin
+ @y+=h
+ w=@w-@rMargin-@x
+ wmax=(w-2*@cMargin)*1000/@FontSize
+ i+=n
+ nl+=1
+ next
+ end
+ if(i==j)
+ i+=n
+ end
+ Cell(w,h,s[j,i-j],0,2,'',0,link)
+ else
+ Cell(w,h,s[j,sep-j],0,2,'',0,link)
+ i=(s[sep]==' ') ? sep+1 : sep
+ end
+ sep=-1
+ j=i
+ l=0
+ if(nl==1)
+ @x=@lMargin
+ w=@w-@rMargin-@x
+ wmax=(w-2*@cMargin)*1000/@FontSize
+ end
+ nl+=1
+ else
+ i+=n
+ if(o>=128)
+ sep=i
+ end
+ end
+ end
+ #Last chunk
+ if(i!=j)
+ Cell(l/1000*@FontSize,h,s[j,i-j],0,0,'',0,link)
+ end
+ end
+
+private
+
+ def putfonts()
+ nf=@n
+ @diffs.each do |diff|
+ #Encodings
+ newobj()
+ out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['+diff+']>>')
+ out('endobj')
+ end
+ # mqr=get_magic_quotes_runtime()
+ # set_magic_quotes_runtime(0)
+ @FontFiles.each_pair do |file, info|
+ #Font file embedding
+ newobj()
+ @FontFiles[file]['n']=@n
+ if(defined('FPDF_FONTPATH'))
+ file=FPDF_FONTPATH+file
+ end
+ size=filesize(file)
+ if(!size)
+ Error('Font file not found')
+ end
+ out('<</Length '+size)
+ if(file[-2]=='.z')
+ out('/Filter /FlateDecode')
+ end
+ out('/Length1 '+info['length1'])
+ unless info['length2'].nil?
+ out('/Length2 '+info['length2']+' /Length3 0')
+ end
+ out('>>')
+ f=fopen(file,'rb')
+ putstream(fread(f,size))
+ fclose(f)
+ out('endobj')
+ end
+ # set_magic_quotes_runtime(mqr)
+ @fonts.each_pair do |k, font|
+ #Font objects
+ newobj()
+ @fonts[k]['n']=@n
+ out('<</Type /Font')
+ if(font['type']=='Type0')
+ putType0(font)
+ else
+ name=font['name']
+ out('/BaseFont /'+name)
+ if(font['type']=='core')
+ #Standard font
+ out('/Subtype /Type1')
+ if(name!='Symbol' and name!='ZapfDingbats')
+ out('/Encoding /WinAnsiEncoding')
+ end
+ else
+ #Additional font
+ out('/Subtype /'+font['type'])
+ out('/FirstChar 32')
+ out('/LastChar 255')
+ out('/Widths '+(@n+1)+' 0 R')
+ out('/FontDescriptor '+(@n+2)+' 0 R')
+ if(font['enc'])
+ if !font['diff'].nil?
+ out('/Encoding '+(nf+font['diff'])+' 0 R')
+ else
+ out('/Encoding /WinAnsiEncoding')
+ end
+ end
+ end
+ out('>>')
+ out('endobj')
+ if(font['type']!='core')
+ #Widths
+ newobj()
+ cw=font['cw']
+ s='['
+ 32.upto(255) do |i|
+ s+=cw[i.chr]+' '
+ end
+ out(s+']')
+ out('endobj')
+ #Descriptor
+ newobj()
+ s='<</Type /FontDescriptor /FontName /'+name
+ font['desc'].each_pair do |k, v|
+ s+=' /'+k+' '+v
+ end
+ file=font['file']
+ if(file)
+ s+=' /FontFile'+(font['type']=='Type1' ? '' : '2')+' '+@FontFiles[file]['n']+' 0 R'
+ end
+ out(s+'>>')
+ out('endobj')
+ end
+ end
+ end
+ end
+
+ def putType0(font)
+ #Type0
+ out('/Subtype /Type0')
+ out('/BaseFont /'+font['name']+'-'+font['CMap'])
+ out('/Encoding /'+font['CMap'])
+ out('/DescendantFonts ['+(@n+1).to_s+' 0 R]')
+ out('>>')
+ out('endobj')
+ #CIDFont
+ newobj()
+ out('<</Type /Font')
+ out('/Subtype /CIDFontType0')
+ out('/BaseFont /'+font['name'])
+ out('/CIDSystemInfo <</Registry (Adobe) /Ordering ('+font['registry']['ordering']+') /Supplement '+font['registry']['supplement'].to_s+'>>')
+ out('/FontDescriptor '+(@n+1).to_s+' 0 R')
+ w='/W [1 ['
+ font['cw'].keys.sort.each {|key|
+ w+=font['cw'][key].to_s + " "
+# ActionController::Base::logger.debug key.to_s
+# ActionController::Base::logger.debug font['cw'][key].to_s
+ }
+ out(w+'] 231 325 500 631 [500] 326 389 500]')
+ out('>>')
+ out('endobj')
+ #Font descriptor
+ newobj()
+ out('<</Type /FontDescriptor')
+ out('/FontName /'+font['name'])
+ out('/Flags 6')
+ out('/FontBBox [0 -200 1000 900]')
+ out('/ItalicAngle 0')
+ out('/Ascent 800')
+ out('/Descent -200')
+ out('/CapHeight 800')
+ out('/StemV 60')
+ out('>>')
+ out('endobj')
+ end
+end
diff --git a/vendor/plugins/rfpdf/lib/rfpdf/korean.rb b/vendor/plugins/rfpdf/lib/rfpdf/korean.rb
new file mode 100644
index 000000000..64131405e
--- /dev/null
+++ b/vendor/plugins/rfpdf/lib/rfpdf/korean.rb
@@ -0,0 +1,436 @@
+# Copyright (c) 2006 4ssoM LLC <www.4ssoM.com>
+# 1.12 contributed by Ed Moss.
+#
+# The MIT License
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# This is direct port of korean.php
+#
+# Korean PDF support.
+#
+# Usage is as follows:
+#
+# require 'fpdf'
+# require 'chinese'
+# pdf = FPDF.new
+# pdf.extend(PDF_Korean)
+#
+# This allows it to be combined with other extensions, such as the bookmark
+# module.
+
+module PDF_Korean
+
+UHC_widths={' ' => 333, '!' => 416, '"' => 416, '#' => 833, '$' => 625, '%' => 916, '&' => 833, '\'' => 250,
+ '(' => 500, ')' => 500, '*' => 500, '+' => 833, ',' => 291, '-' => 833, '.' => 291, '/' => 375, '0' => 625, '1' => 625,
+ '2' => 625, '3' => 625, '4' => 625, '5' => 625, '6' => 625, '7' => 625, '8' => 625, '9' => 625, ':' => 333, ';' => 333,
+ '<' => 833, '=' => 833, '>' => 916, '?' => 500, '@' => 1000, 'A' => 791, 'B' => 708, 'C' => 708, 'D' => 750, 'E' => 708,
+ 'F' => 666, 'G' => 750, 'H' => 791, 'I' => 375, 'J' => 500, 'K' => 791, 'L' => 666, 'M' => 916, 'N' => 791, 'O' => 750,
+ 'P' => 666, 'Q' => 750, 'R' => 708, 'S' => 666, 'T' => 791, 'U' => 791, 'V' => 750, 'W' => 1000, 'X' => 708, 'Y' => 708,
+ 'Z' => 666, '[' => 500, '\\' => 375, ']' => 500, '^' => 500, '_' => 500, '`' => 333, 'a' => 541, 'b' => 583, 'c' => 541,
+ 'd' => 583, 'e' => 583, 'f' => 375, 'g' => 583, 'h' => 583, 'i' => 291, 'j' => 333, 'k' => 583, 'l' => 291, 'm' => 875,
+ 'n' => 583, 'o' => 583, 'p' => 583, 'q' => 583, 'r' => 458, 's' => 541, 't' => 375, 'u' => 583, 'v' => 583, 'w' => 833,
+ 'x' => 625, 'y' => 625, 'z' => 500, '{' => 583, '|' => 583, '}' => 583, '~' => 750}
+
+ def AddCIDFont(family,style,name,cw,cMap,registry)
+ fontkey=family.downcase+style.upcase
+ unless @fonts[fontkey].nil?
+ Error("Font already added: family style")
+ end
+ i=@fonts.length+1
+ name=name.gsub(' ','')
+ @fonts[fontkey]={'i'=>i,'type'=>'Type0','name'=>name,'up'=>-130,'ut'=>40,'cw'=>cw,
+ 'CMap'=>cMap,'registry'=>registry}
+ end
+
+ def AddCIDFonts(family,name,cw,cMap,registry)
+ AddCIDFont(family,'',name,cw,cMap,registry)
+ AddCIDFont(family,'B',name+',Bold',cw,cMap,registry)
+ AddCIDFont(family,'I',name+',Italic',cw,cMap,registry)
+ AddCIDFont(family,'BI',name+',BoldItalic',cw,cMap,registry)
+ end
+
+ def AddUHCFont(family='UHC',name='HYSMyeongJoStd-Medium-Acro')
+ #Add UHC font with proportional Latin
+ cw=UHC_widths
+ cMap='KSCms-UHC-H'
+ registry={'ordering'=>'Korea1','supplement'=>1}
+ AddCIDFonts(family,name,cw,cMap,registry)
+ end
+
+ def AddUHChwFont(family='UHC-hw',name='HYSMyeongJoStd-Medium-Acro')
+ #Add UHC font with half-witdh Latin
+ 32.upto(126) do |i|
+ cw[i.chr]=500
+ end
+ cMap='KSCms-UHC-HW-H'
+ registry={'ordering'=>'Korea1','supplement'=>1}
+ AddCIDFonts(family,name,cw,cMap,registry)
+ end
+
+ def GetStringWidth(s)
+ if(@CurrentFont['type']=='Type0')
+ return GetMBStringWidth(s)
+ else
+ return super(s)
+ end
+ end
+
+ def GetMBStringWidth(s)
+ #Multi-byte version of GetStringWidth()
+ l=0
+ cw=@CurrentFont['cw']
+ nb=s.length
+ i=0
+ while(i<nb)
+ c=s[i]
+ if(c<128)
+ l+=cw[c.chr]
+ i+=1
+ else
+ l+=1000
+ i+=2
+ end
+ end
+ return l*@FontSize/1000
+ end
+
+ def MultiCell(w,h,txt,border=0,align='L',fill=0)
+ if(@CurrentFont['type']=='Type0')
+ MBMultiCell(w,h,txt,border,align,fill)
+ else
+ super(w,h,txt,border,align,fill)
+ end
+ end
+
+ def MBMultiCell(w,h,txt,border=0,align='L',fill=0)
+ #Multi-byte version of MultiCell()
+ cw=@CurrentFont['cw']
+ if(w==0)
+ w=@w-@rMargin-@x
+ end
+ wmax=(w-2*@cMargin)*1000/@FontSize
+ s=txt.gsub("\r",'')
+ nb=s.length
+ if(nb>0 and s[nb-1]=="\n")
+ nb-=1
+ end
+ b=0
+ if(border)
+ if(border==1)
+ border='LTRB'
+ b='LRT'
+ b2='LR'
+ else
+ b2=''
+ if(border.index('L').nil?)
+ b2+='L'
+ end
+ if(border.index('R').nil?)
+ b2+='R'
+ end
+ b=border.index('T').nil? ? b2+'T' : b2
+ end
+ end
+ sep=-1
+ i=0
+ j=0
+ l=0
+ nl=1
+ while(i<nb)
+ #Get next character
+ c=s[i]
+ #Check if ASCII or MB
+ ascii=(c<128)
+ if(c=="\n")
+ #Explicit line break
+ Cell(w,h,s[j,i-j],b,2,align,fill)
+ i+=1
+ sep=-1
+ j=i
+ l=0
+ nl+=1
+ if(border and nl==2)
+ b=b2
+ end
+ next
+ end
+ if(!ascii)
+ sep=i
+ ls=l
+ elsif(c==' ')
+ sep=i
+ ls=l
+ end
+ l+=ascii ? cw[c.chr] : 1000
+ if(l>wmax)
+ #Automatic line break
+ if(sep==-1 or i==j)
+ if(i==j)
+ i+=ascii ? 1 : 2
+ end
+ Cell(w,h,s[j,i-j],b,2,align,fill)
+ else
+ Cell(w,h,s[j,sep-j],b,2,align,fill)
+ i=(s[sep]==' ') ? sep+1 : sep
+ end
+ sep=-1
+ j=i
+ l=0
+ nl+=1
+ if(border and nl==2)
+ b=b2
+ end
+ else
+ i+=ascii ? 1 : 2
+ end
+ end
+ #Last chunk
+ if(border and not border.index('B').nil?)
+ b+='B'
+ end
+ Cell(w,h,s[j,i-j],b,2,align,fill)
+ @x=@lMargin
+ end
+
+ def Write(h,txt,link='')
+ if(@CurrentFont['type']=='Type0')
+ MBWrite(h,txt,link)
+ else
+ super(h,txt,link)
+ end
+ end
+
+ def MBWrite(h,txt,link)
+ #Multi-byte version of Write()
+ cw=@CurrentFont['cw']
+ w=@w-@rMargin-@x
+ wmax=(w-2*@cMargin)*1000/@FontSize
+ s=txt.gsub("\r",'')
+ nb=s.length
+ sep=-1
+ i=0
+ j=0
+ l=0
+ nl=1
+ while(i<nb)
+ #Get next character
+ c=s[i]
+ #Check if ASCII or MB
+ ascii=(c<128)
+ if(c=="\n")
+ #Explicit line break
+ Cell(w,h,s[j,i-j],0,2,'',0,link)
+ i+=1
+ sep=-1
+ j=i
+ l=0
+ if(nl==1)
+ @x=@lMargin
+ w=@w-@rMargin-@x
+ wmax=(w-2*@cMargin)*1000/@FontSize
+ end
+ nl+=1
+ next
+ end
+ if(!ascii or c==' ')
+ sep=i
+ end
+ l+=ascii ? cw[c.chr] : 1000
+ if(l>wmax)
+ #Automatic line break
+ if(sep==-1 or i==j)
+ if(@x>@lMargin)
+ #Move to next line
+ @x=@lMargin
+ @y+=h
+ w=@w-@rMargin-@x
+ wmax=(w-2*@cMargin)*1000/@FontSize
+ i+=1
+ nl+=1
+ next
+ end
+ if(i==j)
+ i+=ascii ? 1 : 2
+ end
+ Cell(w,h,s[j,i-j],0,2,'',0,link)
+ else
+ Cell(w,h,s[j,sep-j],0,2,'',0,link)
+ i=(s[sep]==' ') ? sep+1 : sep
+ end
+ sep=-1
+ j=i
+ l=0
+ if(nl==1)
+ @x=@lMargin
+ w=@w-@rMargin-@x
+ wmax=(w-2*@cMargin)*1000/@FontSize
+ end
+ nl+=1
+ else
+ i+=ascii ? 1 : 2
+ end
+ end
+ #Last chunk
+ if(i!=j)
+ Cell(l/1000*@FontSize,h,s[j,i-j],0,0,'',0,link)
+ end
+ end
+
+private
+
+ def putfonts()
+ nf=@n
+ @diffs.each do |diff|
+ #Encodings
+ newobj()
+ out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['+diff+']>>')
+ out('endobj')
+ end
+ # mqr=get_magic_quotes_runtime()
+ # set_magic_quotes_runtime(0)
+ @FontFiles.each_pair do |file, info|
+ #Font file embedding
+ newobj()
+ @FontFiles[file]['n']=@n
+ if(defined('FPDF_FONTPATH'))
+ file=FPDF_FONTPATH+file
+ end
+ size=filesize(file)
+ if(!size)
+ Error('Font file not found')
+ end
+ out('<</Length '+size)
+ if(file[-2]=='.z')
+ out('/Filter /FlateDecode')
+ end
+ out('/Length1 '+info['length1'])
+ if(not info['length2'].nil?)
+ out('/Length2 '+info['length2']+' /Length3 0')
+ end
+ out('>>')
+ f=fopen(file,'rb')
+ putstream(fread(f,size))
+ fclose(f)
+ out('endobj')
+ end
+ # set_magic_quotes_runtime(mqr)
+ @fonts.each_pair do |k, font|
+ #Font objects
+ newobj()
+ @fonts[k]['n']=@n
+ out('<</Type /Font')
+ if(font['type']=='Type0')
+ putType0(font)
+ else
+ name=font['name']
+ out('/BaseFont /'+name)
+ if(font['type']=='core')
+ #Standard font
+ out('/Subtype /Type1')
+ if(name!='Symbol' and name!='ZapfDingbats')
+ out('/Encoding /WinAnsiEncoding')
+ end
+ else
+ #Additional font
+ out('/Subtype /'+font['type'])
+ out('/FirstChar 32')
+ out('/LastChar 255')
+ out('/Widths '+(@n+1)+' 0 R')
+ out('/FontDescriptor '+(@n+2)+' 0 R')
+ if(font['enc'])
+ if(not font['diff'].nil?)
+ out('/Encoding '+(nf+font['diff'])+' 0 R')
+ else
+ out('/Encoding /WinAnsiEncoding')
+ end
+ end
+ end
+ out('>>')
+ out('endobj')
+ if(font['type']!='core')
+ #Widths
+ newobj()
+ cw=font['cw']
+ s='['
+ 32.upto(255) do |i|
+ s+=cw[i.chr]+' '
+ end
+ out(s+']')
+ out('endobj')
+ #Descriptor
+ newobj()
+ s='<</Type /FontDescriptor /FontName /'+name
+ font['desc'].each_pair do |k, v|
+ s+=' /'+k+' '+v
+ end
+ file=font['file']
+ if(file)
+ s+=' /FontFile'+(font['type']=='Type1' ? '' : '2')+' '+@FontFiles[file]['n']+' 0 R'
+ end
+ out(s+'>>')
+ out('endobj')
+ end
+ end
+ end
+ end
+
+ def putType0(font)
+ #Type0
+ out('/Subtype /Type0')
+ out('/BaseFont /'+font['name']+'-'+font['CMap'])
+ out('/Encoding /'+font['CMap'])
+ out('/DescendantFonts ['+(@n+1).to_s+' 0 R]')
+ out('>>')
+ out('endobj')
+ #CIDFont
+ newobj()
+ out('<</Type /Font')
+ out('/Subtype /CIDFontType0')
+ out('/BaseFont /'+font['name'])
+ out('/CIDSystemInfo <</Registry (Adobe) /Ordering ('+font['registry']['ordering']+') /Supplement '+font['registry']['supplement'].to_s+'>>')
+ out('/FontDescriptor '+(@n+1).to_s+' 0 R')
+ if(font['CMap']=='KSCms-UHC-HW-H')
+ w='8094 8190 500'
+ else
+ w='1 ['
+ font['cw'].keys.sort.each {|key|
+ w+=font['cw'][key].to_s + " "
+ # ActionController::Base::logger.debug key.to_s
+ # ActionController::Base::logger.debug font['cw'][key].to_s
+ }
+ w +=']'
+ end
+ out('/W ['+w+']>>')
+ out('endobj')
+ #Font descriptor
+ newobj()
+ out('<</Type /FontDescriptor')
+ out('/FontName /'+font['name'])
+ out('/Flags 6')
+ out('/FontBBox [0 -200 1000 900]')
+ out('/ItalicAngle 0')
+ out('/Ascent 800')
+ out('/Descent -200')
+ out('/CapHeight 800')
+ out('/StemV 50')
+ out('>>')
+ out('endobj')
+ end
+end
diff --git a/vendor/plugins/rfpdf/lib/rfpdf/makefont.rb b/vendor/plugins/rfpdf/lib/rfpdf/makefont.rb
new file mode 100644
index 000000000..ffc98b48f
--- /dev/null
+++ b/vendor/plugins/rfpdf/lib/rfpdf/makefont.rb
@@ -0,0 +1,1787 @@
+#!/usr/bin/env ruby
+#
+# Utility to generate font definition files
+# Version: 1.1
+# Date: 2006-07-19
+#
+# Changelog:
+# Version 1.1 - Brian Ollenberger
+# - Fixed a very small bug in MakeFont for generating FontDef.diff.
+
+Charencodings = {
+# Central Europe
+ 'cp1250' => [
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'exclam', 'quotedbl', 'numbersign',
+ 'dollar', 'percent', 'ampersand', 'quotesingle',
+ 'parenleft', 'parenright', 'asterisk', 'plus',
+ 'comma', 'hyphen', 'period', 'slash',
+ 'zero', 'one', 'two', 'three',
+ 'four', 'five', 'six', 'seven',
+ 'eight', 'nine', 'colon', 'semicolon',
+ 'less', 'equal', 'greater', 'question',
+ 'at', 'A', 'B', 'C',
+ 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K',
+ 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S',
+ 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', 'bracketleft',
+ 'backslash', 'bracketright', 'asciicircum', 'underscore',
+ 'grave', 'a', 'b', 'c',
+ 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k',
+ 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's',
+ 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', 'braceleft',
+ 'bar', 'braceright', 'asciitilde', '.notdef',
+ 'Euro', '.notdef', 'quotesinglbase', '.notdef',
+ 'quotedblbase', 'ellipsis', 'dagger', 'daggerdbl',
+ '.notdef', 'perthousand', 'Scaron', 'guilsinglleft',
+ 'Sacute', 'Tcaron', 'Zcaron', 'Zacute',
+ '.notdef', 'quoteleft', 'quoteright', 'quotedblleft',
+ 'quotedblright', 'bullet', 'endash', 'emdash',
+ '.notdef', 'trademark', 'scaron', 'guilsinglright',
+ 'sacute', 'tcaron', 'zcaron', 'zacute',
+ 'space', 'caron', 'breve', 'Lslash',
+ 'currency', 'Aogonek', 'brokenbar', 'section',
+ 'dieresis', 'copyright', 'Scedilla', 'guillemotleft',
+ 'logicalnot', 'hyphen', 'registered', 'Zdotaccent',
+ 'degree', 'plusminus', 'ogonek', 'lslash',
+ 'acute', 'mu', 'paragraph', 'periodcentered',
+ 'cedilla', 'aogonek', 'scedilla', 'guillemotright',
+ 'Lcaron', 'hungarumlaut', 'lcaron', 'zdotaccent',
+ 'Racute', 'Aacute', 'Acircumflex', 'Abreve',
+ 'Adieresis', 'Lacute', 'Cacute', 'Ccedilla',
+ 'Ccaron', 'Eacute', 'Eogonek', 'Edieresis',
+ 'Ecaron', 'Iacute', 'Icircumflex', 'Dcaron',
+ 'Dcroat', 'Nacute', 'Ncaron', 'Oacute',
+ 'Ocircumflex', 'Ohungarumlaut', 'Odieresis', 'multiply',
+ 'Rcaron', 'Uring', 'Uacute', 'Uhungarumlaut',
+ 'Udieresis', 'Yacute', 'Tcommaaccent', 'germandbls',
+ 'racute', 'aacute', 'acircumflex', 'abreve',
+ 'adieresis', 'lacute', 'cacute', 'ccedilla',
+ 'ccaron', 'eacute', 'eogonek', 'edieresis',
+ 'ecaron', 'iacute', 'icircumflex', 'dcaron',
+ 'dcroat', 'nacute', 'ncaron', 'oacute',
+ 'ocircumflex', 'ohungarumlaut', 'odieresis', 'divide',
+ 'rcaron', 'uring', 'uacute', 'uhungarumlaut',
+ 'udieresis', 'yacute', 'tcommaaccent', 'dotaccent'
+ ],
+# Cyrillic
+ 'cp1251' => [
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'exclam', 'quotedbl', 'numbersign',
+ 'dollar', 'percent', 'ampersand', 'quotesingle',
+ 'parenleft', 'parenright', 'asterisk', 'plus',
+ 'comma', 'hyphen', 'period', 'slash',
+ 'zero', 'one', 'two', 'three',
+ 'four', 'five', 'six', 'seven',
+ 'eight', 'nine', 'colon', 'semicolon',
+ 'less', 'equal', 'greater', 'question',
+ 'at', 'A', 'B', 'C',
+ 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K',
+ 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S',
+ 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', 'bracketleft',
+ 'backslash', 'bracketright', 'asciicircum', 'underscore',
+ 'grave', 'a', 'b', 'c',
+ 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k',
+ 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's',
+ 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', 'braceleft',
+ 'bar', 'braceright', 'asciitilde', '.notdef',
+ 'afii10051', 'afii10052', 'quotesinglbase', 'afii10100',
+ 'quotedblbase', 'ellipsis', 'dagger', 'daggerdbl',
+ 'Euro', 'perthousand', 'afii10058', 'guilsinglleft',
+ 'afii10059', 'afii10061', 'afii10060', 'afii10145',
+ 'afii10099', 'quoteleft', 'quoteright', 'quotedblleft',
+ 'quotedblright', 'bullet', 'endash', 'emdash',
+ '.notdef', 'trademark', 'afii10106', 'guilsinglright',
+ 'afii10107', 'afii10109', 'afii10108', 'afii10193',
+ 'space', 'afii10062', 'afii10110', 'afii10057',
+ 'currency', 'afii10050', 'brokenbar', 'section',
+ 'afii10023', 'copyright', 'afii10053', 'guillemotleft',
+ 'logicalnot', 'hyphen', 'registered', 'afii10056',
+ 'degree', 'plusminus', 'afii10055', 'afii10103',
+ 'afii10098', 'mu', 'paragraph', 'periodcentered',
+ 'afii10071', 'afii61352', 'afii10101', 'guillemotright',
+ 'afii10105', 'afii10054', 'afii10102', 'afii10104',
+ 'afii10017', 'afii10018', 'afii10019', 'afii10020',
+ 'afii10021', 'afii10022', 'afii10024', 'afii10025',
+ 'afii10026', 'afii10027', 'afii10028', 'afii10029',
+ 'afii10030', 'afii10031', 'afii10032', 'afii10033',
+ 'afii10034', 'afii10035', 'afii10036', 'afii10037',
+ 'afii10038', 'afii10039', 'afii10040', 'afii10041',
+ 'afii10042', 'afii10043', 'afii10044', 'afii10045',
+ 'afii10046', 'afii10047', 'afii10048', 'afii10049',
+ 'afii10065', 'afii10066', 'afii10067', 'afii10068',
+ 'afii10069', 'afii10070', 'afii10072', 'afii10073',
+ 'afii10074', 'afii10075', 'afii10076', 'afii10077',
+ 'afii10078', 'afii10079', 'afii10080', 'afii10081',
+ 'afii10082', 'afii10083', 'afii10084', 'afii10085',
+ 'afii10086', 'afii10087', 'afii10088', 'afii10089',
+ 'afii10090', 'afii10091', 'afii10092', 'afii10093',
+ 'afii10094', 'afii10095', 'afii10096', 'afii10097'
+ ],
+# Western Europe
+ 'cp1252' => [
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'exclam', 'quotedbl', 'numbersign',
+ 'dollar', 'percent', 'ampersand', 'quotesingle',
+ 'parenleft', 'parenright', 'asterisk', 'plus',
+ 'comma', 'hyphen', 'period', 'slash',
+ 'zero', 'one', 'two', 'three',
+ 'four', 'five', 'six', 'seven',
+ 'eight', 'nine', 'colon', 'semicolon',
+ 'less', 'equal', 'greater', 'question',
+ 'at', 'A', 'B', 'C',
+ 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K',
+ 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S',
+ 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', 'bracketleft',
+ 'backslash', 'bracketright', 'asciicircum', 'underscore',
+ 'grave', 'a', 'b', 'c',
+ 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k',
+ 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's',
+ 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', 'braceleft',
+ 'bar', 'braceright', 'asciitilde', '.notdef',
+ 'Euro', '.notdef', 'quotesinglbase', 'florin',
+ 'quotedblbase', 'ellipsis', 'dagger', 'daggerdbl',
+ 'circumflex', 'perthousand', 'Scaron', 'guilsinglleft',
+ 'OE', '.notdef', 'Zcaron', '.notdef',
+ '.notdef', 'quoteleft', 'quoteright', 'quotedblleft',
+ 'quotedblright', 'bullet', 'endash', 'emdash',
+ 'tilde', 'trademark', 'scaron', 'guilsinglright',
+ 'oe', '.notdef', 'zcaron', 'Ydieresis',
+ 'space', 'exclamdown', 'cent', 'sterling',
+ 'currency', 'yen', 'brokenbar', 'section',
+ 'dieresis', 'copyright', 'ordfeminine', 'guillemotleft',
+ 'logicalnot', 'hyphen', 'registered', 'macron',
+ 'degree', 'plusminus', 'twosuperior', 'threesuperior',
+ 'acute', 'mu', 'paragraph', 'periodcentered',
+ 'cedilla', 'onesuperior', 'ordmasculine', 'guillemotright',
+ 'onequarter', 'onehalf', 'threequarters', 'questiondown',
+ 'Agrave', 'Aacute', 'Acircumflex', 'Atilde',
+ 'Adieresis', 'Aring', 'AE', 'Ccedilla',
+ 'Egrave', 'Eacute', 'Ecircumflex', 'Edieresis',
+ 'Igrave', 'Iacute', 'Icircumflex', 'Idieresis',
+ 'Eth', 'Ntilde', 'Ograve', 'Oacute',
+ 'Ocircumflex', 'Otilde', 'Odieresis', 'multiply',
+ 'Oslash', 'Ugrave', 'Uacute', 'Ucircumflex',
+ 'Udieresis', 'Yacute', 'Thorn', 'germandbls',
+ 'agrave', 'aacute', 'acircumflex', 'atilde',
+ 'adieresis', 'aring', 'ae', 'ccedilla',
+ 'egrave', 'eacute', 'ecircumflex', 'edieresis',
+ 'igrave', 'iacute', 'icircumflex', 'idieresis',
+ 'eth', 'ntilde', 'ograve', 'oacute',
+ 'ocircumflex', 'otilde', 'odieresis', 'divide',
+ 'oslash', 'ugrave', 'uacute', 'ucircumflex',
+ 'udieresis', 'yacute', 'thorn', 'ydieresis'
+ ],
+# Greek
+ 'cp1253' => [
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'exclam', 'quotedbl', 'numbersign',
+ 'dollar', 'percent', 'ampersand', 'quotesingle',
+ 'parenleft', 'parenright', 'asterisk', 'plus',
+ 'comma', 'hyphen', 'period', 'slash',
+ 'zero', 'one', 'two', 'three',
+ 'four', 'five', 'six', 'seven',
+ 'eight', 'nine', 'colon', 'semicolon',
+ 'less', 'equal', 'greater', 'question',
+ 'at', 'A', 'B', 'C',
+ 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K',
+ 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S',
+ 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', 'bracketleft',
+ 'backslash', 'bracketright', 'asciicircum', 'underscore',
+ 'grave', 'a', 'b', 'c',
+ 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k',
+ 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's',
+ 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', 'braceleft',
+ 'bar', 'braceright', 'asciitilde', '.notdef',
+ 'Euro', '.notdef', 'quotesinglbase', 'florin',
+ 'quotedblbase', 'ellipsis', 'dagger', 'daggerdbl',
+ '.notdef', 'perthousand', '.notdef', 'guilsinglleft',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', 'quoteleft', 'quoteright', 'quotedblleft',
+ 'quotedblright', 'bullet', 'endash', 'emdash',
+ '.notdef', 'trademark', '.notdef', 'guilsinglright',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'dieresistonos', 'Alphatonos', 'sterling',
+ 'currency', 'yen', 'brokenbar', 'section',
+ 'dieresis', 'copyright', '.notdef', 'guillemotleft',
+ 'logicalnot', 'hyphen', 'registered', 'afii00208',
+ 'degree', 'plusminus', 'twosuperior', 'threesuperior',
+ 'tonos', 'mu', 'paragraph', 'periodcentered',
+ 'Epsilontonos', 'Etatonos', 'Iotatonos', 'guillemotright',
+ 'Omicrontonos', 'onehalf', 'Upsilontonos', 'Omegatonos',
+ 'iotadieresistonos','Alpha', 'Beta', 'Gamma',
+ 'Delta', 'Epsilon', 'Zeta', 'Eta',
+ 'Theta', 'Iota', 'Kappa', 'Lambda',
+ 'Mu', 'Nu', 'Xi', 'Omicron',
+ 'Pi', 'Rho', '.notdef', 'Sigma',
+ 'Tau', 'Upsilon', 'Phi', 'Chi',
+ 'Psi', 'Omega', 'Iotadieresis', 'Upsilondieresis',
+ 'alphatonos', 'epsilontonos', 'etatonos', 'iotatonos',
+ 'upsilondieresistonos','alpha', 'beta', 'gamma',
+ 'delta', 'epsilon', 'zeta', 'eta',
+ 'theta', 'iota', 'kappa', 'lambda',
+ 'mu', 'nu', 'xi', 'omicron',
+ 'pi', 'rho', 'sigma1', 'sigma',
+ 'tau', 'upsilon', 'phi', 'chi',
+ 'psi', 'omega', 'iotadieresis', 'upsilondieresis',
+ 'omicrontonos', 'upsilontonos', 'omegatonos', '.notdef'
+ ],
+# Turkish
+ 'cp1254' => [
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'exclam', 'quotedbl', 'numbersign',
+ 'dollar', 'percent', 'ampersand', 'quotesingle',
+ 'parenleft', 'parenright', 'asterisk', 'plus',
+ 'comma', 'hyphen', 'period', 'slash',
+ 'zero', 'one', 'two', 'three',
+ 'four', 'five', 'six', 'seven',
+ 'eight', 'nine', 'colon', 'semicolon',
+ 'less', 'equal', 'greater', 'question',
+ 'at', 'A', 'B', 'C',
+ 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K',
+ 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S',
+ 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', 'bracketleft',
+ 'backslash', 'bracketright', 'asciicircum', 'underscore',
+ 'grave', 'a', 'b', 'c',
+ 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k',
+ 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's',
+ 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', 'braceleft',
+ 'bar', 'braceright', 'asciitilde', '.notdef',
+ 'Euro', '.notdef', 'quotesinglbase', 'florin',
+ 'quotedblbase', 'ellipsis', 'dagger', 'daggerdbl',
+ 'circumflex', 'perthousand', 'Scaron', 'guilsinglleft',
+ 'OE', '.notdef', '.notdef', '.notdef',
+ '.notdef', 'quoteleft', 'quoteright', 'quotedblleft',
+ 'quotedblright', 'bullet', 'endash', 'emdash',
+ 'tilde', 'trademark', 'scaron', 'guilsinglright',
+ 'oe', '.notdef', '.notdef', 'Ydieresis',
+ 'space', 'exclamdown', 'cent', 'sterling',
+ 'currency', 'yen', 'brokenbar', 'section',
+ 'dieresis', 'copyright', 'ordfeminine', 'guillemotleft',
+ 'logicalnot', 'hyphen', 'registered', 'macron',
+ 'degree', 'plusminus', 'twosuperior', 'threesuperior',
+ 'acute', 'mu', 'paragraph', 'periodcentered',
+ 'cedilla', 'onesuperior', 'ordmasculine', 'guillemotright',
+ 'onequarter', 'onehalf', 'threequarters', 'questiondown',
+ 'Agrave', 'Aacute', 'Acircumflex', 'Atilde',
+ 'Adieresis', 'Aring', 'AE', 'Ccedilla',
+ 'Egrave', 'Eacute', 'Ecircumflex', 'Edieresis',
+ 'Igrave', 'Iacute', 'Icircumflex', 'Idieresis',
+ 'Gbreve', 'Ntilde', 'Ograve', 'Oacute',
+ 'Ocircumflex', 'Otilde', 'Odieresis', 'multiply',
+ 'Oslash', 'Ugrave', 'Uacute', 'Ucircumflex',
+ 'Udieresis', 'Idotaccent', 'Scedilla', 'germandbls',
+ 'agrave', 'aacute', 'acircumflex', 'atilde',
+ 'adieresis', 'aring', 'ae', 'ccedilla',
+ 'egrave', 'eacute', 'ecircumflex', 'edieresis',
+ 'igrave', 'iacute', 'icircumflex', 'idieresis',
+ 'gbreve', 'ntilde', 'ograve', 'oacute',
+ 'ocircumflex', 'otilde', 'odieresis', 'divide',
+ 'oslash', 'ugrave', 'uacute', 'ucircumflex',
+ 'udieresis', 'dotlessi', 'scedilla', 'ydieresis'
+ ],
+# Hebrew
+ 'cp1255' => [
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'exclam', 'quotedbl', 'numbersign',
+ 'dollar', 'percent', 'ampersand', 'quotesingle',
+ 'parenleft', 'parenright', 'asterisk', 'plus',
+ 'comma', 'hyphen', 'period', 'slash',
+ 'zero', 'one', 'two', 'three',
+ 'four', 'five', 'six', 'seven',
+ 'eight', 'nine', 'colon', 'semicolon',
+ 'less', 'equal', 'greater', 'question',
+ 'at', 'A', 'B', 'C',
+ 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K',
+ 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S',
+ 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', 'bracketleft',
+ 'backslash', 'bracketright', 'asciicircum', 'underscore',
+ 'grave', 'a', 'b', 'c',
+ 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k',
+ 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's',
+ 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', 'braceleft',
+ 'bar', 'braceright', 'asciitilde', '.notdef',
+ 'Euro', '.notdef', 'quotesinglbase', 'florin',
+ 'quotedblbase', 'ellipsis', 'dagger', 'daggerdbl',
+ 'circumflex', 'perthousand', '.notdef', 'guilsinglleft',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', 'quoteleft', 'quoteright', 'quotedblleft',
+ 'quotedblright', 'bullet', 'endash', 'emdash',
+ 'tilde', 'trademark', '.notdef', 'guilsinglright',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'exclamdown', 'cent', 'sterling',
+ 'afii57636', 'yen', 'brokenbar', 'section',
+ 'dieresis', 'copyright', 'multiply', 'guillemotleft',
+ 'logicalnot', 'sfthyphen', 'registered', 'macron',
+ 'degree', 'plusminus', 'twosuperior', 'threesuperior',
+ 'acute', 'mu', 'paragraph', 'middot',
+ 'cedilla', 'onesuperior', 'divide', 'guillemotright',
+ 'onequarter', 'onehalf', 'threequarters', 'questiondown',
+ 'afii57799', 'afii57801', 'afii57800', 'afii57802',
+ 'afii57793', 'afii57794', 'afii57795', 'afii57798',
+ 'afii57797', 'afii57806', '.notdef', 'afii57796',
+ 'afii57807', 'afii57839', 'afii57645', 'afii57841',
+ 'afii57842', 'afii57804', 'afii57803', 'afii57658',
+ 'afii57716', 'afii57717', 'afii57718', 'gereshhebrew',
+ 'gershayimhebrew','.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'afii57664', 'afii57665', 'afii57666', 'afii57667',
+ 'afii57668', 'afii57669', 'afii57670', 'afii57671',
+ 'afii57672', 'afii57673', 'afii57674', 'afii57675',
+ 'afii57676', 'afii57677', 'afii57678', 'afii57679',
+ 'afii57680', 'afii57681', 'afii57682', 'afii57683',
+ 'afii57684', 'afii57685', 'afii57686', 'afii57687',
+ 'afii57688', 'afii57689', 'afii57690', '.notdef',
+ '.notdef', 'afii299', 'afii300', '.notdef'
+ ],
+# Baltic
+ 'cp1257' => [
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'exclam', 'quotedbl', 'numbersign',
+ 'dollar', 'percent', 'ampersand', 'quotesingle',
+ 'parenleft', 'parenright', 'asterisk', 'plus',
+ 'comma', 'hyphen', 'period', 'slash',
+ 'zero', 'one', 'two', 'three',
+ 'four', 'five', 'six', 'seven',
+ 'eight', 'nine', 'colon', 'semicolon',
+ 'less', 'equal', 'greater', 'question',
+ 'at', 'A', 'B', 'C',
+ 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K',
+ 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S',
+ 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', 'bracketleft',
+ 'backslash', 'bracketright', 'asciicircum', 'underscore',
+ 'grave', 'a', 'b', 'c',
+ 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k',
+ 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's',
+ 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', 'braceleft',
+ 'bar', 'braceright', 'asciitilde', '.notdef',
+ 'Euro', '.notdef', 'quotesinglbase', '.notdef',
+ 'quotedblbase', 'ellipsis', 'dagger', 'daggerdbl',
+ '.notdef', 'perthousand', '.notdef', 'guilsinglleft',
+ '.notdef', 'dieresis', 'caron', 'cedilla',
+ '.notdef', 'quoteleft', 'quoteright', 'quotedblleft',
+ 'quotedblright', 'bullet', 'endash', 'emdash',
+ '.notdef', 'trademark', '.notdef', 'guilsinglright',
+ '.notdef', 'macron', 'ogonek', '.notdef',
+ 'space', '.notdef', 'cent', 'sterling',
+ 'currency', '.notdef', 'brokenbar', 'section',
+ 'Oslash', 'copyright', 'Rcommaaccent', 'guillemotleft',
+ 'logicalnot', 'hyphen', 'registered', 'AE',
+ 'degree', 'plusminus', 'twosuperior', 'threesuperior',
+ 'acute', 'mu', 'paragraph', 'periodcentered',
+ 'oslash', 'onesuperior', 'rcommaaccent', 'guillemotright',
+ 'onequarter', 'onehalf', 'threequarters', 'ae',
+ 'Aogonek', 'Iogonek', 'Amacron', 'Cacute',
+ 'Adieresis', 'Aring', 'Eogonek', 'Emacron',
+ 'Ccaron', 'Eacute', 'Zacute', 'Edotaccent',
+ 'Gcommaaccent', 'Kcommaaccent', 'Imacron', 'Lcommaaccent',
+ 'Scaron', 'Nacute', 'Ncommaaccent', 'Oacute',
+ 'Omacron', 'Otilde', 'Odieresis', 'multiply',
+ 'Uogonek', 'Lslash', 'Sacute', 'Umacron',
+ 'Udieresis', 'Zdotaccent', 'Zcaron', 'germandbls',
+ 'aogonek', 'iogonek', 'amacron', 'cacute',
+ 'adieresis', 'aring', 'eogonek', 'emacron',
+ 'ccaron', 'eacute', 'zacute', 'edotaccent',
+ 'gcommaaccent', 'kcommaaccent', 'imacron', 'lcommaaccent',
+ 'scaron', 'nacute', 'ncommaaccent', 'oacute',
+ 'omacron', 'otilde', 'odieresis', 'divide',
+ 'uogonek', 'lslash', 'sacute', 'umacron',
+ 'udieresis', 'zdotaccent', 'zcaron', 'dotaccent'
+ ],
+# Vietnamese
+ 'cp1258' => [
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'exclam', 'quotedbl', 'numbersign',
+ 'dollar', 'percent', 'ampersand', 'quotesingle',
+ 'parenleft', 'parenright', 'asterisk', 'plus',
+ 'comma', 'hyphen', 'period', 'slash',
+ 'zero', 'one', 'two', 'three',
+ 'four', 'five', 'six', 'seven',
+ 'eight', 'nine', 'colon', 'semicolon',
+ 'less', 'equal', 'greater', 'question',
+ 'at', 'A', 'B', 'C',
+ 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K',
+ 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S',
+ 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', 'bracketleft',
+ 'backslash', 'bracketright', 'asciicircum', 'underscore',
+ 'grave', 'a', 'b', 'c',
+ 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k',
+ 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's',
+ 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', 'braceleft',
+ 'bar', 'braceright', 'asciitilde', '.notdef',
+ 'Euro', '.notdef', 'quotesinglbase', 'florin',
+ 'quotedblbase', 'ellipsis', 'dagger', 'daggerdbl',
+ 'circumflex', 'perthousand', '.notdef', 'guilsinglleft',
+ 'OE', '.notdef', '.notdef', '.notdef',
+ '.notdef', 'quoteleft', 'quoteright', 'quotedblleft',
+ 'quotedblright', 'bullet', 'endash', 'emdash',
+ 'tilde', 'trademark', '.notdef', 'guilsinglright',
+ 'oe', '.notdef', '.notdef', 'Ydieresis',
+ 'space', 'exclamdown', 'cent', 'sterling',
+ 'currency', 'yen', 'brokenbar', 'section',
+ 'dieresis', 'copyright', 'ordfeminine', 'guillemotleft',
+ 'logicalnot', 'hyphen', 'registered', 'macron',
+ 'degree', 'plusminus', 'twosuperior', 'threesuperior',
+ 'acute', 'mu', 'paragraph', 'periodcentered',
+ 'cedilla', 'onesuperior', 'ordmasculine', 'guillemotright',
+ 'onequarter', 'onehalf', 'threequarters', 'questiondown',
+ 'Agrave', 'Aacute', 'Acircumflex', 'Abreve',
+ 'Adieresis', 'Aring', 'AE', 'Ccedilla',
+ 'Egrave', 'Eacute', 'Ecircumflex', 'Edieresis',
+ 'gravecomb', 'Iacute', 'Icircumflex', 'Idieresis',
+ 'Dcroat', 'Ntilde', 'hookabovecomb', 'Oacute',
+ 'Ocircumflex', 'Ohorn', 'Odieresis', 'multiply',
+ 'Oslash', 'Ugrave', 'Uacute', 'Ucircumflex',
+ 'Udieresis', 'Uhorn', 'tildecomb', 'germandbls',
+ 'agrave', 'aacute', 'acircumflex', 'abreve',
+ 'adieresis', 'aring', 'ae', 'ccedilla',
+ 'egrave', 'eacute', 'ecircumflex', 'edieresis',
+ 'acutecomb', 'iacute', 'icircumflex', 'idieresis',
+ 'dcroat', 'ntilde', 'dotbelowcomb', 'oacute',
+ 'ocircumflex', 'ohorn', 'odieresis', 'divide',
+ 'oslash', 'ugrave', 'uacute', 'ucircumflex',
+ 'udieresis', 'uhorn', 'dong', 'ydieresis'
+ ],
+# Thai
+ 'cp874' => [
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'exclam', 'quotedbl', 'numbersign',
+ 'dollar', 'percent', 'ampersand', 'quotesingle',
+ 'parenleft', 'parenright', 'asterisk', 'plus',
+ 'comma', 'hyphen', 'period', 'slash',
+ 'zero', 'one', 'two', 'three',
+ 'four', 'five', 'six', 'seven',
+ 'eight', 'nine', 'colon', 'semicolon',
+ 'less', 'equal', 'greater', 'question',
+ 'at', 'A', 'B', 'C',
+ 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K',
+ 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S',
+ 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', 'bracketleft',
+ 'backslash', 'bracketright', 'asciicircum', 'underscore',
+ 'grave', 'a', 'b', 'c',
+ 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k',
+ 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's',
+ 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', 'braceleft',
+ 'bar', 'braceright', 'asciitilde', '.notdef',
+ 'Euro', '.notdef', '.notdef', '.notdef',
+ '.notdef', 'ellipsis', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', 'quoteleft', 'quoteright', 'quotedblleft',
+ 'quotedblright', 'bullet', 'endash', 'emdash',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'kokaithai', 'khokhaithai', 'khokhuatthai',
+ 'khokhwaithai', 'khokhonthai', 'khorakhangthai', 'ngonguthai',
+ 'chochanthai', 'chochingthai', 'chochangthai', 'sosothai',
+ 'chochoethai', 'yoyingthai', 'dochadathai', 'topatakthai',
+ 'thothanthai', 'thonangmonthothai', 'thophuthaothai', 'nonenthai',
+ 'dodekthai', 'totaothai', 'thothungthai', 'thothahanthai',
+ 'thothongthai', 'nonuthai', 'bobaimaithai', 'poplathai',
+ 'phophungthai', 'fofathai', 'phophanthai', 'fofanthai',
+ 'phosamphaothai', 'momathai', 'yoyakthai', 'roruathai',
+ 'ruthai', 'lolingthai', 'luthai', 'wowaenthai',
+ 'sosalathai', 'sorusithai', 'sosuathai', 'hohipthai',
+ 'lochulathai', 'oangthai', 'honokhukthai', 'paiyannoithai',
+ 'saraathai', 'maihanakatthai', 'saraaathai', 'saraamthai',
+ 'saraithai', 'saraiithai', 'sarauethai', 'saraueethai',
+ 'sarauthai', 'sarauuthai', 'phinthuthai', '.notdef',
+ '.notdef', '.notdef', '.notdef', 'bahtthai',
+ 'saraethai', 'saraaethai', 'saraothai', 'saraaimaimuanthai',
+ 'saraaimaimalaithai', 'lakkhangyaothai', 'maiyamokthai', 'maitaikhuthai',
+ 'maiekthai', 'maithothai', 'maitrithai', 'maichattawathai',
+ 'thanthakhatthai', 'nikhahitthai', 'yamakkanthai', 'fongmanthai',
+ 'zerothai', 'onethai', 'twothai', 'threethai',
+ 'fourthai', 'fivethai', 'sixthai', 'seventhai',
+ 'eightthai', 'ninethai', 'angkhankhuthai', 'khomutthai',
+ '.notdef', '.notdef', '.notdef', '.notdef'
+ ],
+# Western Europe
+ 'ISO-8859-1' => [
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'exclam', 'quotedbl', 'numbersign',
+ 'dollar', 'percent', 'ampersand', 'quotesingle',
+ 'parenleft', 'parenright', 'asterisk', 'plus',
+ 'comma', 'hyphen', 'period', 'slash',
+ 'zero', 'one', 'two', 'three',
+ 'four', 'five', 'six', 'seven',
+ 'eight', 'nine', 'colon', 'semicolon',
+ 'less', 'equal', 'greater', 'question',
+ 'at', 'A', 'B', 'C',
+ 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K',
+ 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S',
+ 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', 'bracketleft',
+ 'backslash', 'bracketright', 'asciicircum', 'underscore',
+ 'grave', 'a', 'b', 'c',
+ 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k',
+ 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's',
+ 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', 'braceleft',
+ 'bar', 'braceright', 'asciitilde', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'exclamdown', 'cent', 'sterling',
+ 'currency', 'yen', 'brokenbar', 'section',
+ 'dieresis', 'copyright', 'ordfeminine', 'guillemotleft',
+ 'logicalnot', 'hyphen', 'registered', 'macron',
+ 'degree', 'plusminus', 'twosuperior', 'threesuperior',
+ 'acute', 'mu', 'paragraph', 'periodcentered',
+ 'cedilla', 'onesuperior', 'ordmasculine', 'guillemotright',
+ 'onequarter', 'onehalf', 'threequarters', 'questiondown',
+ 'Agrave', 'Aacute', 'Acircumflex', 'Atilde',
+ 'Adieresis', 'Aring', 'AE', 'Ccedilla',
+ 'Egrave', 'Eacute', 'Ecircumflex', 'Edieresis',
+ 'Igrave', 'Iacute', 'Icircumflex', 'Idieresis',
+ 'Eth', 'Ntilde', 'Ograve', 'Oacute',
+ 'Ocircumflex', 'Otilde', 'Odieresis', 'multiply',
+ 'Oslash', 'Ugrave', 'Uacute', 'Ucircumflex',
+ 'Udieresis', 'Yacute', 'Thorn', 'germandbls',
+ 'agrave', 'aacute', 'acircumflex', 'atilde',
+ 'adieresis', 'aring', 'ae', 'ccedilla',
+ 'egrave', 'eacute', 'ecircumflex', 'edieresis',
+ 'igrave', 'iacute', 'icircumflex', 'idieresis',
+ 'eth', 'ntilde', 'ograve', 'oacute',
+ 'ocircumflex', 'otilde', 'odieresis', 'divide',
+ 'oslash', 'ugrave', 'uacute', 'ucircumflex',
+ 'udieresis', 'yacute', 'thorn', 'ydieresis'
+ ],
+# Central Europe
+ 'ISO-8859-2' => [
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'exclam', 'quotedbl', 'numbersign',
+ 'dollar', 'percent', 'ampersand', 'quotesingle',
+ 'parenleft', 'parenright', 'asterisk', 'plus',
+ 'comma', 'hyphen', 'period', 'slash',
+ 'zero', 'one', 'two', 'three',
+ 'four', 'five', 'six', 'seven',
+ 'eight', 'nine', 'colon', 'semicolon',
+ 'less', 'equal', 'greater', 'question',
+ 'at', 'A', 'B', 'C',
+ 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K',
+ 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S',
+ 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', 'bracketleft',
+ 'backslash', 'bracketright', 'asciicircum', 'underscore',
+ 'grave', 'a', 'b', 'c',
+ 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k',
+ 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's',
+ 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', 'braceleft',
+ 'bar', 'braceright', 'asciitilde', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'Aogonek', 'breve', 'Lslash',
+ 'currency', 'Lcaron', 'Sacute', 'section',
+ 'dieresis', 'Scaron', 'Scedilla', 'Tcaron',
+ 'Zacute', 'hyphen', 'Zcaron', 'Zdotaccent',
+ 'degree', 'aogonek', 'ogonek', 'lslash',
+ 'acute', 'lcaron', 'sacute', 'caron',
+ 'cedilla', 'scaron', 'scedilla', 'tcaron',
+ 'zacute', 'hungarumlaut', 'zcaron', 'zdotaccent',
+ 'Racute', 'Aacute', 'Acircumflex', 'Abreve',
+ 'Adieresis', 'Lacute', 'Cacute', 'Ccedilla',
+ 'Ccaron', 'Eacute', 'Eogonek', 'Edieresis',
+ 'Ecaron', 'Iacute', 'Icircumflex', 'Dcaron',
+ 'Dcroat', 'Nacute', 'Ncaron', 'Oacute',
+ 'Ocircumflex', 'Ohungarumlaut', 'Odieresis', 'multiply',
+ 'Rcaron', 'Uring', 'Uacute', 'Uhungarumlaut',
+ 'Udieresis', 'Yacute', 'Tcommaaccent', 'germandbls',
+ 'racute', 'aacute', 'acircumflex', 'abreve',
+ 'adieresis', 'lacute', 'cacute', 'ccedilla',
+ 'ccaron', 'eacute', 'eogonek', 'edieresis',
+ 'ecaron', 'iacute', 'icircumflex', 'dcaron',
+ 'dcroat', 'nacute', 'ncaron', 'oacute',
+ 'ocircumflex', 'ohungarumlaut', 'odieresis', 'divide',
+ 'rcaron', 'uring', 'uacute', 'uhungarumlaut',
+ 'udieresis', 'yacute', 'tcommaaccent', 'dotaccent'
+ ],
+# Baltic
+ 'ISO-8859-4' => [
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'exclam', 'quotedbl', 'numbersign',
+ 'dollar', 'percent', 'ampersand', 'quotesingle',
+ 'parenleft', 'parenright', 'asterisk', 'plus',
+ 'comma', 'hyphen', 'period', 'slash',
+ 'zero', 'one', 'two', 'three',
+ 'four', 'five', 'six', 'seven',
+ 'eight', 'nine', 'colon', 'semicolon',
+ 'less', 'equal', 'greater', 'question',
+ 'at', 'A', 'B', 'C',
+ 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K',
+ 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S',
+ 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', 'bracketleft',
+ 'backslash', 'bracketright', 'asciicircum', 'underscore',
+ 'grave', 'a', 'b', 'c',
+ 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k',
+ 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's',
+ 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', 'braceleft',
+ 'bar', 'braceright', 'asciitilde', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'Aogonek', 'kgreenlandic', 'Rcommaaccent',
+ 'currency', 'Itilde', 'Lcommaaccent', 'section',
+ 'dieresis', 'Scaron', 'Emacron', 'Gcommaaccent',
+ 'Tbar', 'hyphen', 'Zcaron', 'macron',
+ 'degree', 'aogonek', 'ogonek', 'rcommaaccent',
+ 'acute', 'itilde', 'lcommaaccent', 'caron',
+ 'cedilla', 'scaron', 'emacron', 'gcommaaccent',
+ 'tbar', 'Eng', 'zcaron', 'eng',
+ 'Amacron', 'Aacute', 'Acircumflex', 'Atilde',
+ 'Adieresis', 'Aring', 'AE', 'Iogonek',
+ 'Ccaron', 'Eacute', 'Eogonek', 'Edieresis',
+ 'Edotaccent', 'Iacute', 'Icircumflex', 'Imacron',
+ 'Dcroat', 'Ncommaaccent', 'Omacron', 'Kcommaaccent',
+ 'Ocircumflex', 'Otilde', 'Odieresis', 'multiply',
+ 'Oslash', 'Uogonek', 'Uacute', 'Ucircumflex',
+ 'Udieresis', 'Utilde', 'Umacron', 'germandbls',
+ 'amacron', 'aacute', 'acircumflex', 'atilde',
+ 'adieresis', 'aring', 'ae', 'iogonek',
+ 'ccaron', 'eacute', 'eogonek', 'edieresis',
+ 'edotaccent', 'iacute', 'icircumflex', 'imacron',
+ 'dcroat', 'ncommaaccent', 'omacron', 'kcommaaccent',
+ 'ocircumflex', 'otilde', 'odieresis', 'divide',
+ 'oslash', 'uogonek', 'uacute', 'ucircumflex',
+ 'udieresis', 'utilde', 'umacron', 'dotaccent'
+ ],
+# Cyrillic
+ 'ISO-8859-5' => [
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'exclam', 'quotedbl', 'numbersign',
+ 'dollar', 'percent', 'ampersand', 'quotesingle',
+ 'parenleft', 'parenright', 'asterisk', 'plus',
+ 'comma', 'hyphen', 'period', 'slash',
+ 'zero', 'one', 'two', 'three',
+ 'four', 'five', 'six', 'seven',
+ 'eight', 'nine', 'colon', 'semicolon',
+ 'less', 'equal', 'greater', 'question',
+ 'at', 'A', 'B', 'C',
+ 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K',
+ 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S',
+ 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', 'bracketleft',
+ 'backslash', 'bracketright', 'asciicircum', 'underscore',
+ 'grave', 'a', 'b', 'c',
+ 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k',
+ 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's',
+ 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', 'braceleft',
+ 'bar', 'braceright', 'asciitilde', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'afii10023', 'afii10051', 'afii10052',
+ 'afii10053', 'afii10054', 'afii10055', 'afii10056',
+ 'afii10057', 'afii10058', 'afii10059', 'afii10060',
+ 'afii10061', 'hyphen', 'afii10062', 'afii10145',
+ 'afii10017', 'afii10018', 'afii10019', 'afii10020',
+ 'afii10021', 'afii10022', 'afii10024', 'afii10025',
+ 'afii10026', 'afii10027', 'afii10028', 'afii10029',
+ 'afii10030', 'afii10031', 'afii10032', 'afii10033',
+ 'afii10034', 'afii10035', 'afii10036', 'afii10037',
+ 'afii10038', 'afii10039', 'afii10040', 'afii10041',
+ 'afii10042', 'afii10043', 'afii10044', 'afii10045',
+ 'afii10046', 'afii10047', 'afii10048', 'afii10049',
+ 'afii10065', 'afii10066', 'afii10067', 'afii10068',
+ 'afii10069', 'afii10070', 'afii10072', 'afii10073',
+ 'afii10074', 'afii10075', 'afii10076', 'afii10077',
+ 'afii10078', 'afii10079', 'afii10080', 'afii10081',
+ 'afii10082', 'afii10083', 'afii10084', 'afii10085',
+ 'afii10086', 'afii10087', 'afii10088', 'afii10089',
+ 'afii10090', 'afii10091', 'afii10092', 'afii10093',
+ 'afii10094', 'afii10095', 'afii10096', 'afii10097',
+ 'afii61352', 'afii10071', 'afii10099', 'afii10100',
+ 'afii10101', 'afii10102', 'afii10103', 'afii10104',
+ 'afii10105', 'afii10106', 'afii10107', 'afii10108',
+ 'afii10109', 'section', 'afii10110', 'afii10193'
+ ],
+# Greek
+ 'ISO-8859-7' => [
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'exclam', 'quotedbl', 'numbersign',
+ 'dollar', 'percent', 'ampersand', 'quotesingle',
+ 'parenleft', 'parenright', 'asterisk', 'plus',
+ 'comma', 'hyphen', 'period', 'slash',
+ 'zero', 'one', 'two', 'three',
+ 'four', 'five', 'six', 'seven',
+ 'eight', 'nine', 'colon', 'semicolon',
+ 'less', 'equal', 'greater', 'question',
+ 'at', 'A', 'B', 'C',
+ 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K',
+ 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S',
+ 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', 'bracketleft',
+ 'backslash', 'bracketright', 'asciicircum', 'underscore',
+ 'grave', 'a', 'b', 'c',
+ 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k',
+ 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's',
+ 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', 'braceleft',
+ 'bar', 'braceright', 'asciitilde', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'quoteleft', 'quoteright', 'sterling',
+ '.notdef', '.notdef', 'brokenbar', 'section',
+ 'dieresis', 'copyright', '.notdef', 'guillemotleft',
+ 'logicalnot', 'hyphen', '.notdef', 'afii00208',
+ 'degree', 'plusminus', 'twosuperior', 'threesuperior',
+ 'tonos', 'dieresistonos', 'Alphatonos', 'periodcentered',
+ 'Epsilontonos', 'Etatonos', 'Iotatonos', 'guillemotright',
+ 'Omicrontonos', 'onehalf', 'Upsilontonos', 'Omegatonos',
+ 'iotadieresistonos','Alpha', 'Beta', 'Gamma',
+ 'Delta', 'Epsilon', 'Zeta', 'Eta',
+ 'Theta', 'Iota', 'Kappa', 'Lambda',
+ 'Mu', 'Nu', 'Xi', 'Omicron',
+ 'Pi', 'Rho', '.notdef', 'Sigma',
+ 'Tau', 'Upsilon', 'Phi', 'Chi',
+ 'Psi', 'Omega', 'Iotadieresis', 'Upsilondieresis',
+ 'alphatonos', 'epsilontonos', 'etatonos', 'iotatonos',
+ 'upsilondieresistonos','alpha', 'beta', 'gamma',
+ 'delta', 'epsilon', 'zeta', 'eta',
+ 'theta', 'iota', 'kappa', 'lambda',
+ 'mu', 'nu', 'xi', 'omicron',
+ 'pi', 'rho', 'sigma1', 'sigma',
+ 'tau', 'upsilon', 'phi', 'chi',
+ 'psi', 'omega', 'iotadieresis', 'upsilondieresis',
+ 'omicrontonos', 'upsilontonos', 'omegatonos', '.notdef'
+ ],
+# Turkish
+ 'ISO-8859-9' => [
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'exclam', 'quotedbl', 'numbersign',
+ 'dollar', 'percent', 'ampersand', 'quotesingle',
+ 'parenleft', 'parenright', 'asterisk', 'plus',
+ 'comma', 'hyphen', 'period', 'slash',
+ 'zero', 'one', 'two', 'three',
+ 'four', 'five', 'six', 'seven',
+ 'eight', 'nine', 'colon', 'semicolon',
+ 'less', 'equal', 'greater', 'question',
+ 'at', 'A', 'B', 'C',
+ 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K',
+ 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S',
+ 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', 'bracketleft',
+ 'backslash', 'bracketright', 'asciicircum', 'underscore',
+ 'grave', 'a', 'b', 'c',
+ 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k',
+ 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's',
+ 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', 'braceleft',
+ 'bar', 'braceright', 'asciitilde', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'exclamdown', 'cent', 'sterling',
+ 'currency', 'yen', 'brokenbar', 'section',
+ 'dieresis', 'copyright', 'ordfeminine', 'guillemotleft',
+ 'logicalnot', 'hyphen', 'registered', 'macron',
+ 'degree', 'plusminus', 'twosuperior', 'threesuperior',
+ 'acute', 'mu', 'paragraph', 'periodcentered',
+ 'cedilla', 'onesuperior', 'ordmasculine', 'guillemotright',
+ 'onequarter', 'onehalf', 'threequarters', 'questiondown',
+ 'Agrave', 'Aacute', 'Acircumflex', 'Atilde',
+ 'Adieresis', 'Aring', 'AE', 'Ccedilla',
+ 'Egrave', 'Eacute', 'Ecircumflex', 'Edieresis',
+ 'Igrave', 'Iacute', 'Icircumflex', 'Idieresis',
+ 'Gbreve', 'Ntilde', 'Ograve', 'Oacute',
+ 'Ocircumflex', 'Otilde', 'Odieresis', 'multiply',
+ 'Oslash', 'Ugrave', 'Uacute', 'Ucircumflex',
+ 'Udieresis', 'Idotaccent', 'Scedilla', 'germandbls',
+ 'agrave', 'aacute', 'acircumflex', 'atilde',
+ 'adieresis', 'aring', 'ae', 'ccedilla',
+ 'egrave', 'eacute', 'ecircumflex', 'edieresis',
+ 'igrave', 'iacute', 'icircumflex', 'idieresis',
+ 'gbreve', 'ntilde', 'ograve', 'oacute',
+ 'ocircumflex', 'otilde', 'odieresis', 'divide',
+ 'oslash', 'ugrave', 'uacute', 'ucircumflex',
+ 'udieresis', 'dotlessi', 'scedilla', 'ydieresis'
+ ],
+# Thai
+ 'ISO-8859-11' => [
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'exclam', 'quotedbl', 'numbersign',
+ 'dollar', 'percent', 'ampersand', 'quotesingle',
+ 'parenleft', 'parenright', 'asterisk', 'plus',
+ 'comma', 'hyphen', 'period', 'slash',
+ 'zero', 'one', 'two', 'three',
+ 'four', 'five', 'six', 'seven',
+ 'eight', 'nine', 'colon', 'semicolon',
+ 'less', 'equal', 'greater', 'question',
+ 'at', 'A', 'B', 'C',
+ 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K',
+ 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S',
+ 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', 'bracketleft',
+ 'backslash', 'bracketright', 'asciicircum', 'underscore',
+ 'grave', 'a', 'b', 'c',
+ 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k',
+ 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's',
+ 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', 'braceleft',
+ 'bar', 'braceright', 'asciitilde', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'kokaithai', 'khokhaithai', 'khokhuatthai',
+ 'khokhwaithai', 'khokhonthai', 'khorakhangthai', 'ngonguthai',
+ 'chochanthai', 'chochingthai', 'chochangthai', 'sosothai',
+ 'chochoethai', 'yoyingthai', 'dochadathai', 'topatakthai',
+ 'thothanthai', 'thonangmonthothai','thophuthaothai', 'nonenthai',
+ 'dodekthai', 'totaothai', 'thothungthai', 'thothahanthai',
+ 'thothongthai', 'nonuthai', 'bobaimaithai', 'poplathai',
+ 'phophungthai', 'fofathai', 'phophanthai', 'fofanthai',
+ 'phosamphaothai', 'momathai', 'yoyakthai', 'roruathai',
+ 'ruthai', 'lolingthai', 'luthai', 'wowaenthai',
+ 'sosalathai', 'sorusithai', 'sosuathai', 'hohipthai',
+ 'lochulathai', 'oangthai', 'honokhukthai', 'paiyannoithai',
+ 'saraathai', 'maihanakatthai', 'saraaathai', 'saraamthai',
+ 'saraithai', 'saraiithai', 'sarauethai', 'saraueethai',
+ 'sarauthai', 'sarauuthai', 'phinthuthai', '.notdef',
+ '.notdef', '.notdef', '.notdef', 'bahtthai',
+ 'saraethai', 'saraaethai', 'saraothai', 'saraaimaimuanthai',
+ 'saraaimaimalaithai','lakkhangyaothai','maiyamokthai', 'maitaikhuthai',
+ 'maiekthai', 'maithothai', 'maitrithai', 'maichattawathai',
+ 'thanthakhatthai','nikhahitthai', 'yamakkanthai', 'fongmanthai',
+ 'zerothai', 'onethai', 'twothai', 'threethai',
+ 'fourthai', 'fivethai', 'sixthai', 'seventhai',
+ 'eightthai', 'ninethai', 'angkhankhuthai', 'khomutthai',
+ '.notdef', '.notdef', '.notdef', '.notdef'
+ ],
+# Western Europe
+ 'ISO-8859-15' => [
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'exclam', 'quotedbl', 'numbersign',
+ 'dollar', 'percent', 'ampersand', 'quotesingle',
+ 'parenleft', 'parenright', 'asterisk', 'plus',
+ 'comma', 'hyphen', 'period', 'slash',
+ 'zero', 'one', 'two', 'three',
+ 'four', 'five', 'six', 'seven',
+ 'eight', 'nine', 'colon', 'semicolon',
+ 'less', 'equal', 'greater', 'question',
+ 'at', 'A', 'B', 'C',
+ 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K',
+ 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S',
+ 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', 'bracketleft',
+ 'backslash', 'bracketright', 'asciicircum', 'underscore',
+ 'grave', 'a', 'b', 'c',
+ 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k',
+ 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's',
+ 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', 'braceleft',
+ 'bar', 'braceright', 'asciitilde', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'exclamdown', 'cent', 'sterling',
+ 'Euro', 'yen', 'Scaron', 'section',
+ 'scaron', 'copyright', 'ordfeminine', 'guillemotleft',
+ 'logicalnot', 'hyphen', 'registered', 'macron',
+ 'degree', 'plusminus', 'twosuperior', 'threesuperior',
+ 'Zcaron', 'mu', 'paragraph', 'periodcentered',
+ 'zcaron', 'onesuperior', 'ordmasculine', 'guillemotright',
+ 'OE', 'oe', 'Ydieresis', 'questiondown',
+ 'Agrave', 'Aacute', 'Acircumflex', 'Atilde',
+ 'Adieresis', 'Aring', 'AE', 'Ccedilla',
+ 'Egrave', 'Eacute', 'Ecircumflex', 'Edieresis',
+ 'Igrave', 'Iacute', 'Icircumflex', 'Idieresis',
+ 'Eth', 'Ntilde', 'Ograve', 'Oacute',
+ 'Ocircumflex', 'Otilde', 'Odieresis', 'multiply',
+ 'Oslash', 'Ugrave', 'Uacute', 'Ucircumflex',
+ 'Udieresis', 'Yacute', 'Thorn', 'germandbls',
+ 'agrave', 'aacute', 'acircumflex', 'atilde',
+ 'adieresis', 'aring', 'ae', 'ccedilla',
+ 'egrave', 'eacute', 'ecircumflex', 'edieresis',
+ 'igrave', 'iacute', 'icircumflex', 'idieresis',
+ 'eth', 'ntilde', 'ograve', 'oacute',
+ 'ocircumflex', 'otilde', 'odieresis', 'divide',
+ 'oslash', 'ugrave', 'uacute', 'ucircumflex',
+ 'udieresis', 'yacute', 'thorn', 'ydieresis'
+ ],
+# Central Europe
+ 'ISO-8859-16' => [
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'exclam', 'quotedbl', 'numbersign',
+ 'dollar', 'percent', 'ampersand', 'quotesingle',
+ 'parenleft', 'parenright', 'asterisk', 'plus',
+ 'comma', 'hyphen', 'period', 'slash',
+ 'zero', 'one', 'two', 'three',
+ 'four', 'five', 'six', 'seven',
+ 'eight', 'nine', 'colon', 'semicolon',
+ 'less', 'equal', 'greater', 'question',
+ 'at', 'A', 'B', 'C',
+ 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K',
+ 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S',
+ 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', 'bracketleft',
+ 'backslash', 'bracketright', 'asciicircum', 'underscore',
+ 'grave', 'a', 'b', 'c',
+ 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k',
+ 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's',
+ 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', 'braceleft',
+ 'bar', 'braceright', 'asciitilde', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'Aogonek', 'aogonek', 'Lslash',
+ 'Euro', 'quotedblbase', 'Scaron', 'section',
+ 'scaron', 'copyright', 'Scommaaccent', 'guillemotleft',
+ 'Zacute', 'hyphen', 'zacute', 'Zdotaccent',
+ 'degree', 'plusminus', 'Ccaron', 'lslash',
+ 'Zcaron', 'quotedblright', 'paragraph', 'periodcentered',
+ 'zcaron', 'ccaron', 'scommaaccent', 'guillemotright',
+ 'OE', 'oe', 'Ydieresis', 'zdotaccent',
+ 'Agrave', 'Aacute', 'Acircumflex', 'Abreve',
+ 'Adieresis', 'Cacute', 'AE', 'Ccedilla',
+ 'Egrave', 'Eacute', 'Ecircumflex', 'Edieresis',
+ 'Igrave', 'Iacute', 'Icircumflex', 'Idieresis',
+ 'Dcroat', 'Nacute', 'Ograve', 'Oacute',
+ 'Ocircumflex', 'Ohungarumlaut', 'Odieresis', 'Sacute',
+ 'Uhungarumlaut', 'Ugrave', 'Uacute', 'Ucircumflex',
+ 'Udieresis', 'Eogonek', 'Tcommaaccent', 'germandbls',
+ 'agrave', 'aacute', 'acircumflex', 'abreve',
+ 'adieresis', 'cacute', 'ae', 'ccedilla',
+ 'egrave', 'eacute', 'ecircumflex', 'edieresis',
+ 'igrave', 'iacute', 'icircumflex', 'idieresis',
+ 'dcroat', 'nacute', 'ograve', 'oacute',
+ 'ocircumflex', 'ohungarumlaut', 'odieresis', 'sacute',
+ 'uhungarumlaut', 'ugrave', 'uacute', 'ucircumflex',
+ 'udieresis', 'eogonek', 'tcommaaccent', 'ydieresis'
+ ],
+# Russian
+ 'KOI8-R' => [
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'exclam', 'quotedbl', 'numbersign',
+ 'dollar', 'percent', 'ampersand', 'quotesingle',
+ 'parenleft', 'parenright', 'asterisk', 'plus',
+ 'comma', 'hyphen', 'period', 'slash',
+ 'zero', 'one', 'two', 'three',
+ 'four', 'five', 'six', 'seven',
+ 'eight', 'nine', 'colon', 'semicolon',
+ 'less', 'equal', 'greater', 'question',
+ 'at', 'A', 'B', 'C',
+ 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K',
+ 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S',
+ 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', 'bracketleft',
+ 'backslash', 'bracketright', 'asciicircum', 'underscore',
+ 'grave', 'a', 'b', 'c',
+ 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k',
+ 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's',
+ 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', 'braceleft',
+ 'bar', 'braceright', 'asciitilde', '.notdef',
+ 'SF100000', 'SF110000', 'SF010000', 'SF030000',
+ 'SF020000', 'SF040000', 'SF080000', 'SF090000',
+ 'SF060000', 'SF070000', 'SF050000', 'upblock',
+ 'dnblock', 'block', 'lfblock', 'rtblock',
+ 'ltshade', 'shade', 'dkshade', 'integraltp',
+ 'filledbox', 'periodcentered', 'radical', 'approxequal',
+ 'lessequal', 'greaterequal', 'space', 'integralbt',
+ 'degree', 'twosuperior', 'periodcentered', 'divide',
+ 'SF430000', 'SF240000', 'SF510000', 'afii10071',
+ 'SF520000', 'SF390000', 'SF220000', 'SF210000',
+ 'SF250000', 'SF500000', 'SF490000', 'SF380000',
+ 'SF280000', 'SF270000', 'SF260000', 'SF360000',
+ 'SF370000', 'SF420000', 'SF190000', 'afii10023',
+ 'SF200000', 'SF230000', 'SF470000', 'SF480000',
+ 'SF410000', 'SF450000', 'SF460000', 'SF400000',
+ 'SF540000', 'SF530000', 'SF440000', 'copyright',
+ 'afii10096', 'afii10065', 'afii10066', 'afii10088',
+ 'afii10069', 'afii10070', 'afii10086', 'afii10068',
+ 'afii10087', 'afii10074', 'afii10075', 'afii10076',
+ 'afii10077', 'afii10078', 'afii10079', 'afii10080',
+ 'afii10081', 'afii10097', 'afii10082', 'afii10083',
+ 'afii10084', 'afii10085', 'afii10072', 'afii10067',
+ 'afii10094', 'afii10093', 'afii10073', 'afii10090',
+ 'afii10095', 'afii10091', 'afii10089', 'afii10092',
+ 'afii10048', 'afii10017', 'afii10018', 'afii10040',
+ 'afii10021', 'afii10022', 'afii10038', 'afii10020',
+ 'afii10039', 'afii10026', 'afii10027', 'afii10028',
+ 'afii10029', 'afii10030', 'afii10031', 'afii10032',
+ 'afii10033', 'afii10049', 'afii10034', 'afii10035',
+ 'afii10036', 'afii10037', 'afii10024', 'afii10019',
+ 'afii10046', 'afii10045', 'afii10025', 'afii10042',
+ 'afii10047', 'afii10043', 'afii10041', 'afii10044'
+ ],
+# Ukrainian
+ 'KOI8-U' => [
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef',
+ 'space', 'exclam', 'quotedbl', 'numbersign',
+ 'dollar', 'percent', 'ampersand', 'quotesingle',
+ 'parenleft', 'parenright', 'asterisk', 'plus',
+ 'comma', 'hyphen', 'period', 'slash',
+ 'zero', 'one', 'two', 'three',
+ 'four', 'five', 'six', 'seven',
+ 'eight', 'nine', 'colon', 'semicolon',
+ 'less', 'equal', 'greater', 'question',
+ 'at', 'A', 'B', 'C',
+ 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K',
+ 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S',
+ 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', 'bracketleft',
+ 'backslash', 'bracketright', 'asciicircum', 'underscore',
+ 'grave', 'a', 'b', 'c',
+ 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k',
+ 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's',
+ 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', 'braceleft',
+ 'bar', 'braceright', 'asciitilde', '.notdef',
+ 'SF100000', 'SF110000', 'SF010000', 'SF030000',
+ 'SF020000', 'SF040000', 'SF080000', 'SF090000',
+ 'SF060000', 'SF070000', 'SF050000', 'upblock',
+ 'dnblock', 'block', 'lfblock', 'rtblock',
+ 'ltshade', 'shade', 'dkshade', 'integraltp',
+ 'filledbox', 'bullet', 'radical', 'approxequal',
+ 'lessequal', 'greaterequal', 'space', 'integralbt',
+ 'degree', 'twosuperior', 'periodcentered', 'divide',
+ 'SF430000', 'SF240000', 'SF510000', 'afii10071',
+ 'afii10101', 'SF390000', 'afii10103', 'afii10104',
+ 'SF250000', 'SF500000', 'SF490000', 'SF380000',
+ 'SF280000', 'afii10098', 'SF260000', 'SF360000',
+ 'SF370000', 'SF420000', 'SF190000', 'afii10023',
+ 'afii10053', 'SF230000', 'afii10055', 'afii10056',
+ 'SF410000', 'SF450000', 'SF460000', 'SF400000',
+ 'SF540000', 'afii10050', 'SF440000', 'copyright',
+ 'afii10096', 'afii10065', 'afii10066', 'afii10088',
+ 'afii10069', 'afii10070', 'afii10086', 'afii10068',
+ 'afii10087', 'afii10074', 'afii10075', 'afii10076',
+ 'afii10077', 'afii10078', 'afii10079', 'afii10080',
+ 'afii10081', 'afii10097', 'afii10082', 'afii10083',
+ 'afii10084', 'afii10085', 'afii10072', 'afii10067',
+ 'afii10094', 'afii10093', 'afii10073', 'afii10090',
+ 'afii10095', 'afii10091', 'afii10089', 'afii10092',
+ 'afii10048', 'afii10017', 'afii10018', 'afii10040',
+ 'afii10021', 'afii10022', 'afii10038', 'afii10020',
+ 'afii10039', 'afii10026', 'afii10027', 'afii10028',
+ 'afii10029', 'afii10030', 'afii10031', 'afii10032',
+ 'afii10033', 'afii10049', 'afii10034', 'afii10035',
+ 'afii10036', 'afii10037', 'afii10024', 'afii10019',
+ 'afii10046', 'afii10045', 'afii10025', 'afii10042',
+ 'afii10047', 'afii10043', 'afii10041', 'afii10044'
+ ]
+}
+
+def ReadAFM(file, map)
+
+ # Read a font metric file
+ a = IO.readlines(file)
+
+ raise "File no found: #{file}" if a.size == 0
+
+ widths = {}
+ fm = {}
+ fix = { 'Edot' => 'Edotaccent', 'edot' => 'edotaccent',
+ 'Idot' => 'Idotaccent',
+ 'Zdot' => 'Zdotaccent', 'zdot' => 'zdotaccent',
+ 'Odblacute' => 'Ohungarumlaut', 'odblacute' => 'ohungarumlaut',
+ 'Udblacute' => 'Uhungarumlaut', 'udblacute' => 'uhungarumlaut',
+ 'Gcedilla' => 'Gcommaaccent', 'gcedilla' => 'gcommaaccent',
+ 'Kcedilla' => 'Kcommaaccent', 'kcedilla' => 'kcommaaccent',
+ 'Lcedilla' => 'Lcommaaccent', 'lcedilla' => 'lcommaaccent',
+ 'Ncedilla' => 'Ncommaaccent', 'ncedilla' => 'ncommaaccent',
+ 'Rcedilla' => 'Rcommaaccent', 'rcedilla' => 'rcommaaccent',
+ 'Scedilla' => 'Scommaaccent',' scedilla' => 'scommaaccent',
+ 'Tcedilla' => 'Tcommaaccent',' tcedilla' => 'tcommaaccent',
+ 'Dslash' => 'Dcroat', 'dslash' => 'dcroat',
+ 'Dmacron' => 'Dcroat', 'dmacron' => 'dcroat',
+ 'combininggraveaccent' => 'gravecomb',
+ 'combininghookabove' => 'hookabovecomb',
+ 'combiningtildeaccent' => 'tildecomb',
+ 'combiningacuteaccent' => 'acutecomb',
+ 'combiningdotbelow' => 'dotbelowcomb',
+ 'dongsign' => 'dong'
+ }
+
+ a.each do |line|
+
+ e = line.rstrip.split(' ')
+ next if e.size < 2
+
+ code = e[0]
+ param = e[1]
+
+ if code == 'C' then
+
+ # Character metrics
+ cc = e[1].to_i
+ w = e[4]
+ gn = e[7]
+
+ gn = 'Euro' if gn[-4, 4] == '20AC'
+
+ if fix[gn] then
+
+ # Fix incorrect glyph name
+ 0.upto(map.size - 1) do |i|
+ if map[i] == fix[gn] then
+ map[i] = gn
+ end
+ end
+ end
+
+ if map.size == 0 then
+ # Symbolic font: use built-in encoding
+ widths[cc] = w
+ else
+ widths[gn] = w
+ fm['CapXHeight'] = e[13].to_i if gn == 'X'
+ end
+
+ fm['MissingWidth'] = w if gn == '.notdef'
+
+ elsif code == 'FontName' then
+ fm['FontName'] = param
+ elsif code == 'Weight' then
+ fm['Weight'] = param
+ elsif code == 'ItalicAngle' then
+ fm['ItalicAngle'] = param.to_f
+ elsif code == 'Ascender' then
+ fm['Ascender'] = param.to_i
+ elsif code == 'Descender' then
+ fm['Descender'] = param.to_i
+ elsif code == 'UnderlineThickness' then
+ fm['UnderlineThickness'] = param.to_i
+ elsif code == 'UnderlinePosition' then
+ fm['UnderlinePosition'] = param.to_i
+ elsif code == 'IsFixedPitch' then
+ fm['IsFixedPitch'] = (param == 'true')
+ elsif code == 'FontBBox' then
+ fm['FontBBox'] = "[#{e[1]},#{e[2]},#{e[3]},#{e[4]}]"
+ elsif code == 'CapHeight' then
+ fm['CapHeight'] = param.to_i
+ elsif code == 'StdVW' then
+ fm['StdVW'] = param.to_i
+ end
+ end
+
+ raise 'FontName not found' unless fm['FontName']
+
+ if map.size > 0 then
+ widths['.notdef'] = 600 unless widths['.notdef']
+
+ if (widths['Delta'] == nil) && widths['increment'] then
+ widths['Delta'] = widths['increment']
+ end
+
+ # Order widths according to map
+ 0.upto(255) do |i|
+ if widths[map[i]] == nil
+ puts "Warning: character #{map[i]} is missing"
+ widths[i] = widths['.notdef']
+ else
+ widths[i] = widths[map[i]]
+ end
+ end
+ end
+
+ fm['Widths'] = widths
+
+ return fm
+end
+
+def MakeFontDescriptor(fm, symbolic)
+
+ # Ascent
+ asc = fm['Ascender'] ? fm['Ascender'] : 1000
+ fd = "{\n 'Ascent' => '#{asc}'"
+
+ # Descent
+ desc = fm['Descender'] ? fm['Descender'] : -200
+ fd += ", 'Descent' => '#{desc}'"
+
+ # CapHeight
+ if fm['CapHeight'] then
+ ch = fm['CapHeight']
+ elsif fm['CapXHeight']
+ ch = fm['CapXHeight']
+ else
+ ch = asc
+ end
+ fd += ", 'CapHeight' => '#{ch}'"
+
+ # Flags
+ flags = 0
+
+ if fm['IsFixedPitch'] then
+ flags += 1 << 0
+ end
+
+ if symbolic then
+ flags += 1 << 2
+ else
+ flags += 1 << 5
+ end
+
+ if fm['ItalicAngle'] && (fm['ItalicAngle'] != 0) then
+ flags += 1 << 6
+ end
+
+ fd += ",\n 'Flags' => '#{flags}'"
+
+ # FontBBox
+ if fm['FontBBox'] then
+ fbb = fm['FontBBox'].gsub(/,/, ' ')
+ else
+ fbb = "[0 #{desc - 100} 1000 #{asc + 100}]"
+ end
+
+ fd += ", 'FontBBox' => '#{fbb}'"
+
+ # ItalicAngle
+ ia = fm['ItalicAngle'] ? fm['ItalicAngle'] : 0
+ fd += ",\n 'ItalicAngle' => '#{ia}'"
+
+ # StemV
+ if fm['StdVW'] then
+ stemv = fm['StdVW']
+ elsif fm['Weight'] && (/bold|black/i =~ fm['Weight'])
+ stemv = 120
+ else
+ stemv = 70
+ end
+
+ fd += ", 'StemV' => '#{stemv}'"
+
+ # MissingWidth
+ if fm['MissingWidth'] then
+ fd += ", 'MissingWidth' => '#{fm['MissingWidth']}'"
+ end
+
+ fd += "\n }"
+ return fd
+end
+
+def MakeWidthArray(fm)
+
+ # Make character width array
+ s = " [\n "
+
+ cw = fm['Widths']
+
+ 0.upto(255) do |i|
+ s += "%5d" % cw[i]
+ s += "," if i != 255
+ s += "\n " if (i % 8) == 7
+ end
+
+ s += ']'
+
+ return s
+end
+
+def MakeFontEncoding(map)
+
+ # Build differences from reference encoding
+ ref = Charencodings['cp1252']
+ s = ''
+ last = 0
+ 32.upto(255) do |i|
+ if map[i] != ref[i] then
+ if i != last + 1 then
+ s += i.to_s + ' '
+ end
+ last = i
+ s += '/' + map[i] + ' '
+ end
+ end
+ return s.rstrip
+end
+
+def ReadShort(f)
+ a = f.read(2).unpack('n')
+ return a[0]
+end
+
+def ReadLong(f)
+ a = f.read(4).unpack('N')
+ return a[0]
+end
+
+def CheckTTF(file)
+
+ rl = false
+ pp = false
+ e = false
+
+ # Check if font license allows embedding
+ File.open(file, 'rb') do |f|
+
+ # Extract number of tables
+ f.seek(4, IO::SEEK_CUR)
+ nb = ReadShort(f)
+ f.seek(6, IO::SEEK_CUR)
+
+ # Seek OS/2 table
+ found = false
+ 0.upto(nb - 1) do |i|
+ if f.read(4) == 'OS/2' then
+ found = true
+ break
+ end
+
+ f.seek(12, IO::SEEK_CUR)
+ end
+
+ if ! found then
+ return
+ end
+
+ f.seek(4, IO::SEEK_CUR)
+ offset = ReadLong(f)
+ f.seek(offset, IO::SEEK_SET)
+
+ # Extract fsType flags
+ f.seek(8, IO::SEEK_CUR)
+ fsType = ReadShort(f)
+
+ rl = (fsType & 0x02) != 0
+ pp = (fsType & 0x04) != 0
+ e = (fsType & 0x08) != 0
+ end
+
+ if rl && ( ! pp) && ( ! e) then
+ puts 'Warning: font license does not allow embedding'
+ end
+end
+
+#
+# fontfile: path to TTF file (or empty string if not to be embedded)
+# afmfile: path to AFM file
+# enc: font encoding (or empty string for symbolic fonts)
+# patch: optional patch for encoding
+# type : font type if $fontfile is empty
+#
+def MakeFont(fontfile, afmfile, enc = 'cp1252', patch = {}, type = 'TrueType')
+ # Generate a font definition file
+ if (enc != nil) && (enc != '') then
+ map = Charencodings[enc]
+ patch.each { |cc, gn| map[cc] = gn }
+ else
+ map = []
+ end
+
+ raise "Error: AFM file not found: #{afmfile}" unless File.exists?(afmfile)
+
+ fm = ReadAFM(afmfile, map)
+
+ if (enc != nil) && (enc != '') then
+ diff = MakeFontEncoding(map)
+ else
+ diff = ''
+ end
+
+ fd = MakeFontDescriptor(fm, (map.size == 0))
+
+ # Find font type
+ if fontfile then
+ ext = File.extname(fontfile).downcase.sub(/^\./, '')
+
+ if ext == 'ttf' then
+ type = 'TrueType'
+ elsif ext == 'pfb'
+ type = 'Type1'
+ else
+ raise "Error: unrecognized font file extension: #{ext}"
+ end
+ else
+ raise "Error: incorrect font type: #{type}" if (type != 'TrueType') && (type != 'Type1')
+ end
+ printf "type = #{type}\n"
+ # Start generation
+ s = "# #{fm['FontName']} font definition\n\n"
+ s += "module FontDef\n"
+ s += " def FontDef.type\n '#{type}'\n end\n"
+ s += " def FontDef.name\n '#{fm['FontName']}'\n end\n"
+ s += " def FontDef.desc\n #{fd}\n end\n"
+
+ if fm['UnderlinePosition'] == nil then
+ fm['UnderlinePosition'] = -100
+ end
+
+ if fm['UnderlineThickness'] == nil then
+ fm['UnderlineThickness'] = 50
+ end
+
+ s += " def FontDef.up\n #{fm['UnderlinePosition']}\n end\n"
+ s += " def FontDef.ut\n #{fm['UnderlineThickness']}\n end\n"
+
+ w = MakeWidthArray(fm)
+ s += " def FontDef.cw\n#{w}\n end\n"
+
+ s += " def FontDef.enc\n '#{enc}'\n end\n"
+ s += " def FontDef.diff\n #{(diff == nil) || (diff == '') ? 'nil' : '\'' + diff '\''}\n end\n"
+
+ basename = File.basename(afmfile, '.*')
+
+ if fontfile then
+ # Embedded font
+ if ! File.exist?(fontfile) then
+ raise "Error: font file not found: #{fontfile}"
+ end
+
+ if type == 'TrueType' then
+ CheckTTF(fontfile)
+ end
+
+ file = ''
+ File.open(fontfile, 'rb') do |f|
+ file = f.read()
+ end
+
+ if type == 'Type1' then
+ # Find first two sections and discard third one
+ header = file[0] == 128
+ file = file[6, file.length - 6] if header
+
+ pos = file.index('eexec')
+ raise 'Error: font file does not seem to be valid Type1' if pos == nil
+
+ size1 = pos + 6
+
+ file = file[0, size1] + file[size1 + 6, file.length - (size1 + 6)] if header && file[size1] == 128
+
+ pos = file.index('00000000')
+ raise 'Error: font file does not seem to be valid Type1' if pos == nil
+
+ size2 = pos - size1
+ file = file[0, size1 + size2]
+ end
+
+ if require 'zlib' then
+ File.open(basename + '.z', 'wb') { |f| f.write(Zlib::Deflate.deflate(file)) }
+ s += " def FontDef.file\n '#{basename}.z'\n end\n"
+ puts "Font file compressed ('#{basename}.z')"
+ else
+ s += " def FontDef.file\n '#{File.basename(fontfile)}'\n end\n"
+ puts 'Notice: font file could not be compressed (zlib not available)'
+ end
+
+ if type == 'Type1' then
+ s += " def FontDef.size1\n '#{size1}'\n end\n"
+ s += " def FontDef.size2\n '#{size2}'\n end\n"
+ else
+ s += " def FontDef.originalsize\n '#{File.size(fontfile)}'\n end\n"
+ end
+
+ else
+ # Not embedded font
+ s += " def FontDef.file\n ''\n end\n"
+ end
+
+ s += "end\n"
+ File.open(basename + '.rb', 'w') { |file| file.write(s)}
+ puts "Font definition file generated (#{basename}.rb)"
+end
+
+
+if $0 == __FILE__ then
+ if ARGV.length >= 3 then
+ enc = ARGV[2]
+ else
+ enc = 'cp1252'
+ end
+
+ if ARGV.length >= 4 then
+ patch = ARGV[3]
+ else
+ patch = {}
+ end
+
+ if ARGV.length >= 5 then
+ type = ARGV[4]
+ else
+ type = 'TrueType'
+ end
+
+ MakeFont(ARGV[0], ARGV[1], enc, patch, type)
+end
diff --git a/vendor/plugins/rfpdf/lib/rfpdf/rfpdf.rb b/vendor/plugins/rfpdf/lib/rfpdf/rfpdf.rb
new file mode 100644
index 000000000..5ad882903
--- /dev/null
+++ b/vendor/plugins/rfpdf/lib/rfpdf/rfpdf.rb
@@ -0,0 +1,346 @@
+module RFPDF
+ COLOR_PALETTE = {
+ :black => [0x00, 0x00, 0x00],
+ :white => [0xff, 0xff, 0xff],
+ }.freeze
+
+ # Draw a line from (<tt>x1, y1</tt>) to (<tt>x2, y2</tt>).
+ #
+ # Options are:
+ # * <tt>:line_color</tt> - Default value is <tt>COLOR_PALETTE[:black]</tt>.
+ # * <tt>:line_width</tt> - Default value is <tt>0.5</tt>.
+ #
+ # Example:
+ #
+ # draw_line(x1, y1, x1, y1+h, :line_color => ReportHelper::COLOR_PALETTE[:dark_blue], :line_width => 1)
+ #
+ def draw_line(x1, y1, x2, y2, options = {})
+ options[:line_color] ||= COLOR_PALETTE[:black]
+ options[:line_width] ||= 0.5
+ set_draw_color(options[:line_color])
+ SetLineWidth(options[:line_width])
+ Line(x1, y1, x2, y2)
+ end
+
+ # Draw a string of <tt>text</tt> at (<tt>x, y</tt>).
+ #
+ # Options are:
+ # * <tt>:font_color</tt> - Default value is <tt>COLOR_PALETTE[:black]</tt>.
+ # * <tt>:font_size</tt> - Default value is <tt>10</tt>.
+ # * <tt>:font_style</tt> - Default value is nothing or <tt>''</tt>.
+ #
+ # Example:
+ #
+ # draw_text(x, y, header_left, :font_size => 10)
+ #
+ def draw_text(x, y, text, options = {})
+ options[:font_color] ||= COLOR_PALETTE[:black]
+ options[:font_size] ||= 10
+ options[:font_style] ||= ''
+ set_text_color(options[:font_color])
+ SetFont('Arial', options[:font_style], options[:font_size])
+ SetXY(x, y)
+ Write(options[:font_size] + 4, text)
+ end
+
+ # Draw a block of <tt>text</tt> at (<tt>x, y</tt>) bounded by <tt>left_margin</tt> and <tt>right_margin</tt>. Both
+ # margins are measured from their corresponding edge.
+ #
+ # Options are:
+ # * <tt>:font_color</tt> - Default value is <tt>COLOR_PALETTE[:black]</tt>.
+ # * <tt>:font_size</tt> - Default value is <tt>10</tt>.
+ # * <tt>:font_style</tt> - Default value is nothing or <tt>''</tt>.
+ #
+ # Example:
+ #
+ # draw_text_block(left_margin, 85, "question", left_margin, 280,
+ # :font_color => ReportHelper::COLOR_PALETTE[:dark_blue],
+ # :font_size => 12,
+ # :font_style => 'I')
+ #
+ def draw_text_block(x, y, text, left_margin, right_margin, options = {})
+ options[:font_color] ||= COLOR_PALETTE[:black]
+ options[:font_size] ||= 10
+ options[:font_style] ||= ''
+ set_text_color(options[:font_color])
+ SetFont('Arial', options[:font_style], options[:font_size])
+ SetXY(x, y)
+ SetLeftMargin(left_margin)
+ SetRightMargin(right_margin)
+ Write(options[:font_size] + 4, text)
+ SetMargins(0,0,0)
+ end
+
+ # Draw a box at (<tt>x, y</tt>), <tt>w</tt> wide and <tt>h</tt> high.
+ #
+ # Options are:
+ # * <tt>:border</tt> - Draw a border, 0 = no, 1 = yes? Default value is <tt>1</tt>.
+ # * <tt>:border_color</tt> - Default value is <tt>COLOR_PALETTE[:black]</tt>.
+ # * <tt>:border_width</tt> - Default value is <tt>0.5</tt>.
+ # * <tt>:fill</tt> - Fill the box, 0 = no, 1 = yes? Default value is <tt>1</tt>.
+ # * <tt>:fill_color</tt> - Default value is nothing or <tt>COLOR_PALETTE[:white]</tt>.
+ #
+ # Example:
+ #
+ # draw_box(x, y - 1, 38, 22)
+ #
+ def draw_box(x, y, w, h, options = {})
+ options[:border] ||= 1
+ options[:border_color] ||= COLOR_PALETTE[:black]
+ options[:border_width] ||= 0.5
+ options[:fill] ||= 1
+ options[:fill_color] ||= COLOR_PALETTE[:white]
+ SetLineWidth(options[:border_width])
+ set_draw_color(options[:border_color])
+ set_fill_color(options[:fill_color])
+ fd = ""
+ fd = "D" if options[:border] == 1
+ fd += "F" if options[:fill] == 1
+ Rect(x, y, w, h, fd)
+ end
+
+ # Draw a string of <tt>text</tt> at (<tt>x, y</tt>) in a box <tt>w</tt> wide and <tt>h</tt> high.
+ #
+ # Options are:
+ # * <tt>:align</tt> - Vertical alignment 'C' = center, 'L' = left, 'R' = right. Default value is <tt>'C'</tt>.
+ # * <tt>:border</tt> - Draw a border, 0 = no, 1 = yes? Default value is <tt>0</tt>.
+ # * <tt>:border_color</tt> - Default value is <tt>COLOR_PALETTE[:black]</tt>.
+ # * <tt>:border_width</tt> - Default value is <tt>0.5</tt>.
+ # * <tt>:fill</tt> - Fill the box, 0 = no, 1 = yes? Default value is <tt>1</tt>.
+ # * <tt>:fill_color</tt> - Default value is nothing or <tt>COLOR_PALETTE[:white]</tt>.
+ # * <tt>:font_color</tt> - Default value is <tt>COLOR_PALETTE[:black]</tt>.
+ # * <tt>:font_size</tt> - Default value is nothing or <tt>8</tt>.
+ # * <tt>:font_style</tt> - 'B' = bold, 'I' = italic, 'U' = underline. Default value is nothing <tt>''</tt>.
+ # * <tt>:padding</tt> - Default value is nothing or <tt>2</tt>.
+ # * <tt>:valign</tt> - 'M' = middle, 'T' = top, 'B' = bottom. Default value is nothing or <tt>'M'</tt>.
+ #
+ # Example:
+ #
+ # draw_text_box(x, y - 1, 38, 22,
+ # "your_score_title",
+ # :fill => 0,
+ # :font_color => ReportHelper::COLOR_PALETTE[:blue],
+ # :font_line_spacing => 0,
+ # :font_style => "B",
+ # :valign => "M")
+ #
+ def draw_text_box(x, y, w, h, text, options = {})
+ options[:align] ||= 'C'
+ options[:border] ||= 0
+ options[:border_color] ||= COLOR_PALETTE[:black]
+ options[:border_width] ||= 0.5
+ options[:fill] ||= 1
+ options[:fill_color] ||= COLOR_PALETTE[:white]
+ options[:font_color] ||= COLOR_PALETTE[:black]
+ options[:font_size] ||= 8
+ options[:font_line_spacing] ||= options[:font_size] * 0.3
+ options[:font_style] ||= ''
+ options[:padding] ||= 2
+ options[:valign] ||= "M"
+ if options[:fill] == 1 or options[:border] == 1
+ draw_box(x, y, w, h, options)
+ end
+ SetMargins(0,0,0)
+ set_text_color(options[:font_color])
+ font_size = options[:font_size]
+ SetFont('Arial', options[:font_style], font_size)
+ font_size += options[:font_line_spacing]
+ case options[:valign]
+ when "B"
+ y -= options[:padding]
+ text = "\n" + text if text["\n"].nil?
+ when "T"
+ y += options[:padding]
+ end
+ SetXY(x, y)
+ if GetStringWidth(text) > w or not text["\n"].nil? or options[:valign] == "T"
+ font_size += options[:font_size] * 0.1
+ #TODO 2006-07-21 Level=1 - this is assuming a 2 line text
+ SetXY(x, y + ((h - (font_size * 2)) / 2)) if options[:valign] == "M"
+ MultiCell(w, font_size, text, 0, options[:align])
+ else
+ Cell(w, h, text, 0, 0, options[:align])
+ end
+ end
+
+ # Draw a string of <tt>text</tt> at (<tt>x, y</tt>) as a title.
+ #
+ # Options are:
+ # * <tt>:font_color</tt> - Default value is <tt>COLOR_PALETTE[:black]</tt>.
+ # * <tt>:font_size</tt> - Default value is <tt>18</tt>.
+ # * <tt>:font_style</tt> - Default value is nothing or <tt>''</tt>.
+ #
+ # Example:
+ #
+ # draw_title(left_margin, 60,
+ # "title:",
+ # :font_color => ReportHelper::COLOR_PALETTE[:dark_blue])
+ #
+ def draw_title(x, y, title, options = {})
+ options[:font_color] ||= COLOR_PALETTE[:black]
+ options[:font_size] ||= 18
+ options[:font_style] ||= ''
+ set_text_color(options[:font_color])
+ SetFont('Arial', options[:font_style], options[:font_size])
+ SetXY(x, y)
+ Write(options[:font_size] + 2, title)
+ end
+
+ # Set the draw color. Default value is <tt>COLOR_PALETTE[:black]</tt>.
+ #
+ # Example:
+ #
+ # set_draw_color(ReportHelper::COLOR_PALETTE[:dark_blue])
+ #
+ def set_draw_color(color = COLOR_PALETTE[:black])
+ SetDrawColor(color[0], color[1], color[2])
+ end
+
+ # Set the fill color. Default value is <tt>COLOR_PALETTE[:white]</tt>.
+ #
+ # Example:
+ #
+ # set_fill_color(ReportHelper::COLOR_PALETTE[:dark_blue])
+ #
+ def set_fill_color(color = COLOR_PALETTE[:white])
+ SetFillColor(color[0], color[1], color[2])
+ end
+
+ # Set the text color. Default value is <tt>COLOR_PALETTE[:white]</tt>.
+ #
+ # Example:
+ #
+ # set_text_color(ReportHelper::COLOR_PALETTE[:dark_blue])
+ #
+ def set_text_color(color = COLOR_PALETTE[:black])
+ SetTextColor(color[0], color[1], color[2])
+ end
+
+ # Write a string containing html characters. Default value is <tt>COLOR_PALETTE[:white]</tt>.
+ #
+ # Options are:
+ # * <tt>:height</tt> - Line height. Default value is <tt>20</tt>.
+ #
+ # Example:
+ #
+ # write_html(html, :height => 12)
+ #
+ def write_html(html, options = {})
+ options[:height] ||= 20
+ #HTML parser
+ @href = nil
+ @style = {}
+ html.gsub!("\n",' ')
+ re = %r{ ( <!--.*?--> |
+ < (?:
+ [^<>"] +
+ |
+ " (?: \\. | [^\\"]+ ) * "
+ ) *
+ >
+ ) }xm
+
+ html.split(re).each do |value|
+ if "<" == value[0,1]
+ #Tag
+ if (value[1, 1] == '/')
+ close_tag(value[2..-2], options)
+ else
+ tag = value[1..-2]
+ open_tag(tag, options)
+ end
+ else
+ #Text
+ if @href
+ put_link(@href,value)
+ else
+ Write(options[:height], value)
+ end
+ end
+ end
+ end
+
+ def open_tag(tag, options = {}) #:nodoc:
+ #Opening tag
+ tag = tag.to_s.upcase
+ set_style(tag, true) if tag == 'B' or tag == 'I' or tag == 'U'
+ @href = options['HREF'] if tag == 'A'
+ Ln(options[:height]) if tag == 'BR'
+ end
+
+ def close_tag(tag, options = {}) #:nodoc:
+ #Closing tag
+ tag = tag.to_s.upcase
+ set_style(tag, false) if tag == 'B' or tag == 'I' or tag == 'U'
+ @href = '' if $tag == 'A'
+ end
+
+ def set_style(tag, enable = true) #:nodoc:
+ #Modify style and select corresponding font
+ style = ""
+ @style[tag] = enable
+ ['B','I','U'].each do |s|
+ style += s if not @style[s].nil? and @style[s]
+ end
+ SetFont('', style)
+ end
+
+ def put_link(url, txt) #:nodoc:
+ #Put a hyperlink
+ SetTextColor(0,0,255)
+ set_style('U',true)
+ Write(5, txt, url)
+ set_style('U',false)
+ SetTextColor(0)
+ end
+end
+
+# class FPDF
+# alias_method :set_margins , :SetMargins
+# alias_method :set_left_margin , :SetLeftMargin
+# alias_method :set_top_margin , :SetTopMargin
+# alias_method :set_right_margin , :SetRightMargin
+# alias_method :set_auto_pagebreak , :SetAutoPageBreak
+# alias_method :set_display_mode , :SetDisplayMode
+# alias_method :set_compression , :SetCompression
+# alias_method :set_title , :SetTitle
+# alias_method :set_subject , :SetSubject
+# alias_method :set_author , :SetAuthor
+# alias_method :set_keywords , :SetKeywords
+# alias_method :set_creator , :SetCreator
+# alias_method :set_draw_color , :SetDrawColor
+# alias_method :set_fill_color , :SetFillColor
+# alias_method :set_text_color , :SetTextColor
+# alias_method :set_line_width , :SetLineWidth
+# alias_method :set_font , :SetFont
+# alias_method :set_font_size , :SetFontSize
+# alias_method :set_link , :SetLink
+# alias_method :set_y , :SetY
+# alias_method :set_xy , :SetXY
+# alias_method :get_string_width , :GetStringWidth
+# alias_method :get_x , :GetX
+# alias_method :set_x , :SetX
+# alias_method :get_y , :GetY
+# alias_method :accept_pagev_break , :AcceptPageBreak
+# alias_method :add_font , :AddFont
+# alias_method :add_link , :AddLink
+# alias_method :add_page , :AddPage
+# alias_method :alias_nb_pages , :AliasNbPages
+# alias_method :cell , :Cell
+# alias_method :close , :Close
+# alias_method :error , :Error
+# alias_method :footer , :Footer
+# alias_method :header , :Header
+# alias_method :image , :Image
+# alias_method :line , :Line
+# alias_method :link , :Link
+# alias_method :ln , :Ln
+# alias_method :multi_cell , :MultiCell
+# alias_method :open , :Open
+# alias_method :Open , :open
+# alias_method :output , :Output
+# alias_method :page_no , :PageNo
+# alias_method :rect , :Rect
+# alias_method :text , :Text
+# alias_method :write , :Write
+# end
diff --git a/vendor/plugins/rfpdf/lib/rfpdf/view.rb b/vendor/plugins/rfpdf/lib/rfpdf/view.rb
new file mode 100644
index 000000000..185811202
--- /dev/null
+++ b/vendor/plugins/rfpdf/lib/rfpdf/view.rb
@@ -0,0 +1,75 @@
+# Copyright (c) 2006 4ssoM LLC <www.4ssoM.com>
+#
+# The MIT License
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# Thanks go out to Bruce Williams of codefluency who created RTex. This
+# template handler is modification of his work.
+#
+# Example Registration
+#
+# ActionView::Base::register_template_handler 'rfpdf', RFpdfView
+
+module RFPDF
+
+ class View
+
+ def initialize(action_view)
+ @action_view = action_view
+ # Override with @options_for_rfpdf Hash in your controller
+ @options = {
+ # Run through latex first? (for table of contents, etc)
+ :pre_process => false,
+ # Debugging mode; raises exception
+ :debug => false,
+ # Filename of pdf to generate
+ :file_name => "#{@action_view.controller.action_name}.pdf",
+ # Temporary Directory
+ :temp_dir => "#{File.expand_path(RAILS_ROOT)}/tmp"
+ }.merge(@action_view.controller.instance_eval{ @options_for_rfpdf } || {}).with_indifferent_access
+ end
+
+ def render(template, local_assigns = {})
+ @pdf_name = "Default.pdf" if @pdf_name.nil?
+ unless @action_view.controller.headers["Content-Type"] == 'application/pdf'
+ @generate = true
+ @action_view.controller.headers["Content-Type"] = 'application/pdf'
+ @action_view.controller.headers["Content-disposition:"] = "inline; filename=\"#{@options[:file_name]}\""
+ end
+ assigns = @action_view.assigns.dup
+
+ if content_for_layout = @action_view.instance_variable_get("@content_for_layout")
+ assigns['content_for_layout'] = content_for_layout
+ end
+
+ result = @action_view.instance_eval do
+ assigns.each do |key,val|
+ instance_variable_set "@#{key}", val
+ end
+ local_assigns.each do |key,val|
+ class << self; self; end.send(:define_method,key){ val }
+ end
+ ERB.new(template).result(binding)
+ end
+ end
+
+ end
+
+end \ No newline at end of file
diff --git a/vendor/plugins/rfpdf/test/test_helper.rb b/vendor/plugins/rfpdf/test/test_helper.rb
new file mode 100644
index 000000000..2e2ea3bc5
--- /dev/null
+++ b/vendor/plugins/rfpdf/test/test_helper.rb
@@ -0,0 +1 @@
+#!/usr/bin/env ruby \ No newline at end of file