1688 lines
78 KiB
Python
1688 lines
78 KiB
Python
#!/usr/bin/env python
|
|
# -*- coding: latin-1 -*-
|
|
# ******************************************************************************
|
|
# * Software: FPDF for python *
|
|
# * Version: 1.54c *
|
|
# * Date: 2010-09-10 *
|
|
# * License: LGPL v3.0 *
|
|
# * *
|
|
# * Original Author (PHP): Olivier PLATHEY 2004-12-31 *
|
|
# * Ported to Python 2.4 by Max (maxpat78@yahoo.it) on 2006-05 *
|
|
# * Maintainer: Mariano Reingart (reingart@gmail.com) et al since 2008 (est.) *
|
|
# * NOTE: 'I' and 'D' destinations are disabled, and simply print to STDOUT *
|
|
# *****************************************************************************/
|
|
|
|
from datetime import datetime
|
|
import math
|
|
import os, sys, zlib, struct
|
|
|
|
try:
|
|
# Check if PIL is available, necessary for JPEG support.
|
|
import Image
|
|
except ImportError:
|
|
Image = None
|
|
|
|
def substr(s, start, length=-1):
|
|
if length < 0:
|
|
length=len(s)-start
|
|
return s[start:start+length]
|
|
|
|
def sprintf(fmt, *args): return fmt % args
|
|
|
|
# Global variables
|
|
FPDF_VERSION='1.54b'
|
|
FPDF_FONT_DIR=os.path.join(os.path.dirname(__file__),'font')
|
|
fpdf_charwidths = {}
|
|
|
|
class FPDF:
|
|
#Private properties
|
|
#~ page; #current page number
|
|
#~ n; #current object number
|
|
#~ offsets; #array of object offsets
|
|
#~ buffer; #buffer holding in-memory PDF
|
|
#~ pages; #array containing pages
|
|
#~ state; #current document state
|
|
#~ compress; #compression flag
|
|
#~ def_orientation; #default orientation
|
|
#~ cur_orientation; #current orientation
|
|
#~ orientation_changes; #array indicating orientation changes
|
|
#~ k; #scale factor (number of points in user unit)
|
|
#~ fw_pt,fh_pt; #dimensions of page format in points
|
|
#~ fw,fh; #dimensions of page format in user unit
|
|
#~ w_pt,h_pt; #current dimensions of page in points
|
|
#~ w,h; #current dimensions of page in user unit
|
|
#~ l_margin; #left margin
|
|
#~ t_margin; #top margin
|
|
#~ r_margin; #right margin
|
|
#~ b_margin; #page break margin
|
|
#~ c_margin; #cell margin
|
|
#~ x,y; #current position in user unit for cell positioning
|
|
#~ lasth; #height of last cell printed
|
|
#~ line_width; #line width in user unit
|
|
#~ core_fonts; #array of standard font names
|
|
#~ fonts; #array of used fonts
|
|
#~ font_files; #array of font files
|
|
#~ diffs; #array of encoding differences
|
|
#~ images; #array of used images
|
|
#~ page_links; #array of links in pages
|
|
#~ links; #array of internal links
|
|
#~ font_family; #current font family
|
|
#~ font_style; #current font style
|
|
#~ underline; #underlining flag
|
|
#~ current_font; #current font info
|
|
#~ font_size_pt; #current font size in points
|
|
#~ font_size; #current font size in user unit
|
|
#~ draw_color; #commands for drawing color
|
|
#~ fill_color; #commands for filling color
|
|
#~ text_color; #commands for text color
|
|
#~ color_flag; #indicates whether fill and text colors are different
|
|
#~ ws; #word spacing
|
|
#~ auto_page_break; #automatic page breaking
|
|
#~ page_break_trigger; #threshold used to trigger page breaks
|
|
#~ in_footer; #flag set when processing footer
|
|
#~ zoom_mode; #zoom display mode
|
|
#~ layout_mode; #layout display mode
|
|
#~ title; #title
|
|
#~ subject; #subject
|
|
#~ author; #author
|
|
#~ keywords; #keywords
|
|
#~ creator; #creator
|
|
#~ alias_nb_pages; #alias for total number of pages
|
|
#~ pdf_version; #PDF version number
|
|
|
|
# ******************************************************************************
|
|
# * *
|
|
# * Public methods *
|
|
# * *
|
|
# *******************************************************************************/
|
|
def __init__(self, orientation='P',unit='mm',format='A4'):
|
|
#Some checks
|
|
self._dochecks()
|
|
#Initialization of properties
|
|
self.offsets={}
|
|
self.page=0
|
|
self.n=2
|
|
self.buffer=''
|
|
self.pages={}
|
|
self.orientation_changes={}
|
|
self.state=0
|
|
self.fonts={}
|
|
self.font_files={}
|
|
self.diffs={}
|
|
self.images={}
|
|
self.page_links={}
|
|
self.links={}
|
|
self.in_footer=0
|
|
self.lastw=0
|
|
self.lasth=0
|
|
self.font_family=''
|
|
self.font_style=''
|
|
self.font_size_pt=12
|
|
self.underline=0
|
|
self.draw_color='0 G'
|
|
self.fill_color='0 g'
|
|
self.text_color='0 g'
|
|
self.color_flag=0
|
|
self.ws=0
|
|
self.angle=0
|
|
#Standard fonts
|
|
self.core_fonts={'courier':'Courier','courierB':'Courier-Bold','courierI':'Courier-Oblique','courierBI':'Courier-BoldOblique',
|
|
'helvetica':'Helvetica','helveticaB':'Helvetica-Bold','helveticaI':'Helvetica-Oblique','helveticaBI':'Helvetica-BoldOblique',
|
|
'times':'Times-Roman','timesB':'Times-Bold','timesI':'Times-Italic','timesBI':'Times-BoldItalic',
|
|
'symbol':'Symbol','zapfdingbats':'ZapfDingbats'}
|
|
#Scale factor
|
|
if(unit=='pt'):
|
|
self.k=1
|
|
elif(unit=='mm'):
|
|
self.k=72/25.4
|
|
elif(unit=='cm'):
|
|
self.k=72/2.54
|
|
elif(unit=='in'):
|
|
self.k=72
|
|
else:
|
|
self.error('Incorrect unit: '+unit)
|
|
#Page format
|
|
if(isinstance(format,basestring)):
|
|
format=format.lower()
|
|
if(format=='a3'):
|
|
format=(841.89,1190.55)
|
|
elif(format=='a4'):
|
|
format=(595.28,841.89)
|
|
elif(format=='a5'):
|
|
format=(420.94,595.28)
|
|
elif(format=='letter'):
|
|
format=(612,792)
|
|
elif(format=='legal'):
|
|
format=(612,1008)
|
|
else:
|
|
self.error('Unknown page format: '+format)
|
|
self.fw_pt=format[0]
|
|
self.fh_pt=format[1]
|
|
else:
|
|
self.fw_pt=format[0]*self.k
|
|
self.fh_pt=format[1]*self.k
|
|
self.fw=self.fw_pt/self.k
|
|
self.fh=self.fh_pt/self.k
|
|
#Page orientation
|
|
orientation=orientation.lower()
|
|
if(orientation=='p' or orientation=='portrait'):
|
|
self.def_orientation='P'
|
|
self.w_pt=self.fw_pt
|
|
self.h_pt=self.fh_pt
|
|
elif(orientation=='l' or orientation=='landscape'):
|
|
self.def_orientation='L'
|
|
self.w_pt=self.fh_pt
|
|
self.h_pt=self.fw_pt
|
|
else:
|
|
self.error('Incorrect orientation: '+orientation)
|
|
self.cur_orientation=self.def_orientation
|
|
self.w=self.w_pt/self.k
|
|
self.h=self.h_pt/self.k
|
|
#Page margins (1 cm)
|
|
margin=28.35/self.k
|
|
self.set_margins(margin,margin)
|
|
#Interior cell margin (1 mm)
|
|
self.c_margin=margin/10.0
|
|
#line width (0.2 mm)
|
|
self.line_width=.567/self.k
|
|
#Automatic page break
|
|
self.set_auto_page_break(1,2*margin)
|
|
#Full width display mode
|
|
self.set_display_mode('fullwidth')
|
|
#Enable compression
|
|
self.set_compression(1)
|
|
#Set default PDF version number
|
|
self.pdf_version='1.3'
|
|
|
|
def set_margins(self, left,top,right=-1):
|
|
"Set left, top and right margins"
|
|
self.l_margin=left
|
|
self.t_margin=top
|
|
if(right==-1):
|
|
right=left
|
|
self.r_margin=right
|
|
|
|
def set_left_margin(self, margin):
|
|
"Set left margin"
|
|
self.l_margin=margin
|
|
if(self.page>0 and self.x<margin):
|
|
self.x=margin
|
|
|
|
def set_top_margin(self, margin):
|
|
"Set top margin"
|
|
self.t_margin=margin
|
|
|
|
def set_right_margin(self, margin):
|
|
"Set right margin"
|
|
self.r_margin=margin
|
|
|
|
def set_auto_page_break(self, auto,margin=0):
|
|
"Set auto page break mode and triggering margin"
|
|
self.auto_page_break=auto
|
|
self.b_margin=margin
|
|
self.page_break_trigger=self.h-margin
|
|
|
|
def set_display_mode(self, zoom,layout='continuous'):
|
|
"Set display mode in viewer"
|
|
if(zoom=='fullpage' or zoom=='fullwidth' or zoom=='real' or zoom=='default' or not isinstance(zoom,basestring)):
|
|
self.zoom_mode=zoom
|
|
else:
|
|
self.error('Incorrect zoom display mode: '+zoom)
|
|
if(layout=='single' or layout=='continuous' or layout=='two' or layout=='default'):
|
|
self.layout_mode=layout
|
|
else:
|
|
self.error('Incorrect layout display mode: '+layout)
|
|
|
|
def set_compression(self, compress):
|
|
"Set page compression"
|
|
self.compress=compress
|
|
|
|
def set_title(self, title):
|
|
"Title of document"
|
|
self.title=title
|
|
|
|
def set_subject(self, subject):
|
|
"Subject of document"
|
|
self.subject=subject
|
|
|
|
def set_author(self, author):
|
|
"Author of document"
|
|
self.author=author
|
|
|
|
def set_keywords(self, keywords):
|
|
"Keywords of document"
|
|
self.keywords=keywords
|
|
|
|
def set_creator(self, creator):
|
|
"Creator of document"
|
|
self.creator=creator
|
|
|
|
def alias_nb_pages(self, alias='{nb}'):
|
|
"Define an alias for total number of pages"
|
|
self.str_alias_nb_pages=alias
|
|
return alias
|
|
|
|
def error(self, msg):
|
|
"Fatal error"
|
|
raise RuntimeError('FPDF error: '+msg)
|
|
|
|
def open(self):
|
|
"Begin document"
|
|
self.state=1
|
|
|
|
def close(self):
|
|
"Terminate document"
|
|
if(self.state==3):
|
|
return
|
|
if(self.page==0):
|
|
self.add_page()
|
|
#Page footer
|
|
self.in_footer=1
|
|
self.footer()
|
|
self.in_footer=0
|
|
#close page
|
|
self._endpage()
|
|
#close document
|
|
self._enddoc()
|
|
|
|
def add_page(self, orientation=''):
|
|
"Start a new page"
|
|
if(self.state==0):
|
|
self.open()
|
|
family=self.font_family
|
|
if self.underline:
|
|
style = self.font_style + 'U'
|
|
else:
|
|
style = self.font_style
|
|
size=self.font_size_pt
|
|
lw=self.line_width
|
|
dc=self.draw_color
|
|
fc=self.fill_color
|
|
tc=self.text_color
|
|
cf=self.color_flag
|
|
if(self.page>0):
|
|
#Page footer
|
|
self.in_footer=1
|
|
self.footer()
|
|
self.in_footer=0
|
|
#close page
|
|
self._endpage()
|
|
#Start new page
|
|
self._beginpage(orientation)
|
|
#Set line cap style to square
|
|
self._out('2 J')
|
|
#Set line width
|
|
self.line_width=lw
|
|
self._out(sprintf('%.2f w',lw*self.k))
|
|
#Set font
|
|
if(family):
|
|
self.set_font(family,style,size)
|
|
#Set colors
|
|
self.draw_color=dc
|
|
if(dc!='0 G'):
|
|
self._out(dc)
|
|
self.fill_color=fc
|
|
if(fc!='0 g'):
|
|
self._out(fc)
|
|
self.text_color=tc
|
|
self.color_flag=cf
|
|
#Page header
|
|
self.header()
|
|
#Restore line width
|
|
if(self.line_width!=lw):
|
|
self.line_width=lw
|
|
self._out(sprintf('%.2f w',lw*self.k))
|
|
#Restore font
|
|
if(family):
|
|
self.set_font(family,style,size)
|
|
#Restore colors
|
|
if(self.draw_color!=dc):
|
|
self.draw_color=dc
|
|
self._out(dc)
|
|
if(self.fill_color!=fc):
|
|
self.fill_color=fc
|
|
self._out(fc)
|
|
self.text_color=tc
|
|
self.color_flag=cf
|
|
|
|
def header(self):
|
|
"Header to be implemented in your own inherited class"
|
|
pass
|
|
|
|
def footer(self):
|
|
"Footer to be implemented in your own inherited class"
|
|
pass
|
|
|
|
def page_no(self):
|
|
"Get current page number"
|
|
return self.page
|
|
|
|
def set_draw_color(self, r,g=-1,b=-1):
|
|
"Set color for all stroking operations"
|
|
if((r==0 and g==0 and b==0) or g==-1):
|
|
self.draw_color=sprintf('%.3f G',r/255.0)
|
|
else:
|
|
self.draw_color=sprintf('%.3f %.3f %.3f RG',r/255.0,g/255.0,b/255.0)
|
|
if(self.page>0):
|
|
self._out(self.draw_color)
|
|
|
|
def set_fill_color(self,r,g=-1,b=-1):
|
|
"Set color for all filling operations"
|
|
if((r==0 and g==0 and b==0) or g==-1):
|
|
self.fill_color=sprintf('%.3f g',r/255.0)
|
|
else:
|
|
self.fill_color=sprintf('%.3f %.3f %.3f rg',r/255.0,g/255.0,b/255.0)
|
|
self.color_flag=(self.fill_color!=self.text_color)
|
|
if(self.page>0):
|
|
self._out(self.fill_color)
|
|
|
|
def set_text_color(self, r,g=-1,b=-1):
|
|
"Set color for text"
|
|
if((r==0 and g==0 and b==0) or g==-1):
|
|
self.text_color=sprintf('%.3f g',r/255.0)
|
|
else:
|
|
self.text_color=sprintf('%.3f %.3f %.3f rg',r/255.0,g/255.0,b/255.0)
|
|
self.color_flag=(self.fill_color!=self.text_color)
|
|
|
|
def get_string_width(self, s):
|
|
"Get width of a string in the current font"
|
|
cw=self.current_font['cw']
|
|
w=0
|
|
l=len(s)
|
|
for i in xrange(0, l):
|
|
w += cw.get(s[i],0)
|
|
return w*self.font_size/1000.0
|
|
|
|
def set_line_width(self, width):
|
|
"Set line width"
|
|
self.line_width=width
|
|
if(self.page>0):
|
|
self._out(sprintf('%.2f w',width*self.k))
|
|
|
|
def line(self, x1,y1,x2,y2):
|
|
"Draw a line"
|
|
self._out(sprintf('%.2f %.2f m %.2f %.2f l S',x1*self.k,(self.h-y1)*self.k,x2*self.k,(self.h-y2)*self.k))
|
|
|
|
def rect(self, x,y,w,h,style=''):
|
|
"Draw a rectangle"
|
|
if(style=='F'):
|
|
op='f'
|
|
elif(style=='FD' or style=='DF'):
|
|
op='B'
|
|
else:
|
|
op='S'
|
|
self._out(sprintf('%.2f %.2f %.2f %.2f re %s',x*self.k,(self.h-y)*self.k,w*self.k,-h*self.k,op))
|
|
|
|
def add_font(self, family,style='',fname=''):
|
|
"Add a TrueType or Type1 font"
|
|
family=family.lower()
|
|
if(fname==''):
|
|
fname=family.replace(' ','')+style.lower()+'.font'
|
|
fname=os.path.join(FPDF_FONT_DIR,fname)
|
|
if(family=='arial'):
|
|
family='helvetica'
|
|
style=style.upper()
|
|
if(style=='IB'):
|
|
style='BI'
|
|
fontkey=family+style
|
|
if fontkey in self.fonts:
|
|
self.error('Font already added: '+family+' '+style)
|
|
execfile(fname, globals(), globals())
|
|
if 'name' not in globals():
|
|
self.error('Could not include font definition file')
|
|
i=len(self.fonts)+1
|
|
self.fonts[fontkey]={'i':i,'type':type,'name':name,'desc':desc,'up':up,'ut':ut,'cw':cw,'enc':enc,'file':filename}
|
|
if(diff):
|
|
#Search existing encodings
|
|
d=0
|
|
nb=len(self.diffs)
|
|
for i in xrange(1,nb+1):
|
|
if(self.diffs[i]==diff):
|
|
d=i
|
|
break
|
|
if(d==0):
|
|
d=nb+1
|
|
self.diffs[d]=diff
|
|
self.fonts[fontkey]['diff']=d
|
|
if(filename):
|
|
if(type=='TrueType'):
|
|
self.font_files[filename]={'length1':originalsize}
|
|
else:
|
|
self.font_files[filename]={'length1':size1,'length2':size2}
|
|
|
|
def set_font(self, family,style='',size=0):
|
|
"Select a font; size given in points"
|
|
family=family.lower()
|
|
if(family==''):
|
|
family=self.font_family
|
|
if(family=='arial'):
|
|
family='helvetica'
|
|
elif(family=='symbol' or family=='zapfdingbats'):
|
|
style=''
|
|
style=style.upper()
|
|
if('U' in style):
|
|
self.underline=1
|
|
style=style.replace('U','')
|
|
else:
|
|
self.underline=0
|
|
if(style=='IB'):
|
|
style='BI'
|
|
if(size==0):
|
|
size=self.font_size_pt
|
|
#Test if font is already selected
|
|
if(self.font_family==family and self.font_style==style and self.font_size_pt==size):
|
|
return
|
|
#Test if used for the first time
|
|
fontkey=family+style
|
|
if fontkey not in self.fonts:
|
|
#Check if one of the standard fonts
|
|
if fontkey in self.core_fonts:
|
|
if fontkey not in fpdf_charwidths:
|
|
#Load metric file
|
|
name=os.path.join(FPDF_FONT_DIR,family)
|
|
if(family=='times' or family=='helvetica'):
|
|
name+=style.lower()
|
|
execfile(name+'.font')
|
|
if fontkey not in fpdf_charwidths:
|
|
self.error('Could not include font metric file for'+fontkey)
|
|
i=len(self.fonts)+1
|
|
self.fonts[fontkey]={'i':i,'type':'core','name':self.core_fonts[fontkey],'up':-100,'ut':50,'cw':fpdf_charwidths[fontkey]}
|
|
else:
|
|
self.error('Undefined font: '+family+' '+style)
|
|
#Select it
|
|
self.font_family=family
|
|
self.font_style=style
|
|
self.font_size_pt=size
|
|
self.font_size=size/self.k
|
|
self.current_font=self.fonts[fontkey]
|
|
if(self.page>0):
|
|
self._out(sprintf('BT /F%d %.2f Tf ET',self.current_font['i'],self.font_size_pt))
|
|
|
|
def set_font_size(self, size):
|
|
"Set font size in points"
|
|
if(self.font_size_pt==size):
|
|
return
|
|
self.font_size_pt=size
|
|
self.font_size=size/self.k
|
|
if(self.page>0):
|
|
self._out(sprintf('BT /F%d %.2f Tf ET',self.current_font['i'],self.font_size_pt))
|
|
|
|
def add_link(self):
|
|
"Create a new internal link"
|
|
n=len(self.links)+1
|
|
self.links[n]=(0,0)
|
|
return n
|
|
|
|
def set_link(self, link,y=0,page=-1):
|
|
"Set destination of internal link"
|
|
if(y==-1):
|
|
y=self.y
|
|
if(page==-1):
|
|
page=self.page
|
|
self.links[link]=[page,y]
|
|
|
|
def link(self, x,y,w,h,link):
|
|
"Put a link on the page"
|
|
if not self.page in self.page_links:
|
|
self.page_links[self.page] = []
|
|
self.page_links[self.page] += [(x*self.k,self.h_pt-y*self.k,w*self.k,h*self.k,link),]
|
|
|
|
def text(self, x,y,txt):
|
|
"Output a string"
|
|
s=sprintf('BT %.2f %.2f Td (%s) Tj ET',x*self.k,(self.h-y)*self.k,self._escape(txt))
|
|
if(self.underline and txt!=''):
|
|
s+=' '+self._dounderline(x,y,txt)
|
|
if(self.color_flag):
|
|
s='q '+self.text_color+' '+s+' Q'
|
|
self._out(s)
|
|
|
|
def rotate(self, angle, x=None, y=None):
|
|
if x is None:
|
|
x = self.x
|
|
if y is None:
|
|
y = self.y;
|
|
if self.angle!=0:
|
|
self._out('Q')
|
|
self.angle = angle
|
|
if angle!=0:
|
|
angle *= math.pi/180;
|
|
c = math.cos(angle);
|
|
s = math.sin(angle);
|
|
cx = x*self.k;
|
|
cy = (self.h-y)*self.k
|
|
s = sprintf('q %.5F %.5F %.5F %.5F %.2F %.2F cm 1 0 0 1 %.2F %.2F cm',c,s,-s,c,cx,cy,-cx,-cy)
|
|
self._out(s)
|
|
|
|
def accept_page_break(self):
|
|
"Accept automatic page break or not"
|
|
return self.auto_page_break
|
|
|
|
def cell(self, w,h=0,txt='',border=0,ln=0,align='',fill=0,link=''):
|
|
"Output a cell"
|
|
k=self.k
|
|
if(self.y+h>self.page_break_trigger and not self.in_footer and self.accept_page_break()):
|
|
#Automatic page break
|
|
x=self.x
|
|
ws=self.ws
|
|
if(ws>0):
|
|
self.ws=0
|
|
self._out('0 Tw')
|
|
self.add_page(self.cur_orientation)
|
|
self.x=x
|
|
if(ws>0):
|
|
self.ws=ws
|
|
self._out(sprintf('%.3f Tw',ws*k))
|
|
if(w==0):
|
|
w=self.w-self.r_margin-self.x
|
|
s=''
|
|
if(fill==1 or border==1):
|
|
if(fill==1):
|
|
if border==1:
|
|
op='B'
|
|
else:
|
|
op='f'
|
|
else:
|
|
op='S'
|
|
s=sprintf('%.2f %.2f %.2f %.2f re %s ',self.x*k,(self.h-self.y)*k,w*k,-h*k,op)
|
|
if(isinstance(border,basestring)):
|
|
x=self.x
|
|
y=self.y
|
|
if('L' in border):
|
|
s+=sprintf('%.2f %.2f m %.2f %.2f l S ',x*k,(self.h-y)*k,x*k,(self.h-(y+h))*k)
|
|
if('T' in border):
|
|
s+=sprintf('%.2f %.2f m %.2f %.2f l S ',x*k,(self.h-y)*k,(x+w)*k,(self.h-y)*k)
|
|
if('R' in border):
|
|
s+=sprintf('%.2f %.2f m %.2f %.2f l S ',(x+w)*k,(self.h-y)*k,(x+w)*k,(self.h-(y+h))*k)
|
|
if('B' in border):
|
|
s+=sprintf('%.2f %.2f m %.2f %.2f l S ',x*k,(self.h-(y+h))*k,(x+w)*k,(self.h-(y+h))*k)
|
|
if(txt!=''):
|
|
if(align=='R'):
|
|
dx=w-self.c_margin-self.get_string_width(txt)
|
|
elif(align=='C'):
|
|
dx=(w-self.get_string_width(txt))/2.0
|
|
else:
|
|
dx=self.c_margin
|
|
if(self.color_flag):
|
|
s+='q '+self.text_color+' '
|
|
txt2=txt.replace('\\','\\\\').replace(')','\\)').replace('(','\\(')
|
|
s+=sprintf('BT %.2f %.2f Td (%s) Tj ET',(self.x+dx)*k,(self.h-(self.y+.5*h+.3*self.font_size))*k,txt2)
|
|
if(self.underline):
|
|
s+=' '+self._dounderline(self.x+dx,self.y+.5*h+.3*self.font_size,txt)
|
|
if(self.color_flag):
|
|
s+=' Q'
|
|
if(link):
|
|
self.link(self.x+dx,self.y+.5*h-.5*self.font_size,self.get_string_width(txt),self.font_size,link)
|
|
if(s):
|
|
self._out(s)
|
|
self.lasth=h
|
|
if(ln>0):
|
|
#Go to next line
|
|
self.y+=h
|
|
if(ln==1):
|
|
self.x=self.l_margin
|
|
else:
|
|
self.x+=w
|
|
|
|
def multi_cell(self, w,h,txt,border=0,align='J',fill=0, split_only=False):
|
|
"Output text with automatic or explicit line breaks"
|
|
ret = [] # if split_only = True, returns splited text cells
|
|
cw=self.current_font['cw']
|
|
if(w==0):
|
|
w=self.w-self.r_margin-self.x
|
|
wmax=(w-2*self.c_margin)*1000.0/self.font_size
|
|
s=txt.replace("\r",'')
|
|
nb=len(s)
|
|
if(nb>0 and s[nb-1]=="\n"):
|
|
nb-=1
|
|
b=0
|
|
if(border):
|
|
if(border==1):
|
|
border='LTRB'
|
|
b='LRT'
|
|
b2='LR'
|
|
else:
|
|
b2=''
|
|
if('L' in border):
|
|
b2+='L'
|
|
if('R' in border):
|
|
b2+='R'
|
|
if ('T' in border):
|
|
b=b2+'T'
|
|
else:
|
|
b=b2
|
|
sep=-1
|
|
i=0
|
|
j=0
|
|
l=0
|
|
ns=0
|
|
nl=1
|
|
while(i<nb):
|
|
#Get next character
|
|
c=s[i]
|
|
if(c=="\n"):
|
|
#Explicit line break
|
|
if(self.ws>0):
|
|
self.ws=0
|
|
self._out('0 Tw')
|
|
if not split_only:
|
|
self.cell(w,h,substr(s,j,i-j),b,2,align,fill)
|
|
else:
|
|
ret.append(substr(s,j,i-j))
|
|
i+=1
|
|
sep=-1
|
|
j=i
|
|
l=0
|
|
ns=0
|
|
nl+=1
|
|
if(border and nl==2):
|
|
b=b2
|
|
continue
|
|
if(c==' '):
|
|
sep=i
|
|
ls=l
|
|
ns+=1
|
|
l+=cw.get(c,0)
|
|
if(l>wmax):
|
|
#Automatic line break
|
|
if(sep==-1):
|
|
if(i==j):
|
|
i+=1
|
|
if(self.ws>0):
|
|
self.ws=0
|
|
self._out('0 Tw')
|
|
if not split_only:
|
|
self.cell(w,h,substr(s,j,i-j),b,2,align,fill)
|
|
else:
|
|
ret.append(substr(s,j,i-j))
|
|
else:
|
|
if(align=='J'):
|
|
if ns>1:
|
|
self.ws=(wmax-ls)/1000.0*self.font_size/(ns-1)
|
|
else:
|
|
self.ws=0
|
|
self._out(sprintf('%.3f Tw',self.ws*self.k))
|
|
if not split_only:
|
|
self.cell(w,h,substr(s,j,sep-j),b,2,align,fill)
|
|
else:
|
|
ret.append(substr(s,j,sep-j))
|
|
i=sep+1
|
|
sep=-1
|
|
j=i
|
|
l=0
|
|
ns=0
|
|
nl+=1
|
|
if(border and nl==2):
|
|
b=b2
|
|
else:
|
|
i+=1
|
|
#Last chunk
|
|
if(self.ws>0):
|
|
self.ws=0
|
|
self._out('0 Tw')
|
|
if(border and 'B' in border):
|
|
b+='B'
|
|
if not split_only:
|
|
self.cell(w,h,substr(s,j,i-j),b,2,align,fill)
|
|
else:
|
|
ret.append(substr(s,j,i-j))
|
|
self.x=self.l_margin
|
|
return ret
|
|
|
|
def write(self, h,txt,link=''):
|
|
"Output text in flowing mode"
|
|
cw=self.current_font['cw']
|
|
w=self.w-self.r_margin-self.x
|
|
wmax=(w-2*self.c_margin)*1000.0/self.font_size
|
|
s=txt.replace("\r",'')
|
|
nb=len(s)
|
|
sep=-1
|
|
i=0
|
|
j=0
|
|
l=0
|
|
nl=1
|
|
while(i<nb):
|
|
#Get next character
|
|
c=s[i]
|
|
if(c=="\n"):
|
|
#Explicit line break
|
|
self.cell(w,h,substr(s,j,i-j),0,2,'',0,link)
|
|
i+=1
|
|
sep=-1
|
|
j=i
|
|
l=0
|
|
if(nl==1):
|
|
self.x=self.l_margin
|
|
w=self.w-self.r_margin-self.x
|
|
wmax=(w-2*self.c_margin)*1000.0/self.font_size
|
|
nl+=1
|
|
continue
|
|
if(c==' '):
|
|
sep=i
|
|
l+=cw.get(c,0)
|
|
if(l>wmax):
|
|
#Automatic line break
|
|
if(sep==-1):
|
|
if(self.x>self.l_margin):
|
|
#Move to next line
|
|
self.x=self.l_margin
|
|
self.y+=h
|
|
w=self.w-self.r_margin-self.x
|
|
wmax=(w-2*self.c_margin)*1000.0/self.font_size
|
|
i+=1
|
|
nl+=1
|
|
continue
|
|
if(i==j):
|
|
i+=1
|
|
self.cell(w,h,substr(s,j,i-j),0,2,'',0,link)
|
|
else:
|
|
self.cell(w,h,substr(s,j,sep-j),0,2,'',0,link)
|
|
i=sep+1
|
|
sep=-1
|
|
j=i
|
|
l=0
|
|
if(nl==1):
|
|
self.x=self.l_margin
|
|
w=self.w-self.r_margin-self.x
|
|
wmax=(w-2*self.c_margin)*1000.0/self.font_size
|
|
nl+=1
|
|
else:
|
|
i+=1
|
|
#Last chunk
|
|
if(i!=j):
|
|
self.cell(l/1000.0*self.font_size,h,substr(s,j),0,0,'',0,link)
|
|
|
|
def image(self, name,x,y,w=0,h=0,type='',link=''):
|
|
"Put an image on the page"
|
|
if not name in self.images:
|
|
#First use of image, get info
|
|
if(type==''):
|
|
pos=name.rfind('.')
|
|
if(not pos):
|
|
self.error('image file has no extension and no type was specified: '+name)
|
|
type=substr(name,pos+1)
|
|
type=type.lower()
|
|
if(type=='jpg' or type=='jpeg'):
|
|
info=self._parsejpg(name)
|
|
elif(type=='png'):
|
|
info=self._parsepng(name)
|
|
else:
|
|
#Allow for additional formats
|
|
mtd='_parse'+type
|
|
if not hasattr(self,mtd):
|
|
self.error('Unsupported image type: '+type)
|
|
info=self.mtd(name)
|
|
info['i']=len(self.images)+1
|
|
self.images[name]=info
|
|
else:
|
|
info=self.images[name]
|
|
#Automatic width and height calculation if needed
|
|
if(w==0 and h==0):
|
|
#Put image at 72 dpi
|
|
w=info['w']/self.k
|
|
h=info['h']/self.k
|
|
if(w==0):
|
|
w=h*info['w']/info['h']
|
|
if(h==0):
|
|
h=w*info['h']/info['w']
|
|
self._out(sprintf('q %.2f 0 0 %.2f %.2f %.2f cm /I%d Do Q',w*self.k,h*self.k,x*self.k,(self.h-(y+h))*self.k,info['i']))
|
|
if(link):
|
|
self.link(x,y,w,h,link)
|
|
|
|
def ln(self, h=''):
|
|
"Line Feed; default value is last cell height"
|
|
self.x=self.l_margin
|
|
if(isinstance(h, basestring)):
|
|
self.y+=self.lasth
|
|
else:
|
|
self.y+=h
|
|
|
|
def get_x(self):
|
|
"Get x position"
|
|
return self.x
|
|
|
|
def set_x(self, x):
|
|
"Set x position"
|
|
if(x>=0):
|
|
self.x=x
|
|
else:
|
|
self.x=self.w+x
|
|
|
|
def get_y(self):
|
|
"Get y position"
|
|
return self.y
|
|
|
|
def set_y(self, y):
|
|
"Set y position and reset x"
|
|
self.x=self.l_margin
|
|
if(y>=0):
|
|
self.y=y
|
|
else:
|
|
self.y=self.h+y
|
|
|
|
def set_xy(self, x,y):
|
|
"Set x and y positions"
|
|
self.set_y(y)
|
|
self.set_x(x)
|
|
|
|
def output(self, name='',dest=''):
|
|
"Output PDF to some destination"
|
|
#Finish document if necessary
|
|
if(self.state<3):
|
|
self.close()
|
|
#Normalize parameters
|
|
# if(type(dest)==type(bool())):
|
|
# if dest:
|
|
# dest='D'
|
|
# else:
|
|
# dest='F'
|
|
dest=dest.upper()
|
|
if(dest==''):
|
|
if(name==''):
|
|
name='doc.pdf'
|
|
dest='I'
|
|
else:
|
|
dest='F'
|
|
if dest=='I':
|
|
print self.buffer
|
|
elif dest=='D':
|
|
print self.buffer
|
|
elif dest=='F':
|
|
#Save to local file
|
|
f=file(name,'wb')
|
|
if(not f):
|
|
self.error('Unable to create output file: '+name)
|
|
f.write(self.buffer)
|
|
f.close()
|
|
elif dest=='S':
|
|
#Return as a string
|
|
return self.buffer
|
|
else:
|
|
self.error('Incorrect output destination: '+dest)
|
|
return ''
|
|
|
|
# ******************************************************************************
|
|
# * *
|
|
# * Protected methods *
|
|
# * *
|
|
# *******************************************************************************/
|
|
def _dochecks(self):
|
|
#Check for locale-related bug
|
|
# if(1.1==1):
|
|
# self.error("Don\'t alter the locale before including class file");
|
|
#Check for decimal separator
|
|
if(sprintf('%.1f',1.0)!='1.0'):
|
|
import locale
|
|
locale.setlocale(locale.LC_NUMERIC,'C')
|
|
|
|
def _getfontpath(self):
|
|
return FPDF_FONT_DIR+'/'
|
|
|
|
def _putpages(self):
|
|
nb=self.page
|
|
if hasattr(self,'str_alias_nb_pages'):
|
|
#Replace number of pages
|
|
for n in xrange(1,nb+1):
|
|
self.pages[n]=self.pages[n].replace(self.str_alias_nb_pages,str(nb))
|
|
if(self.def_orientation=='P'):
|
|
w_pt=self.fw_pt
|
|
h_pt=self.fh_pt
|
|
else:
|
|
w_pt=self.fh_pt
|
|
h_pt=self.fw_pt
|
|
if self.compress:
|
|
filter='/Filter /FlateDecode '
|
|
else:
|
|
filter=''
|
|
for n in xrange(1,nb+1):
|
|
#Page
|
|
self._newobj()
|
|
self._out('<</Type /Page')
|
|
self._out('/Parent 1 0 R')
|
|
if n in self.orientation_changes:
|
|
self._out(sprintf('/MediaBox [0 0 %.2f %.2f]',h_pt,w_pt))
|
|
self._out('/Resources 2 0 R')
|
|
if self.page_links and n in self.page_links:
|
|
#Links
|
|
annots='/Annots ['
|
|
for pl in self.page_links[n]:
|
|
rect=sprintf('%.2f %.2f %.2f %.2f',pl[0],pl[1],pl[0]+pl[2],pl[1]-pl[3])
|
|
annots+='<</Type /Annot /Subtype /Link /Rect ['+rect+'] /Border [0 0 0] '
|
|
if(isinstance(pl[4],basestring)):
|
|
annots+='/A <</S /URI /URI '+self._textstring(pl[4])+'>>>>'
|
|
else:
|
|
l=self.links[pl[4]]
|
|
if l[0] in self.orientation_changes:
|
|
h=w_pt
|
|
else:
|
|
h=h_pt
|
|
annots+=sprintf('/Dest [%d 0 R /XYZ 0 %.2f null]>>',1+2*l[0],h-l[1]*self.k)
|
|
self._out(annots+']')
|
|
self._out('/Contents '+str(self.n+1)+' 0 R>>')
|
|
self._out('endobj')
|
|
#Page content
|
|
if self.compress:
|
|
p = zlib.compress(self.pages[n])
|
|
else:
|
|
p = self.pages[n]
|
|
self._newobj()
|
|
self._out('<<'+filter+'/Length '+str(len(p))+'>>')
|
|
self._putstream(p)
|
|
self._out('endobj')
|
|
#Pages root
|
|
self.offsets[1]=len(self.buffer)
|
|
self._out('1 0 obj')
|
|
self._out('<</Type /Pages')
|
|
kids='/Kids ['
|
|
for i in xrange(0,nb):
|
|
kids+=str(3+2*i)+' 0 R '
|
|
self._out(kids+']')
|
|
self._out('/Count '+str(nb))
|
|
self._out(sprintf('/MediaBox [0 0 %.2f %.2f]',w_pt,h_pt))
|
|
self._out('>>')
|
|
self._out('endobj')
|
|
|
|
def _putfonts(self):
|
|
nf=self.n
|
|
for diff in self.diffs:
|
|
#Encodings
|
|
self._newobj()
|
|
self._out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['+self.diffs[diff]+']>>')
|
|
self._out('endobj')
|
|
for name,info in self.font_files.iteritems():
|
|
#Font file embedding
|
|
self._newobj()
|
|
self.font_files[name]['n']=self.n
|
|
font=''
|
|
f=file(self._getfontpath()+name,'rb',1)
|
|
if(not f):
|
|
self.error('Font file not found')
|
|
font=f.read()
|
|
f.close()
|
|
compressed=(substr(name,-2)=='.z')
|
|
if(not compressed and 'length2' in info):
|
|
header=(ord(font[0])==128)
|
|
if(header):
|
|
#Strip first binary header
|
|
font=substr(font,6)
|
|
if(header and ord(font[info['length1']])==128):
|
|
#Strip second binary header
|
|
font=substr(font,0,info['length1'])+substr(font,info['length1']+6)
|
|
self._out('<</Length '+str(len(font)))
|
|
if(compressed):
|
|
self._out('/Filter /FlateDecode')
|
|
self._out('/Length1 '+str(info['length1']))
|
|
if('length2' in info):
|
|
self._out('/Length2 '+str(info['length2'])+' /Length3 0')
|
|
self._out('>>')
|
|
self._putstream(font)
|
|
self._out('endobj')
|
|
for k,font in self.fonts.iteritems():
|
|
#Font objects
|
|
self.fonts[k]['n']=self.n+1
|
|
type=font['type']
|
|
name=font['name']
|
|
if(type=='core'):
|
|
#Standard font
|
|
self._newobj()
|
|
self._out('<</Type /Font')
|
|
self._out('/BaseFont /'+name)
|
|
self._out('/Subtype /Type1')
|
|
if(name!='Symbol' and name!='ZapfDingbats'):
|
|
self._out('/Encoding /WinAnsiEncoding')
|
|
self._out('>>')
|
|
self._out('endobj')
|
|
elif(type=='Type1' or type=='TrueType'):
|
|
#Additional Type1 or TrueType font
|
|
self._newobj()
|
|
self._out('<</Type /Font')
|
|
self._out('/BaseFont /'+name)
|
|
self._out('/Subtype /'+type)
|
|
self._out('/FirstChar 32 /LastChar 255')
|
|
self._out('/Widths '+str(self.n+1)+' 0 R')
|
|
self._out('/FontDescriptor '+str(self.n+2)+' 0 R')
|
|
if(font['enc']):
|
|
if('diff' in font):
|
|
self._out('/Encoding '+str(nf+font['diff'])+' 0 R')
|
|
else:
|
|
self._out('/Encoding /WinAnsiEncoding')
|
|
self._out('>>')
|
|
self._out('endobj')
|
|
#Widths
|
|
self._newobj()
|
|
cw=font['cw']
|
|
s='['
|
|
for i in xrange(32,256):
|
|
# Get doesn't rise exception; returns 0 instead of None if not set
|
|
s+=str(cw.get(chr(i)) or 0)+' '
|
|
self._out(s+']')
|
|
self._out('endobj')
|
|
#Descriptor
|
|
self._newobj()
|
|
s='<</Type /FontDescriptor /FontName /'+name
|
|
for k,v in font['desc'].iteritems():
|
|
s+=' /'+str(k)+' '+str(v)
|
|
filename=font['file']
|
|
if(filename):
|
|
s+=' /FontFile'
|
|
if type!='Type1':
|
|
s+='2'
|
|
s+=' '+str(self.font_files[filename]['n'])+' 0 R'
|
|
self._out(s+'>>')
|
|
self._out('endobj')
|
|
else:
|
|
#Allow for additional types
|
|
mtd='_put'+type.lower()
|
|
if(not method_exists(self,mtd)):
|
|
self.error('Unsupported font type: '+type)
|
|
self.mtd(font)
|
|
|
|
def _putimages(self):
|
|
filter=''
|
|
if self.compress:
|
|
filter='/Filter /FlateDecode '
|
|
for filename,info in self.images.iteritems():
|
|
self._newobj()
|
|
self.images[filename]['n']=self.n
|
|
self._out('<</Type /XObject')
|
|
self._out('/Subtype /Image')
|
|
self._out('/Width '+str(info['w']))
|
|
self._out('/Height '+str(info['h']))
|
|
if(info['cs']=='Indexed'):
|
|
self._out('/ColorSpace [/Indexed /DeviceRGB '+str(len(info['pal'])/3-1)+' '+str(self.n+1)+' 0 R]')
|
|
else:
|
|
self._out('/ColorSpace /'+info['cs'])
|
|
if(info['cs']=='DeviceCMYK'):
|
|
self._out('/Decode [1 0 1 0 1 0 1 0]')
|
|
self._out('/BitsPerComponent '+str(info['bpc']))
|
|
if 'f' in info:
|
|
self._out('/Filter /'+info['f'])
|
|
if 'parms' in info:
|
|
self._out(info['parms'])
|
|
if('trns' in info and isinstance(info['trns'],list)):
|
|
trns=''
|
|
for i in xrange(0,len(info['trns'])):
|
|
trns+=str(info['trns'][i])+' '+str(info['trns'][i])+' '
|
|
self._out('/Mask ['+trns+']')
|
|
self._out('/Length '+str(len(info['data']))+'>>')
|
|
self._putstream(info['data'])
|
|
self.images[filename]['data'] = None
|
|
self._out('endobj')
|
|
#Palette
|
|
if(info['cs']=='Indexed'):
|
|
self._newobj()
|
|
if self.compress:
|
|
pal=zlib.compress(info['pal'])
|
|
else:
|
|
pal=info['pal']
|
|
self._out('<<'+filter+'/Length '+str(len(pal))+'>>')
|
|
self._putstream(pal)
|
|
self._out('endobj')
|
|
|
|
def _putxobjectdict(self):
|
|
for image in self.images.values():
|
|
self._out('/I'+str(image['i'])+' '+str(image['n'])+' 0 R')
|
|
|
|
def _putresourcedict(self):
|
|
self._out('/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]')
|
|
self._out('/Font <<')
|
|
for font in self.fonts.values():
|
|
self._out('/F'+str(font['i'])+' '+str(font['n'])+' 0 R')
|
|
self._out('>>')
|
|
self._out('/XObject <<')
|
|
self._putxobjectdict()
|
|
self._out('>>')
|
|
|
|
def _putresources(self):
|
|
self._putfonts()
|
|
self._putimages()
|
|
#Resource dictionary
|
|
self.offsets[2]=len(self.buffer)
|
|
self._out('2 0 obj')
|
|
self._out('<<')
|
|
self._putresourcedict()
|
|
self._out('>>')
|
|
self._out('endobj')
|
|
|
|
def _putinfo(self):
|
|
self._out('/Producer '+self._textstring('PyFPDF '+FPDF_VERSION+' http://pyfpdf.googlecode.com/'))
|
|
if hasattr(self,'title'):
|
|
self._out('/Title '+self._textstring(self.title))
|
|
if hasattr(self,'subject'):
|
|
self._out('/Subject '+self._textstring(self.subject))
|
|
if hasattr(self,'author'):
|
|
self._out('/Author '+self._textstring(self.author))
|
|
if hasattr (self,'keywords'):
|
|
self._out('/Keywords '+self._textstring(self.keywords))
|
|
if hasattr(self,'creator'):
|
|
self._out('/Creator '+self._textstring(self.creator))
|
|
self._out('/CreationDate '+self._textstring('D:'+datetime.now().strftime('%Y%m%d%H%M%S')))
|
|
|
|
def _putcatalog(self):
|
|
self._out('/Type /Catalog')
|
|
self._out('/Pages 1 0 R')
|
|
if(self.zoom_mode=='fullpage'):
|
|
self._out('/OpenAction [3 0 R /Fit]')
|
|
elif(self.zoom_mode=='fullwidth'):
|
|
self._out('/OpenAction [3 0 R /FitH null]')
|
|
elif(self.zoom_mode=='real'):
|
|
self._out('/OpenAction [3 0 R /XYZ null null 1]')
|
|
elif(not isinstance(self.zoom_mode,basestring)):
|
|
self._out('/OpenAction [3 0 R /XYZ null null '+(self.zoom_mode/100)+']')
|
|
if(self.layout_mode=='single'):
|
|
self._out('/PageLayout /SinglePage')
|
|
elif(self.layout_mode=='continuous'):
|
|
self._out('/PageLayout /OneColumn')
|
|
elif(self.layout_mode=='two'):
|
|
self._out('/PageLayout /TwoColumnLeft')
|
|
|
|
def _putheader(self):
|
|
self._out('%PDF-'+self.pdf_version)
|
|
|
|
def _puttrailer(self):
|
|
self._out('/Size '+str(self.n+1))
|
|
self._out('/Root '+str(self.n)+' 0 R')
|
|
self._out('/Info '+str(self.n-1)+' 0 R')
|
|
|
|
def _enddoc(self):
|
|
self._putheader()
|
|
self._putpages()
|
|
self._putresources()
|
|
#Info
|
|
self._newobj()
|
|
self._out('<<')
|
|
self._putinfo()
|
|
self._out('>>')
|
|
self._out('endobj')
|
|
#Catalog
|
|
self._newobj()
|
|
self._out('<<')
|
|
self._putcatalog()
|
|
self._out('>>')
|
|
self._out('endobj')
|
|
#Cross-ref
|
|
o=len(self.buffer)
|
|
self._out('xref')
|
|
self._out('0 '+(str(self.n+1)))
|
|
self._out('0000000000 65535 f ')
|
|
for i in xrange(1,self.n+1):
|
|
self._out(sprintf('%010d 00000 n ',self.offsets[i]))
|
|
#Trailer
|
|
self._out('trailer')
|
|
self._out('<<')
|
|
self._puttrailer()
|
|
self._out('>>')
|
|
self._out('startxref')
|
|
self._out(o)
|
|
self._out('%%EOF')
|
|
self.state=3
|
|
|
|
def _beginpage(self, orientation):
|
|
self.page+=1
|
|
self.pages[self.page]=''
|
|
self.state=2
|
|
self.x=self.l_margin
|
|
self.y=self.t_margin
|
|
self.font_family=''
|
|
#Page orientation
|
|
if(not orientation):
|
|
orientation=self.def_orientation
|
|
else:
|
|
orientation=orientation[0].upper()
|
|
if(orientation!=self.def_orientation):
|
|
self.orientation_changes[self.page]=1
|
|
if(orientation!=self.cur_orientation):
|
|
#Change orientation
|
|
if(orientation=='P'):
|
|
self.w_pt=self.fw_pt
|
|
self.h_pt=self.fh_pt
|
|
self.w=self.fw
|
|
self.h=self.fh
|
|
else:
|
|
self.w_pt=self.fh_pt
|
|
self.h_pt=self.fw_pt
|
|
self.w=self.fh
|
|
self.h=self.fw
|
|
self.page_break_trigger=self.h-self.b_margin
|
|
self.cur_orientation=orientation
|
|
|
|
def _endpage(self):
|
|
#End of page contents
|
|
self.state=1
|
|
|
|
def _newobj(self):
|
|
#Begin a new object
|
|
self.n+=1
|
|
self.offsets[self.n]=len(self.buffer)
|
|
self._out(str(self.n)+' 0 obj')
|
|
|
|
def _dounderline(self, x,y,txt):
|
|
#Underline text
|
|
up=self.current_font['up']
|
|
ut=self.current_font['ut']
|
|
w=self.get_string_width(txt)+self.ws*txt.count(' ')
|
|
return sprintf('%.2f %.2f %.2f %.2f re f',x*self.k,(self.h-(y-up/1000.0*self.font_size))*self.k,w*self.k,-ut/1000.0*self.font_size_pt)
|
|
|
|
def _parsejpg(self, filename):
|
|
# Extract info from a JPEG file
|
|
if Image is None:
|
|
self.error('PIL not installed')
|
|
try:
|
|
f = open(filename, 'rb')
|
|
im = Image.open(f)
|
|
except Exception, e:
|
|
self.error('Missing or incorrect image file: %s. error: %s' % (filename, str(e)))
|
|
else:
|
|
a = im.size
|
|
# We shouldn't get into here, as Jpeg is RGB=8bpp right(?), but, just in case...
|
|
bpc=8
|
|
if im.mode == 'RGB':
|
|
colspace='DeviceRGB'
|
|
elif im.mode == 'CMYK':
|
|
colspace='DeviceCMYK'
|
|
else:
|
|
colspace='DeviceGray'
|
|
|
|
# Read whole file from the start
|
|
f.seek(0)
|
|
data = f.read()
|
|
f.close()
|
|
return {'w':a[0],'h':a[1],'cs':colspace,'bpc':bpc,'f':'DCTDecode','data':data}
|
|
|
|
def _parsepng(self, name):
|
|
#Extract info from a PNG file
|
|
if name.startswith("http://") or name.startswith("https://"):
|
|
import urllib
|
|
f = urllib.urlopen(name)
|
|
else:
|
|
f=open(name,'rb')
|
|
if(not f):
|
|
self.error("Can't open image file: "+name)
|
|
#Check signature
|
|
if(f.read(8)!='\x89'+'PNG'+'\r'+'\n'+'\x1a'+'\n'):
|
|
self.error('Not a PNG file: '+name)
|
|
#Read header chunk
|
|
f.read(4)
|
|
if(f.read(4)!='IHDR'):
|
|
self.error('Incorrect PNG file: '+name)
|
|
w=self._freadint(f)
|
|
h=self._freadint(f)
|
|
bpc=ord(f.read(1))
|
|
if(bpc>8):
|
|
self.error('16-bit depth not supported: '+name)
|
|
ct=ord(f.read(1))
|
|
if(ct==0):
|
|
colspace='DeviceGray'
|
|
elif(ct==2):
|
|
colspace='DeviceRGB'
|
|
elif(ct==3):
|
|
colspace='Indexed'
|
|
else:
|
|
self.error('Alpha channel not supported: '+name)
|
|
if(ord(f.read(1))!=0):
|
|
self.error('Unknown compression method: '+name)
|
|
if(ord(f.read(1))!=0):
|
|
self.error('Unknown filter method: '+name)
|
|
if(ord(f.read(1))!=0):
|
|
self.error('Interlacing not supported: '+name)
|
|
f.read(4)
|
|
parms='/DecodeParms <</Predictor 15 /Colors '
|
|
if ct==2:
|
|
parms+='3'
|
|
else:
|
|
parms+='1'
|
|
parms+=' /BitsPerComponent '+str(bpc)+' /Columns '+str(w)+'>>'
|
|
#Scan chunks looking for palette, transparency and image data
|
|
pal=''
|
|
trns=''
|
|
data=''
|
|
n=1
|
|
while n != None:
|
|
n=self._freadint(f)
|
|
type=f.read(4)
|
|
if(type=='PLTE'):
|
|
#Read palette
|
|
pal=f.read(n)
|
|
f.read(4)
|
|
elif(type=='tRNS'):
|
|
#Read transparency info
|
|
t=f.read(n)
|
|
if(ct==0):
|
|
trns=[ord(substr(t,1,1)),]
|
|
elif(ct==2):
|
|
trns=[ord(substr(t,1,1)),ord(substr(t,3,1)),ord(substr(t,5,1))]
|
|
else:
|
|
pos=t.find('\x00')
|
|
if(pos!=-1):
|
|
trns=[pos,]
|
|
f.read(4)
|
|
elif(type=='IDAT'):
|
|
#Read image data block
|
|
data+=f.read(n)
|
|
f.read(4)
|
|
elif(type=='IEND'):
|
|
break
|
|
else:
|
|
f.read(n+4)
|
|
if(colspace=='Indexed' and not pal):
|
|
self.error('Missing palette in '+name)
|
|
f.close()
|
|
return {'w':w,'h':h,'cs':colspace,'bpc':bpc,'f':'FlateDecode','parms':parms,'pal':pal,'trns':trns,'data':data}
|
|
|
|
def _freadint(self, f):
|
|
#Read a 4-byte integer from file
|
|
try:
|
|
return struct.unpack('>HH',f.read(4))[1]
|
|
except:
|
|
return None
|
|
|
|
def _textstring(self, s):
|
|
#Format a text string
|
|
return '('+self._escape(s)+')'
|
|
|
|
def _escape(self, s):
|
|
#Add \ before \, ( and )
|
|
return s.replace('\\','\\\\').replace(')','\\)').replace('(','\\(')
|
|
|
|
def _putstream(self, s):
|
|
self._out('stream')
|
|
self._out(s)
|
|
self._out('endstream')
|
|
|
|
def _out(self, s):
|
|
#Add a line to the document
|
|
if(self.state==2):
|
|
self.pages[self.page]+=s+"\n"
|
|
else:
|
|
self.buffer+=str(s)+"\n"
|
|
|
|
def interleaved2of5(self, txt, x, y, w=1.0, h=10.0):
|
|
"Barcode I2of5 (numeric), adds a 0 if odd lenght"
|
|
narrow = w / 3.0
|
|
wide = w
|
|
|
|
# wide/narrow codes for the digits
|
|
bar_char={}
|
|
bar_char['0'] = 'nnwwn'
|
|
bar_char['1'] = 'wnnnw'
|
|
bar_char['2'] = 'nwnnw'
|
|
bar_char['3'] = 'wwnnn'
|
|
bar_char['4'] = 'nnwnw'
|
|
bar_char['5'] = 'wnwnn'
|
|
bar_char['6'] = 'nwwnn'
|
|
bar_char['7'] = 'nnnww'
|
|
bar_char['8'] = 'wnnwn'
|
|
bar_char['9'] = 'nwnwn'
|
|
bar_char['A'] = 'nn'
|
|
bar_char['Z'] = 'wn'
|
|
|
|
self.set_fill_color(0)
|
|
code = txt
|
|
# add leading zero if code-length is odd
|
|
if len(code) % 2 != 0:
|
|
code = '0' + code
|
|
|
|
# add start and stop codes
|
|
code = 'AA' + code.lower() + 'ZA'
|
|
|
|
for i in xrange(0, len(code), 2):
|
|
# choose next pair of digits
|
|
char_bar = code[i];
|
|
char_space = code[i+1];
|
|
# check whether it is a valid digit
|
|
if not char_bar in bar_char.keys():
|
|
raise RuntimeError ('Caract�r "%s" inv�lido para el c�digo de barras I25: ' % char_bar)
|
|
if not char_space in bar_char.keys():
|
|
raise RuntimeError ('Caract�r "%s" inv�lido para el c�digo de barras I25: ' % char_space)
|
|
|
|
# create a wide/narrow-sequence (first digit=bars, second digit=spaces)
|
|
seq = ''
|
|
for s in xrange(0, len(bar_char[char_bar])):
|
|
seq += bar_char[char_bar][s] + bar_char[char_space][s]
|
|
|
|
for bar in xrange(0, len(seq)):
|
|
# set line_width depending on value
|
|
if seq[bar] == 'n':
|
|
line_width = narrow
|
|
else:
|
|
line_width = wide
|
|
|
|
# draw every second value, because the second digit of the pair is represented by the spaces
|
|
if bar % 2 == 0:
|
|
self.rect(x, y, line_width, h, 'F')
|
|
|
|
x += line_width
|
|
|
|
|
|
def code39(self, txt, x, y, w=1.5, h=5.0):
|
|
"Barcode 3of9"
|
|
wide = w
|
|
narrow = w /3.0
|
|
gap = narrow
|
|
|
|
bar_char={}
|
|
bar_char['0'] = 'nnnwwnwnn'
|
|
bar_char['1'] = 'wnnwnnnnw'
|
|
bar_char['2'] = 'nnwwnnnnw'
|
|
bar_char['3'] = 'wnwwnnnnn'
|
|
bar_char['4'] = 'nnnwwnnnw'
|
|
bar_char['5'] = 'wnnwwnnnn'
|
|
bar_char['6'] = 'nnwwwnnnn'
|
|
bar_char['7'] = 'nnnwnnwnw'
|
|
bar_char['8'] = 'wnnwnnwnn'
|
|
bar_char['9'] = 'nnwwnnwnn'
|
|
bar_char['A'] = 'wnnnnwnnw'
|
|
bar_char['B'] = 'nnwnnwnnw'
|
|
bar_char['C'] = 'wnwnnwnnn'
|
|
bar_char['D'] = 'nnnnwwnnw'
|
|
bar_char['E'] = 'wnnnwwnnn'
|
|
bar_char['F'] = 'nnwnwwnnn'
|
|
bar_char['G'] = 'nnnnnwwnw'
|
|
bar_char['H'] = 'wnnnnwwnn'
|
|
bar_char['I'] = 'nnwnnwwnn'
|
|
bar_char['J'] = 'nnnnwwwnn'
|
|
bar_char['K'] = 'wnnnnnnww'
|
|
bar_char['L'] = 'nnwnnnnww'
|
|
bar_char['M'] = 'wnwnnnnwn'
|
|
bar_char['N'] = 'nnnnwnnww'
|
|
bar_char['O'] = 'wnnnwnnwn'
|
|
bar_char['P'] = 'nnwnwnnwn'
|
|
bar_char['Q'] = 'nnnnnnwww'
|
|
bar_char['R'] = 'wnnnnnwwn'
|
|
bar_char['S'] = 'nnwnnnwwn'
|
|
bar_char['T'] = 'nnnnwnwwn'
|
|
bar_char['U'] = 'wwnnnnnnw'
|
|
bar_char['V'] = 'nwwnnnnnw'
|
|
bar_char['W'] = 'wwwnnnnnn'
|
|
bar_char['X'] = 'nwnnwnnnw'
|
|
bar_char['Y'] = 'wwnnwnnnn'
|
|
bar_char['Z'] = 'nwwnwnnnn'
|
|
bar_char['-'] = 'nwnnnnwnw'
|
|
bar_char['.'] = 'wwnnnnwnn'
|
|
bar_char[' '] = 'nwwnnnwnn'
|
|
bar_char['*'] = 'nwnnwnwnn'
|
|
bar_char['$'] = 'nwnwnwnnn'
|
|
bar_char['/'] = 'nwnwnnnwn'
|
|
bar_char['+'] = 'nwnnnwnwn'
|
|
bar_char['%'] = 'nnnwnwnwn'
|
|
|
|
self.set_fill_color(0)
|
|
code = txt
|
|
|
|
code = code.upper()
|
|
for i in xrange (0, len(code), 2):
|
|
char_bar = code[i];
|
|
|
|
if not char_bar in bar_char.keys():
|
|
raise RuntimeError ('Caracter "%s" inv�lido para el c�digo de barras' % char_bar)
|
|
|
|
seq= ''
|
|
for s in xrange(0, len(bar_char[char_bar])):
|
|
seq += bar_char[char_bar][s]
|
|
|
|
for bar in xrange(0, len(seq)):
|
|
if seq[bar] == 'n':
|
|
line_width = narrow
|
|
else:
|
|
line_width = wide
|
|
|
|
if bar % 2 == 0:
|
|
self.rect(x,y,line_width,h,'F')
|
|
x += line_width
|
|
x += gap
|
|
|
|
#End of class
|
|
|
|
# Fonts:
|
|
|
|
fpdf_charwidths['courier']={}
|
|
|
|
for i in xrange(0,256):
|
|
fpdf_charwidths['courier'][chr(i)]=600
|
|
fpdf_charwidths['courierB']=fpdf_charwidths['courier']
|
|
fpdf_charwidths['courierI']=fpdf_charwidths['courier']
|
|
fpdf_charwidths['courierBI']=fpdf_charwidths['courier']
|
|
|
|
fpdf_charwidths['helvetica']={
|
|
'\x00':278,'\x01':278,'\x02':278,'\x03':278,'\x04':278,'\x05':278,'\x06':278,'\x07':278,'\x08':278,'\t':278,'\n':278,'\x0b':278,'\x0c':278,'\r':278,'\x0e':278,'\x0f':278,'\x10':278,'\x11':278,'\x12':278,'\x13':278,'\x14':278,'\x15':278,
|
|
'\x16':278,'\x17':278,'\x18':278,'\x19':278,'\x1a':278,'\x1b':278,'\x1c':278,'\x1d':278,'\x1e':278,'\x1f':278,' ':278,'!':278,'"':355,'#':556,'$':556,'%':889,'&':667,'\'':191,'(':333,')':333,'*':389,'+':584,
|
|
',':278,'-':333,'.':278,'/':278,'0':556,'1':556,'2':556,'3':556,'4':556,'5':556,'6':556,'7':556,'8':556,'9':556,':':278,';':278,'<':584,'=':584,'>':584,'?':556,'@':1015,'A':667,
|
|
'B':667,'C':722,'D':722,'E':667,'F':611,'G':778,'H':722,'I':278,'J':500,'K':667,'L':556,'M':833,'N':722,'O':778,'P':667,'Q':778,'R':722,'S':667,'T':611,'U':722,'V':667,'W':944,
|
|
'X':667,'Y':667,'Z':611,'[':278,'\\':278,']':278,'^':469,'_':556,'`':333,'a':556,'b':556,'c':500,'d':556,'e':556,'f':278,'g':556,'h':556,'i':222,'j':222,'k':500,'l':222,'m':833,
|
|
'n':556,'o':556,'p':556,'q':556,'r':333,'s':500,'t':278,'u':556,'v':500,'w':722,'x':500,'y':500,'z':500,'{':334,'|':260,'}':334,'~':584,'\x7f':350,'\x80':556,'\x81':350,'\x82':222,'\x83':556,
|
|
'\x84':333,'\x85':1000,'\x86':556,'\x87':556,'\x88':333,'\x89':1000,'\x8a':667,'\x8b':333,'\x8c':1000,'\x8d':350,'\x8e':611,'\x8f':350,'\x90':350,'\x91':222,'\x92':222,'\x93':333,'\x94':333,'\x95':350,'\x96':556,'\x97':1000,'\x98':333,'\x99':1000,
|
|
'\x9a':500,'\x9b':333,'\x9c':944,'\x9d':350,'\x9e':500,'\x9f':667,'\xa0':278,'\xa1':333,'\xa2':556,'\xa3':556,'\xa4':556,'\xa5':556,'\xa6':260,'\xa7':556,'\xa8':333,'\xa9':737,'\xaa':370,'\xab':556,'\xac':584,'\xad':333,'\xae':737,'\xaf':333,
|
|
'\xb0':400,'\xb1':584,'\xb2':333,'\xb3':333,'\xb4':333,'\xb5':556,'\xb6':537,'\xb7':278,'\xb8':333,'\xb9':333,'\xba':365,'\xbb':556,'\xbc':834,'\xbd':834,'\xbe':834,'\xbf':611,'\xc0':667,'\xc1':667,'\xc2':667,'\xc3':667,'\xc4':667,'\xc5':667,
|
|
'\xc6':1000,'\xc7':722,'\xc8':667,'\xc9':667,'\xca':667,'\xcb':667,'\xcc':278,'\xcd':278,'\xce':278,'\xcf':278,'\xd0':722,'\xd1':722,'\xd2':778,'\xd3':778,'\xd4':778,'\xd5':778,'\xd6':778,'\xd7':584,'\xd8':778,'\xd9':722,'\xda':722,'\xdb':722,
|
|
'\xdc':722,'\xdd':667,'\xde':667,'\xdf':611,'\xe0':556,'\xe1':556,'\xe2':556,'\xe3':556,'\xe4':556,'\xe5':556,'\xe6':889,'\xe7':500,'\xe8':556,'\xe9':556,'\xea':556,'\xeb':556,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':556,'\xf1':556,
|
|
'\xf2':556,'\xf3':556,'\xf4':556,'\xf5':556,'\xf6':556,'\xf7':584,'\xf8':611,'\xf9':556,'\xfa':556,'\xfb':556,'\xfc':556,'\xfd':500,'\xfe':556,'\xff':500}
|
|
|
|
fpdf_charwidths['helveticaB']={
|
|
'\x00':278,'\x01':278,'\x02':278,'\x03':278,'\x04':278,'\x05':278,'\x06':278,'\x07':278,'\x08':278,'\t':278,'\n':278,'\x0b':278,'\x0c':278,'\r':278,'\x0e':278,'\x0f':278,'\x10':278,'\x11':278,'\x12':278,'\x13':278,'\x14':278,'\x15':278,
|
|
'\x16':278,'\x17':278,'\x18':278,'\x19':278,'\x1a':278,'\x1b':278,'\x1c':278,'\x1d':278,'\x1e':278,'\x1f':278,' ':278,'!':333,'"':474,'#':556,'$':556,'%':889,'&':722,'\'':238,'(':333,')':333,'*':389,'+':584,
|
|
',':278,'-':333,'.':278,'/':278,'0':556,'1':556,'2':556,'3':556,'4':556,'5':556,'6':556,'7':556,'8':556,'9':556,':':333,';':333,'<':584,'=':584,'>':584,'?':611,'@':975,'A':722,
|
|
'B':722,'C':722,'D':722,'E':667,'F':611,'G':778,'H':722,'I':278,'J':556,'K':722,'L':611,'M':833,'N':722,'O':778,'P':667,'Q':778,'R':722,'S':667,'T':611,'U':722,'V':667,'W':944,
|
|
'X':667,'Y':667,'Z':611,'[':333,'\\':278,']':333,'^':584,'_':556,'`':333,'a':556,'b':611,'c':556,'d':611,'e':556,'f':333,'g':611,'h':611,'i':278,'j':278,'k':556,'l':278,'m':889,
|
|
'n':611,'o':611,'p':611,'q':611,'r':389,'s':556,'t':333,'u':611,'v':556,'w':778,'x':556,'y':556,'z':500,'{':389,'|':280,'}':389,'~':584,'\x7f':350,'\x80':556,'\x81':350,'\x82':278,'\x83':556,
|
|
'\x84':500,'\x85':1000,'\x86':556,'\x87':556,'\x88':333,'\x89':1000,'\x8a':667,'\x8b':333,'\x8c':1000,'\x8d':350,'\x8e':611,'\x8f':350,'\x90':350,'\x91':278,'\x92':278,'\x93':500,'\x94':500,'\x95':350,'\x96':556,'\x97':1000,'\x98':333,'\x99':1000,
|
|
'\x9a':556,'\x9b':333,'\x9c':944,'\x9d':350,'\x9e':500,'\x9f':667,'\xa0':278,'\xa1':333,'\xa2':556,'\xa3':556,'\xa4':556,'\xa5':556,'\xa6':280,'\xa7':556,'\xa8':333,'\xa9':737,'\xaa':370,'\xab':556,'\xac':584,'\xad':333,'\xae':737,'\xaf':333,
|
|
'\xb0':400,'\xb1':584,'\xb2':333,'\xb3':333,'\xb4':333,'\xb5':611,'\xb6':556,'\xb7':278,'\xb8':333,'\xb9':333,'\xba':365,'\xbb':556,'\xbc':834,'\xbd':834,'\xbe':834,'\xbf':611,'\xc0':722,'\xc1':722,'\xc2':722,'\xc3':722,'\xc4':722,'\xc5':722,
|
|
'\xc6':1000,'\xc7':722,'\xc8':667,'\xc9':667,'\xca':667,'\xcb':667,'\xcc':278,'\xcd':278,'\xce':278,'\xcf':278,'\xd0':722,'\xd1':722,'\xd2':778,'\xd3':778,'\xd4':778,'\xd5':778,'\xd6':778,'\xd7':584,'\xd8':778,'\xd9':722,'\xda':722,'\xdb':722,
|
|
'\xdc':722,'\xdd':667,'\xde':667,'\xdf':611,'\xe0':556,'\xe1':556,'\xe2':556,'\xe3':556,'\xe4':556,'\xe5':556,'\xe6':889,'\xe7':556,'\xe8':556,'\xe9':556,'\xea':556,'\xeb':556,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':611,'\xf1':611,
|
|
'\xf2':611,'\xf3':611,'\xf4':611,'\xf5':611,'\xf6':611,'\xf7':584,'\xf8':611,'\xf9':611,'\xfa':611,'\xfb':611,'\xfc':611,'\xfd':556,'\xfe':611,'\xff':556
|
|
}
|
|
|
|
fpdf_charwidths['helveticaBI']={
|
|
'\x00':278,'\x01':278,'\x02':278,'\x03':278,'\x04':278,'\x05':278,'\x06':278,'\x07':278,'\x08':278,'\t':278,'\n':278,'\x0b':278,'\x0c':278,'\r':278,'\x0e':278,'\x0f':278,'\x10':278,'\x11':278,'\x12':278,'\x13':278,'\x14':278,'\x15':278,
|
|
'\x16':278,'\x17':278,'\x18':278,'\x19':278,'\x1a':278,'\x1b':278,'\x1c':278,'\x1d':278,'\x1e':278,'\x1f':278,' ':278,'!':333,'"':474,'#':556,'$':556,'%':889,'&':722,'\'':238,'(':333,')':333,'*':389,'+':584,
|
|
',':278,'-':333,'.':278,'/':278,'0':556,'1':556,'2':556,'3':556,'4':556,'5':556,'6':556,'7':556,'8':556,'9':556,':':333,';':333,'<':584,'=':584,'>':584,'?':611,'@':975,'A':722,
|
|
'B':722,'C':722,'D':722,'E':667,'F':611,'G':778,'H':722,'I':278,'J':556,'K':722,'L':611,'M':833,'N':722,'O':778,'P':667,'Q':778,'R':722,'S':667,'T':611,'U':722,'V':667,'W':944,
|
|
'X':667,'Y':667,'Z':611,'[':333,'\\':278,']':333,'^':584,'_':556,'`':333,'a':556,'b':611,'c':556,'d':611,'e':556,'f':333,'g':611,'h':611,'i':278,'j':278,'k':556,'l':278,'m':889,
|
|
'n':611,'o':611,'p':611,'q':611,'r':389,'s':556,'t':333,'u':611,'v':556,'w':778,'x':556,'y':556,'z':500,'{':389,'|':280,'}':389,'~':584,'\x7f':350,'\x80':556,'\x81':350,'\x82':278,'\x83':556,
|
|
'\x84':500,'\x85':1000,'\x86':556,'\x87':556,'\x88':333,'\x89':1000,'\x8a':667,'\x8b':333,'\x8c':1000,'\x8d':350,'\x8e':611,'\x8f':350,'\x90':350,'\x91':278,'\x92':278,'\x93':500,'\x94':500,'\x95':350,'\x96':556,'\x97':1000,'\x98':333,'\x99':1000,
|
|
'\x9a':556,'\x9b':333,'\x9c':944,'\x9d':350,'\x9e':500,'\x9f':667,'\xa0':278,'\xa1':333,'\xa2':556,'\xa3':556,'\xa4':556,'\xa5':556,'\xa6':280,'\xa7':556,'\xa8':333,'\xa9':737,'\xaa':370,'\xab':556,'\xac':584,'\xad':333,'\xae':737,'\xaf':333,
|
|
'\xb0':400,'\xb1':584,'\xb2':333,'\xb3':333,'\xb4':333,'\xb5':611,'\xb6':556,'\xb7':278,'\xb8':333,'\xb9':333,'\xba':365,'\xbb':556,'\xbc':834,'\xbd':834,'\xbe':834,'\xbf':611,'\xc0':722,'\xc1':722,'\xc2':722,'\xc3':722,'\xc4':722,'\xc5':722,
|
|
'\xc6':1000,'\xc7':722,'\xc8':667,'\xc9':667,'\xca':667,'\xcb':667,'\xcc':278,'\xcd':278,'\xce':278,'\xcf':278,'\xd0':722,'\xd1':722,'\xd2':778,'\xd3':778,'\xd4':778,'\xd5':778,'\xd6':778,'\xd7':584,'\xd8':778,'\xd9':722,'\xda':722,'\xdb':722,
|
|
'\xdc':722,'\xdd':667,'\xde':667,'\xdf':611,'\xe0':556,'\xe1':556,'\xe2':556,'\xe3':556,'\xe4':556,'\xe5':556,'\xe6':889,'\xe7':556,'\xe8':556,'\xe9':556,'\xea':556,'\xeb':556,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':611,'\xf1':611,
|
|
'\xf2':611,'\xf3':611,'\xf4':611,'\xf5':611,'\xf6':611,'\xf7':584,'\xf8':611,'\xf9':611,'\xfa':611,'\xfb':611,'\xfc':611,'\xfd':556,'\xfe':611,'\xff':556}
|
|
|
|
fpdf_charwidths['helveticaI']={
|
|
'\x00':278,'\x01':278,'\x02':278,'\x03':278,'\x04':278,'\x05':278,'\x06':278,'\x07':278,'\x08':278,'\t':278,'\n':278,'\x0b':278,'\x0c':278,'\r':278,'\x0e':278,'\x0f':278,'\x10':278,'\x11':278,'\x12':278,'\x13':278,'\x14':278,'\x15':278,
|
|
'\x16':278,'\x17':278,'\x18':278,'\x19':278,'\x1a':278,'\x1b':278,'\x1c':278,'\x1d':278,'\x1e':278,'\x1f':278,' ':278,'!':278,'"':355,'#':556,'$':556,'%':889,'&':667,'\'':191,'(':333,')':333,'*':389,'+':584,
|
|
',':278,'-':333,'.':278,'/':278,'0':556,'1':556,'2':556,'3':556,'4':556,'5':556,'6':556,'7':556,'8':556,'9':556,':':278,';':278,'<':584,'=':584,'>':584,'?':556,'@':1015,'A':667,
|
|
'B':667,'C':722,'D':722,'E':667,'F':611,'G':778,'H':722,'I':278,'J':500,'K':667,'L':556,'M':833,'N':722,'O':778,'P':667,'Q':778,'R':722,'S':667,'T':611,'U':722,'V':667,'W':944,
|
|
'X':667,'Y':667,'Z':611,'[':278,'\\':278,']':278,'^':469,'_':556,'`':333,'a':556,'b':556,'c':500,'d':556,'e':556,'f':278,'g':556,'h':556,'i':222,'j':222,'k':500,'l':222,'m':833,
|
|
'n':556,'o':556,'p':556,'q':556,'r':333,'s':500,'t':278,'u':556,'v':500,'w':722,'x':500,'y':500,'z':500,'{':334,'|':260,'}':334,'~':584,'\x7f':350,'\x80':556,'\x81':350,'\x82':222,'\x83':556,
|
|
'\x84':333,'\x85':1000,'\x86':556,'\x87':556,'\x88':333,'\x89':1000,'\x8a':667,'\x8b':333,'\x8c':1000,'\x8d':350,'\x8e':611,'\x8f':350,'\x90':350,'\x91':222,'\x92':222,'\x93':333,'\x94':333,'\x95':350,'\x96':556,'\x97':1000,'\x98':333,'\x99':1000,
|
|
'\x9a':500,'\x9b':333,'\x9c':944,'\x9d':350,'\x9e':500,'\x9f':667,'\xa0':278,'\xa1':333,'\xa2':556,'\xa3':556,'\xa4':556,'\xa5':556,'\xa6':260,'\xa7':556,'\xa8':333,'\xa9':737,'\xaa':370,'\xab':556,'\xac':584,'\xad':333,'\xae':737,'\xaf':333,
|
|
'\xb0':400,'\xb1':584,'\xb2':333,'\xb3':333,'\xb4':333,'\xb5':556,'\xb6':537,'\xb7':278,'\xb8':333,'\xb9':333,'\xba':365,'\xbb':556,'\xbc':834,'\xbd':834,'\xbe':834,'\xbf':611,'\xc0':667,'\xc1':667,'\xc2':667,'\xc3':667,'\xc4':667,'\xc5':667,
|
|
'\xc6':1000,'\xc7':722,'\xc8':667,'\xc9':667,'\xca':667,'\xcb':667,'\xcc':278,'\xcd':278,'\xce':278,'\xcf':278,'\xd0':722,'\xd1':722,'\xd2':778,'\xd3':778,'\xd4':778,'\xd5':778,'\xd6':778,'\xd7':584,'\xd8':778,'\xd9':722,'\xda':722,'\xdb':722,
|
|
'\xdc':722,'\xdd':667,'\xde':667,'\xdf':611,'\xe0':556,'\xe1':556,'\xe2':556,'\xe3':556,'\xe4':556,'\xe5':556,'\xe6':889,'\xe7':500,'\xe8':556,'\xe9':556,'\xea':556,'\xeb':556,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':556,'\xf1':556,
|
|
'\xf2':556,'\xf3':556,'\xf4':556,'\xf5':556,'\xf6':556,'\xf7':584,'\xf8':611,'\xf9':556,'\xfa':556,'\xfb':556,'\xfc':556,'\xfd':500,'\xfe':556,'\xff':500}
|
|
|
|
fpdf_charwidths['symbol']={
|
|
'\x00':250,'\x01':250,'\x02':250,'\x03':250,'\x04':250,'\x05':250,'\x06':250,'\x07':250,'\x08':250,'\t':250,'\n':250,'\x0b':250,'\x0c':250,'\r':250,'\x0e':250,'\x0f':250,'\x10':250,'\x11':250,'\x12':250,'\x13':250,'\x14':250,'\x15':250,
|
|
'\x16':250,'\x17':250,'\x18':250,'\x19':250,'\x1a':250,'\x1b':250,'\x1c':250,'\x1d':250,'\x1e':250,'\x1f':250,' ':250,'!':333,'"':713,'#':500,'$':549,'%':833,'&':778,'\'':439,'(':333,')':333,'*':500,'+':549,
|
|
',':250,'-':549,'.':250,'/':278,'0':500,'1':500,'2':500,'3':500,'4':500,'5':500,'6':500,'7':500,'8':500,'9':500,':':278,';':278,'<':549,'=':549,'>':549,'?':444,'@':549,'A':722,
|
|
'B':667,'C':722,'D':612,'E':611,'F':763,'G':603,'H':722,'I':333,'J':631,'K':722,'L':686,'M':889,'N':722,'O':722,'P':768,'Q':741,'R':556,'S':592,'T':611,'U':690,'V':439,'W':768,
|
|
'X':645,'Y':795,'Z':611,'[':333,'\\':863,']':333,'^':658,'_':500,'`':500,'a':631,'b':549,'c':549,'d':494,'e':439,'f':521,'g':411,'h':603,'i':329,'j':603,'k':549,'l':549,'m':576,
|
|
'n':521,'o':549,'p':549,'q':521,'r':549,'s':603,'t':439,'u':576,'v':713,'w':686,'x':493,'y':686,'z':494,'{':480,'|':200,'}':480,'~':549,'\x7f':0,'\x80':0,'\x81':0,'\x82':0,'\x83':0,
|
|
'\x84':0,'\x85':0,'\x86':0,'\x87':0,'\x88':0,'\x89':0,'\x8a':0,'\x8b':0,'\x8c':0,'\x8d':0,'\x8e':0,'\x8f':0,'\x90':0,'\x91':0,'\x92':0,'\x93':0,'\x94':0,'\x95':0,'\x96':0,'\x97':0,'\x98':0,'\x99':0,
|
|
'\x9a':0,'\x9b':0,'\x9c':0,'\x9d':0,'\x9e':0,'\x9f':0,'\xa0':750,'\xa1':620,'\xa2':247,'\xa3':549,'\xa4':167,'\xa5':713,'\xa6':500,'\xa7':753,'\xa8':753,'\xa9':753,'\xaa':753,'\xab':1042,'\xac':987,'\xad':603,'\xae':987,'\xaf':603,
|
|
'\xb0':400,'\xb1':549,'\xb2':411,'\xb3':549,'\xb4':549,'\xb5':713,'\xb6':494,'\xb7':460,'\xb8':549,'\xb9':549,'\xba':549,'\xbb':549,'\xbc':1000,'\xbd':603,'\xbe':1000,'\xbf':658,'\xc0':823,'\xc1':686,'\xc2':795,'\xc3':987,'\xc4':768,'\xc5':768,
|
|
'\xc6':823,'\xc7':768,'\xc8':768,'\xc9':713,'\xca':713,'\xcb':713,'\xcc':713,'\xcd':713,'\xce':713,'\xcf':713,'\xd0':768,'\xd1':713,'\xd2':790,'\xd3':790,'\xd4':890,'\xd5':823,'\xd6':549,'\xd7':250,'\xd8':713,'\xd9':603,'\xda':603,'\xdb':1042,
|
|
'\xdc':987,'\xdd':603,'\xde':987,'\xdf':603,'\xe0':494,'\xe1':329,'\xe2':790,'\xe3':790,'\xe4':786,'\xe5':713,'\xe6':384,'\xe7':384,'\xe8':384,'\xe9':384,'\xea':384,'\xeb':384,'\xec':494,'\xed':494,'\xee':494,'\xef':494,'\xf0':0,'\xf1':329,
|
|
'\xf2':274,'\xf3':686,'\xf4':686,'\xf5':686,'\xf6':384,'\xf7':384,'\xf8':384,'\xf9':384,'\xfa':384,'\xfb':384,'\xfc':494,'\xfd':494,'\xfe':494,'\xff':0}
|
|
|
|
fpdf_charwidths['times']={
|
|
'\x00':250,'\x01':250,'\x02':250,'\x03':250,'\x04':250,'\x05':250,'\x06':250,'\x07':250,'\x08':250,'\t':250,'\n':250,'\x0b':250,'\x0c':250,'\r':250,'\x0e':250,'\x0f':250,'\x10':250,'\x11':250,'\x12':250,'\x13':250,'\x14':250,'\x15':250,
|
|
'\x16':250,'\x17':250,'\x18':250,'\x19':250,'\x1a':250,'\x1b':250,'\x1c':250,'\x1d':250,'\x1e':250,'\x1f':250,' ':250,'!':333,'"':408,'#':500,'$':500,'%':833,'&':778,'\'':180,'(':333,')':333,'*':500,'+':564,
|
|
',':250,'-':333,'.':250,'/':278,'0':500,'1':500,'2':500,'3':500,'4':500,'5':500,'6':500,'7':500,'8':500,'9':500,':':278,';':278,'<':564,'=':564,'>':564,'?':444,'@':921,'A':722,
|
|
'B':667,'C':667,'D':722,'E':611,'F':556,'G':722,'H':722,'I':333,'J':389,'K':722,'L':611,'M':889,'N':722,'O':722,'P':556,'Q':722,'R':667,'S':556,'T':611,'U':722,'V':722,'W':944,
|
|
'X':722,'Y':722,'Z':611,'[':333,'\\':278,']':333,'^':469,'_':500,'`':333,'a':444,'b':500,'c':444,'d':500,'e':444,'f':333,'g':500,'h':500,'i':278,'j':278,'k':500,'l':278,'m':778,
|
|
'n':500,'o':500,'p':500,'q':500,'r':333,'s':389,'t':278,'u':500,'v':500,'w':722,'x':500,'y':500,'z':444,'{':480,'|':200,'}':480,'~':541,'\x7f':350,'\x80':500,'\x81':350,'\x82':333,'\x83':500,
|
|
'\x84':444,'\x85':1000,'\x86':500,'\x87':500,'\x88':333,'\x89':1000,'\x8a':556,'\x8b':333,'\x8c':889,'\x8d':350,'\x8e':611,'\x8f':350,'\x90':350,'\x91':333,'\x92':333,'\x93':444,'\x94':444,'\x95':350,'\x96':500,'\x97':1000,'\x98':333,'\x99':980,
|
|
'\x9a':389,'\x9b':333,'\x9c':722,'\x9d':350,'\x9e':444,'\x9f':722,'\xa0':250,'\xa1':333,'\xa2':500,'\xa3':500,'\xa4':500,'\xa5':500,'\xa6':200,'\xa7':500,'\xa8':333,'\xa9':760,'\xaa':276,'\xab':500,'\xac':564,'\xad':333,'\xae':760,'\xaf':333,
|
|
'\xb0':400,'\xb1':564,'\xb2':300,'\xb3':300,'\xb4':333,'\xb5':500,'\xb6':453,'\xb7':250,'\xb8':333,'\xb9':300,'\xba':310,'\xbb':500,'\xbc':750,'\xbd':750,'\xbe':750,'\xbf':444,'\xc0':722,'\xc1':722,'\xc2':722,'\xc3':722,'\xc4':722,'\xc5':722,
|
|
'\xc6':889,'\xc7':667,'\xc8':611,'\xc9':611,'\xca':611,'\xcb':611,'\xcc':333,'\xcd':333,'\xce':333,'\xcf':333,'\xd0':722,'\xd1':722,'\xd2':722,'\xd3':722,'\xd4':722,'\xd5':722,'\xd6':722,'\xd7':564,'\xd8':722,'\xd9':722,'\xda':722,'\xdb':722,
|
|
'\xdc':722,'\xdd':722,'\xde':556,'\xdf':500,'\xe0':444,'\xe1':444,'\xe2':444,'\xe3':444,'\xe4':444,'\xe5':444,'\xe6':667,'\xe7':444,'\xe8':444,'\xe9':444,'\xea':444,'\xeb':444,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':500,'\xf1':500,
|
|
'\xf2':500,'\xf3':500,'\xf4':500,'\xf5':500,'\xf6':500,'\xf7':564,'\xf8':500,'\xf9':500,'\xfa':500,'\xfb':500,'\xfc':500,'\xfd':500,'\xfe':500,'\xff':500}
|
|
|
|
fpdf_charwidths['timesB']={
|
|
'\x00':250,'\x01':250,'\x02':250,'\x03':250,'\x04':250,'\x05':250,'\x06':250,'\x07':250,'\x08':250,'\t':250,'\n':250,'\x0b':250,'\x0c':250,'\r':250,'\x0e':250,'\x0f':250,'\x10':250,'\x11':250,'\x12':250,'\x13':250,'\x14':250,'\x15':250,
|
|
'\x16':250,'\x17':250,'\x18':250,'\x19':250,'\x1a':250,'\x1b':250,'\x1c':250,'\x1d':250,'\x1e':250,'\x1f':250,' ':250,'!':333,'"':555,'#':500,'$':500,'%':1000,'&':833,'\'':278,'(':333,')':333,'*':500,'+':570,
|
|
',':250,'-':333,'.':250,'/':278,'0':500,'1':500,'2':500,'3':500,'4':500,'5':500,'6':500,'7':500,'8':500,'9':500,':':333,';':333,'<':570,'=':570,'>':570,'?':500,'@':930,'A':722,
|
|
'B':667,'C':722,'D':722,'E':667,'F':611,'G':778,'H':778,'I':389,'J':500,'K':778,'L':667,'M':944,'N':722,'O':778,'P':611,'Q':778,'R':722,'S':556,'T':667,'U':722,'V':722,'W':1000,
|
|
'X':722,'Y':722,'Z':667,'[':333,'\\':278,']':333,'^':581,'_':500,'`':333,'a':500,'b':556,'c':444,'d':556,'e':444,'f':333,'g':500,'h':556,'i':278,'j':333,'k':556,'l':278,'m':833,
|
|
'n':556,'o':500,'p':556,'q':556,'r':444,'s':389,'t':333,'u':556,'v':500,'w':722,'x':500,'y':500,'z':444,'{':394,'|':220,'}':394,'~':520,'\x7f':350,'\x80':500,'\x81':350,'\x82':333,'\x83':500,
|
|
'\x84':500,'\x85':1000,'\x86':500,'\x87':500,'\x88':333,'\x89':1000,'\x8a':556,'\x8b':333,'\x8c':1000,'\x8d':350,'\x8e':667,'\x8f':350,'\x90':350,'\x91':333,'\x92':333,'\x93':500,'\x94':500,'\x95':350,'\x96':500,'\x97':1000,'\x98':333,'\x99':1000,
|
|
'\x9a':389,'\x9b':333,'\x9c':722,'\x9d':350,'\x9e':444,'\x9f':722,'\xa0':250,'\xa1':333,'\xa2':500,'\xa3':500,'\xa4':500,'\xa5':500,'\xa6':220,'\xa7':500,'\xa8':333,'\xa9':747,'\xaa':300,'\xab':500,'\xac':570,'\xad':333,'\xae':747,'\xaf':333,
|
|
'\xb0':400,'\xb1':570,'\xb2':300,'\xb3':300,'\xb4':333,'\xb5':556,'\xb6':540,'\xb7':250,'\xb8':333,'\xb9':300,'\xba':330,'\xbb':500,'\xbc':750,'\xbd':750,'\xbe':750,'\xbf':500,'\xc0':722,'\xc1':722,'\xc2':722,'\xc3':722,'\xc4':722,'\xc5':722,
|
|
'\xc6':1000,'\xc7':722,'\xc8':667,'\xc9':667,'\xca':667,'\xcb':667,'\xcc':389,'\xcd':389,'\xce':389,'\xcf':389,'\xd0':722,'\xd1':722,'\xd2':778,'\xd3':778,'\xd4':778,'\xd5':778,'\xd6':778,'\xd7':570,'\xd8':778,'\xd9':722,'\xda':722,'\xdb':722,
|
|
'\xdc':722,'\xdd':722,'\xde':611,'\xdf':556,'\xe0':500,'\xe1':500,'\xe2':500,'\xe3':500,'\xe4':500,'\xe5':500,'\xe6':722,'\xe7':444,'\xe8':444,'\xe9':444,'\xea':444,'\xeb':444,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':500,'\xf1':556,
|
|
'\xf2':500,'\xf3':500,'\xf4':500,'\xf5':500,'\xf6':500,'\xf7':570,'\xf8':500,'\xf9':556,'\xfa':556,'\xfb':556,'\xfc':556,'\xfd':500,'\xfe':556,'\xff':500}
|
|
|
|
fpdf_charwidths['timesBI']={
|
|
'\x00':250,'\x01':250,'\x02':250,'\x03':250,'\x04':250,'\x05':250,'\x06':250,'\x07':250,'\x08':250,'\t':250,'\n':250,'\x0b':250,'\x0c':250,'\r':250,'\x0e':250,'\x0f':250,'\x10':250,'\x11':250,'\x12':250,'\x13':250,'\x14':250,'\x15':250,
|
|
'\x16':250,'\x17':250,'\x18':250,'\x19':250,'\x1a':250,'\x1b':250,'\x1c':250,'\x1d':250,'\x1e':250,'\x1f':250,' ':250,'!':389,'"':555,'#':500,'$':500,'%':833,'&':778,'\'':278,'(':333,')':333,'*':500,'+':570,
|
|
',':250,'-':333,'.':250,'/':278,'0':500,'1':500,'2':500,'3':500,'4':500,'5':500,'6':500,'7':500,'8':500,'9':500,':':333,';':333,'<':570,'=':570,'>':570,'?':500,'@':832,'A':667,
|
|
'B':667,'C':667,'D':722,'E':667,'F':667,'G':722,'H':778,'I':389,'J':500,'K':667,'L':611,'M':889,'N':722,'O':722,'P':611,'Q':722,'R':667,'S':556,'T':611,'U':722,'V':667,'W':889,
|
|
'X':667,'Y':611,'Z':611,'[':333,'\\':278,']':333,'^':570,'_':500,'`':333,'a':500,'b':500,'c':444,'d':500,'e':444,'f':333,'g':500,'h':556,'i':278,'j':278,'k':500,'l':278,'m':778,
|
|
'n':556,'o':500,'p':500,'q':500,'r':389,'s':389,'t':278,'u':556,'v':444,'w':667,'x':500,'y':444,'z':389,'{':348,'|':220,'}':348,'~':570,'\x7f':350,'\x80':500,'\x81':350,'\x82':333,'\x83':500,
|
|
'\x84':500,'\x85':1000,'\x86':500,'\x87':500,'\x88':333,'\x89':1000,'\x8a':556,'\x8b':333,'\x8c':944,'\x8d':350,'\x8e':611,'\x8f':350,'\x90':350,'\x91':333,'\x92':333,'\x93':500,'\x94':500,'\x95':350,'\x96':500,'\x97':1000,'\x98':333,'\x99':1000,
|
|
'\x9a':389,'\x9b':333,'\x9c':722,'\x9d':350,'\x9e':389,'\x9f':611,'\xa0':250,'\xa1':389,'\xa2':500,'\xa3':500,'\xa4':500,'\xa5':500,'\xa6':220,'\xa7':500,'\xa8':333,'\xa9':747,'\xaa':266,'\xab':500,'\xac':606,'\xad':333,'\xae':747,'\xaf':333,
|
|
'\xb0':400,'\xb1':570,'\xb2':300,'\xb3':300,'\xb4':333,'\xb5':576,'\xb6':500,'\xb7':250,'\xb8':333,'\xb9':300,'\xba':300,'\xbb':500,'\xbc':750,'\xbd':750,'\xbe':750,'\xbf':500,'\xc0':667,'\xc1':667,'\xc2':667,'\xc3':667,'\xc4':667,'\xc5':667,
|
|
'\xc6':944,'\xc7':667,'\xc8':667,'\xc9':667,'\xca':667,'\xcb':667,'\xcc':389,'\xcd':389,'\xce':389,'\xcf':389,'\xd0':722,'\xd1':722,'\xd2':722,'\xd3':722,'\xd4':722,'\xd5':722,'\xd6':722,'\xd7':570,'\xd8':722,'\xd9':722,'\xda':722,'\xdb':722,
|
|
'\xdc':722,'\xdd':611,'\xde':611,'\xdf':500,'\xe0':500,'\xe1':500,'\xe2':500,'\xe3':500,'\xe4':500,'\xe5':500,'\xe6':722,'\xe7':444,'\xe8':444,'\xe9':444,'\xea':444,'\xeb':444,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':500,'\xf1':556,
|
|
'\xf2':500,'\xf3':500,'\xf4':500,'\xf5':500,'\xf6':500,'\xf7':570,'\xf8':500,'\xf9':556,'\xfa':556,'\xfb':556,'\xfc':556,'\xfd':444,'\xfe':500,'\xff':444}
|
|
|
|
fpdf_charwidths['timesI']={
|
|
'\x00':250,'\x01':250,'\x02':250,'\x03':250,'\x04':250,'\x05':250,'\x06':250,'\x07':250,'\x08':250,'\t':250,'\n':250,'\x0b':250,'\x0c':250,'\r':250,'\x0e':250,'\x0f':250,'\x10':250,'\x11':250,'\x12':250,'\x13':250,'\x14':250,'\x15':250,
|
|
'\x16':250,'\x17':250,'\x18':250,'\x19':250,'\x1a':250,'\x1b':250,'\x1c':250,'\x1d':250,'\x1e':250,'\x1f':250,' ':250,'!':333,'"':420,'#':500,'$':500,'%':833,'&':778,'\'':214,'(':333,')':333,'*':500,'+':675,
|
|
',':250,'-':333,'.':250,'/':278,'0':500,'1':500,'2':500,'3':500,'4':500,'5':500,'6':500,'7':500,'8':500,'9':500,':':333,';':333,'<':675,'=':675,'>':675,'?':500,'@':920,'A':611,
|
|
'B':611,'C':667,'D':722,'E':611,'F':611,'G':722,'H':722,'I':333,'J':444,'K':667,'L':556,'M':833,'N':667,'O':722,'P':611,'Q':722,'R':611,'S':500,'T':556,'U':722,'V':611,'W':833,
|
|
'X':611,'Y':556,'Z':556,'[':389,'\\':278,']':389,'^':422,'_':500,'`':333,'a':500,'b':500,'c':444,'d':500,'e':444,'f':278,'g':500,'h':500,'i':278,'j':278,'k':444,'l':278,'m':722,
|
|
'n':500,'o':500,'p':500,'q':500,'r':389,'s':389,'t':278,'u':500,'v':444,'w':667,'x':444,'y':444,'z':389,'{':400,'|':275,'}':400,'~':541,'\x7f':350,'\x80':500,'\x81':350,'\x82':333,'\x83':500,
|
|
'\x84':556,'\x85':889,'\x86':500,'\x87':500,'\x88':333,'\x89':1000,'\x8a':500,'\x8b':333,'\x8c':944,'\x8d':350,'\x8e':556,'\x8f':350,'\x90':350,'\x91':333,'\x92':333,'\x93':556,'\x94':556,'\x95':350,'\x96':500,'\x97':889,'\x98':333,'\x99':980,
|
|
'\x9a':389,'\x9b':333,'\x9c':667,'\x9d':350,'\x9e':389,'\x9f':556,'\xa0':250,'\xa1':389,'\xa2':500,'\xa3':500,'\xa4':500,'\xa5':500,'\xa6':275,'\xa7':500,'\xa8':333,'\xa9':760,'\xaa':276,'\xab':500,'\xac':675,'\xad':333,'\xae':760,'\xaf':333,
|
|
'\xb0':400,'\xb1':675,'\xb2':300,'\xb3':300,'\xb4':333,'\xb5':500,'\xb6':523,'\xb7':250,'\xb8':333,'\xb9':300,'\xba':310,'\xbb':500,'\xbc':750,'\xbd':750,'\xbe':750,'\xbf':500,'\xc0':611,'\xc1':611,'\xc2':611,'\xc3':611,'\xc4':611,'\xc5':611,
|
|
'\xc6':889,'\xc7':667,'\xc8':611,'\xc9':611,'\xca':611,'\xcb':611,'\xcc':333,'\xcd':333,'\xce':333,'\xcf':333,'\xd0':722,'\xd1':667,'\xd2':722,'\xd3':722,'\xd4':722,'\xd5':722,'\xd6':722,'\xd7':675,'\xd8':722,'\xd9':722,'\xda':722,'\xdb':722,
|
|
'\xdc':722,'\xdd':556,'\xde':611,'\xdf':500,'\xe0':500,'\xe1':500,'\xe2':500,'\xe3':500,'\xe4':500,'\xe5':500,'\xe6':667,'\xe7':444,'\xe8':444,'\xe9':444,'\xea':444,'\xeb':444,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':500,'\xf1':500,
|
|
'\xf2':500,'\xf3':500,'\xf4':500,'\xf5':500,'\xf6':500,'\xf7':675,'\xf8':500,'\xf9':500,'\xfa':500,'\xfb':500,'\xfc':500,'\xfd':444,'\xfe':500,'\xff':444}
|
|
|
|
fpdf_charwidths['zapfdingbats']={
|
|
'\x00':0,'\x01':0,'\x02':0,'\x03':0,'\x04':0,'\x05':0,'\x06':0,'\x07':0,'\x08':0,'\t':0,'\n':0,'\x0b':0,'\x0c':0,'\r':0,'\x0e':0,'\x0f':0,'\x10':0,'\x11':0,'\x12':0,'\x13':0,'\x14':0,'\x15':0,
|
|
'\x16':0,'\x17':0,'\x18':0,'\x19':0,'\x1a':0,'\x1b':0,'\x1c':0,'\x1d':0,'\x1e':0,'\x1f':0,' ':278,'!':974,'"':961,'#':974,'$':980,'%':719,'&':789,'\'':790,'(':791,')':690,'*':960,'+':939,
|
|
',':549,'-':855,'.':911,'/':933,'0':911,'1':945,'2':974,'3':755,'4':846,'5':762,'6':761,'7':571,'8':677,'9':763,':':760,';':759,'<':754,'=':494,'>':552,'?':537,'@':577,'A':692,
|
|
'B':786,'C':788,'D':788,'E':790,'F':793,'G':794,'H':816,'I':823,'J':789,'K':841,'L':823,'M':833,'N':816,'O':831,'P':923,'Q':744,'R':723,'S':749,'T':790,'U':792,'V':695,'W':776,
|
|
'X':768,'Y':792,'Z':759,'[':707,'\\':708,']':682,'^':701,'_':826,'`':815,'a':789,'b':789,'c':707,'d':687,'e':696,'f':689,'g':786,'h':787,'i':713,'j':791,'k':785,'l':791,'m':873,
|
|
'n':761,'o':762,'p':762,'q':759,'r':759,'s':892,'t':892,'u':788,'v':784,'w':438,'x':138,'y':277,'z':415,'{':392,'|':392,'}':668,'~':668,'\x7f':0,'\x80':390,'\x81':390,'\x82':317,'\x83':317,
|
|
'\x84':276,'\x85':276,'\x86':509,'\x87':509,'\x88':410,'\x89':410,'\x8a':234,'\x8b':234,'\x8c':334,'\x8d':334,'\x8e':0,'\x8f':0,'\x90':0,'\x91':0,'\x92':0,'\x93':0,'\x94':0,'\x95':0,'\x96':0,'\x97':0,'\x98':0,'\x99':0,
|
|
'\x9a':0,'\x9b':0,'\x9c':0,'\x9d':0,'\x9e':0,'\x9f':0,'\xa0':0,'\xa1':732,'\xa2':544,'\xa3':544,'\xa4':910,'\xa5':667,'\xa6':760,'\xa7':760,'\xa8':776,'\xa9':595,'\xaa':694,'\xab':626,'\xac':788,'\xad':788,'\xae':788,'\xaf':788,
|
|
'\xb0':788,'\xb1':788,'\xb2':788,'\xb3':788,'\xb4':788,'\xb5':788,'\xb6':788,'\xb7':788,'\xb8':788,'\xb9':788,'\xba':788,'\xbb':788,'\xbc':788,'\xbd':788,'\xbe':788,'\xbf':788,'\xc0':788,'\xc1':788,'\xc2':788,'\xc3':788,'\xc4':788,'\xc5':788,
|
|
'\xc6':788,'\xc7':788,'\xc8':788,'\xc9':788,'\xca':788,'\xcb':788,'\xcc':788,'\xcd':788,'\xce':788,'\xcf':788,'\xd0':788,'\xd1':788,'\xd2':788,'\xd3':788,'\xd4':894,'\xd5':838,'\xd6':1016,'\xd7':458,'\xd8':748,'\xd9':924,'\xda':748,'\xdb':918,
|
|
'\xdc':927,'\xdd':928,'\xde':928,'\xdf':834,'\xe0':873,'\xe1':828,'\xe2':924,'\xe3':924,'\xe4':917,'\xe5':930,'\xe6':931,'\xe7':463,'\xe8':883,'\xe9':836,'\xea':836,'\xeb':867,'\xec':867,'\xed':696,'\xee':696,'\xef':874,'\xf0':0,'\xf1':874,
|
|
'\xf2':760,'\xf3':946,'\xf4':771,'\xf5':865,'\xf6':771,'\xf7':888,'\xf8':967,'\xf9':888,'\xfa':831,'\xfb':873,'\xfc':927,'\xfd':970,'\xfe':918,'\xff':0}
|
|
|
|
|
|
|