Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for C39 in templates #170

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions docs/ReferenceManual.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
* [add_link](reference/add_link.md) - create an internal link
* [add_page](reference/add_page.md) - add a new page
* [alias_nb_pages](reference/alias_nb_pages.md) - define an alias for number of pages
* [interleaved2of5](reference/interleaved2of5.md) - add a new barcode with Interleaved 2 of 5 schema
* [code39](reference/code39.md) - add a new barcode with C39 schema
* [cell](reference/cell.md) - print a cell
* [close](reference/close.md) - terminate the document
* [error](reference/error.md) - fatal error
Expand Down Expand Up @@ -54,7 +56,7 @@
* [write](reference/write.md) - print flowing text

## Additional API ##

These features are not available in the original FPDF and were implemented after forking.

* [dashed_line](reference/dashed_line.md) - draw a dashed line
Expand All @@ -63,4 +65,3 @@ These features are not available in the original FPDF and were implemented after
* [set_doc_option](reference/set_doc_option.md) - set document options
* [set_stretching](reference/set_stretching.md) - set horizontal font stretching
* [write_html](reference/write_html.md) - print text with HTML markup

6 changes: 4 additions & 2 deletions docs/Templates.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ The header contains the page format, title of the document and other metadata.
Elements have the following properties (columns in a CSV, fields in a database):

* name: placeholder identification
* type: 'T': texts, 'L': lines, 'I': images, 'B': boxes, 'BC': barcodes
* type: 'T': texts, 'L': lines, 'I': images, 'B': boxes, 'BC': barcodes (Interleaved
2 of 5) - alias for BCI25, 'BCI25': barcodes (Interleaved 2 of 5), 'BCC39': barcodes
(C39),
* x1, y1, x2, y2: top-left, bottom-right coordinates (in mm)
* font: e.g. "Arial"
* size: text size in points, e.g. 10
Expand Down Expand Up @@ -45,7 +47,7 @@ Note the following, the definition of a template will contain the elements. The

from fpdf import Template

