new pyfpdf, thanks Mariano
This commit is contained in:
2
VERSION
2
VERSION
@@ -1 +1 @@
|
||||
Version 2.00.0 (2012-08-22 19:47:08) dev
|
||||
Version 2.00.0 (2012-08-23 08:31:01) dev
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Read more about this http://code.google.com/p/pyfpdf
|
||||
@@ -1,5 +1,16 @@
|
||||
from fpdf import FPDF
|
||||
from html import HTMLMixin
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"FPDF for python"
|
||||
|
||||
__license__ = "LGPL 3.0"
|
||||
__version__ = "1.7"
|
||||
|
||||
from fpdf import *
|
||||
try:
|
||||
from html import HTMLMixin
|
||||
except ImportError:
|
||||
import warnings
|
||||
warnings.warn("web2py gluon package not installed, required for html2pdf")
|
||||
|
||||
from template import Template
|
||||
|
||||
|
||||
|
||||
@@ -1,736 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: latin-1 -*-
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation; either version 3, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
|
||||
"Visual Template designer for PyFPDF (using wxPython OGL library)"
|
||||
|
||||
__author__ = "Mariano Reingart <reingart@gmail.com>"
|
||||
__copyright__ = "Copyright (C) 2011 Mariano Reingart"
|
||||
__license__ = "GPL 3.0"
|
||||
__version__ = "1.01a"
|
||||
|
||||
# Based on:
|
||||
# * pySjetch.py wxPython sample application
|
||||
# * OGL.py and other wxPython demo modules
|
||||
|
||||
|
||||
import os, sys
|
||||
import wx
|
||||
import wx.lib.ogl as ogl
|
||||
from wx.lib.wordwrap import wordwrap
|
||||
|
||||
DEBUG = True
|
||||
|
||||
|
||||
class CustomDialog(wx.Dialog):
|
||||
"A dinamyc dialog to ask user about arbitrary fields"
|
||||
|
||||
def __init__(
|
||||
self, parent, ID, title, size=wx.DefaultSize, pos=wx.DefaultPosition,
|
||||
style=wx.DEFAULT_DIALOG_STYLE, fields=None, data=None,
|
||||
):
|
||||
|
||||
wx.Dialog.__init__ (self, parent, ID, title, pos, size, style)
|
||||
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
self.textctrls = {}
|
||||
for field in fields:
|
||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||
label = wx.StaticText(self, -1, field)
|
||||
label.SetHelpText("This is the help text for the label")
|
||||
box.Add(label, 1, wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||
text = wx.TextCtrl(self, -1, "", size=(80,-1))
|
||||
text.SetHelpText("Here's some help text for field #1")
|
||||
if field in data:
|
||||
text.SetValue(repr(data[field]))
|
||||
box.Add(text, 1, wx.ALIGN_CENTRE|wx.ALL, 1)
|
||||
sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 1)
|
||||
self.textctrls[field] = text
|
||||
|
||||
line = wx.StaticLine(self, -1, size=(20,-1), style=wx.LI_HORIZONTAL)
|
||||
sizer.Add(line, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.TOP, 5)
|
||||
|
||||
btnsizer = wx.StdDialogButtonSizer()
|
||||
|
||||
btn = wx.Button(self, wx.ID_OK)
|
||||
btn.SetHelpText("The OK button completes the dialog")
|
||||
btn.SetDefault()
|
||||
btnsizer.AddButton(btn)
|
||||
|
||||
btn = wx.Button(self, wx.ID_CANCEL)
|
||||
btn.SetHelpText("The Cancel button cancels the dialog. (Cool, huh?)")
|
||||
btnsizer.AddButton(btn)
|
||||
btnsizer.Realize()
|
||||
|
||||
sizer.Add(btnsizer, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
|
||||
|
||||
self.SetSizer(sizer)
|
||||
sizer.Fit(self)
|
||||
|
||||
@classmethod
|
||||
def do_input(Class, parent, title, fields, data):
|
||||
dlg = Class(parent, -1, title, size=(350, 200),
|
||||
style=wx.DEFAULT_DIALOG_STYLE, # & ~wx.CLOSE_BOX,
|
||||
fields=fields, data=data
|
||||
)
|
||||
dlg.CenterOnScreen()
|
||||
while 1:
|
||||
val = dlg.ShowModal()
|
||||
if val == wx.ID_OK:
|
||||
values = {}
|
||||
for field in fields:
|
||||
try:
|
||||
values[field] = eval(dlg.textctrls[field].GetValue())
|
||||
except Exception, e:
|
||||
msg = wx.MessageDialog(parent, unicode(e),
|
||||
"Error in field %s" % field,
|
||||
wx.OK | wx.ICON_INFORMATION
|
||||
)
|
||||
msg.ShowModal()
|
||||
msg.Destroy()
|
||||
break
|
||||
else:
|
||||
return dict([(field, values[field]) for field in fields])
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
class MyEvtHandler(ogl.ShapeEvtHandler):
|
||||
"Custom Event Handler for Shapes"
|
||||
def __init__(self, callback):
|
||||
ogl.ShapeEvtHandler.__init__(self)
|
||||
self.callback = callback
|
||||
|
||||
def OnLeftClick(self, x, y, keys=0, attachment=0):
|
||||
shape = self.GetShape()
|
||||
canvas = shape.GetCanvas()
|
||||
dc = wx.ClientDC(canvas)
|
||||
canvas.PrepareDC(dc)
|
||||
|
||||
if shape.Selected() and keys & ogl.KEY_SHIFT:
|
||||
shape.Select(False, dc)
|
||||
#canvas.Redraw(dc)
|
||||
canvas.Refresh(False)
|
||||
else:
|
||||
redraw = False
|
||||
shapeList = canvas.GetDiagram().GetShapeList()
|
||||
toUnselect = []
|
||||
|
||||
for s in shapeList:
|
||||
if s.Selected() and not keys & ogl.KEY_SHIFT:
|
||||
# If we unselect it now then some of the objects in
|
||||
# shapeList will become invalid (the control points are
|
||||
# shapes too!) and bad things will happen...
|
||||
toUnselect.append(s)
|
||||
|
||||
shape.Select(True, dc)
|
||||
|
||||
if toUnselect:
|
||||
for s in toUnselect:
|
||||
s.Select(False, dc)
|
||||
##canvas.Redraw(dc)
|
||||
canvas.Refresh(False)
|
||||
|
||||
self.callback()
|
||||
|
||||
def OnEndDragLeft(self, x, y, keys=0, attachment=0):
|
||||
shape = self.GetShape()
|
||||
ogl.ShapeEvtHandler.OnEndDragLeft(self, x, y, keys, attachment)
|
||||
|
||||
if not shape.Selected():
|
||||
self.OnLeftClick(x, y, keys, attachment)
|
||||
|
||||
self.callback()
|
||||
|
||||
def OnSizingEndDragLeft(self, pt, x, y, keys, attch):
|
||||
ogl.ShapeEvtHandler.OnSizingEndDragLeft(self, pt, x, y, keys, attch)
|
||||
self.callback()
|
||||
|
||||
def OnMovePost(self, dc, x, y, oldX, oldY, display):
|
||||
shape = self.GetShape()
|
||||
ogl.ShapeEvtHandler.OnMovePost(self, dc, x, y, oldX, oldY, display)
|
||||
self.callback()
|
||||
if "wxMac" in wx.PlatformInfo:
|
||||
shape.GetCanvas().Refresh(False)
|
||||
|
||||
def OnLeftDoubleClick(self, x, y, keys = 0, attachment = 0):
|
||||
self.callback("LeftDoubleClick")
|
||||
|
||||
def OnRightClick(self, *dontcare):
|
||||
self.callback("RightClick")
|
||||
|
||||
|
||||
class Element(object):
|
||||
"Visual class that represent a placeholder in the template"
|
||||
|
||||
fields = ['name', 'type',
|
||||
'x1', 'y1', 'x2', 'y2',
|
||||
'font', 'size',
|
||||
'bold', 'italic', 'underline',
|
||||
'foreground', 'background',
|
||||
'align', 'text', 'priority',]
|
||||
|
||||
def __init__(self, canvas=None, frame=None, zoom=5.0, static=False, **kwargs):
|
||||
self.kwargs = kwargs
|
||||
self.zoom = zoom
|
||||
self.frame = frame
|
||||
self.canvas = canvas
|
||||
self.static = static
|
||||
|
||||
name = kwargs['name']
|
||||
kwargs['type']
|
||||
type = kwargs['type']
|
||||
|
||||
x, y, w, h = self.set_coordinates(kwargs['x1'], kwargs['y1'], kwargs['x2'], kwargs['y2'])
|
||||
|
||||
text = kwargs['text']
|
||||
|
||||
shape = self.shape = ogl.RectangleShape(w, h)
|
||||
|
||||
if not static:
|
||||
shape.SetDraggable(True, True)
|
||||
|
||||
shape.SetX(x)
|
||||
shape.SetY(y)
|
||||
#if pen: shape.SetPen(pen)
|
||||
#if brush: shape.SetBrush(brush)
|
||||
shape.SetBrush(wx.TRANSPARENT_BRUSH)
|
||||
|
||||
if type not in ('L', 'B', 'BC'):
|
||||
if not static:
|
||||
pen = wx.LIGHT_GREY_PEN
|
||||
else:
|
||||
pen = wx.RED_PEN
|
||||
shape.SetPen(pen)
|
||||
|
||||
self.text = kwargs['text']
|
||||
|
||||
evthandler = MyEvtHandler(self.evt_callback)
|
||||
evthandler.SetShape(shape)
|
||||
evthandler.SetPreviousHandler(shape.GetEventHandler())
|
||||
shape.SetEventHandler(evthandler)
|
||||
shape.SetCentreResize(False)
|
||||
shape.SetMaintainAspectRatio(False)
|
||||
|
||||
canvas.AddShape( shape )
|
||||
|
||||
@classmethod
|
||||
def new(Class, parent):
|
||||
data = dict(name='some_name', type='T',
|
||||
x1=5.0, y1=5.0, x2=100.0, y2=10.0,
|
||||
font="Arial", size=12,
|
||||
bold=False, italic=False, underline=False,
|
||||
foreground= 0x000000, background=0xFFFFFF,
|
||||
align="L", text="", priority=0)
|
||||
data = CustomDialog.do_input(parent, 'New element', Class.fields, data)
|
||||
if data:
|
||||
return Class(canvas=parent.canvas, frame=parent, **data)
|
||||
|
||||
def edit(self):
|
||||
"Edit current element (show a dialog box with all fields)"
|
||||
data = self.kwargs.copy()
|
||||
x1, y1, x2, y2 = self.get_coordinates()
|
||||
data.update(dict(name=self.name,
|
||||
text=self.text,
|
||||
x1=x1, y1=y1, x2=x2, y2=y2,
|
||||
))
|
||||
data = CustomDialog.do_input(self.frame, 'Edit element', self.fields, data)
|
||||
if data:
|
||||
self.kwargs.update(data)
|
||||
self.name = data['name']
|
||||
self.text = data['text']
|
||||
x,y, w, h = self.set_coordinates(data['x1'], data['y1'], data['x2'], data['y2'])
|
||||
self.shape.SetX(x)
|
||||
self.shape.SetY(y)
|
||||
self.shape.SetWidth(w)
|
||||
self.shape.SetHeight(h)
|
||||
self.canvas.Refresh(False)
|
||||
self.canvas.GetDiagram().ShowAll(1)
|
||||
|
||||
def edit_text(self):
|
||||
"Allow text edition (i.e. for doubleclick)"
|
||||
dlg = wx.TextEntryDialog(
|
||||
self.frame, 'Text for %s' % self.name,
|
||||
'Edit Text', '')
|
||||
if self.text:
|
||||
dlg.SetValue(self.text)
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
self.text = dlg.GetValue().encode("latin1")
|
||||
dlg.Destroy()
|
||||
|
||||
def copy(self):
|
||||
"Return an identical duplicate"
|
||||
kwargs = self.as_dict()
|
||||
element = Element(canvas=self.canvas, frame=self.frame, zoom=self.zoom, static=self.static, **kwargs)
|
||||
return element
|
||||
|
||||
def remove(self):
|
||||
"Erases visual shape from OGL canvas (element must be deleted manually)"
|
||||
self.canvas.RemoveShape(self.shape)
|
||||
|
||||
def move(self, dx, dy):
|
||||
"Change pdf coordinates (converting to wx internal values)"
|
||||
x1, y1, x2, y2 = self.get_coordinates()
|
||||
x1 += dx
|
||||
x2 += dx
|
||||
y1 += dy
|
||||
y2 += dy
|
||||
x, y, w, h = self.set_coordinates(x1, y1, x2, y2)
|
||||
self.shape.SetX(x)
|
||||
self.shape.SetY(y)
|
||||
|
||||
def evt_callback(self, evt_type=None):
|
||||
"Event dispatcher"
|
||||
if evt_type=="LeftDoubleClick":
|
||||
self.edit_text()
|
||||
if evt_type=='RightClick':
|
||||
self.edit()
|
||||
|
||||
# update the status bar
|
||||
x1, y1, x2, y2 = self.get_coordinates()
|
||||
self.frame.SetStatusText("%s (%0.2f, %0.2f) - (%0.2f, %0.2f)" %
|
||||
(self.name, x1, y1, x2, y2))
|
||||
|
||||
def get_coordinates(self):
|
||||
"Convert from wx to pdf coordinates"
|
||||
x, y = self.shape.GetX(), self.shape.GetY()
|
||||
w, h = self.shape.GetBoundingBoxMax()
|
||||
w -= 1
|
||||
h -= 1
|
||||
x1 = x/self.zoom - w/self.zoom/2.0
|
||||
x2 = x/self.zoom + w/self.zoom/2.0
|
||||
y1 = y/self.zoom - h/self.zoom/2.0
|
||||
y2 = y/self.zoom + h/self.zoom/2.0
|
||||
return x1, y1, x2, y2
|
||||
|
||||
def set_coordinates(self, x1, y1, x2, y2):
|
||||
"Convert from pdf to wx coordinates"
|
||||
x1 = x1 * self.zoom
|
||||
x2 = x2 * self.zoom
|
||||
y1 = y1 * self.zoom
|
||||
y2 = y2 * self.zoom
|
||||
|
||||
# shapes seems to be centred, pdf coord not
|
||||
w = max(x1, x2) - min(x1, x2) + 1
|
||||
h = max(y1, y2) - min(y1, y2) + 1
|
||||
x = (min(x1, x2) + w/2.0)
|
||||
y = (min(y1, y2) + h/2.0)
|
||||
return x, y, w, h
|
||||
|
||||
def text(self, txt=None):
|
||||
if txt is not None:
|
||||
if not isinstance(txt,str):
|
||||
txt = str(txt)
|
||||
self.kwargs['text'] = txt
|
||||
self.shape.ClearText()
|
||||
for line in txt.split('\n'):
|
||||
self.shape.AddText(unicode(line, "latin1"))
|
||||
self.canvas.Refresh(False)
|
||||
return self.kwargs['text']
|
||||
text = property(text, text)
|
||||
|
||||
def set_x(self, x):
|
||||
self.shape.SetX(x)
|
||||
self.canvas.Refresh(False)
|
||||
self.evt_callback()
|
||||
def set_y(self, y):
|
||||
self.shape.SetY(y)
|
||||
self.canvas.Refresh(False)
|
||||
self.evt_callback()
|
||||
def get_x(self):
|
||||
return self.shape.GetX()
|
||||
def get_y(self):
|
||||
return self.shape.GetY()
|
||||
|
||||
x = property(get_x, set_x)
|
||||
y = property(get_y, set_y)
|
||||
|
||||
def selected(self, sel=None):
|
||||
if sel is not None:
|
||||
print "Setting Select(%s)" % sel
|
||||
self.shape.Select(sel)
|
||||
return self.shape.Selected()
|
||||
selected = property(selected, selected)
|
||||
|
||||
def name(self, name=None):
|
||||
if name is not None:
|
||||
self.kwargs['name'] = name
|
||||
return self.kwargs['name']
|
||||
name = property(name, name)
|
||||
|
||||
def __contains__(self, k):
|
||||
"Implement in keyword for searchs"
|
||||
return k in self.name.lower() or self.text and k in self.text.lower()
|
||||
|
||||
def as_dict(self):
|
||||
"Return a dictionary representation, used by pyfpdf"
|
||||
d = self.kwargs
|
||||
x1, y1, x2, y2 = self.get_coordinates()
|
||||
d.update({
|
||||
'x1': x1, 'y1': y1, 'x2': x2, 'y2': y2,
|
||||
'text': self.text})
|
||||
return d
|
||||
|
||||
|
||||
class AppFrame(wx.Frame):
|
||||
"OGL Designer main window"
|
||||
title = "PyFPDF Template Designer (wx OGL)"
|
||||
|
||||
def __init__(self):
|
||||
wx.Frame.__init__( self,
|
||||
None, -1, self.title,
|
||||
size=(640,480),
|
||||
style=wx.DEFAULT_FRAME_STYLE )
|
||||
sys.excepthook = self.except_hook
|
||||
self.filename = ""
|
||||
# Create a toolbar:
|
||||
tsize = (16,16)
|
||||
self.toolbar = self.CreateToolBar(wx.TB_HORIZONTAL | wx.NO_BORDER | wx.TB_FLAT)
|
||||
|
||||
artBmp = wx.ArtProvider.GetBitmap
|
||||
self.toolbar.AddSimpleTool(
|
||||
wx.ID_NEW, artBmp(wx.ART_NEW, wx.ART_TOOLBAR, tsize), "New")
|
||||
self.toolbar.AddSimpleTool(
|
||||
wx.ID_OPEN, artBmp(wx.ART_FILE_OPEN, wx.ART_TOOLBAR, tsize), "Open")
|
||||
self.toolbar.AddSimpleTool(
|
||||
wx.ID_SAVE, artBmp(wx.ART_FILE_SAVE, wx.ART_TOOLBAR, tsize), "Save")
|
||||
self.toolbar.AddSimpleTool(
|
||||
wx.ID_SAVEAS, artBmp(wx.ART_FILE_SAVE_AS, wx.ART_TOOLBAR, tsize),
|
||||
"Save As...")
|
||||
#-------
|
||||
self.toolbar.AddSeparator()
|
||||
self.toolbar.AddSimpleTool(
|
||||
wx.ID_UNDO, artBmp(wx.ART_UNDO, wx.ART_TOOLBAR, tsize), "Undo")
|
||||
self.toolbar.AddSimpleTool(
|
||||
wx.ID_REDO, artBmp(wx.ART_REDO, wx.ART_TOOLBAR, tsize), "Redo")
|
||||
self.toolbar.AddSeparator()
|
||||
#-------
|
||||
self.toolbar.AddSimpleTool(
|
||||
wx.ID_CUT, artBmp(wx.ART_CUT, wx.ART_TOOLBAR, tsize), "Remove")
|
||||
self.toolbar.AddSimpleTool(
|
||||
wx.ID_COPY, artBmp(wx.ART_COPY, wx.ART_TOOLBAR, tsize), "Duplicate")
|
||||
self.toolbar.AddSimpleTool(
|
||||
wx.ID_PASTE, artBmp(wx.ART_PASTE, wx.ART_TOOLBAR, tsize), "Insert")
|
||||
self.toolbar.AddSeparator()
|
||||
self.toolbar.AddSimpleTool(
|
||||
wx.ID_FIND, artBmp(wx.ART_FIND, wx.ART_TOOLBAR, tsize), "Find")
|
||||
self.toolbar.AddSeparator()
|
||||
self.toolbar.AddSimpleTool(
|
||||
wx.ID_PRINT, artBmp(wx.ART_PRINT, wx.ART_TOOLBAR, tsize), "Print")
|
||||
self.toolbar.AddSimpleTool(
|
||||
wx.ID_ABOUT, artBmp(wx.ART_HELP, wx.ART_TOOLBAR, tsize), "About")
|
||||
|
||||
self.toolbar.Realize()
|
||||
|
||||
self.toolbar.EnableTool(wx.ID_SAVEAS, False)
|
||||
self.toolbar.EnableTool(wx.ID_UNDO, False)
|
||||
self.toolbar.EnableTool(wx.ID_REDO, False)
|
||||
|
||||
menu_handlers = [
|
||||
(wx.ID_NEW, self.do_new),
|
||||
(wx.ID_OPEN, self.do_open),
|
||||
(wx.ID_SAVE, self.do_save),
|
||||
(wx.ID_PRINT, self.do_print),
|
||||
(wx.ID_FIND, self.do_find),
|
||||
(wx.ID_CUT, self.do_cut),
|
||||
(wx.ID_COPY, self.do_copy),
|
||||
(wx.ID_PASTE, self.do_paste),
|
||||
(wx.ID_ABOUT, self.do_about),
|
||||
]
|
||||
for menu_id, handler in menu_handlers:
|
||||
self.Bind(wx.EVT_MENU, handler, id = menu_id)
|
||||
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
# put stuff into sizer
|
||||
|
||||
self.CreateStatusBar()
|
||||
|
||||
canvas = self.canvas = ogl.ShapeCanvas( self )
|
||||
maxWidth = 1500
|
||||
maxHeight = 2000
|
||||
canvas.SetScrollbars(20, 20, maxWidth/20, maxHeight/20)
|
||||
sizer.Add( canvas, 1, wx.GROW )
|
||||
|
||||
canvas.SetBackgroundColour("WHITE") #
|
||||
|
||||
diagram = self.diagram = ogl.Diagram()
|
||||
canvas.SetDiagram( diagram )
|
||||
diagram.SetCanvas( canvas )
|
||||
diagram.SetSnapToGrid( False )
|
||||
|
||||
# apply sizer
|
||||
self.SetSizer(sizer)
|
||||
self.SetAutoLayout(1)
|
||||
self.Show(1)
|
||||
|
||||
self.Bind(wx.EVT_CHAR_HOOK, self.on_key_event)
|
||||
self.elements = []
|
||||
|
||||
def on_key_event(self, event):
|
||||
""" Respond to a keypress event.
|
||||
|
||||
We make the arrow keys move the selected object(s) by one pixel in
|
||||
the given direction.
|
||||
"""
|
||||
step = 1
|
||||
if event.ControlDown():
|
||||
step = 20
|
||||
|
||||
if event.GetKeyCode() == wx.WXK_UP:
|
||||
self.move_elements(0, -step)
|
||||
elif event.GetKeyCode() == wx.WXK_DOWN:
|
||||
self.move_elements(0, step)
|
||||
elif event.GetKeyCode() == wx.WXK_LEFT:
|
||||
self.move_elements(-step, 0)
|
||||
elif event.GetKeyCode() == wx.WXK_RIGHT:
|
||||
self.move_elements(step, 0)
|
||||
elif event.GetKeyCode() == wx.WXK_DELETE:
|
||||
self.do_cut()
|
||||
else:
|
||||
event.Skip()
|
||||
|
||||
def do_new(self, evt=None):
|
||||
for element in self.elements:
|
||||
element.remove()
|
||||
self.elements = []
|
||||
# draw paper size guides
|
||||
for k, (w, h) in [('legal', (216, 356)), ('A4', (210, 297)), ('letter', (216, 279))]:
|
||||
self.create_elements(
|
||||
k, 'R', 0, 0, w, h,
|
||||
size=70, foreground=0x808080, priority=-100,
|
||||
canvas=self.canvas, frame=self, static=True)
|
||||
self.diagram.ShowAll( 1 )
|
||||
|
||||
def do_open(self, evt):
|
||||
dlg = wx.FileDialog(
|
||||
self, message="Choose a file",
|
||||
defaultDir=os.getcwd(),
|
||||
defaultFile="invoice.csv",
|
||||
wildcard="CSV Files (*.csv)|*.csv",
|
||||
style=wx.OPEN
|
||||
)
|
||||
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
# This returns a Python list of files that were selected.
|
||||
self.filename = dlg.GetPaths()[0]
|
||||
|
||||
dlg.Destroy()
|
||||
self.SetTitle(self.filename + " - " + self.title)
|
||||
|
||||
self.do_new()
|
||||
tmp = []
|
||||
f = open(self.filename)
|
||||
try:
|
||||
filedata = f.readlines()
|
||||
finally:
|
||||
f.close()
|
||||
for lno, linea in enumerate(filedata):
|
||||
if DEBUG: print "processing line", lno, linea
|
||||
args = []
|
||||
for i,v in enumerate(linea.split(";")):
|
||||
if not v.startswith("'"):
|
||||
v = v.replace(",",".")
|
||||
else:
|
||||
v = v#.decode('latin1')
|
||||
if v.strip()=='':
|
||||
v = None
|
||||
else:
|
||||
v = eval(v.strip())
|
||||
args.append(v)
|
||||
tmp.append(args)
|
||||
|
||||
# sort by z-order (priority)
|
||||
for args in sorted(tmp, key=lambda t: t[-1]):
|
||||
if DEBUG: print args
|
||||
self.create_elements(*args)
|
||||
self.diagram.ShowAll( 1 ) #
|
||||
|
||||
return True
|
||||
|
||||
def do_save(self, evt, filename=None):
|
||||
try:
|
||||
from time import gmtime, strftime
|
||||
ts = strftime("%Y%m%d%H%M%S", gmtime())
|
||||
os.rename(self.filename, self.filename + ts + ".bak")
|
||||
except Exception, e:
|
||||
if DEBUG: print e
|
||||
pass
|
||||
|
||||
def csv_repr(v, decimal_sep="."):
|
||||
if isinstance(v, float):
|
||||
return ("%0.2f" % v).replace(".", decimal_sep)
|
||||
else:
|
||||
return repr(v)
|
||||
|
||||
f = open(self.filename, "w")
|
||||
try:
|
||||
for element in sorted(self.elements, key=lambda e:e.name):
|
||||
if element.static:
|
||||
continue
|
||||
d = element.as_dict()
|
||||
l = [d['name'], d['type'],
|
||||
d['x1'], d['y1'], d['x2'], d['y2'],
|
||||
d['font'], d['size'],
|
||||
d['bold'], d['italic'], d['underline'],
|
||||
d['foreground'], d['background'],
|
||||
d['align'], d['text'], d['priority'],
|
||||
]
|
||||
f.write(";".join([csv_repr(v) for v in l]))
|
||||
f.write("\n")
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
def do_print(self, evt):
|
||||
# genero el renderizador con propiedades del PDF
|
||||
from template import Template
|
||||
t = Template(elements=[e.as_dict() for e in self.elements if not e.static])
|
||||
t.add_page()
|
||||
if not t['logo'] or not os.path.exists(t['logo']):
|
||||
# put a default logo so it doesn't trow an exception
|
||||
logo = os.path.join(os.path.dirname(__file__), 'tutorial','logo.png')
|
||||
t.set('logo', logo)
|
||||
try:
|
||||
t.render(self.filename +".pdf")
|
||||
except:
|
||||
if DEBUG and False:
|
||||
import pdb;
|
||||
pdb.pm()
|
||||
else:
|
||||
raise
|
||||
if sys.platform=="linux2":
|
||||
os.system("evince ""%s""" % self.filename +".pdf")
|
||||
else:
|
||||
os.startfile(self.filename +".pdf")
|
||||
|
||||
def do_find(self, evt):
|
||||
# busco nombre o texto
|
||||
dlg = wx.TextEntryDialog(
|
||||
self, 'Enter text to search for',
|
||||
'Find Text', '')
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
txt = dlg.GetValue().encode("latin1").lower()
|
||||
for element in self.elements:
|
||||
if txt in element:
|
||||
element.selected = True
|
||||
print "Found:", element.name
|
||||
self.canvas.Refresh(False)
|
||||
dlg.Destroy()
|
||||
|
||||
def do_cut(self, evt=None):
|
||||
"Delete selected elements"
|
||||
new_elements = []
|
||||
for element in self.elements:
|
||||
if element.selected:
|
||||
print "Erasing:", element.name
|
||||
element.selected = False
|
||||
self.canvas.Refresh(False)
|
||||
element.remove()
|
||||
else:
|
||||
new_elements.append(element)
|
||||
self.elements = new_elements
|
||||
self.canvas.Refresh(False)
|
||||
self.diagram.ShowAll( 1 )
|
||||
|
||||
def do_copy(self, evt):
|
||||
"Duplicate selected elements"
|
||||
fields = ['qty', 'dx', 'dy']
|
||||
data = {'qty': 1, 'dx': 0.0, 'dy': 5.0}
|
||||
data = CustomDialog.do_input(self, 'Copy elements', fields, data)
|
||||
if data:
|
||||
new_elements = []
|
||||
for i in range(1, data['qty']+1):
|
||||
for element in self.elements:
|
||||
if element.selected:
|
||||
print "Copying:", element.name
|
||||
new_element = element.copy()
|
||||
name = new_element.name
|
||||
if len(name)>2 and name[-2:].isdigit():
|
||||
new_element.name = name[:-2] + "%02d" % (int(name[-2:])+i)
|
||||
else:
|
||||
new_element.name = new_element.name + "_copy"
|
||||
new_element.selected = False
|
||||
new_element.move(data['dx']*i, data['dy']*i)
|
||||
new_elements.append(new_element)
|
||||
self.elements.extend(new_elements)
|
||||
self.canvas.Refresh(False)
|
||||
self.diagram.ShowAll( 1 )
|
||||
|
||||
def do_paste(self, evt):
|
||||
"Insert new elements"
|
||||
element = Element.new(self)
|
||||
if element:
|
||||
self.canvas.Refresh(False)
|
||||
self.elements.append(element)
|
||||
self.diagram.ShowAll( 1 )
|
||||
|
||||
def create_elements(self, name, type, x1, y1, x2, y2,
|
||||
font="Arial", size=12,
|
||||
bold=False, italic=False, underline=False,
|
||||
foreground= 0x000000, background=0xFFFFFF,
|
||||
align="L", text="", priority=0, canvas=None, frame=None, static=False,
|
||||
**kwargs):
|
||||
element = Element(name=name, type=type, x1=x1, y1=y1, x2=x2, y2=y2,
|
||||
font=font, size=size,
|
||||
bold=bold, italic=italic, underline=underline,
|
||||
foreground= foreground, background=background,
|
||||
align=align, text=text, priority=priority,
|
||||
canvas=canvas or self.canvas, frame=frame or self,
|
||||
static=static)
|
||||
self.elements.append(element)
|
||||
|
||||
def move_elements(self, x, y):
|
||||
for element in self.elements:
|
||||
if element.selected:
|
||||
print "moving", element.name, x, y
|
||||
element.x = element.x + x
|
||||
element.y = element.y + y
|
||||
|
||||
def do_about(self, evt):
|
||||
info = wx.AboutDialogInfo()
|
||||
info.Name = self.title
|
||||
info.Version = __version__
|
||||
info.Copyright = __copyright__
|
||||
info.Description = (
|
||||
"Visual Template designer for PyFPDF (using wxPython OGL library)\n"
|
||||
"Input files are CSV format describing the layout, separated by ;\n"
|
||||
"Use toolbar buttons to open, save, print (preview) your template, "
|
||||
"and there are buttons to find, add, remove or duplicate elements.\n"
|
||||
"Over an element, a double left click opens edit text dialog, "
|
||||
"and a right click opens edit properties dialog. \n"
|
||||
"Multiple element can be selected with shift left click. \n"
|
||||
"Use arrow keys or drag-and-drop to move elements.\n"
|
||||
"For further information see project webpage:"
|
||||
)
|
||||
info.WebSite = ("http://code.google.com/p/pyfpdf/wiki/Templates",
|
||||
"pyfpdf Google Code Project")
|
||||
info.Developers = [ __author__, ]
|
||||
|
||||
info.License = wordwrap(__license__, 500, wx.ClientDC(self))
|
||||
|
||||
# Then we call wx.AboutBox giving it that info object
|
||||
wx.AboutBox(info)
|
||||
|
||||
def except_hook(self, type, value, trace):
|
||||
import traceback
|
||||
exc = traceback.format_exception(type, value, trace)
|
||||
for e in exc: wx.LogError(e)
|
||||
wx.LogError('Unhandled Error: %s: %s'%(str(type), str(value)))
|
||||
|
||||
|
||||
app = wx.PySimpleApp()
|
||||
ogl.OGLInitialize()
|
||||
frame = AppFrame()
|
||||
app.MainLoop()
|
||||
app.Destroy()
|
||||
|
||||
|
||||
|
||||
156
gluon/contrib/pyfpdf/fonts.py
Normal file
156
gluon/contrib/pyfpdf/fonts.py
Normal file
@@ -0,0 +1,156 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: latin-1 -*-
|
||||
|
||||
# Fonts:
|
||||
|
||||
fpdf_charwidths = {}
|
||||
|
||||
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}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -26,22 +26,23 @@ def hex2dec(color = "#000000"):
|
||||
class HTML2FPDF(HTMLParser):
|
||||
"Render basic HTML to FPDF"
|
||||
|
||||
def __init__(self, pdf, image_map, **kwargs):
|
||||
def __init__(self, pdf):
|
||||
HTMLParser.__init__(self)
|
||||
self.image_map = image_map
|
||||
self.style = {}
|
||||
self.pre = False
|
||||
self.href = ''
|
||||
self.align = ''
|
||||
self.page_links = {}
|
||||
self.font_list = ("times","courier", "helvetica")
|
||||
self.font = None
|
||||
self.font_stack = []
|
||||
self.pdf = pdf
|
||||
self.r = self.g = self.b = 0
|
||||
self.indent = 0
|
||||
self.bullet = []
|
||||
self.font_face="times" # initialize font
|
||||
self.color=0 # initialize font color
|
||||
self.set_font(kwargs.get("font","times"), kwargs.get("fontsize",12))
|
||||
self.set_font("times", 12)
|
||||
self.font_face = "times" # initialize font
|
||||
self.color = 0 #initialize font color
|
||||
self.table = None # table attributes
|
||||
self.table_col_width = None # column (header) widths
|
||||
self.table_col_index = None # current column index
|
||||
@@ -53,7 +54,7 @@ class HTML2FPDF(HTMLParser):
|
||||
self.thead = None
|
||||
self.tfoot = None
|
||||
self.theader_out = self.tfooter_out = False
|
||||
|
||||
|
||||
def width2mm(self, length):
|
||||
if length[-1]=='%':
|
||||
total = self.pdf.w - self.pdf.r_margin - self.pdf.l_margin
|
||||
@@ -66,7 +67,10 @@ class HTML2FPDF(HTMLParser):
|
||||
def handle_data(self, txt):
|
||||
if self.td is not None: # drawing a table?
|
||||
if 'width' not in self.td and 'colspan' not in self.td:
|
||||
l = [self.table_col_width[self.table_col_index]]
|
||||
try:
|
||||
l = [self.table_col_width[self.table_col_index]]
|
||||
except IndexError:
|
||||
raise RuntimeError("Table column/cell width not specified, unable to continue")
|
||||
elif 'colspan' in self.td:
|
||||
i = self.table_col_index
|
||||
colspan = int(self.td['colspan'])
|
||||
@@ -83,7 +87,7 @@ class HTML2FPDF(HTMLParser):
|
||||
else:
|
||||
self.set_style('B',True)
|
||||
border = border or 'B'
|
||||
align = self.td.get('align', 'C')[0].upper()
|
||||
align = 'C'
|
||||
bgcolor = hex2dec(self.td.get('bgcolor', self.tr.get('bgcolor', '')))
|
||||
# parsing table header/footer (drawn later):
|
||||
if self.thead is not None:
|
||||
@@ -97,13 +101,13 @@ class HTML2FPDF(HTMLParser):
|
||||
self.pdf.add_page()
|
||||
self.theader_out = self.tfooter_out = False
|
||||
if self.tfoot is None and self.thead is None:
|
||||
if not self.theader_out:
|
||||
if not self.theader_out:
|
||||
self.output_table_header()
|
||||
self.box_shadow(w, h, bgcolor)
|
||||
if DEBUG: print "td cell", self.pdf.x, w, txt, "*"
|
||||
self.pdf.cell(w,h,txt,border,0,align)
|
||||
elif self.table is not None:
|
||||
# ignore anything else than td inside a table
|
||||
# ignore anything else than td inside a table
|
||||
pass
|
||||
elif self.align:
|
||||
if DEBUG: print "cell", txt, "*"
|
||||
@@ -138,7 +142,7 @@ class HTML2FPDF(HTMLParser):
|
||||
self.pdf.set_x(self.table_offset)
|
||||
#self.pdf.set_x(x)
|
||||
self.theader_out = True
|
||||
|
||||
|
||||
def output_table_footer(self):
|
||||
if self.tfooter:
|
||||
x = self.pdf.x
|
||||
@@ -152,7 +156,7 @@ class HTML2FPDF(HTMLParser):
|
||||
if int(self.table.get('border', 0)):
|
||||
self.output_table_sep()
|
||||
self.tfooter_out = True
|
||||
|
||||
|
||||
def output_table_sep(self):
|
||||
self.pdf.set_x(self.table_offset)
|
||||
x1 = self.pdf.x
|
||||
@@ -173,7 +177,7 @@ class HTML2FPDF(HTMLParser):
|
||||
if tag=='p':
|
||||
self.pdf.ln(5)
|
||||
if attrs:
|
||||
self.align=attrs['align'].lower()
|
||||
if attrs: self.align = attrs.get('align')
|
||||
if tag in ('h1', 'h2', 'h3', 'h4', 'h5', 'h6'):
|
||||
k = (2, 1.5, 1.17, 1, 0.83, 0.67)[int(tag[1])]
|
||||
self.pdf.ln(5*k)
|
||||
@@ -208,6 +212,8 @@ class HTML2FPDF(HTMLParser):
|
||||
self.pdf.write(self.h,'%s%s ' % (' '*5*self.indent, bullet))
|
||||
self.set_text_color()
|
||||
if tag=='font':
|
||||
# save previous font state:
|
||||
self.font_stack.append((self.font_face, self.font_size, self.color))
|
||||
if 'color' in attrs:
|
||||
self.color = hex2dec(attrs['color'])
|
||||
self.set_text_color(*color)
|
||||
@@ -234,6 +240,7 @@ class HTML2FPDF(HTMLParser):
|
||||
self.tfooter = []
|
||||
self.thead = None
|
||||
self.tfoot = None
|
||||
self.table_h = 0
|
||||
self.pdf.ln()
|
||||
if tag=='tr':
|
||||
self.tr = dict([(k.lower(), v) for k,v in attrs.items()])
|
||||
@@ -244,7 +251,7 @@ class HTML2FPDF(HTMLParser):
|
||||
if tag=='th':
|
||||
self.td = dict([(k.lower(), v) for k,v in attrs.items()])
|
||||
self.th = True
|
||||
if self.td['width']:
|
||||
if 'width' in self.td:
|
||||
self.table_col_width.append(self.td['width'])
|
||||
if tag=='thead':
|
||||
self.thead = {}
|
||||
@@ -258,8 +265,7 @@ class HTML2FPDF(HTMLParser):
|
||||
h = px2mm(attrs.get('height',0))
|
||||
if self.align and self.align[0].upper() == 'C':
|
||||
x = (self.pdf.w-x)/2.0 - w/2.0
|
||||
self.pdf.image(self.image_map(attrs['src']),
|
||||
x, y, w, h, link=self.href)
|
||||
self.pdf.image(attrs['src'], x, y, w, h, link=self.href)
|
||||
self.pdf.set_x(x+w)
|
||||
self.pdf.set_y(y+h)
|
||||
if tag=='b' or tag=='i' or tag=='u':
|
||||
@@ -324,12 +330,13 @@ class HTML2FPDF(HTMLParser):
|
||||
self.td = None
|
||||
self.th = False
|
||||
if tag=='font':
|
||||
if self.color:
|
||||
# recover last font state
|
||||
face, size, color = self.font_stack.pop()
|
||||
if face:
|
||||
self.pdf.set_text_color(0,0,0)
|
||||
self.color = None
|
||||
if self.font_face:
|
||||
self.set_font('Times',12)
|
||||
|
||||
self.set_font(face, size)
|
||||
self.font = None
|
||||
if tag=='center':
|
||||
self.align = None
|
||||
|
||||
@@ -345,7 +352,7 @@ class HTML2FPDF(HTMLParser):
|
||||
self.set_style('u', False)
|
||||
self.set_style('b', False)
|
||||
self.set_style('i', False)
|
||||
self.set_text_color()
|
||||
self.set_text_color()
|
||||
|
||||
def set_style(self, tag=None, enable=None):
|
||||
#Modify style and select corresponding font
|
||||
@@ -367,7 +374,7 @@ class HTML2FPDF(HTMLParser):
|
||||
self.r = r
|
||||
self.g = g
|
||||
self.b = b
|
||||
|
||||
|
||||
def put_link(self, url, txt):
|
||||
#Put a hyperlink
|
||||
self.set_text_color(0,0,255)
|
||||
@@ -381,79 +388,9 @@ class HTML2FPDF(HTMLParser):
|
||||
self.pdf.line(self.pdf.get_x(),self.pdf.get_y(),self.pdf.get_x()+187,self.pdf.get_y())
|
||||
self.pdf.ln(3)
|
||||
|
||||
class HTMLMixin():
|
||||
def write_html(self, text, image_map=lambda x:x, **kwargs):
|
||||
class HTMLMixin(object):
|
||||
def write_html(self, text):
|
||||
"Parse HTML and convert it to PDF"
|
||||
h2p = HTML2FPDF(self,image_map=image_map,**kwargs)
|
||||
h2p = HTML2FPDF(self)
|
||||
h2p.feed(text)
|
||||
|
||||
if __name__=='__main__':
|
||||
html="""
|
||||
<H1 align="center">html2fpdf</H1>
|
||||
<h2>Basic usage</h2>
|
||||
<p>You can now easily print text mixing different
|
||||
styles : <B>bold</B>, <I>italic</I>, <U>underlined</U>, or
|
||||
<B><I><U>all at once</U></I></B>!<BR>You can also insert links
|
||||
on text, such as <A HREF="http://www.fpdf.org">www.fpdf.org</A>,
|
||||
or on an image: click on the logo.<br>
|
||||
<center>
|
||||
<A HREF="http://www.fpdf.org"><img src="tutorial/logo.png" width="104" height="71"></A>
|
||||
</center>
|
||||
<h3>Sample List</h3>
|
||||
<ul><li>option 1</li>
|
||||
<ol><li>option 2</li></ol>
|
||||
<li>option 3</li></ul>
|
||||
|
||||
<table border="0" align="center" width="50%">
|
||||
<thead><tr><th width="30%">Header 1</th><th width="70%">header 2</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>cell 1</td><td>cell 2</td></tr>
|
||||
<tr><td>cell 2</td><td>cell 3</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
<table border="1">
|
||||
<thead><tr bgcolor="#A0A0A0"><th width="30%">Header 1</th><th width="70%">header 2</th></tr></thead>
|
||||
<tfoot><tr bgcolor="#E0E0E0"><td>footer 1</td><td>footer 2</td></tr></tfoot>
|
||||
<tbody>
|
||||
<tr><td>cell 1</td><td>cell 2</td></tr>
|
||||
<tr>
|
||||
<td width="30%">cell 1</td><td width="70%" bgcolor="#D0D0FF" align='right'>cell 2</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tbody><tr><td colspan="2">cell spanned</td></tr></tbody>
|
||||
<tbody>
|
||||
""" + """<tr bgcolor="#F0F0F0">
|
||||
<td>cell 3</td><td>cell 4</td>
|
||||
</tr><tr bgcolor="#FFFFFF">
|
||||
<td>cell 5</td><td>cell 6</td>
|
||||
</tr>""" * 200 + """
|
||||
</tbody>
|
||||
</table>
|
||||
"""
|
||||
|
||||
class MyFPDF(FPDF, HTMLMixin):
|
||||
def header(self):
|
||||
self.image('tutorial/logo_pb.png',10,8,33)
|
||||
self.set_font('Arial','B',15)
|
||||
self.cell(80)
|
||||
self.cell(30,10,'Title',1,0,'C')
|
||||
self.ln(20)
|
||||
|
||||
def footer(self):
|
||||
self.set_y(-15)
|
||||
self.set_font('Arial','I',8)
|
||||
txt = 'Page %s of %s' % (self.page_no(), self.alias_nb_pages())
|
||||
self.cell(0,10,txt,0,0,'C')
|
||||
|
||||
pdf=MyFPDF()
|
||||
#First page
|
||||
pdf.add_page()
|
||||
pdf.write_html(html)
|
||||
pdf.output('html.pdf','F')
|
||||
|
||||
import os
|
||||
os.system("evince html.pdf")
|
||||
|
||||
|
||||
|
||||
49
gluon/contrib/pyfpdf/php.py
Normal file
49
gluon/contrib/pyfpdf/php.py
Normal file
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: latin-1 -*-
|
||||
|
||||
# fpdf php helpers:
|
||||
|
||||
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
|
||||
|
||||
def print_r(array):
|
||||
if not isinstance(array, dict):
|
||||
array = dict([(k, k) for k in array])
|
||||
for k, v in array.items():
|
||||
print "[%s] => %s" % (k, v),
|
||||
|
||||
def UTF8ToUTF16BE(instr, setbom=True):
|
||||
"Converts UTF-8 strings to UTF16-BE."
|
||||
outstr = ""
|
||||
if (setbom):
|
||||
outstr += "\xFE\xFF";
|
||||
if not isinstance(instr, unicode):
|
||||
instr = instr.decode('UTF-8')
|
||||
outstr += instr.encode('UTF-16BE')
|
||||
return outstr
|
||||
|
||||
def UTF8StringToArray(instr):
|
||||
"Converts UTF-8 strings to codepoints array"
|
||||
return [ord(c) for c in instr]
|
||||
|
||||
# ttfints php helpers:
|
||||
|
||||
def die(msg):
|
||||
raise RuntimeError(msg)
|
||||
|
||||
def str_repeat(s, count):
|
||||
return s * count
|
||||
|
||||
def str_pad(s, pad_length=0, pad_char= " ", pad_type= +1 ):
|
||||
if pad_type<0: # pad left
|
||||
return s.rjust(pad_length, pad_char)
|
||||
elif pad_type>0: # pad right
|
||||
return s.ljust(pad_length, pad_char)
|
||||
else: # pad both
|
||||
return s.center(pad_length, pad_char)
|
||||
|
||||
strlen = count = lambda s: len(s)
|
||||
107
gluon/contrib/pyfpdf/template.py
Executable file → Normal file
107
gluon/contrib/pyfpdf/template.py
Executable file → Normal file
@@ -16,8 +16,9 @@ class Template:
|
||||
def __init__(self, infile=None, elements=None, format='A4', orientation='portrait',
|
||||
title='', author='', subject='', creator='', keywords=''):
|
||||
if elements:
|
||||
self.elements = dict([(v['name'].lower(),v) for v in elements])
|
||||
self.handlers = {'T': self.text, 'L': self.line, 'I': self.image,
|
||||
self.elements = elements
|
||||
self.keys = [v['name'].lower() for v in self.elements]
|
||||
self.handlers = {'T': self.text, 'L': self.line, 'I': self.image,
|
||||
'B': self.rect, 'BC': self.barcode, }
|
||||
self.pg_no = 0
|
||||
self.texts = {}
|
||||
@@ -32,34 +33,33 @@ class Template:
|
||||
"Parse template format csv file and create elements dict"
|
||||
keys = ('name','type','x1','y1','x2','y2','font','size',
|
||||
'bold','italic','underline','foreground','background',
|
||||
'align','text','priority')
|
||||
self.elements = {}
|
||||
f = open(infile, 'rb')
|
||||
try:
|
||||
for row in csv.reader(f, delimiter=delimiter):
|
||||
kargs = {}
|
||||
for i,v in enumerate(row):
|
||||
if not v.startswith("'") and decimal_sep!=".":
|
||||
v = v.replace(decimal_sep,".")
|
||||
else:
|
||||
v = v
|
||||
if v=='':
|
||||
v = None
|
||||
else:
|
||||
v = eval(v.strip())
|
||||
kargs[keys[i]] = v
|
||||
self.elements[kargs['name'].lower()] = kargs
|
||||
finally:
|
||||
f.close()
|
||||
'align','text','priority', 'multiline')
|
||||
self.elements = []
|
||||
for row in csv.reader(open(infile, 'rb'), delimiter=delimiter):
|
||||
kargs = {}
|
||||
for i,v in enumerate(row):
|
||||
if not v.startswith("'") and decimal_sep!=".":
|
||||
v = v.replace(decimal_sep,".")
|
||||
else:
|
||||
v = v
|
||||
if v=='':
|
||||
v = None
|
||||
else:
|
||||
v = eval(v.strip())
|
||||
kargs[keys[i]] = v
|
||||
self.elements.append(kargs)
|
||||
self.keys = [v['name'].lower() for v in self.elements]
|
||||
|
||||
def add_page(self):
|
||||
self.pg_no += 1
|
||||
self.texts[self.pg_no] = {}
|
||||
|
||||
|
||||
def __setitem__(self, name, value):
|
||||
if name.lower() in self.elements:
|
||||
if self.has_key(name):
|
||||
if isinstance(value,unicode):
|
||||
value = value.encode("latin1","ignore")
|
||||
elif value is None:
|
||||
value = ""
|
||||
else:
|
||||
value = str(value)
|
||||
self.texts[self.pg_no][name.lower()] = value
|
||||
@@ -67,14 +67,27 @@ class Template:
|
||||
# setitem shortcut (may be further extended)
|
||||
set = __setitem__
|
||||
|
||||
def has_key(self, name):
|
||||
return name.lower() in self.keys
|
||||
|
||||
def __getitem__(self, name):
|
||||
if name.lower() in self.elements:
|
||||
return self.texts[self.pg_no].get(name.lower(), self.elements[name.lower()]['text'])
|
||||
if self.has_key(name):
|
||||
key = name.lower()
|
||||
if key in self.texts:
|
||||
# text for this page:
|
||||
return self.texts[self.pg_no][key]
|
||||
else:
|
||||
# find first element for default text:
|
||||
elements = [element for element in self.elements
|
||||
if element['name'].lower() == key]
|
||||
if elements:
|
||||
return elements[0]['text']
|
||||
|
||||
def split_multicell(self, text, element_name):
|
||||
"Divide (\n) a string using a given element width"
|
||||
pdf = self.pdf
|
||||
element = self.elements[element_name.lower()]
|
||||
element = [element for element in self.elements
|
||||
if element['name'].lower() == element_name.lower()][0]
|
||||
style = ""
|
||||
if element['bold']: style += "B"
|
||||
if element['italic']: style += "I"
|
||||
@@ -88,7 +101,7 @@ class Template:
|
||||
return pdf.multi_cell(w=element['x2']-element['x1'],
|
||||
h=element['y2']-element['y1'],
|
||||
txt=text,align=align,split_only=True)
|
||||
|
||||
|
||||
def render(self, outfile, dest="F"):
|
||||
pdf = self.pdf
|
||||
for pg in range(1, self.pg_no+1):
|
||||
@@ -96,7 +109,7 @@ class Template:
|
||||
pdf.set_font('Arial','B',16)
|
||||
pdf.set_auto_page_break(False,margin=0)
|
||||
|
||||
for element in sorted(self.elements.values(),key=lambda x: x['priority']):
|
||||
for element in sorted(self.elements,key=lambda x: x['priority']):
|
||||
#print "dib",element['type'], element['name'], element['x1'], element['y1'], element['x2'], element['y2']
|
||||
element = element.copy()
|
||||
element['text'] = self.texts[pg].get(element['name'].lower(), element['text'])
|
||||
@@ -105,12 +118,12 @@ class Template:
|
||||
self.handlers[element['type'].upper()](pdf, **element)
|
||||
if 'rotate' in element:
|
||||
pdf.rotate(0)
|
||||
|
||||
|
||||
return pdf.output(outfile, dest)
|
||||
|
||||
def text(self, pdf, x1=0, y1=0, x2=0, y2=0, text='', font="arial", size=10,
|
||||
bold=False, italic=False, underline=False, align="",
|
||||
foreground=0, backgroud=65535,
|
||||
|
||||
def text(self, pdf, x1=0, y1=0, x2=0, y2=0, text='', font="arial", size=10,
|
||||
bold=False, italic=False, underline=False, align="",
|
||||
foreground=0, backgroud=65535, multiline=None,
|
||||
*args, **kwargs):
|
||||
if text:
|
||||
if pdf.text_color!=rgb(foreground):
|
||||
@@ -134,7 +147,19 @@ class Template:
|
||||
##m_k = 72 / 2.54
|
||||
##h = (size/m_k)
|
||||
pdf.set_xy(x1,y1)
|
||||
pdf.cell(w=x2-x1,h=y2-y1,txt=text,border=0,ln=0,align=align)
|
||||
if multiline is None:
|
||||
# multiline==None: write without wrapping/trimming (default)
|
||||
pdf.cell(w=x2-x1,h=y2-y1,txt=text,border=0,ln=0,align=align)
|
||||
elif multiline:
|
||||
# multiline==True: automatic word - warp
|
||||
pdf.multi_cell(w=x2-x1,h=y2-y1,txt=text,border=0,align=align)
|
||||
else:
|
||||
# multiline==False: trim to fit exactly the space defined
|
||||
text = pdf.multi_cell(w=x2-x1, h=y2-y1,
|
||||
txt=text, align=align, split_only=True)[0]
|
||||
print "trimming: *%s*" % text
|
||||
pdf.cell(w=x2-x1,h=y2-y1,txt=text,border=0,ln=0,align=align)
|
||||
|
||||
#pdf.Text(x=x1,y=y1,txt=text)
|
||||
|
||||
def line(self, pdf, x1=0, y1=0, x2=0, y2=0, size=0, foreground=0, *args, **kwargs):
|
||||
@@ -176,7 +201,7 @@ if __name__ == "__main__":
|
||||
title="Sample Invoice", author="Sample Company",
|
||||
subject="Sample Customer", keywords="Electronic TAX Invoice")
|
||||
f.parse_csv(infile="invoice.csv", delimiter=";", decimal_sep=",")
|
||||
|
||||
|
||||
detail = "Lorem ipsum dolor sit amet, consectetur. " * 30
|
||||
items = []
|
||||
for i in range(1, 30):
|
||||
@@ -185,7 +210,7 @@ if __name__ == "__main__":
|
||||
price = round(random.random()*100,3)
|
||||
code = "%s%s%02d" % (chr(random.randint(65,90)), chr(random.randint(65,90)),i)
|
||||
items.append(dict(code=code, unit='u',
|
||||
qty=qty, price=price,
|
||||
qty=qty, price=price,
|
||||
amount=qty*price,
|
||||
ds="%s: %s" % (i,ds)))
|
||||
|
||||
@@ -228,7 +253,7 @@ if __name__ == "__main__":
|
||||
f["company_name"] = "Sample Company"
|
||||
f["company_logo"] = "tutorial/logo.png"
|
||||
f["company_header1"] = "Some Address - somewhere -"
|
||||
f["company_header2"] = "http://www.example.com"
|
||||
f["company_header2"] = "http://www.example.com"
|
||||
f["company_footer1"] = "Tax Code ..."
|
||||
f["company_footer2"] = "Tax/VAT ID ..."
|
||||
f['number'] = '0001-00001234'
|
||||
@@ -236,9 +261,9 @@ if __name__ == "__main__":
|
||||
f['due_date'] = '2099-09-10'
|
||||
f['customer_name'] = "Sample Client"
|
||||
f['customer_address'] = "Siempreviva 1234"
|
||||
|
||||
|
||||
# print line item...
|
||||
li = 0
|
||||
li = 0
|
||||
k = 0
|
||||
total = Decimal("0.00")
|
||||
for it in li_items:
|
||||
@@ -268,11 +293,9 @@ if __name__ == "__main__":
|
||||
else:
|
||||
f['total_label'] = 'SubTotal:'
|
||||
f['total'] = "%0.2f" % total
|
||||
|
||||
|
||||
f.render("./invoice.pdf")
|
||||
if sys.platform.startswith("linux"):
|
||||
os.system("evince ./invoice.pdf")
|
||||
else:
|
||||
os.system("./invoice.pdf")
|
||||
|
||||
|
||||
|
||||
1033
gluon/contrib/pyfpdf/ttfonts.py
Normal file
1033
gluon/contrib/pyfpdf/ttfonts.py
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user