#this will define the ELEMENTS that will compose the template.
#this will define the ELEMENTS that will compose the template.
elements = [
{ 'name': 'company_logo', 'type': 'I', 'x1': 20.0, 'y1': 17.0, 'x2': 78.0, 'y2': 30.0, 'font': None, 'size': 0.0, 'bold': 0, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': 'logo', 'priority': 2, },
{ 'name': 'company_name', 'type': 'T', 'x1': 17.0, 'y1': 32.5, 'x2': 115.0, 'y2': 37.5, 'font': 'Arial', 'size': 12.0, 'bold': 1, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': '', 'priority': 2, },
Expand Down
38 changes: 38 additions & 0 deletions docs/reference/code39.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
## code39 ##

```python
fpdf.code39(txt: str, x: float, y: float, w=1.5, h=5.0)
```

### Description ###

Add a new barcode following C39 schema.

### Parameters ###

txt:
> The text to be represented by the barcode.
> Method accepts characters from following list: `'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%'`.
To be more precise, it's equal to following expression:
`string.digits + string.ascii_uppercase + '-. $/+%'`,. Take a not, method also
accepts `'*'`, but this character is used to escape barcode text and shouldn't be used
to code text.

x:
> Abscissa of upper-left barcode.

y:
> Ordinate of upper-left barcode.

w:
> Width of rectangles the barcode is built on. For example `0` is represented
by `nnnwwnwnn` where 'w' is a rectangle with width equals to `w` and 'n' is equal to
`w/3`

h:
> Height of the barcode


### See also ###

[interleaved2of5](interleaved2of5.md)
36 changes: 36 additions & 0 deletions docs/reference/interleaved2of5.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
## interleaved2of5 ##

```python
fpdf.interleaved2of5(txt: str, x: float, y: float, w=1.0, h=10.0)
```

### Description ###

Add a new barcode following Interleaved 2 of 5 schema.

### Parameters ###

txt:
> The text to be represented by the barcode.
> Method accepts string containing only digits. Take a note, 'A' and 'Z' are
also accepted (do not couse an error), but they lead to generate incorrect
barcodes as those characters are used to escape barcode.

x:
> Abscissa of upper-left barcode.

y:
> Ordinate of upper-left barcode.

w:
> Width of rectangles the barcode is built on. For example `0` is represented
by `nnwwn` where 'w' is a rectangle with width equals to `w` and 'n' is equal to
`w/3`

h:
> Height of the barcode


### See also ###

[code39](code39.md)
4 changes: 3 additions & 1 deletion fpdf/fpdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -2059,7 +2059,9 @@ def code39(self, txt, x, y, w=1.5, h=5.0):
'+': 'nwnnnwnwn', '%': 'nnnwnwnwn',
}
self.set_fill_color(0)
for c in txt.upper():
code = '*' + txt.upper() + '*'

for c in code:
if c not in chars:
raise RuntimeError('Invalid char "%s" for Code39' % c)
for i, d in enumerate(chars[c]):
Expand Down
33 changes: 22 additions & 11 deletions fpdf/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ def __init__(self, infile=None, elements=None, format='A4', orientation='portrai
title='', author='', subject='', creator='', keywords=''):
if elements:
self.load_elements(elements)
self.handlers = {'T': self.text, 'L': self.line, 'I': self.image,
'B': self.rect, 'BC': self.barcode, 'W': self.write, }
self.handlers = {'T': self.text, 'L': self.line, 'I': self.image,
'B': self.rect, 'BC': self.barcode, 'W': self.write,
'BCI25': self.barcodeI25, 'BCC39': self.barcodeC39}
self.texts = {}
pdf = self.pdf = FPDF(format=format,orientation=orientation, unit="mm")
pdf.set_title(title)
Expand All @@ -35,7 +36,7 @@ def load_elements(self, elements):
self.pg_no = 0
self.elements = elements
self.keys = [v['name'].lower() for v in self.elements]

def parse_csv(self, infile, delimiter=",", decimal_sep="."):
"Parse template format csv file and create elements dict"
keys = ('name','type','x1','y1','x2','y2','font','size',
Expand All @@ -51,7 +52,7 @@ def parse_csv(self, infile, delimiter=",", decimal_sep="."):
for row in csv.reader(f, delimiter=delimiter):
kargs = {}
for i,v in enumerate(row):
if not v.startswith("'") and decimal_sep!=".":
if not v.startswith("'") and decimal_sep!=".":
v = v.replace(decimal_sep,".")
else:
v = v
Expand All @@ -66,7 +67,7 @@ def parse_csv(self, infile, delimiter=",", decimal_sep="."):
def add_page(self):
self.pg_no += 1
self.texts[self.pg_no] = {}

def __setitem__(self, name, value):
if name.lower() in self.keys:
if not PY3K and isinstance(value, unicode):
Expand All @@ -82,7 +83,7 @@ def __setitem__(self, name, value):

def has_key(self, name):
return name.lower() in self.keys

def __contains__(self, name):
return self.has_key(name)

Expand Down Expand Up @@ -117,7 +118,7 @@ def split_multicell(self, text, element_name):
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):
Expand All @@ -134,12 +135,12 @@ def render(self, outfile, dest="F"):
self.handlers[element['type'].upper()](pdf, **element)
if 'rotate' in element:
pdf.rotate(0)

if dest:
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="",

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:
Expand Down Expand Up @@ -207,6 +208,16 @@ def barcode(self, pdf, x1=0, y1=0, x2=0, y2=0, text='', font="arial", size=1,
if font == 'interleaved 2of5 nt':
pdf.interleaved2of5(text,x1,y1,w=size,h=y2-y1)

def barcodeI25(self, *args, **kwargs):
barcode(self, *args, **kwargs)

def barcodeC39(self, pdf, x1=0, y1=0, x2=0, y2=0, text='', font="arial", size=1,
foreground=0, *args, **kwargs):
if pdf.draw_color!=rgb(foreground):
pdf.set_draw_color(*rgb(foreground))

pdf.code39(text,x1,y1,w=size,h=y2-y1)

# Added by Derek Schwalenberg [email protected] to allow (url) links in templates (using write method) 2014-02-22
def write(self, pdf, x1=0, y1=0, x2=0, y2=0, text='', font="arial", size=1,
bold=False, italic=False, underline=False, align="", link='http://example.com',
Expand Down