summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md358
-rw-r--r--README.md.template9
-rwxr-xr-xcheck3
-rw-r--r--contrib/barcode/barcode.go10
-rw-r--r--contrib/barcode/barcode_test.go21
-rwxr-xr-xcov1
-rw-r--r--def.go39
-rw-r--r--doc.go357
-rw-r--r--font/calligra.json2
-rw-r--r--font/calligra.zbin25609 -> 25812 bytes
-rw-r--r--fpdf.go340
-rw-r--r--fpdf_test.go210
-rw-r--r--go.mod11
-rw-r--r--image/signature.svg72
-rwxr-xr-xmkdoc23
-rw-r--r--pdf/reference/Fpdf_SVGBasicWrite.pdf1207
-rw-r--r--svgbasic.go40
-rw-r--r--svgwrite.go29
-rw-r--r--template.go11
-rw-r--r--template_impl.go4
-rw-r--r--utf8fontfile.go21
-rw-r--r--util.go24
22 files changed, 1968 insertions, 824 deletions
diff --git a/README.md b/README.md
index 9f0ef59..b402678 100644
--- a/README.md
+++ b/README.md
@@ -1,65 +1,69 @@
-# gofpdf
+# GoFPDF document generator
-![gofpdf](image/logo_gofpdf.jpg?raw=true "gofpdf")
+[![MIT
+licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/jung-kurt/gofpdf/master/LICENSE)
+[![Report](https://goreportcard.com/badge/github.com/jung-kurt/gofpdf)](https://goreportcard.com/report/github.com/jung-kurt/gofpdf)
+[![GoDoc](https://img.shields.io/badge/godoc-GoFPDF-blue.svg)](https://godoc.org/github.com/jung-kurt/gofpdf)
-[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/jung-kurt/gofpdf/master/license.txt)
-[![GoDoc](https://godoc.org/github.com/jung-kurt/gofpdf?status.svg)](https://godoc.org/github.com/jung-kurt/gofpdf)
-[![Build Status](https://travis-ci.org/jung-kurt/gofpdf.svg?branch=master)](https://travis-ci.org/jung-kurt/gofpdf)
+![](https://github.com/jung-kurt/gofpdf/raw/master/image/logo_gofpdf.jpg?raw=true)
-Package gofpdf implements a PDF document generator with high level support for
-text, drawing and images.
+Package gofpdf implements a PDF document generator with high level
+support for text, drawing and images.
## Features
-* Choice of measurement unit, page format and margins
-* Page header and footer management
-* Automatic page breaks, line breaks, and text justification
-* Inclusion of JPEG, PNG, GIF, TIFF and basic path-only SVG images
-* Colors, gradients and alpha channel transparency
-* Outline bookmarks
-* Internal and external links
-* TrueType, Type1 and encoding support
-* Page compression
-* Lines, Bézier curves, arcs, and ellipses
-* Rotation, scaling, skewing, translation, and mirroring
-* Clipping
-* Document protection
-* Layers
-* Templates
-* Barcodes
-* Charting facility
-* UTF-8 support
-
-gofpdf has no dependencies other than the Go standard library. All tests pass
-on Linux, Mac and Windows platforms.
-
-gofpdf supports UTF-8 fonts and "right to left" languages.
-
-Also, support is provided to automatically translate
-UTF-8 runes to code page encodings for languages that have fewer than 256
-glyphs.
+ - UTF-8 support
+ - Choice of measurement unit, page format and margins
+ - Page header and footer management
+ - Automatic page breaks, line breaks, and text justification
+ - Inclusion of JPEG, PNG, GIF, TIFF and basic path-only SVG images
+ - Colors, gradients and alpha channel transparency
+ - Outline bookmarks
+ - Internal and external links
+ - TrueType, Type1 and encoding support
+ - Page compression
+ - Lines, Bézier curves, arcs, and ellipses
+ - Rotation, scaling, skewing, translation, and mirroring
+ - Clipping
+ - Document protection
+ - Layers
+ - Templates
+ - Barcodes
+ - Charting facility
+ - Import PDFs as templates
+
+gofpdf has no dependencies other than the Go standard library. All tests
+pass on Linux, Mac and Windows platforms.
+
+gofpdf supports UTF-8 TrueType fonts and “right-to-left” languages. Note
+that Chinese, Japanese, and Korean characters may not be included in
+many general purpose fonts. For these languages, a specialized font (for
+example,
+[NotoSansSC](https://github.com/jsntn/webfonts/blob/master/NotoSansSC-Regular.ttf)
+for simplified Chinese) can be used.
+
+Also, support is provided to automatically translate UTF-8 runes to code
+page encodings for languages that have fewer than 256 glyphs.
## Installation
-
To install the package on your system, run
-```
+``` shell
go get github.com/jung-kurt/gofpdf
```
Later, to receive updates, run
-```
+``` shell
go get -u -v github.com/jung-kurt/gofpdf/...
```
## Quick Start
-
The following Go code generates a simple PDF file.
-```
+``` go
pdf := gofpdf.New("P", "mm", "A4", "")
pdf.AddPage()
pdf.SetFont("Arial", "B", 16)
@@ -67,171 +71,187 @@ pdf.Cell(40, 10, "Hello, world")
err := pdf.OutputFileAndClose("hello.pdf")
```
-See the functions in the [fpdf_test.go](https://github.com/jung-kurt/gofpdf/blob/master/fpdf_test.go) file (shown as examples in this
-documentation) for more advanced PDF examples.
+See the functions in the
+[fpdf\_test.go](https://github.com/jung-kurt/gofpdf/blob/master/fpdf_test.go)
+file (shown as examples in this documentation) for more advanced PDF
+examples.
## Errors
-
-If an error occurs in an Fpdf method, an internal error field is set. After
-this occurs, Fpdf method calls typically return without performing any
-operations and the error state is retained. This error management scheme
-facilitates PDF generation since individual method calls do not need to be
-examined for failure; it is generally sufficient to wait until after Output()
-is called. For the same reason, if an error occurs in the calling application
-during PDF generation, it may be desirable for the application to transfer the
-error to the Fpdf instance by calling the SetError() method or the SetErrorf()
-method. At any time during the life cycle of the Fpdf instance, the error state
-can be determined with a call to Ok() or Err(). The error itself can be
-retrieved with a call to Error().
+If an error occurs in an Fpdf method, an internal error field is set.
+After this occurs, Fpdf method calls typically return without performing
+any operations and the error state is retained. This error management
+scheme facilitates PDF generation since individual method calls do not
+need to be examined for failure; it is generally sufficient to wait
+until after `Output()` is called. For the same reason, if an error
+occurs in the calling application during PDF generation, it may be
+desirable for the application to transfer the error to the Fpdf instance
+by calling the `SetError()` method or the `SetErrorf()` method. At any
+time during the life cycle of the Fpdf instance, the error state can be
+determined with a call to `Ok()` or `Err()`. The error itself can be
+retrieved with a call to `Error()`.
## Conversion Notes
-
-This package is a relatively straightforward translation from the original [FPDF](http://www.fpdf.org/) library written in PHP (despite the caveat in the introduction to [Effective
-Go](https://golang.org/doc/effective_go.html)). The API names have been retained even though the Go idiom would suggest
-otherwise (for example, pdf.GetX() is used rather than simply pdf.X()). The
-similarity of the two libraries makes the original FPDF website a good source
-of information. It includes a forum and FAQ.
-
-However, some internal changes have been made. Page content is built up using
-buffers (of type bytes.Buffer) rather than repeated string concatenation.
-Errors are handled as explained above rather than panicking. Output is
-generated through an interface of type io.Writer or io.WriteCloser. A number of
-the original PHP methods behave differently based on the type of the arguments
-that are passed to them; in these cases additional methods have been exported
-to provide similar functionality. Font definition files are produced in JSON
-rather than PHP.
+This package is a relatively straightforward translation from the
+original [FPDF](http://www.fpdf.org/) library written in PHP (despite
+the caveat in the introduction to [Effective
+Go](https://golang.org/doc/effective_go.html)). The API names have been
+retained even though the Go idiom would suggest otherwise (for example,
+`pdf.GetX()` is used rather than simply `pdf.X()`). The similarity of
+the two libraries makes the original FPDF website a good source of
+information. It includes a forum and FAQ.
+
+However, some internal changes have been made. Page content is built up
+using buffers (of type bytes.Buffer) rather than repeated string
+concatenation. Errors are handled as explained above rather than
+panicking. Output is generated through an interface of type io.Writer or
+io.WriteCloser. A number of the original PHP methods behave differently
+based on the type of the arguments that are passed to them; in these
+cases additional methods have been exported to provide similar
+functionality. Font definition files are produced in JSON rather than
+PHP.
## Example PDFs
-
-A side effect of running "go test ./..." is the production of a number of
-example PDFs. These can be found in the gofpdf/pdf directory after the tests
-complete.
-
-Please note that these examples run in the context of a test. In order run an
-example as a standalone application, you'll need to examine [fpdf_test.go](https://github.com/jung-kurt/gofpdf/blob/master/fpdf_test.go) for
-some helper routines, for example exampleFilename() and summary().
-
-Example PDFs can be compared with reference copies in order to verify that they
-have been generated as expected. This comparison will be performed if a PDF
-with the same name as the example PDF is placed in the gofpdf/pdf/reference
-directory and if the third argument to ComparePDFFiles() in
-internal/example/example.go is true. (By default it is false.) The routine that
-summarizes an example will look for this file and, if found, will call
-ComparePDFFiles() to check the example PDF for equality with its reference PDF.
-If differences exist between the two files they will be printed to standard
-output and the test will fail. If the reference file is missing, the comparison
-is considered to succeed. In order to successfully compare two PDFs, the
-placement of internal resources must be consistent and the internal creation
-timestamps must be the same. To do this, the methods SetCatalogSort() and
-SetCreationDate() need to be called for both files. This is done automatically
-for all examples.
+A side effect of running `go test ./...` is the production of a number
+of example PDFs. These can be found in the gofpdf/pdf directory after
+the tests complete.
+
+Please note that these examples run in the context of a test. In order
+run an example as a standalone application, you’ll need to examine
+[fpdf\_test.go](https://github.com/jung-kurt/gofpdf/blob/master/fpdf_test.go)
+for some helper routines, for example `exampleFilename()` and
+`summary()`.
+
+Example PDFs can be compared with reference copies in order to verify
+that they have been generated as expected. This comparison will be
+performed if a PDF with the same name as the example PDF is placed in
+the gofpdf/pdf/reference directory and if the third argument to
+`ComparePDFFiles()` in internal/example/example.go is true. (By default
+it is false.) The routine that summarizes an example will look for this
+file and, if found, will call `ComparePDFFiles()` to check the example
+PDF for equality with its reference PDF. If differences exist between
+the two files they will be printed to standard output and the test will
+fail. If the reference file is missing, the comparison is considered to
+succeed. In order to successfully compare two PDFs, the placement of
+internal resources must be consistent and the internal creation
+timestamps must be the same. To do this, the methods `SetCatalogSort()`
+and `SetCreationDate()` need to be called for both files. This is done
+automatically for all examples.
## Nonstandard Fonts
+Nothing special is required to use the standard PDF fonts (courier,
+helvetica, times, zapfdingbats) in your documents other than calling
+`SetFont()`.
-Nothing special is required to use the standard PDF fonts (courier, helvetica,
-times, zapfdingbats) in your documents other than calling SetFont().
+You should use `AddUTF8Font()` or `AddUTF8FontFromBytes()` to add a
+TrueType UTF-8 encoded font. Use `RTL()` and `LTR()` methods switch
+between “right-to-left” and “left-to-right” mode.
-You should use AddUTF8Font or AddUTF8FontFromBytes to add UTF-8 TTF font.
-RTL() and LTR() methods switch between "right to left" and "left to right" mode.
+In order to use a different non-UTF-8 TrueType or Type1 font, you will
+need to generate a font definition file and, if the font will be
+embedded into PDFs, a compressed version of the font file. This is done
+by calling the MakeFont function or using the included makefont command
+line utility. To create the utility, cd into the makefont subdirectory
+and run “go build”. This will produce a standalone executable named
+makefont. Select the appropriate encoding file from the font
+subdirectory and run the command as in the following example.
-In order to use a different non-UTF-8 TrueType or Type1 font, you will need to generate a
-font definition file and, if the font will be embedded into PDFs, a compressed
-version of the font file. This is done by calling the MakeFont function or
-using the included makefont command line utility. To create the utility, cd
-into the makefont subdirectory and run "go build". This will produce a
-standalone executable named makefont. Select the appropriate encoding file from
-the font subdirectory and run the command as in the following example.
-
-```
+``` shell
./makefont --embed --enc=../font/cp1252.map --dst=../font ../font/calligra.ttf
```
-In your PDF generation code, call AddFont() to load the font and, as with the
-standard fonts, SetFont() to begin using it. Most examples, including the
-package example, demonstrate this method. Good sources of free, open-source
-fonts include [Google Fonts](http://www.google.com/fonts/) and [DejaVu Fonts](http://dejavu-fonts.org/).
+In your PDF generation code, call `AddFont()` to load the font and, as
+with the standard fonts, SetFont() to begin using it. Most examples,
+including the package example, demonstrate this method. Good sources of
+free, open-source fonts include [Google
+Fonts](https://fonts.google.com/) and [DejaVu
+Fonts](http://dejavu-fonts.org/).
## Related Packages
-
-The [draw2d](https://github.com/llgcode/draw2d) package is a two dimensional
-vector graphics library that can generate output in different forms. It uses
-gofpdf for its document production mode.
+The [draw2d](https://github.com/llgcode/draw2d) package is a two
+dimensional vector graphics library that can generate output in
+different forms. It uses gofpdf for its document production mode.
## Contributing Changes
-
-gofpdf is a global community effort and you are invited to make it even better.
-If you have implemented a new feature or corrected a problem, please consider
-contributing your change to the project. A contribution that does not directly
-pertain to the core functionality of gofpdf should be placed in its own
-directory directly beneath the `contrib` directory.
+gofpdf is a global community effort and you are invited to make it even
+better. If you have implemented a new feature or corrected a problem,
+please consider contributing your change to the project. A contribution
+that does not directly pertain to the core functionality of gofpdf
+should be placed in its own directory directly beneath the `contrib`
+directory.
Here are guidelines for making submissions. Your change should
-* be compatible with the MIT License
-* be properly documented
-* be formatted with `go fmt`
-* include an example in [fpdf_test.go](https://github.com/jung-kurt/gofpdf/blob/master/fpdf_test.go) if appropriate
-* conform to the standards of [golint](https://github.com/golang/lint) and
-[go vet](https://godoc.org/golang.org/x/tools/cmd/vet), that is, `golint .` and
-`go vet .` should not generate any warnings
-* not diminish [test coverage](https://blog.golang.org/cover)
+ - be compatible with the MIT License
+ - be properly documented
+ - be formatted with `go fmt`
+ - include an example in
+ [fpdf\_test.go](https://github.com/jung-kurt/gofpdf/blob/master/fpdf_test.go)
+ if appropriate
+ - conform to the standards of [golint](https://github.com/golang/lint)
+ and [go vet](https://golang.org/cmd/vet/), that is, `golint .` and
+ `go vet .` should not generate any warnings
+ - not diminish [test coverage](https://blog.golang.org/cover)
-[Pull requests](https://help.github.com/articles/using-pull-requests/) work
-nicely as a means of contributing your changes.
+[Pull requests](https://help.github.com/articles/using-pull-requests/)
+are the preferred means of accepting your changes.
## License
-
-gofpdf is released under the MIT License. It is copyrighted by Kurt Jung and
-the contributors acknowledged below.
+gofpdf is released under the MIT License. It is copyrighted by Kurt Jung
+and the contributors acknowledged below.
## Acknowledgments
-
-This package's code and documentation are closely derived from the [FPDF](http://www.fpdf.org/) library created by Olivier Plathey, and a number of font and
-image resources are copied directly from it. Bruno Michel has provided valuable
-assistance with the code. Drawing support is adapted from the FPDF geometric
-figures script by David Hernández Sanz. Transparency support is adapted from
-the FPDF transparency script by Martin Hall-May. Support for gradients and
-clipping is adapted from FPDF scripts by Andreas Würmser. Support for outline
-bookmarks is adapted from Olivier Plathey by Manuel Cornes. Layer support is
-adapted from Olivier Plathey. Support for transformations is adapted from the
+This package’s code and documentation are closely derived from the
+[FPDF](http://www.fpdf.org/) library created by Olivier Plathey, and a
+number of font and image resources are copied directly from it. Bruno
+Michel has provided valuable assistance with the code. Drawing support
+is adapted from the FPDF geometric figures script by David Hernández
+Sanz. Transparency support is adapted from the FPDF transparency script
+by Martin Hall-May. Support for gradients and clipping is adapted from
+FPDF scripts by Andreas Würmser. Support for outline bookmarks is
+adapted from Olivier Plathey by Manuel Cornes. Layer support is adapted
+from Olivier Plathey. Support for transformations is adapted from the
FPDF transformation script by Moritz Wagner and Andreas Würmser. PDF
-protection is adapted from the work of Klemen Vodopivec for the FPDF product.
-Lawrence Kesteloot provided code to allow an image's extent to be determined
-prior to placement. Support for vertical alignment within a cell was provided
-by Stefan Schroeder. Ivan Daniluk generalized the font and image loading code
-to use the Reader interface while maintaining backward compatibility. Anthony
-Starks provided code for the Polygon function. Robert Lillack provided the
-Beziergon function and corrected some naming issues with the internal curve
-function. Claudio Felber provided implementations for dashed line drawing and
-generalized font loading. Stani Michiels provided support for multi-segment
-path drawing with smooth line joins, line join styles, enhanced fill modes, and
-has helped greatly with package presentation and tests. Templating is adapted
-by Marcus Downing from the FPDF_Tpl library created by Jan Slabon and Setasign.
-Jelmer Snoeck contributed packages that generate a variety of barcodes and help
-with registering images on the web. Jelmer Snoek and Guillermo Pascual
-augmented the basic HTML functionality with aligned text. Kent Quirk
-implemented backwards-compatible support for reading DPI from images that
-support it, and for setting DPI manually and then having it properly taken into
-account when calculating image size. Paulo Coutinho provided support for static
-embedded fonts. Dan Meyers added support for embedded JavaScript. David Fish
-added a generic alias-replacement function to enable, among other things, table
-of contents functionality. Andy Bakun identified and corrected a problem in
-which the internal catalogs were not sorted stably. Paul Montag added encoding
-and decoding functionality for templates, including images that are embedded in
-templates; this allows templates to be stored independently of gofpdf. Paul
-also added support for page boxes used in printing PDF documents. Wojciech
-Matusiak added supported for word spacing. Artem Korotkiy added support of UTF-8 fonts.
+protection is adapted from the work of Klemen Vodopivec for the FPDF
+product. Lawrence Kesteloot provided code to allow an image’s extent to
+be determined prior to placement. Support for vertical alignment within
+a cell was provided by Stefan Schroeder. Ivan Daniluk generalized the
+font and image loading code to use the Reader interface while
+maintaining backward compatibility. Anthony Starks provided code for the
+Polygon function. Robert Lillack provided the Beziergon function and
+corrected some naming issues with the internal curve function. Claudio
+Felber provided implementations for dashed line drawing and generalized
+font loading. Stani Michiels provided support for multi-segment path
+drawing with smooth line joins, line join styles, enhanced fill modes,
+and has helped greatly with package presentation and tests. Templating
+is adapted by Marcus Downing from the FPDF\_Tpl library created by Jan
+Slabon and Setasign. Jelmer Snoeck contributed packages that generate a
+variety of barcodes and help with registering images on the web. Jelmer
+Snoek and Guillermo Pascual augmented the basic HTML functionality with
+aligned text. Kent Quirk implemented backwards-compatible support for
+reading DPI from images that support it, and for setting DPI manually
+and then having it properly taken into account when calculating image
+size. Paulo Coutinho provided support for static embedded fonts. Dan
+Meyers added support for embedded JavaScript. David Fish added a generic
+alias-replacement function to enable, among other things, table of
+contents functionality. Andy Bakun identified and corrected a problem in
+which the internal catalogs were not sorted stably. Paul Montag added
+encoding and decoding functionality for templates, including images that
+are embedded in templates; this allows templates to be stored
+independently of gofpdf. Paul also added support for page boxes used in
+printing PDF documents. Wojciech Matusiak added supported for word
+spacing. Artem Korotkiy added support of UTF-8 fonts. Dave Barnes added
+support for imported objects and templates. Brigham Thompson added
+support for rounded rectangles. Joe Westcott added underline
+functionality and optimized image storage.
## Roadmap
-* Improve test coverage as reported by the coverage tool.
-
-
+ - Improve test coverage as reported by the coverage tool.
diff --git a/README.md.template b/README.md.template
deleted file mode 100644
index 8caf572..0000000
--- a/README.md.template
+++ /dev/null
@@ -1,9 +0,0 @@
-# gofpdf
-
-![gofpdf](image/logo_gofpdf.jpg?raw=true "gofpdf")
-
-[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/jung-kurt/gofpdf/master/license.txt)
-[![GoDoc](https://godoc.org/github.com/jung-kurt/gofpdf?status.svg)](https://godoc.org/github.com/jung-kurt/gofpdf)
-[![Build Status](https://travis-ci.org/jung-kurt/gofpdf.svg?branch=master)](https://travis-ci.org/jung-kurt/gofpdf)
-
-{{.Doc}}
diff --git a/check b/check
deleted file mode 100755
index dcc2519..0000000
--- a/check
+++ /dev/null
@@ -1,3 +0,0 @@
-golint .
-go vet -all .
-gofmt -s -l .
diff --git a/contrib/barcode/barcode.go b/contrib/barcode/barcode.go
index ad84fe5..7e0ac0d 100644
--- a/contrib/barcode/barcode.go
+++ b/contrib/barcode/barcode.go
@@ -93,13 +93,17 @@ func printBarcode(pdf barcodePdf, code string, x, y float64, w, h *float64, flow
}
}
+ scaleToWidthF := float64(scaleToWidth)
+ scaleToHeightF := float64(scaleToHeight)
+
if w != nil {
- scaleToWidth = int(*w)
+ scaleToWidthF = *w
}
if h != nil {
- scaleToHeight = int(*h)
+ scaleToHeightF = *h
}
- pdf.Image(bname, x, y, float64(scaleToWidth), float64(scaleToHeight), flow, "jpg", 0, "")
+
+ pdf.Image(bname, x, y, scaleToWidthF, scaleToHeightF, flow, "jpg", 0, "")
}
diff --git a/contrib/barcode/barcode_test.go b/contrib/barcode/barcode_test.go
index 2b402a3..066ac41 100644
--- a/contrib/barcode/barcode_test.go
+++ b/contrib/barcode/barcode_test.go
@@ -199,3 +199,24 @@ func TestGetUnscaledBarcodeDimensions(t *testing.T) {
// Output:
// Successfully generated ../../pdf/contrib_barcode_GetBarcodeDimensions.pdf
}
+
+// TestBarcodeNonIntegerScalingFactors shows that the barcode may be scaled to non-integer sizes
+func TestBarcodeNonIntegerScalingFactors(t *testing.T) {
+ pdf := gofpdf.New("L", "in", "A4", "")
+ pdf.SetFont("Helvetica", "", 12)
+ pdf.SetFillColor(200, 200, 220)
+ pdf.AddPage()
+
+ key := barcode.RegisterQR(pdf, "qrcode", qr.H, qr.Unicode)
+ var scale float64 = 1.5
+ barcode.BarcodeUnscalable(pdf, key, 0.5, 0.5, &scale, &scale, false)
+
+ pdf.SetDrawColor(255, 0, 0)
+ pdf.Line(0.5, 0.5, 0.5+scale, 0.5+scale)
+
+ fileStr := example.Filename("contrib_barcode_BarcodeScaling")
+ err := pdf.OutputFileAndClose(fileStr)
+ example.Summary(err, fileStr)
+ // Output:
+ // Successfully generated ../../pdf/contrib_barcode_BarcodeScaling.pdf
+}
diff --git a/cov b/cov
deleted file mode 100755
index a07edce..0000000
--- a/cov
+++ /dev/null
@@ -1 +0,0 @@
-go test -coverprofile=coverage && go tool cover -html=coverage
diff --git a/def.go b/def.go
index 205389b..8e2bea5 100644
--- a/def.go
+++ b/def.go
@@ -165,20 +165,20 @@ func (p PointType) XY() (float64, float64) {
// Changes to this structure should be reflected in its GobEncode and GobDecode
// methods.
type ImageInfoType struct {
- data []byte
- smask []byte
- n int
- w float64
- h float64
- cs string
- pal []byte
- bpc int
- f string
- dp string
- trns []int
- scale float64 // document scaling factor
- dpi float64
- i string
+ data []byte // Raw image data
+ smask []byte // Soft Mask, an 8bit per-pixel transparency mask
+ n int // Image object number
+ w float64 // Width
+ h float64 // Height
+ cs string // Color space
+ pal []byte // Image color palette
+ bpc int // Bits Per Component
+ f string // Image filter
+ dp string // DecodeParms
+ trns []int // Transparency mask
+ scale float64 // Document scale factor
+ dpi float64 // Dots-per-inch found from image file (png only)
+ i string // SHA-1 checksum of the above values.
}
func generateImageID(info *ImageInfoType) (string, error) {
@@ -427,6 +427,7 @@ type Pdf interface {
SetFontLoader(loader FontLoader)
SetFontLocation(fontDirStr string)
SetFontSize(size float64)
+ SetFontStyle(styleStr string)
SetFontUnitSize(size float64)
SetFooterFunc(fnc func())
SetFooterFuncLpi(fnc func(lastPage bool))
@@ -451,6 +452,7 @@ type Pdf interface {
SetTextSpotColor(nameStr string, tint byte)
SetTitle(titleStr string, isUTF8 bool)
SetTopMargin(margin float64)
+ SetUnderlineThickness(thickness float64)
SetXmpMetadata(xmpStream []byte)
SetX(x float64)
SetXY(x, y float64)
@@ -503,6 +505,10 @@ type Fpdf struct {
offsets []int // array of object offsets
templates map[string]Template // templates used in this document
templateObjects map[string]int // template object IDs within this document
+ importedObjs map[string][]byte // imported template objects (gofpdi)
+ importedObjPos map[string]map[int]string // imported template objects hashes and their positions (gofpdi)
+ importedTplObjs map[string]string // imported template names and IDs (hashed) (gofpdi)
+ importedTplIDs map[string]int // imported template ids hash to object id int (gofpdi)
buffer fmtBuffer // buffer holding in-memory PDF
pages []*bytes.Buffer // slice[page] of page content; 1-based
state int // current document state
@@ -536,6 +542,7 @@ type Fpdf struct {
fontFamily string // current font family
fontStyle string // current font style
underline bool // underlining flag
+ strikeout bool // strike out flag
currentFont fontDefType // current font info
fontSizePt float64 // current font size in points
fontSize float64 // current font size in user unit
@@ -558,6 +565,7 @@ type Fpdf struct {
zoomMode string // zoom display mode
layoutMode string // layout display mode
xmp []byte // XMP metadata
+ producer string // producer
title string // title
subject string // subject
author string // author
@@ -589,7 +597,8 @@ type Fpdf struct {
// Composite values of colors
draw, fill, text colorType
}
- spotColorMap map[string]spotColorType // Map of named ink-based colors
+ spotColorMap map[string]spotColorType // Map of named ink-based colors
+ userUnderlineThickness float64 // A custom user underline thickness multiplier.
}
type encType struct {
diff --git a/doc.go b/doc.go
index 6492f7e..16cf4ba 100644
--- a/doc.go
+++ b/doc.go
@@ -1,252 +1,269 @@
/*
- * Copyright (c) 2013-2017 Kurt Jung (Gmail: kurt.w.jung)
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
+Package gofpdf implements a PDF document generator with high level
+support for text, drawing and images.
-/*
-Package gofpdf implements a PDF document generator with high level support for
-text, drawing and images.
Features
-• Choice of measurement unit, page format and margins
-• Page header and footer management
+- UTF-8 support
+
+- Choice of measurement unit, page format and margins
+
+- Page header and footer management
+
+- Automatic page breaks, line breaks, and text justification
+
+- Inclusion of JPEG, PNG, GIF, TIFF and basic path-only SVG images
-• Automatic page breaks, line breaks, and text justification
+- Colors, gradients and alpha channel transparency
-• Inclusion of JPEG, PNG, GIF, TIFF and basic path-only SVG images
+- Outline bookmarks
-• Colors, gradients and alpha channel transparency
+- Internal and external links
-• Outline bookmarks
+- TrueType, Type1 and encoding support
-• Internal and external links
+- Page compression
-• TrueType, Type1 and encoding support
+- Lines, Bézier curves, arcs, and ellipses
-• Page compression
+- Rotation, scaling, skewing, translation, and mirroring
-• Lines, Bézier curves, arcs, and ellipses
+- Clipping
-• Rotation, scaling, skewing, translation, and mirroring
+- Document protection
-• Clipping
+- Layers
-• Document protection
+- Templates
-• Layers
+- Barcodes
-• Templates
+- Charting facility
-• Barcodes
+- Import PDFs as templates
-• Charting facility
+gofpdf has no dependencies other than the Go standard library. All tests
+pass on Linux, Mac and Windows platforms.
-gofpdf has no dependencies other than the Go standard library. All tests pass
-on Linux, Mac and Windows platforms.
+gofpdf supports UTF-8 TrueType fonts and “right-to-left” languages. Note
+that Chinese, Japanese, and Korean characters may not be included in
+many general purpose fonts. For these languages, a specialized font (for
+example, NotoSansSC for simplified Chinese) can be used.
+
+Also, support is provided to automatically translate UTF-8 runes to code
+page encodings for languages that have fewer than 256 glyphs.
-Like FPDF version 1.7, from which gofpdf is derived, this package does not yet
-support UTF-8 fonts. In particular, languages that require more than one code
-page such as Chinese, Japanese, and Arabic are not currently supported. This is
-explained in issue 109. However, support is provided to automatically translate
-UTF-8 runes to code page encodings for languages that have fewer than 256
-glyphs.
Installation
To install the package on your system, run
- go get github.com/jung-kurt/gofpdf
+ go get github.com/jung-kurt/gofpdf
Later, to receive updates, run
- go get -u -v github.com/jung-kurt/gofpdf/...
+ go get -u -v github.com/jung-kurt/gofpdf/...
+
Quick Start
The following Go code generates a simple PDF file.
- pdf := gofpdf.New("P", "mm", "A4", "")
- pdf.AddPage()
- pdf.SetFont("Arial", "B", 16)
- pdf.Cell(40, 10, "Hello, world")
- err := pdf.OutputFileAndClose("hello.pdf")
+ pdf := gofpdf.New("P", "mm", "A4", "")
+ pdf.AddPage()
+ pdf.SetFont("Arial", "B", 16)
+ pdf.Cell(40, 10, "Hello, world")
+ err := pdf.OutputFileAndClose("hello.pdf")
See the functions in the fpdf_test.go file (shown as examples in this
documentation) for more advanced PDF examples.
+
Errors
-If an error occurs in an Fpdf method, an internal error field is set. After
-this occurs, Fpdf method calls typically return without performing any
-operations and the error state is retained. This error management scheme
-facilitates PDF generation since individual method calls do not need to be
-examined for failure; it is generally sufficient to wait until after Output()
-is called. For the same reason, if an error occurs in the calling application
-during PDF generation, it may be desirable for the application to transfer the
-error to the Fpdf instance by calling the SetError() method or the SetErrorf()
-method. At any time during the life cycle of the Fpdf instance, the error state
-can be determined with a call to Ok() or Err(). The error itself can be
+If an error occurs in an Fpdf method, an internal error field is set.
+After this occurs, Fpdf method calls typically return without performing
+any operations and the error state is retained. This error management
+scheme facilitates PDF generation since individual method calls do not
+need to be examined for failure; it is generally sufficient to wait
+until after Output() is called. For the same reason, if an error occurs
+in the calling application during PDF generation, it may be desirable
+for the application to transfer the error to the Fpdf instance by
+calling the SetError() method or the SetErrorf() method. At any time
+during the life cycle of the Fpdf instance, the error state can be
+determined with a call to Ok() or Err(). The error itself can be
retrieved with a call to Error().
+
Conversion Notes
-This package is a relatively straightforward translation from the original FPDF
-library written in PHP (despite the caveat in the introduction to Effective
-Go). The API names have been retained even though the Go idiom would suggest
-otherwise (for example, pdf.GetX() is used rather than simply pdf.X()). The
-similarity of the two libraries makes the original FPDF website a good source
-of information. It includes a forum and FAQ.
-
-However, some internal changes have been made. Page content is built up using
-buffers (of type bytes.Buffer) rather than repeated string concatenation.
-Errors are handled as explained above rather than panicking. Output is
-generated through an interface of type io.Writer or io.WriteCloser. A number of
-the original PHP methods behave differently based on the type of the arguments
-that are passed to them; in these cases additional methods have been exported
-to provide similar functionality. Font definition files are produced in JSON
-rather than PHP.
+This package is a relatively straightforward translation from the
+original FPDF library written in PHP (despite the caveat in the
+introduction to Effective Go). The API names have been retained even
+though the Go idiom would suggest otherwise (for example, pdf.GetX() is
+used rather than simply pdf.X()). The similarity of the two libraries
+makes the original FPDF website a good source of information. It
+includes a forum and FAQ.
+
+However, some internal changes have been made. Page content is built up
+using buffers (of type bytes.Buffer) rather than repeated string
+concatenation. Errors are handled as explained above rather than
+panicking. Output is generated through an interface of type io.Writer or
+io.WriteCloser. A number of the original PHP methods behave differently
+based on the type of the arguments that are passed to them; in these
+cases additional methods have been exported to provide similar
+functionality. Font definition files are produced in JSON rather than
+PHP.
+
Example PDFs
-A side effect of running "go test ./..." is the production of a number of
-example PDFs. These can be found in the gofpdf/pdf directory after the tests
-complete.
-
-Please note that these examples run in the context of a test. In order run an
-example as a standalone application, you'll need to examine fpdf_test.go for
-some helper routines, for example exampleFilename() and summary().
-
-Example PDFs can be compared with reference copies in order to verify that they
-have been generated as expected. This comparison will be performed if a PDF
-with the same name as the example PDF is placed in the gofpdf/pdf/reference
-directory and if the third argument to ComparePDFFiles() in
-internal/example/example.go is true. (By default it is false.) The routine that
-summarizes an example will look for this file and, if found, will call
-ComparePDFFiles() to check the example PDF for equality with its reference PDF.
-If differences exist between the two files they will be printed to standard
-output and the test will fail. If the reference file is missing, the comparison
-is considered to succeed. In order to successfully compare two PDFs, the
-placement of internal resources must be consistent and the internal creation
-timestamps must be the same. To do this, the methods SetCatalogSort() and
-SetCreationDate() need to be called for both files. This is done automatically
-for all examples.
+A side effect of running go test ./... is the production of a number of
+example PDFs. These can be found in the gofpdf/pdf directory after the
+tests complete.
+
+Please note that these examples run in the context of a test. In order
+run an example as a standalone application, you’ll need to examine
+fpdf_test.go for some helper routines, for example exampleFilename() and
+summary().
+
+Example PDFs can be compared with reference copies in order to verify
+that they have been generated as expected. This comparison will be
+performed if a PDF with the same name as the example PDF is placed in
+the gofpdf/pdf/reference directory and if the third argument to
+ComparePDFFiles() in internal/example/example.go is true. (By default it
+is false.) The routine that summarizes an example will look for this
+file and, if found, will call ComparePDFFiles() to check the example PDF
+for equality with its reference PDF. If differences exist between the
+two files they will be printed to standard output and the test will
+fail. If the reference file is missing, the comparison is considered to
+succeed. In order to successfully compare two PDFs, the placement of
+internal resources must be consistent and the internal creation
+timestamps must be the same. To do this, the methods SetCatalogSort()
+and SetCreationDate() need to be called for both files. This is done
+automatically for all examples.
+
Nonstandard Fonts
-Nothing special is required to use the standard PDF fonts (courier, helvetica,
-times, zapfdingbats) in your documents other than calling SetFont().
+Nothing special is required to use the standard PDF fonts (courier,
+helvetica, times, zapfdingbats) in your documents other than calling
+SetFont().
+
+You should use AddUTF8Font() or AddUTF8FontFromBytes() to add a TrueType
+UTF-8 encoded font. Use RTL() and LTR() methods switch between
+“right-to-left” and “left-to-right” mode.
+
+In order to use a different non-UTF-8 TrueType or Type1 font, you will
+need to generate a font definition file and, if the font will be
+embedded into PDFs, a compressed version of the font file. This is done
+by calling the MakeFont function or using the included makefont command
+line utility. To create the utility, cd into the makefont subdirectory
+and run “go build”. This will produce a standalone executable named
+makefont. Select the appropriate encoding file from the font
+subdirectory and run the command as in the following example.
-In order to use a different TrueType or Type1 font, you will need to generate a
-font definition file and, if the font will be embedded into PDFs, a compressed
-version of the font file. This is done by calling the MakeFont function or
-using the included makefont command line utility. To create the utility, cd
-into the makefont subdirectory and run "go build". This will produce a
-standalone executable named makefont. Select the appropriate encoding file from
-the font subdirectory and run the command as in the following example.
+ ./makefont --embed --enc=../font/cp1252.map --dst=../font ../font/calligra.ttf
- ./makefont --embed --enc=../font/cp1252.map --dst=../font ../font/calligra.ttf
+In your PDF generation code, call AddFont() to load the font and, as
+with the standard fonts, SetFont() to begin using it. Most examples,
+including the package example, demonstrate this method. Good sources of
+free, open-source fonts include Google Fonts and DejaVu Fonts.
-In your PDF generation code, call AddFont() to load the font and, as with the
-standard fonts, SetFont() to begin using it. Most examples, including the
-package example, demonstrate this method. Good sources of free, open-source
-fonts include http://www.google.com/fonts/ and http://dejavu-fonts.org/.
Related Packages
-The draw2d package (https://github.com/llgcode/draw2d) is a two dimensional
-vector graphics library that can generate output in different forms. It uses
-gofpdf for its document production mode.
+The draw2d package is a two dimensional vector graphics library that can
+generate output in different forms. It uses gofpdf for its document
+production mode.
+
Contributing Changes
-gofpdf is a global community effort and you are invited to make it even better.
-If you have implemented a new feature or corrected a problem, please consider
-contributing your change to the project. A contribution that does not directly
-pertain to the core functionality of gofpdf should be placed in its own
-directory directly beneath the `contrib` directory.
+gofpdf is a global community effort and you are invited to make it even
+better. If you have implemented a new feature or corrected a problem,
+please consider contributing your change to the project. A contribution
+that does not directly pertain to the core functionality of gofpdf
+should be placed in its own directory directly beneath the contrib
+directory.
Here are guidelines for making submissions. Your change should
-• be compatible with the MIT License
-• be properly documented
+- be compatible with the MIT License
+
+- be properly documented
-• be formatted with `go fmt`
+- be formatted with go fmt
-• include an example in fpdf_test.go if appropriate
+- include an example in fpdf_test.go if appropriate
-• conform to the standards of golint (https://github.com/golang/lint) and
-go vet (https://godoc.org/golang.org/x/tools/cmd/vet), that is, `golint .` and
-`go vet .` should not generate any warnings
+- conform to the standards of golint and go vet, that is, golint . and
+go vet . should not generate any warnings
-• not diminish test coverage (https://blog.golang.org/cover)
+- not diminish test coverage
+
+Pull requests are the preferred means of accepting your changes.
-Pull requests (https://help.github.com/articles/using-pull-requests/) work
-nicely as a means of contributing your changes.
License
-gofpdf is released under the MIT License. It is copyrighted by Kurt Jung and
-the contributors acknowledged below.
+gofpdf is released under the MIT License. It is copyrighted by Kurt Jung
+and the contributors acknowledged below.
+
Acknowledgments
-This package's code and documentation are closely derived from the FPDF library
-(http://www.fpdf.org/) created by Olivier Plathey, and a number of font and
-image resources are copied directly from it. Bruno Michel has provided valuable
-assistance with the code. Drawing support is adapted from the FPDF geometric
-figures script by David Hernández Sanz. Transparency support is adapted from
-the FPDF transparency script by Martin Hall-May. Support for gradients and
-clipping is adapted from FPDF scripts by Andreas Würmser. Support for outline
-bookmarks is adapted from Olivier Plathey by Manuel Cornes. Layer support is
-adapted from Olivier Plathey. Support for transformations is adapted from the
-FPDF transformation script by Moritz Wagner and Andreas Würmser. PDF
-protection is adapted from the work of Klemen Vodopivec for the FPDF product.
-Lawrence Kesteloot provided code to allow an image's extent to be determined
-prior to placement. Support for vertical alignment within a cell was provided
-by Stefan Schroeder. Ivan Daniluk generalized the font and image loading code
-to use the Reader interface while maintaining backward compatibility. Anthony
-Starks provided code for the Polygon function. Robert Lillack provided the
-Beziergon function and corrected some naming issues with the internal curve
-function. Claudio Felber provided implementations for dashed line drawing and
-generalized font loading. Stani Michiels provided support for multi-segment
-path drawing with smooth line joins, line join styles, enhanced fill modes, and
-has helped greatly with package presentation and tests. Templating is adapted
-by Marcus Downing from the FPDF_Tpl library created by Jan Slabon and Setasign.
-Jelmer Snoeck contributed packages that generate a variety of barcodes and help
-with registering images on the web. Jelmer Snoek and Guillermo Pascual
-augmented the basic HTML functionality with aligned text. Kent Quirk
-implemented backwards-compatible support for reading DPI from images that
-support it, and for setting DPI manually and then having it properly taken into
-account when calculating image size. Paulo Coutinho provided support for static
-embedded fonts. Dan Meyers added support for embedded JavaScript. David Fish
-added a generic alias-replacement function to enable, among other things, table
-of contents functionality. Andy Bakun identified and corrected a problem in
-which the internal catalogs were not sorted stably. Paul Montag added encoding
-and decoding functionality for templates, including images that are embedded in
-templates; this allows templates to be stored independently of gofpdf. Paul
-also added support for page boxes used in printing PDF documents. Wojciech
-Matusiak added supported for word spacing.
+This package’s code and documentation are closely derived from the FPDF
+library created by Olivier Plathey, and a number of font and image
+resources are copied directly from it. Bruno Michel has provided
+valuable assistance with the code. Drawing support is adapted from the
+FPDF geometric figures script by David Hernández Sanz. Transparency
+support is adapted from the FPDF transparency script by Martin Hall-May.
+Support for gradients and clipping is adapted from FPDF scripts by
+Andreas Würmser. Support for outline bookmarks is adapted from Olivier
+Plathey by Manuel Cornes. Layer support is adapted from Olivier Plathey.
+Support for transformations is adapted from the FPDF transformation
+script by Moritz Wagner and Andreas Würmser. PDF protection is adapted
+from the work of Klemen Vodopivec for the FPDF product. Lawrence
+Kesteloot provided code to allow an image’s extent to be determined
+prior to placement. Support for vertical alignment within a cell was
+provided by Stefan Schroeder. Ivan Daniluk generalized the font and
+image loading code to use the Reader interface while maintaining
+backward compatibility. Anthony Starks provided code for the Polygon
+function. Robert Lillack provided the Beziergon function and corrected
+some naming issues with the internal curve function. Claudio Felber
+provided implementations for dashed line drawing and generalized font
+loading. Stani Michiels provided support for multi-segment path drawing
+with smooth line joins, line join styles, enhanced fill modes, and has
+helped greatly with package presentation and tests. Templating is
+adapted by Marcus Downing from the FPDF_Tpl library created by Jan
+Slabon and Setasign. Jelmer Snoeck contributed packages that generate a
+variety of barcodes and help with registering images on the web. Jelmer
+Snoek and Guillermo Pascual augmented the basic HTML functionality with
+aligned text. Kent Quirk implemented backwards-compatible support for
+reading DPI from images that support it, and for setting DPI manually
+and then having it properly taken into account when calculating image
+size. Paulo Coutinho provided support for static embedded fonts. Dan
+Meyers added support for embedded JavaScript. David Fish added a generic
+alias-replacement function to enable, among other things, table of
+contents functionality. Andy Bakun identified and corrected a problem in
+which the internal catalogs were not sorted stably. Paul Montag added
+encoding and decoding functionality for templates, including images that
+are embedded in templates; this allows templates to be stored
+independently of gofpdf. Paul also added support for page boxes used in
+printing PDF documents. Wojciech Matusiak added supported for word
+spacing. Artem Korotkiy added support of UTF-8 fonts. Dave Barnes added
+support for imported objects and templates. Brigham Thompson added
+support for rounded rectangles. Joe Westcott added underline
+functionality and optimized image storage.
-Roadmap
-• Handle UTF-8 source text natively. Until then, automatic translation of
-UTF-8 runes to code page bytes is provided.
+Roadmap
-• Improve test coverage as reported by the coverage tool.
+- Improve test coverage as reported by the coverage tool.
*/
package gofpdf
diff --git a/font/calligra.json b/font/calligra.json
index b968074..e49c9bd 100644
--- a/font/calligra.json
+++ b/font/calligra.json
@@ -1 +1 @@
-{"Tp":"TrueType","Name":"CalligrapherRegular","Desc":{"Ascent":899,"Descent":-234,"CapHeight":899,"Flags":32,"FontBBox":{"Xmin":-173,"Ymin":-234,"Xmax":1328,"Ymax":899},"ItalicAngle":0,"StemV":70,"MissingWidth":800},"Up":-200,"Ut":20,"Cw":[800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,282,324,405,584,632,980,776,259,299,299,377,600,259,432,254,597,529,298,451,359,525,423,464,417,457,479,275,282,600,600,600,501,800,743,636,598,712,608,562,680,756,308,314,676,552,1041,817,729,569,698,674,618,673,805,753,1238,716,754,599,315,463,315,600,547,278,581,564,440,571,450,347,628,611,283,283,560,252,976,595,508,549,540,395,441,307,614,556,915,559,597,452,315,222,315,600,800,800,800,0,0,0,780,0,0,278,0,0,0,1064,800,0,800,800,259,259,470,470,500,300,600,278,990,0,0,790,800,800,754,282,324,450,640,518,603,0,519,254,800,349,0,0,432,800,278,0,0,0,0,278,614,0,254,278,0,305,0,0,0,0,501,743,743,743,743,743,743,1060,598,608,608,608,608,308,308,308,308,0,817,729,729,729,729,729,0,729,805,805,805,805,0,0,688,581,581,581,581,581,581,792,440,450,450,450,450,283,283,283,283,0,595,508,508,508,508,508,0,508,614,614,614,614,0,0,597],"Enc":"cp1252","Diff":"","File":"calligra.z","Size1":0,"Size2":0,"OriginalSize":40120,"I":0,"N":0,"DiffN":0} \ No newline at end of file
+{"Tp":"TrueType","Name":"CalligrapherRegular","Desc":{"Ascent":899,"Descent":-234,"CapHeight":899,"Flags":32,"FontBBox":{"Xmin":-173,"Ymin":-234,"Xmax":1328,"Ymax":899},"ItalicAngle":0,"StemV":70,"MissingWidth":800},"Up":-200,"Ut":20,"Cw":[800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,282,324,405,584,632,980,776,259,299,299,377,600,259,432,254,597,529,298,451,359,525,423,464,417,457,479,275,282,600,600,600,501,800,743,636,598,712,608,562,680,756,308,314,676,552,1041,817,729,569,698,674,618,673,805,753,1238,716,754,599,315,463,315,600,547,278,581,564,440,571,450,347,628,611,283,283,560,252,976,595,508,549,540,395,441,307,614,556,915,559,597,452,315,222,315,600,800,800,800,0,0,0,780,0,0,278,0,0,0,1064,800,0,800,800,259,259,470,470,500,300,600,278,990,0,0,790,800,800,754,282,324,450,640,518,603,0,519,254,800,349,0,0,432,800,278,0,0,0,0,278,614,0,254,278,0,305,0,0,0,0,501,743,743,743,743,743,743,1060,598,608,608,608,608,308,308,308,308,0,817,729,729,729,729,729,0,729,805,805,805,805,0,0,688,581,581,581,581,581,581,792,440,450,450,450,450,283,283,283,283,0,595,508,508,508,508,508,0,508,614,614,614,614,0,0,597],"Enc":"cp1252","Diff":"","File":"calligra.z","Size1":0,"Size2":0,"OriginalSize":40120,"N":0,"DiffN":0} \ No newline at end of file
diff --git a/font/calligra.z b/font/calligra.z
index c64353f..b6c5c07 100644
--- a/font/calligra.z
+++ b/font/calligra.z
Binary files differ
diff --git a/fpdf.go b/fpdf.go
index fa79033..f5062cc 100644
--- a/fpdf.go
+++ b/fpdf.go
@@ -85,6 +85,10 @@ func fpdfNew(orientationStr, unitStr, sizeStr, fontDirStr string, size SizeType)
f.diffs = make([]string, 0, 8)
f.templates = make(map[string]Template)
f.templateObjects = make(map[string]int)
+ f.importedObjs = make(map[string][]byte, 0)
+ f.importedObjPos = make(map[string]map[int]string, 0)
+ f.importedTplObjs = make(map[string]string)
+ f.importedTplIDs = make(map[string]int, 0)
f.images = make(map[string]*ImageInfoType)
f.pageLinks = make([][]linkType, 0, 8)
f.pageLinks = append(f.pageLinks, make([]linkType, 0, 0)) // pageLinks[0] is unused (1-based)
@@ -98,6 +102,7 @@ func fpdfNew(orientationStr, unitStr, sizeStr, fontDirStr string, size SizeType)
f.fontStyle = ""
f.SetFontSize(12)
f.underline = false
+ f.strikeout = false
f.setDrawColor(0, 0, 0)
f.setFillColor(0, 0, 0)
f.setTextColor(0, 0, 0)
@@ -194,9 +199,11 @@ func fpdfNew(orientationStr, unitStr, sizeStr, fontDirStr string, size SizeType)
f.gradientList = append(f.gradientList, gradientType{}) // gradientList[0] is unused
// Set default PDF version number
f.pdfVersion = "1.3"
+ f.SetProducer("FPDF "+cnFpdfVersion, true)
f.layerInit()
f.catalogSort = gl.catalogSort
f.creationDate = gl.creationDate
+ f.userUnderlineThickness = 1
return
}
@@ -555,6 +562,15 @@ func (f *Fpdf) SetCompression(compress bool) {
f.compress = compress
}
+// SetProducer defines the producer of the document. isUTF8 indicates if the string
+// is encoded in ISO-8859-1 (false) or UTF-8 (true).
+func (f *Fpdf) SetProducer(producerStr string, isUTF8 bool) {
+ if isUTF8 {
+ producerStr = utf8toutf16(producerStr)
+ }
+ f.producer = producerStr
+}
+
// SetTitle defines the title of the document. isUTF8 indicates if the string
// is encoded in ISO-8859-1 (false) or UTF-8 (true).
func (f *Fpdf) SetTitle(titleStr string, isUTF8 bool) {
@@ -618,12 +634,12 @@ func (f *Fpdf) AliasNbPages(aliasStr string) {
f.aliasNbPagesStr = aliasStr
}
-// enable right to left mode
+// RTL enables right-to-left mode
func (f *Fpdf) RTL() {
f.isRTL = true
}
-// disable right to left mode
+// LTR disables right-to-left mode
func (f *Fpdf) LTR() {
f.isRTL = false
}
@@ -711,6 +727,9 @@ func (f *Fpdf) AddPageFormat(orientationStr string, size SizeType) {
if f.underline {
style += "U"
}
+ if f.strikeout {
+ style += "S"
+ }
fontsize := f.fontSizePt
lw := f.lineWidth
dc := f.color.draw
@@ -1099,6 +1118,58 @@ func (f *Fpdf) Rect(x, y, w, h float64, styleStr string) {
f.outf("%.2f %.2f %.2f %.2f re %s", x*f.k, (f.h-y)*f.k, w*f.k, -h*f.k, fillDrawOp(styleStr))
}
+// RoundedRect outputs a rectangle of width w and height h with the upper left
+// corner positioned at point (x, y). It can be drawn (border only), filled
+// (with no border) or both. styleStr can be "F" for filled, "D" for outlined
+// only, or "DF" or "FD" for outlined and filled. An empty string will be
+// replaced with "D". Drawing uses the current draw color and line width
+// centered on the rectangle's perimeter. Filling uses the current fill color.
+// The rounded corners of the rectangle are specified by radius r. corners is a
+// string that includes "1" to round the upper left corner, "2" to round the
+// upper right corner, "3" to round the lower right corner, and "4" to round
+// the lower left corner. The RoundedRect example demonstrates this method.
+func (f *Fpdf) RoundedRect(x, y, w, h, r float64, corners string, stylestr string) {
+ // This routine was adapted by Brigham Thompson from a script by Christophe Prugnaud
+ k := f.k
+ hp := f.h
+ myArc := r * (4.0 / 3.0) * (math.Sqrt2 - 1.0)
+ f.outf("q %.5f %.5f m", (x+r)*k, (hp-y)*k)
+ xc := x + w - r
+ yc := y + r
+ f.outf("%.5f %.5f l", xc*k, (hp-y)*k)
+ if strings.Contains(corners, "2") == false {
+ f.outf("%.5f %.5f l", (x+w)*k, (hp-y)*k)
+ } else {
+ f.clipArc(xc+myArc, yc-r, xc+r, yc-myArc, xc+r, yc)
+ }
+ xc = x + w - r
+ yc = y + h - r
+ f.outf("%.5f %.5f l", (x+w)*k, (hp-yc)*k)
+ if strings.Contains(corners, "3") == false {
+ f.outf("%.5f %.5f l", (x+w)*k, (hp-(y+h))*k)
+ } else {
+ f.clipArc(xc+r, yc+myArc, xc+myArc, yc+r, xc, yc+r)
+ }
+ xc = x + r
+ yc = y + h - r
+ f.outf("%.5f %.5f l", xc*k, (hp-(y+h))*k)
+ if strings.Contains(corners, "4") == false {
+ f.outf("%.5f %.5f l", x*k, (hp-(y+h))*k)
+ } else {
+ f.clipArc(xc-myArc, yc+r, xc-r, yc+myArc, xc-r, yc)
+ }
+ xc = x + r
+ yc = y + r
+ f.outf("%.5f %.5f l", x*k, (hp-yc)*k)
+ if strings.Contains(corners, "1") == false {
+ f.outf("%.5f %.5f l", x*k, (hp-y)*k)
+ f.outf("%.5f %.5f l", (x+r)*k, (hp-y)*k)
+ } else {
+ f.clipArc(xc-r, yc-myArc, xc-myArc, yc-r, xc, yc-r)
+ }
+ f.out(fillDrawOp(stylestr))
+}
+
// Circle draws a circle centered on point (x, y) with radius r.
//
// styleStr can be "F" for filled, "D" for outlined only, or "DF" or "FD" for
@@ -1558,7 +1629,7 @@ func (f *Fpdf) ClipEnd() {
// definition file to be added. The file will be loaded from the font directory
// specified in the call to New() or SetFontLocation().
func (f *Fpdf) AddFont(familyStr, styleStr, fileStr string) {
- f.addFont(familyStr, styleStr, fileStr, false)
+ f.addFont(fontFamilyEscape(familyStr), styleStr, fileStr, false)
}
// AddUTF8Font imports a TrueType font with utf-8 symbols and makes it available.
@@ -1582,7 +1653,7 @@ func (f *Fpdf) AddFont(familyStr, styleStr, fileStr string) {
// definition file to be added. The file will be loaded from the font directory
// specified in the call to New() or SetFontLocation().
func (f *Fpdf) AddUTF8Font(familyStr, styleStr, fileStr string) {
- f.addFont(familyStr, styleStr, fileStr, true)
+ f.addFont(fontFamilyEscape(familyStr), styleStr, fileStr, true)
}
func (f *Fpdf) addFont(familyStr, styleStr, fileStr string, isUTF8 bool) {
@@ -1599,17 +1670,27 @@ func (f *Fpdf) addFont(familyStr, styleStr, fileStr string, isUTF8 bool) {
if ok {
return
}
- ttfStat, _ := os.Stat(fileStr)
+ var ttfStat os.FileInfo
+ var err error
+ fileStr = path.Join(f.fontpath, fileStr)
+ ttfStat, err = os.Stat(fileStr)
+ if err != nil {
+ f.SetError(err)
+ return
+ }
originalSize := ttfStat.Size()
Type := "UTF8"
-
- utf8Bytes, _ := ioutil.ReadFile(fileStr)
+ var utf8Bytes []byte
+ utf8Bytes, err = ioutil.ReadFile(fileStr)
+ if err != nil {
+ f.SetError(err)
+ return
+ }
reader := fileReader{readerPosition: 0, array: utf8Bytes}
utf8File := newUTF8Font(&reader)
-
- err := utf8File.parseFile()
+ err = utf8File.parseFile()
if err != nil {
- fmt.Printf("get metrics Error: %e\n", err)
+ f.SetError(err)
return
}
@@ -1698,7 +1779,7 @@ func makeSubsetRange(end int) map[int]int {
//
// zFileBytes contain all bytes of Z file.
func (f *Fpdf) AddFontFromBytes(familyStr, styleStr string, jsonFileBytes, zFileBytes []byte) {
- f.addFontFromBytes(familyStr, styleStr, jsonFileBytes, zFileBytes, nil)
+ f.addFontFromBytes(fontFamilyEscape(familyStr), styleStr, jsonFileBytes, zFileBytes, nil)
}
// AddUTF8FontFromBytes imports a TrueType font with utf-8 symbols from static
@@ -1717,7 +1798,7 @@ func (f *Fpdf) AddFontFromBytes(familyStr, styleStr string, jsonFileBytes, zFile
//
// zFileBytes contain all bytes of Z file.
func (f *Fpdf) AddUTF8FontFromBytes(familyStr, styleStr string, utf8Bytes []byte) {
- f.addFontFromBytes(familyStr, styleStr, nil, nil, utf8Bytes)
+ f.addFontFromBytes(fontFamilyEscape(familyStr), styleStr, nil, nil, utf8Bytes)
}
func (f *Fpdf) addFontFromBytes(familyStr, styleStr string, jsonFileBytes, zFileBytes, utf8Bytes []byte) {
@@ -1736,9 +1817,9 @@ func (f *Fpdf) addFontFromBytes(familyStr, styleStr string, jsonFileBytes, zFile
if utf8Bytes != nil {
- if styleStr == "IB" {
- styleStr = "BI"
- }
+ // if styleStr == "IB" {
+ // styleStr = "BI"
+ // }
Type := "UTF8"
reader := fileReader{readerPosition: 0, array: utf8Bytes}
@@ -1856,6 +1937,7 @@ func (f *Fpdf) AddFontFromReader(familyStr, styleStr string, r io.Reader) {
return
}
// dbg("Adding family [%s], style [%s]", familyStr, styleStr)
+ familyStr = fontFamilyEscape(familyStr)
var ok bool
fontkey := getFontKey(familyStr, styleStr)
_, ok = f.fonts[fontkey]
@@ -1904,7 +1986,7 @@ func (f *Fpdf) GetFontDesc(familyStr, styleStr string) FontDescType {
if familyStr == "" {
return f.currentFont.Desc
}
- return f.fonts[getFontKey(familyStr, styleStr)].Desc
+ return f.fonts[getFontKey(fontFamilyEscape(familyStr), styleStr)].Desc
}
// SetFont sets the font used to print character strings. It is mandatory to
@@ -1927,9 +2009,9 @@ func (f *Fpdf) GetFontDesc(familyStr, styleStr string) FontDescType {
// insensitive): "Courier" for fixed-width, "Helvetica" or "Arial" for sans
// serif, "Times" for serif, "Symbol" or "ZapfDingbats" for symbolic.
//
-// styleStr can be "B" (bold), "I" (italic), "U" (underscore) or any
-// combination. The default value (specified with an empty string) is regular.
-// Bold and italic styles do not apply to Symbol and ZapfDingbats.
+// styleStr can be "B" (bold), "I" (italic), "U" (underscore), "S" (strike-out)
+// or any combination. The default value (specified with an empty string) is
+// regular. Bold and italic styles do not apply to Symbol and ZapfDingbats.
//
// size is the font size measured in points. The default value is the current
// size. If no size has been specified since the beginning of the document, the
@@ -1941,6 +2023,7 @@ func (f *Fpdf) SetFont(familyStr, styleStr string, size float64) {
return
}
// dbg("SetFont")
+ familyStr = fontFamilyEscape(familyStr)
var ok bool
if familyStr == "" {
familyStr = f.fontFamily
@@ -1952,6 +2035,10 @@ func (f *Fpdf) SetFont(familyStr, styleStr string, size float64) {
if f.underline {
styleStr = strings.Replace(styleStr, "U", "", -1)
}
+ f.strikeout = strings.Contains(styleStr, "S")
+ if f.strikeout {
+ styleStr = strings.Replace(styleStr, "S", "", -1)
+ }
if styleStr == "IB" {
styleStr = "BI"
}
@@ -2008,6 +2095,11 @@ func (f *Fpdf) SetFont(familyStr, styleStr string, size float64) {
return
}
+// SetFontStyle sets the style of the current font. See also SetFont()
+func (f *Fpdf) SetFontStyle(styleStr string) {
+ f.SetFont(f.fontFamily, styleStr, f.fontSizePt)
+}
+
// SetFontSize defines the size of the current font. Size is specified in
// points (1/ 72 inch). See also SetFontUnitSize().
func (f *Fpdf) SetFontSize(size float64) {
@@ -2091,6 +2183,9 @@ func (f *Fpdf) Bookmark(txtStr string, level int, y float64) {
if y == -1 {
y = f.y
}
+ if f.isCurrentUTF8 {
+ txtStr = utf8toutf16(txtStr)
+ }
f.outlines = append(f.outlines, outlineType{text: txtStr, level: level, y: y, p: f.PageNo(), prev: -1, last: -1, next: -1, first: -1})
}
@@ -2102,7 +2197,7 @@ func (f *Fpdf) Text(x, y float64, txtStr string) {
var txt2 string
if f.isCurrentUTF8 {
if f.isRTL {
- txtStr = revertText(txtStr)
+ txtStr = reverseText(txtStr)
x -= f.GetStringWidth(txtStr)
}
txt2 = f.escape(utf8toutf16(txtStr, false))
@@ -2116,6 +2211,9 @@ func (f *Fpdf) Text(x, y float64, txtStr string) {
if f.underline && txtStr != "" {
s += " " + f.dounderline(x, y, txtStr)
}
+ if f.strikeout && txtStr != "" {
+ s += " " + f.dostrikeout(x, y, txtStr)
+ }
if f.colorFlag {
s = sprintf("q %s %s Q", f.color.text.str, s)
}
@@ -2294,7 +2392,7 @@ func (f *Fpdf) CellFormat(w, h float64, txtStr, borderStr string, ln int,
//If multibyte, Tw has no effect - do word spacing using an adjustment before each space
if (f.ws != 0 || alignStr == "J") && f.isCurrentUTF8 { // && f.ws != 0
if f.isRTL {
- txtStr = revertText(txtStr)
+ txtStr = reverseText(txtStr)
}
wmax := int(math.Ceil((w - 2*f.cMargin) * 1000 / f.fontSize))
for _, uni := range []rune(txtStr) {
@@ -2319,7 +2417,7 @@ func (f *Fpdf) CellFormat(w, h float64, txtStr, borderStr string, ln int,
var txt2 string
if f.isCurrentUTF8 {
if f.isRTL {
- txtStr = revertText(txtStr)
+ txtStr = reverseText(txtStr)
}
txt2 = f.escape(utf8toutf16(txtStr, false))
for _, uni := range []rune(txtStr) {
@@ -2340,6 +2438,9 @@ func (f *Fpdf) CellFormat(w, h float64, txtStr, borderStr string, ln int,
if f.underline {
s.printf(" %s", f.dounderline(f.x+dx, f.y+dy+.5*h+.3*f.fontSize, txtStr))
}
+ if f.strikeout {
+ s.printf(" %s", f.dostrikeout(f.x+dx, f.y+dy+.5*h+.3*f.fontSize, txtStr))
+ }
if f.colorFlag {
s.printf(" Q")
}
@@ -2365,18 +2466,18 @@ func (f *Fpdf) CellFormat(w, h float64, txtStr, borderStr string, ln int,
}
// Revert string to use in RTL languages
-func revertText(text string) string {
+func reverseText(text string) string {
oldText := []rune(text)
newText := make([]rune, len(oldText))
- lenght := len(oldText) - 1
+ length := len(oldText) - 1
for i, r := range oldText {
- newText[lenght-i] = r
+ newText[length-i] = r
}
return string(newText)
}
// Cell is a simpler version of CellFormat with no fill, border, links or
-// special alignment.
+// special alignment. The Cell_strikeout() example demonstrates this method.
func (f *Fpdf) Cell(w, h float64, txtStr string) {
f.CellFormat(w, h, txtStr, "", 0, "L", false, 0, "")
}
@@ -2393,6 +2494,9 @@ func (f *Fpdf) Cellf(w, h float64, fmtStr string, args ...interface{}) {
// used to determine the total height of wrapped text for vertical placement
// purposes.
//
+// This method is useful for codepage-based fonts only. For UTF-8 encoded text,
+// use SplitText().
+//
// You can use MultiCell if you want to print a text on several lines in a
// simple way.
func (f *Fpdf) SplitLines(txt []byte, w float64) [][]byte {
@@ -2454,6 +2558,9 @@ func (f *Fpdf) SplitLines(txt []byte, w float64) [][]byte {
//
// h indicates the line height of each cell in the unit of measure specified in New().
func (f *Fpdf) MultiCell(w, h float64, txtStr, borderStr, alignStr string, fill bool) {
+ if f.err != nil {
+ return
+ }
// dbg("MultiCell")
if alignStr == "" {
alignStr = "J"
@@ -2464,20 +2571,23 @@ func (f *Fpdf) MultiCell(w, h float64, txtStr, borderStr, alignStr string, fill
}
wmax := int(math.Ceil((w - 2*f.cMargin) * 1000 / f.fontSize))
s := strings.Replace(txtStr, "\r", "", -1)
+ srune := []rune(s)
+ // remove extra line breaks
var nb int
if f.isCurrentUTF8 {
- nb = len([]rune(s))
- for nb > 0 && []rune(s)[nb-1] == '\n' {
+ nb = len(srune)
+ for nb > 0 && srune[nb-1] == '\n' {
nb--
- s = string([]rune(s)[0:nb])
}
+ srune = srune[0:nb]
} else {
nb = len(s)
- if nb > 0 && []byte(s)[nb-1] == '\n' {
+ bytes2 := []byte(s)
+ for nb > 0 && bytes2[nb-1] == '\n' {
nb--
- s = s[0:nb]
}
+ s = s[0:nb]
}
// dbg("[%s]\n", s)
var b, b2 string
@@ -2513,9 +2623,9 @@ func (f *Fpdf) MultiCell(w, h float64, txtStr, borderStr, alignStr string, fill
// Get next character
var c rune
if f.isCurrentUTF8 {
- c = []rune(s)[i]
+ c = srune[i]
} else {
- c = rune([]byte(s)[i])
+ c = rune(s[i])
}
if c == '\n' {
// Explicit line break
@@ -2533,7 +2643,7 @@ func (f *Fpdf) MultiCell(w, h float64, txtStr, borderStr, alignStr string, fill
newAlignStr = "L"
}
}
- f.CellFormat(w, h, string([]rune(s)[j:i]), b, 2, newAlignStr, fill, 0, "")
+ f.CellFormat(w, h, string(srune[j:i]), b, 2, newAlignStr, fill, 0, "")
} else {
f.CellFormat(w, h, s[j:i], b, 2, alignStr, fill, 0, "")
}
@@ -2548,7 +2658,7 @@ func (f *Fpdf) MultiCell(w, h float64, txtStr, borderStr, alignStr string, fill
}
continue
}
- if c == ' ' {
+ if c == ' ' || isChinese(c) {
sep = i
ls = l
ns++
@@ -2569,7 +2679,7 @@ func (f *Fpdf) MultiCell(w, h float64, txtStr, borderStr, alignStr string, fill
f.out("0 Tw")
}
if f.isCurrentUTF8 {
- f.CellFormat(w, h, string([]rune(s)[j:i]), b, 2, alignStr, fill, 0, "")
+ f.CellFormat(w, h, string(srune[j:i]), b, 2, alignStr, fill, 0, "")
} else {
f.CellFormat(w, h, s[j:i], b, 2, alignStr, fill, 0, "")
}
@@ -2583,7 +2693,7 @@ func (f *Fpdf) MultiCell(w, h float64, txtStr, borderStr, alignStr string, fill
f.outf("%.3f Tw", f.ws*f.k)
}
if f.isCurrentUTF8 {
- f.CellFormat(w, h, string([]rune(s)[j:sep]), b, 2, alignStr, fill, 0, "")
+ f.CellFormat(w, h, string(srune[j:sep]), b, 2, alignStr, fill, 0, "")
} else {
f.CellFormat(w, h, s[j:sep], b, 2, alignStr, fill, 0, "")
}
@@ -2617,7 +2727,7 @@ func (f *Fpdf) MultiCell(w, h float64, txtStr, borderStr, alignStr string, fill
alignStr = ""
}
}
- f.CellFormat(w, h, string([]rune(s)[j:i]), b, 2, alignStr, fill, 0, "")
+ f.CellFormat(w, h, string(srune[j:i]), b, 2, alignStr, fill, 0, "")
} else {
f.CellFormat(w, h, s[j:i], b, 2, alignStr, fill, 0, "")
}
@@ -2652,7 +2762,7 @@ func (f *Fpdf) write(h float64, txtStr string, link int, linkStr string) {
if f.isCurrentUTF8 {
c = []rune(s)[i]
} else {
- c = rune([]byte(s)[i])
+ c = rune(byte(s[i]))
}
if c == '\n' {
// Explicit line break
@@ -2775,12 +2885,20 @@ func (f *Fpdf) WriteLinkID(h float64, displayStr string, linkID int) {
func (f *Fpdf) WriteAligned(width, lineHeight float64, textStr, alignStr string) {
lMargin, _, rMargin, _ := f.GetMargins()
+ pageWidth, _ := f.GetPageSize()
if width == 0 {
- pageWidth, _ := f.GetPageSize()
width = pageWidth - (lMargin + rMargin)
}
- lines := f.SplitLines([]byte(textStr), width)
+ var lines []string
+
+ if f.isCurrentUTF8 {
+ lines = f.SplitText(textStr, width)
+ } else {
+ for _, line := range f.SplitLines([]byte(textStr), width) {
+ lines = append(lines, string(line))
+ }
+ }
for _, lineBt := range lines {
lineStr := string(lineBt)
@@ -2796,7 +2914,9 @@ func (f *Fpdf) WriteAligned(width, lineHeight float64, textStr, alignStr string)
f.Write(lineHeight, lineStr)
f.SetLeftMargin(lMargin)
default:
+ f.SetRightMargin(pageWidth - lMargin - width)
f.Write(lineHeight, lineStr)
+ f.SetRightMargin(rMargin)
}
}
}
@@ -3084,6 +3204,88 @@ func (f *Fpdf) GetImageInfo(imageStr string) (info *ImageInfoType) {
return f.images[imageStr]
}
+// ImportObjects imports objects from gofpdi into current document
+func (f *Fpdf) ImportObjects(objs map[string][]byte) {
+ for k, v := range objs {
+ f.importedObjs[k] = v
+ }
+}
+
+// ImportObjPos imports object hash positions from gofpdi
+func (f *Fpdf) ImportObjPos(objPos map[string]map[int]string) {
+ for k, v := range objPos {
+ f.importedObjPos[k] = v
+ }
+}
+
+// putImportedTemplates writes the imported template objects to the PDF
+func (f *Fpdf) putImportedTemplates() {
+ nOffset := f.n + 1
+
+ // keep track of list of sha1 hashes (to be replaced with integers)
+ objsIDHash := make([]string, len(f.importedObjs))
+
+ // actual object data with new id
+ objsIDData := make([][]byte, len(f.importedObjs))
+
+ // Populate hash slice and data slice
+ i := 0
+ for k, v := range f.importedObjs {
+ objsIDHash[i] = k
+ objsIDData[i] = v
+
+ i++
+ }
+
+ // Populate a lookup table to get an object id from a hash
+ hashToObjID := make(map[string]int, len(f.importedObjs))
+ for i = 0; i < len(objsIDHash); i++ {
+ hashToObjID[objsIDHash[i]] = i + nOffset
+ }
+
+ // Now, replace hashes inside data with %040d object id
+ for i = 0; i < len(objsIDData); i++ {
+ // get hash
+ hash := objsIDHash[i]
+
+ for pos, h := range f.importedObjPos[hash] {
+ // Convert object id into a 40 character string padded with spaces
+ objIDPadded := fmt.Sprintf("%40s", fmt.Sprintf("%d", hashToObjID[h]))
+
+ // Convert objIDPadded into []byte
+ objIDBytes := []byte(objIDPadded)
+
+ // Replace sha1 hash with object id padded
+ for j := pos; j < pos+40; j++ {
+ objsIDData[i][j] = objIDBytes[j-pos]
+ }
+ }
+
+ // Save objsIDHash so that procset dictionary has the correct object ids
+ f.importedTplIDs[hash] = i + nOffset
+ }
+
+ // Now, put objects
+ for i = 0; i < len(objsIDData); i++ {
+ f.newobj()
+ f.out(string(objsIDData[i]))
+ }
+}
+
+// UseImportedTemplate uses imported template from gofpdi. It draws imported
+// PDF page onto page.
+func (f *Fpdf) UseImportedTemplate(tplName string, scaleX float64, scaleY float64, tX float64, tY float64) {
+ f.outf("q 0 J 1 w 0 j 0 G 0 g q %.4F 0 0 %.4F %.4F %.4F cm %s Do Q Q\n", scaleX*f.k, scaleY*f.k, tX*f.k, (tY+f.h)*f.k, tplName)
+}
+
+// ImportTemplates imports gofpdi template names into importedTplObjs for
+// inclusion in the procset dictionary
+func (f *Fpdf) ImportTemplates(tpls map[string]string) {
+ for tplName, tplID := range tpls {
+ f.importedTplObjs[tplName] = tplID
+ }
+}
+
// GetConversionRatio returns the conversion ratio based on the unit given when
// creating the PDF.
func (f *Fpdf) GetConversionRatio() float64 {
@@ -3356,15 +3558,29 @@ func blankCount(str string) (count int) {
return
}
+// SetUnderlineThickness accepts a multiplier for adjusting the text underline
+// thickness, defaulting to 1. See SetUnderlineThickness example.
+func (f *Fpdf) SetUnderlineThickness(thickness float64) {
+ f.userUnderlineThickness = thickness
+}
+
// Underline text
func (f *Fpdf) dounderline(x, y float64, txt string) string {
up := float64(f.currentFont.Up)
- ut := float64(f.currentFont.Ut)
+ ut := float64(f.currentFont.Ut) * f.userUnderlineThickness
w := f.GetStringWidth(txt) + f.ws*float64(blankCount(txt))
return sprintf("%.2f %.2f %.2f %.2f re f", x*f.k,
(f.h-(y-up/1000*f.fontSize))*f.k, w*f.k, -ut/1000*f.fontSizePt)
}
+func (f *Fpdf) dostrikeout(x, y float64, txt string) string {
+ up := float64(f.currentFont.Up)
+ ut := float64(f.currentFont.Ut)
+ w := f.GetStringWidth(txt) + f.ws*float64(blankCount(txt))
+ return sprintf("%.2f %.2f %.2f %.2f re f", x*f.k,
+ (f.h-(y+4*up/1000*f.fontSize))*f.k, w*f.k, -ut/1000*f.fontSizePt)
+}
+
func bufEqual(buf []byte, str string) bool {
return string(buf[0:len(str)]) == str
}
@@ -3939,8 +4155,6 @@ func (f *Fpdf) generateCIDFontMap(font *fontDefType, LastRune int) {
}
interval = true
cidArray[rangeID].put("interval", 1)
- ui := 0
- ui = ui + 1
} else {
if interval {
// new range
@@ -3990,8 +4204,8 @@ func (f *Fpdf) generateCIDFontMap(font *fontDefType, LastRune int) {
previousKey = key
}
nextKey = key + cws
- ui := ws.getIndex("interval")
- ui = ui + 1
+ // ui := ws.getIndex("interval")
+ // ui = ui + 1
if ws.getIndex("interval") >= 0 {
if cws > 3 {
isInterval = true
@@ -4028,6 +4242,7 @@ func implode(sep string, arr []int) string {
return s.String()
}
+// arrayCountValues counts the occurrences of each item in the $mp array.
func arrayCountValues(mp []int) map[int]int {
answer := make(map[int]int)
for _, v := range mp {
@@ -4056,11 +4271,31 @@ func (f *Fpdf) putimages() {
for key = range f.images {
keyList = append(keyList, key)
}
+
+ // Sort the keyList []string by the corresponding image's width.
if f.catalogSort {
sort.SliceStable(keyList, func(i, j int) bool { return f.images[keyList[i]].w < f.images[keyList[j]].w })
}
+
+ // Maintain a list of inserted image SHA-1 hashes, with their
+ // corresponding object ID number.
+ insertedImages := map[string]int{}
+
for _, key = range keyList {
- f.putimage(f.images[key])
+ image := f.images[key]
+
+ // Check if this image has already been inserted using it's SHA-1 hash.
+ insertedImageObjN, isFound := insertedImages[image.i]
+
+ // If found, skip inserting the image as a new object, and
+ // use the object ID from the insertedImages map.
+ // If not, insert the image into the PDF and store the object ID.
+ if isFound {
+ image.n = insertedImageObjN
+ } else {
+ f.putimage(image)
+ insertedImages[image.i] = image.n
+ }
}
}
@@ -4158,6 +4393,12 @@ func (f *Fpdf) putxobjectdict() {
}
}
}
+ {
+ for tplName, objID := range f.importedTplObjs {
+ // here replace obj id hash with n
+ f.outf("%s %d 0 R", tplName, f.importedTplIDs[objID])
+ }
+ }
}
func (f *Fpdf) putresourcedict() {
@@ -4273,6 +4514,7 @@ func (f *Fpdf) putresources() {
}
f.putimages()
f.putTemplates()
+ f.putImportedTemplates() // gofpdi
// Resource dictionary
f.offsets[2] = f.buffer.Len()
f.out("2 0 obj")
@@ -4299,7 +4541,9 @@ func (f *Fpdf) putresources() {
func (f *Fpdf) putinfo() {
var tm time.Time
- f.outf("/Producer %s", f.textstring("FPDF "+cnFpdfVersion))
+ if len(f.producer) > 0 {
+ f.outf("/Producer %s", f.textstring(f.producer))
+ }
if len(f.title) > 0 {
f.outf("/Title %s", f.textstring(f.title))
}
diff --git a/fpdf_test.go b/fpdf_test.go
index 6042fab..5035bd8 100644
--- a/fpdf_test.go
+++ b/fpdf_test.go
@@ -858,7 +858,37 @@ func ExampleFpdf_ImageOptions() {
// Successfully generated pdf/Fpdf_ImageOptions.pdf
}
-// This examples demonstrates Landscape mode with images.
+// ExampleFpdf_RegisterImageOptionsReader demonstrates how to load an image
+// from a io.Reader (in this case, a file) and register it with options.
+func ExampleFpdf_RegisterImageOptionsReader() {
+ var (
+ opt gofpdf.ImageOptions
+ pdfStr string
+ fl *os.File
+ err error
+ )
+
+ pdfStr = example.Filename("Fpdf_RegisterImageOptionsReader")
+ pdf := gofpdf.New("P", "mm", "A4", "")
+ pdf.AddPage()
+ pdf.SetFont("Arial", "", 11)
+ fl, err = os.Open(example.ImageFile("logo.png"))
+ if err == nil {
+ opt.ImageType = "png"
+ opt.AllowNegativePosition = true
+ _ = pdf.RegisterImageOptionsReader("logo", opt, fl)
+ fl.Close()
+ for x := -20.0; x <= 40.0; x += 5 {
+ pdf.ImageOptions("logo", x, x+30, 0, 0, false, opt, 0, "")
+ }
+ err = pdf.OutputFileAndClose(pdfStr)
+ }
+ example.Summary(err, pdfStr)
+ // Output:
+ // Successfully generated pdf/Fpdf_RegisterImageOptionsReader.pdf
+}
+
+// This example demonstrates Landscape mode with images.
func ExampleFpdf_SetAcceptPageBreakFunc() {
var y0 float64
var crrntCol int
@@ -918,7 +948,7 @@ func ExampleFpdf_SetAcceptPageBreakFunc() {
// Successfully generated pdf/Fpdf_SetAcceptPageBreakFunc_landscape.pdf
}
-// This examples tests corner cases as reported by the gocov tool.
+// This example tests corner cases as reported by the gocov tool.
func ExampleFpdf_SetKeywords() {
var err error
fileStr := example.Filename("Fpdf_SetKeywords")
@@ -2389,7 +2419,7 @@ func ExampleFpdf_SubWrite() {
// ExampleFpdf_SetPage demomstrates the SetPage() method, allowing content
// generation to be deferred until all pages have been added.
func ExampleFpdf_SetPage() {
- rnd := rand.New(rand.NewSource(0)) // Make reproducable documents
+ rnd := rand.New(rand.NewSource(0)) // Make reproducible documents
pdf := gofpdf.New("L", "cm", "A4", "")
pdf.SetFont("Times", "", 12)
@@ -2523,6 +2553,10 @@ func ExampleFpdf_TransformRotate() {
// ExampleFpdf_AddUTF8Font demonstrates how use the font
// with utf-8 mode
func ExampleFpdf_AddUTF8Font() {
+ var fileStr string
+ var txtStr []byte
+ var err error
+
pdf := gofpdf.New("P", "mm", "A4", "")
pdf.AddPage()
@@ -2532,23 +2566,167 @@ func ExampleFpdf_AddUTF8Font() {
pdf.AddUTF8Font("dejavu", "I", example.FontFile("DejaVuSansCondensed-Oblique.ttf"))
pdf.AddUTF8Font("dejavu", "BI", example.FontFile("DejaVuSansCondensed-BoldOblique.ttf"))
- txtStr, _ := ioutil.ReadFile(example.TextFile("utf-8test.txt"))
+ fileStr = example.Filename("Fpdf_AddUTF8Font")
+ txtStr, err = ioutil.ReadFile(example.TextFile("utf-8test.txt"))
+ if err == nil {
+
+ pdf.SetFont("dejavu", "B", 17)
+ pdf.MultiCell(100, 8, "Text in different languages :", "", "C", false)
+ pdf.SetFont("dejavu", "", 14)
+ pdf.MultiCell(100, 5, string(txtStr), "", "C", false)
+ pdf.Ln(15)
- pdf.SetFont("dejavu", "B", 17)
- pdf.MultiCell(100, 8, "Text in different languages :", "", "C", false)
- pdf.SetFont("dejavu", "", 14)
- pdf.MultiCell(100, 5, string(txtStr), "", "C", false)
- pdf.Ln(15)
+ txtStr, err = ioutil.ReadFile(example.TextFile("utf-8test2.txt"))
+ if err == nil {
- txtStr, _ = ioutil.ReadFile(example.TextFile("utf-8test2.txt"))
- pdf.SetFont("dejavu", "BI", 17)
- pdf.MultiCell(100, 8, "Greek text with alignStr = \"J\":", "", "C", false)
- pdf.SetFont("dejavu", "I", 14)
- pdf.MultiCell(100, 5, string(txtStr), "", "J", false)
+ pdf.SetFont("dejavu", "BI", 17)
+ pdf.MultiCell(100, 8, "Greek text with alignStr = \"J\":", "", "C", false)
+ pdf.SetFont("dejavu", "I", 14)
+ pdf.MultiCell(100, 5, string(txtStr), "", "J", false)
+ err = pdf.OutputFileAndClose(fileStr)
- fileStr := example.Filename("Fpdf_AddUTF8Font")
- err := pdf.OutputFileAndClose(fileStr)
+ }
+ }
example.Summary(err, fileStr)
// Output:
// Successfully generated pdf/Fpdf_AddUTF8Font.pdf
}
+
+// ExampleUTF8CutFont demonstrates how generate a TrueType font subset.
+func ExampleUTF8CutFont() {
+ var pdfFileStr, fullFontFileStr, subFontFileStr string
+ var subFont, fullFont []byte
+ var err error
+
+ pdfFileStr = example.Filename("Fpdf_UTF8CutFont")
+ fullFontFileStr = example.FontFile("calligra.ttf")
+ fullFont, err = ioutil.ReadFile(fullFontFileStr)
+ if err == nil {
+ subFontFileStr = "calligra_abcde.ttf"
+ subFont = gofpdf.UTF8CutFont(fullFont, "abcde")
+ err = ioutil.WriteFile(subFontFileStr, subFont, 0600)
+ if err == nil {
+ y := 24.0
+ pdf := gofpdf.New("P", "mm", "A4", "")
+ fontHt := 17.0
+ lineHt := pdf.PointConvert(fontHt)
+ write := func(format string, args ...interface{}) {
+ pdf.SetXY(24.0, y)
+ pdf.Cell(200.0, lineHt, fmt.Sprintf(format, args...))
+ y += lineHt
+ }
+ writeSize := func(fileStr string) {
+ var info os.FileInfo
+ var err error
+ info, err = os.Stat(fileStr)
+ if err == nil {
+ write("%6d: size of %s", info.Size(), fileStr)
+ }
+ }
+ pdf.AddPage()
+ pdf.AddUTF8Font("calligra", "", subFontFileStr)
+ pdf.SetFont("calligra", "", fontHt)
+ write("cabbed")
+ write("vwxyz")
+ pdf.SetFont("courier", "", fontHt)
+ writeSize(fullFontFileStr)
+ writeSize(subFontFileStr)
+ err = pdf.OutputFileAndClose(pdfFileStr)
+ os.Remove(subFontFileStr)
+ }
+ }
+ example.Summary(err, pdfFileStr)
+ // Output:
+ // Successfully generated pdf/Fpdf_UTF8CutFont.pdf
+}
+
+func ExampleFpdf_RoundedRect() {
+ const (
+ wd = 40.0
+ hgap = 10.0
+ radius = 10.0
+ ht = 60.0
+ vgap = 10.0
+ )
+ corner := func(b1, b2, b3, b4 bool) (cstr string) {
+ if b1 {
+ cstr = "1"
+ }
+ if b2 {
+ cstr += "2"
+ }
+ if b3 {
+ cstr += "3"
+ }
+ if b4 {
+ cstr += "4"
+ }
+ return
+ }
+ pdf := gofpdf.New("P", "mm", "A4", "") // 210 x 297
+ pdf.AddPage()
+ pdf.SetLineWidth(0.5)
+ y := vgap
+ r := 40
+ g := 30
+ b := 20
+ for row := 0; row < 4; row++ {
+ x := hgap
+ for col := 0; col < 4; col++ {
+ pdf.SetFillColor(r, g, b)
+ pdf.RoundedRect(x, y, wd, ht, radius, corner(row&1 == 1, row&2 == 2, col&1 == 1, col&2 == 2), "FD")
+ r += 8
+ g += 10
+ b += 12
+ x += wd + hgap
+ }
+ y += ht + vgap
+ }
+ fileStr := example.Filename("Fpdf_RoundedRect")
+ err := pdf.OutputFileAndClose(fileStr)
+ example.Summary(err, fileStr)
+ // Output:
+ // Successfully generated pdf/Fpdf_RoundedRect.pdf
+}
+
+// ExampleFpdf_SetUnderlineThickness demonstrates how to adjust the text
+// underline thickness.
+func ExampleFpdf_SetUnderlineThickness() {
+ pdf := gofpdf.New("P", "mm", "A4", "") // 210mm x 297mm
+ pdf.AddPage()
+ pdf.SetFont("Arial", "U", 12)
+
+ pdf.SetUnderlineThickness(0.5)
+ pdf.CellFormat(0, 10, "Thin underline", "", 1, "", false, 0, "")
+
+ pdf.SetUnderlineThickness(1)
+ pdf.CellFormat(0, 10, "Normal underline", "", 1, "", false, 0, "")
+
+ pdf.SetUnderlineThickness(2)
+ pdf.CellFormat(0, 10, "Thicker underline", "", 1, "", false, 0, "")
+
+ fileStr := example.Filename("Fpdf_UnderlineThickness")
+ err := pdf.OutputFileAndClose(fileStr)
+ example.Summary(err, fileStr)
+ // Output:
+ // Successfully generated pdf/Fpdf_UnderlineThickness.pdf
+}
+
+// ExampleFpdf_Cell_strikeout demonstrates striked-out text
+func ExampleFpdf_Cell_strikeout() {
+
+ pdf := gofpdf.New("P", "mm", "A4", "") // 210mm x 297mm
+ pdf.AddPage()
+
+ for fontSize := 4; fontSize < 40; fontSize += 10 {
+ pdf.SetFont("Arial", "S", float64(fontSize))
+ pdf.SetXY(0, float64(fontSize))
+ pdf.Cell(40, 10, "Hello World")
+ }
+
+ fileStr := example.Filename("Fpdf_Cell_strikeout")
+ err := pdf.OutputFileAndClose(fileStr)
+ example.Summary(err, fileStr)
+ // Output:
+ // Successfully generated pdf/Fpdf_Cell_strikeout.pdf
+}
diff --git a/go.mod b/go.mod
index c7a180d..dee309c 100644
--- a/go.mod
+++ b/go.mod
@@ -1 +1,12 @@
module github.com/jung-kurt/gofpdf
+
+go 1.12
+
+require (
+ github.com/boombuler/barcode v1.0.0
+ github.com/phpdave11/gofpdi v1.0.7
+ github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58
+ golang.org/x/image v0.0.0-20190902063713-cb417be4ba39
+)
+
+replace gofpdf => ./
diff --git a/image/signature.svg b/image/signature.svg
index cdbb4af..956c3c6 100644
--- a/image/signature.svg
+++ b/image/signature.svg
@@ -1,43 +1,73 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="4010" height="570">
+<svg xmlns="http://www.w3.org/2000/svg" height="1106" width="3990">
<path
- d="m 243.83517,126.31141 c 50.21866,26.50627 126.75595,-3.87395 151.46369,-35.94162 24.70774,-32.067668 10.41159,-51.980992 -16.41089,-58.072772 -26.82248,-6.09178 -42.17661,10.494756 -57.68933,33.13636 -15.51272,22.641602 -22.3395,49.640452 -26.04984,89.319922 -3.71034,39.67947 -2.57151,103.67609 -16.65175,144.69433 -14.08024,41.01824 -40.79012,59.98014 -80.0876,71.50199 -39.29748,11.52185 -96.60749,6.67866 -126.372403,-24.20296 -29.764916,-30.88162 -24.693439,-84.55794 0.62001,-107.05538 25.313453,-22.49744 49.916583,-21.8463 53.386943,18.74456 3.47036,40.59086 -77.347631,106.99944 -102.157291,102.59574 -24.80966,-4.4037 -9.193082,0 -13.789623,0" />
+ d="m 234.43804,111.69821 c 50.21866,26.50627 126.75595,-3.87395 151.46369,-35.941621 24.70774,-32.067668 10.41159,-51.980992 -16.41089,-58.072772 -26.82248,-6.09178 -42.17661,10.494756 -57.68933,33.13636 -15.51272,22.641602 -22.3395,49.640453 -26.04984,89.319923 -3.71034,39.67947 -2.57151,103.67609 -16.65175,144.69433 -14.08024,41.01824 -40.79012,59.98014 -80.0876,71.50199 -39.29748,11.52185 -96.607494,6.67866 -126.372407,-24.20296 -29.764916,-30.88162 -24.693439,-84.55794 0.62001,-107.05538 25.313453,-22.49744 49.916587,-21.8463 53.386947,18.74456 3.47036,40.59086 -77.347635,106.99944 -102.157295,102.59574 -24.80966,-4.4037 -9.1930819,0 -13.78962288,0" />
<path
- d="m 544.84659,276.92526 c 16.02735,-13.54645 29.98118,-31.39768 32.51139,-52.84016 1.4974,-10.24434 -1.94415,-22.06454 -11.64632,-27.13714 -22.66026,-14.31032 -51.37591,-9.68663 -75.27088,-1.12303 -29.57925,11.19994 -56.66841,28.48168 -80.87983,48.69857 -15.56749,13.48245 -30.31327,28.65126 -40.17476,46.87113 -10.56334,25.04076 5.93271,58.80187 33.76392,62.35287 20.97698,3.69753 41.31134,-5.15667 59.15595,-15.26739 23.68053,-12.07041 45.37059,-27.68722 65.11773,-45.42392 5.85816,-4.99109 11.66007,-10.04795 17.4228,-15.14884" />
+ d="m 535.44946,262.31206 c 16.02735,-13.54645 29.98118,-31.39768 32.51139,-52.84016 1.4974,-10.24434 -1.94415,-22.06454 -11.64632,-27.13714 -22.66026,-14.31032 -51.37591,-9.68663 -75.27088,-1.12303 -29.57925,11.19994 -56.66841,28.48168 -80.87983,48.69857 -15.56749,13.48245 -30.31327,28.65126 -40.17476,46.87113 -10.56334,25.04076 5.93271,58.80187 33.76392,62.35287 20.97698,3.69753 41.31134,-5.15667 59.15595,-15.26739 23.68053,-12.07041 45.37059,-27.68722 65.11773,-45.42392 5.85816,-4.99109 11.66007,-10.04795 17.4228,-15.14884" />
<path
- d="m 614.57518,235.67736 c -39.71057,22.89155 -90.21146,57.33437 -110.62013,81.46882 -20.40867,24.13445 1.74636,32.16167 21.51346,33.96557 19.7671,1.8039 40.22731,-5.81242 63.90833,-18.83825 23.68102,-13.02583 54.88215,-39.05314 73.09016,-60.24005 18.20801,-21.18691 37.84165,-41.69088 43.78312,-57.46575 5.94147,-15.77487 6.81292,-20.38898 -2.3045,-26.03079" />
+ d="m 605.17805,221.06416 c -39.71057,22.89155 -90.21146,57.33437 -110.62013,81.46882 -20.40867,24.13445 1.74636,32.16167 21.51346,33.96557 19.7671,1.8039 40.22731,-5.81242 63.90833,-18.83825 23.68102,-13.02583 54.88215,-39.05314 73.09016,-60.24005 18.20801,-21.18691 37.84165,-41.69088 43.78312,-57.46575 5.94147,-15.77487 6.81292,-20.38898 -2.3045,-26.03079" />
<path
- d="m 586.09449,351.56431 c 59.46452,-49.53559 110.50457,-110.94455 181.15663,-145.53797 21.55772,-14.53068 69.21456,-30.38164 74.52476,8.12435 2.15457,32.87115 -24.99905,56.36851 -41.3729,81.85669 -11.33394,14.91071 -34.85688,47.22341 -38.29416,51.12061 38.40925,-59.07476 94.0006,-105.23813 152.94098,-142.74425 21.53324,-14.17578 76.3474,-17.732 63.14039,22.44093 -6.44013,30.30909 -29.58192,52.20309 -51.31162,72.13403 -22.35245,20.18703 -11.93986,55.81184 21.21245,48.89199 28.04358,-1.72994 49.86098,-21.80465 73.62848,-34.51546 51.0484,-39.90132 89.3284,-97.12351 150.3008,-123.60116 30.7216,-12.02494 70.5868,-23.14241 98.2954,1.38478 22.9075,21.32517 9.8573,56.2678 -7.0675,76.93906 -18.1931,26.99594 -44.6741,46.96256 -74.8471,58.94304 -34.0583,20.33195 -79.3725,18.48794 -110.8061,-6.03301 -1.0838,-0.69666 -2.2533,-1.23366 -3.4004,-1.81269" />
+ d="m 576.69736,336.95111 c 59.46452,-49.53559 110.50457,-110.94455 181.15663,-145.53797 21.55772,-14.53068 69.21456,-30.38164 74.52476,8.12435 2.15457,32.87115 -24.99905,56.36851 -41.3729,81.85669 -11.33394,14.91071 -34.85688,47.22341 -38.29416,51.12061 38.40925,-59.07476 94.0006,-105.23813 152.94098,-142.74425 21.53324,-14.17578 76.3474,-17.732 63.14039,22.44093 -6.44013,30.30909 -29.58192,52.20309 -51.31162,72.13403 -22.35245,20.18703 -11.93986,55.81184 21.21245,48.89199 28.04358,-1.72994 49.86098,-21.80465 73.62851,-34.51546 51.0484,-39.90132 89.3284,-97.12351 150.3008,-123.60116 30.7216,-12.02494 70.5868,-23.14241 98.2954,1.38478 22.9075,21.32517 9.8573,56.2678 -7.0675,76.93906 -18.1931,26.99594 -44.6741,46.96256 -74.8471,58.94304 -34.0583,20.33195 -79.3725,18.48794 -110.8061,-6.03301 -1.0838,-0.69666 -2.2533,-1.23366 -3.4004,-1.81269" />
<path
- d="m 1154.6667,159.26245 c -19.2615,48.72397 -39.2763,98.0821 -71.8076,139.71403 -28.4578,44.00142 -46.4445,94.33551 -79.7245,135.30113 -23.78316,32.93768 -48.80204,65.54924 -80.01549,91.86673 -19.47895,6.1922 -20.04137,-20.7923 -14.66105,-32.91267 12.83153,-36.25521 37.22095,-66.57625 54.90924,-100.3885 22.07476,-38.69659 54.0525,-69.56182 85.7438,-100.24739" />
+ d="m 1145.2696,144.64925 c -19.2615,48.72397 -39.2763,98.0821 -71.8076,139.71403 -28.4578,44.00142 -46.4445,94.33551 -79.72453,135.30113 -23.78316,32.93768 -48.80204,65.54924 -80.01549,91.86673 -19.47895,6.1922 -20.04137,-20.7923 -14.66105,-32.91267 12.83153,-36.25521 37.22095,-66.57625 54.90924,-100.3885 22.07476,-38.69659 54.05253,-69.56182 85.74383,-100.24739" />
<path
- d="m 1076.8889,323.15134 c 41.6055,37.74324 106.1656,40.87499 155.2476,16.47425 79.7307,-33.80513 147.627,-88.69981 215.7912,-140.91414 38.5692,-31.19936 75.8068,-66.58379 98.2999,-111.44269 5.2858,-16.340836 11.2358,-38.191353 -2.3042,-51.988823 -24.8579,-9.392422 -44.7459,19.21292 -62.7133,32.466761 -42.206,41.159272 -75.9104,90.348772 -105.7076,140.969902 -18.1332,33.9424 -36.3441,60.40033 -45.1009,105.84746 -4.8684,25.26636 17.3519,40.01019 38.489,36.24378 27.2382,-1.27906 52.1821,-14.06224 77.2642,-23.5167 20.2617,-9.77194 38.052,-23.75443 55.7341,-37.47313" />
+ d="m 1067.4918,308.53814 c 41.6055,37.74324 106.1656,40.87499 155.2476,16.47425 79.7307,-33.80513 147.627,-88.69981 215.7912,-140.91414 38.5692,-31.19936 75.8068,-66.58379 98.2999,-111.442691 5.2858,-16.340836 11.2358,-38.191353 -2.3042,-51.988823 -24.8579,-9.392422 -44.7459,19.21292 -62.7133,32.466761 -42.206,41.159272 -75.9104,90.348773 -105.7076,140.969903 -18.1332,33.9424 -36.3441,60.40033 -45.1009,105.84746 -4.8684,25.26636 17.3519,40.01019 38.489,36.24378 27.2382,-1.27906 52.1821,-14.06224 77.2642,-23.5167 20.2617,-9.77194 38.052,-23.75443 55.7341,-37.47313" />
<path
- d="m 1518.5556,231.48467 c 45.3671,35.48031 84.7434,37.23796 135.7328,25.17331 14.925,-4.86754 25.7515,-17.97315 30.1445,-32.73996 6.2047,-12.9545 -0.2899,-27.91555 -12.929,-33.8982 -19.5006,-12.36806 -44.6888,-10.55607 -64.9092,-0.92535 -33.4028,14.45512 -59.4353,40.93033 -84.563,66.45243 -13.9248,16.55902 -22.671,38.06079 -22.9956,59.74639 0.7543,12.73146 10.7427,22.65661 22.5942,25.94215 28.6381,11.95988 61.6748,18.05546 91.8527,8.36881 20.1474,-7.27059 39.868,-15.91987 58.8894,-25.73255 22.7573,-13.36221 41.3454,-32.41648 60.072,-50.72036" />
+ d="m 1509.1585,216.87147 c 45.3671,35.48031 84.7434,37.23796 135.7328,25.17331 14.925,-4.86754 25.7515,-17.97315 30.1445,-32.73996 6.2047,-12.9545 -0.2899,-27.91555 -12.929,-33.8982 -19.5006,-12.36806 -44.6888,-10.55607 -64.9092,-0.92535 -33.4028,14.45512 -59.4353,40.93033 -84.563,66.45243 -13.9248,16.55902 -22.671,38.06079 -22.9956,59.74639 0.7543,12.73146 10.7427,22.65661 22.5942,25.94215 28.6381,11.95988 61.6748,18.05546 91.8527,8.36881 20.1474,-7.27059 39.868,-15.91987 58.8894,-25.73255 22.7573,-13.36221 41.3454,-32.41648 60.072,-50.72036" />
<path
- d="m 1789.3889,357.87356 c 28.6993,3.03127 63.3496,2.62457 82.7159,-22.45172 21.6447,-19.99229 43.1941,-48.10952 35.6329,-79.45221 -4.1368,-22.17497 -33.5802,-38.22486 -52.1616,-22.03003 -31.7488,22.47063 -31.372,70.25063 -12.8813,101.12391 23.6727,38.55114 74.0602,50.51158 116.164,41.35476 54.0203,-10.31179 104.4208,-53.87389 110.9357,-110.27278 0.7888,-32.83995 0.7757,-65.72269 4.9445,-98.36663 3.9298,-42.7466 9.9471,-89.084404 39.2166,-122.675001 17.104,-18.491716 51.2258,-26.923352 69.4545,-5.555968 14.6931,19.194858 3.0296,45.294939 -10.7419,61.486039 -16.3416,25.1385 -48.7197,29.13643 -75.3811,36.23743 -26.4792,5.77658 -58.6276,2.75073 -76.1034,-20.51069 -9.6512,-10.71312 -20.4603,-22.76827 -20.6837,-38.053992" />
+ d="m 1779.9918,343.26036 c 28.6993,3.03127 63.3496,2.62457 82.7159,-22.45172 21.6447,-19.99229 43.1941,-48.10952 35.6329,-79.45221 -4.1368,-22.17497 -33.5802,-38.22486 -52.1616,-22.03003 -31.7488,22.47063 -31.372,70.25063 -12.8813,101.12391 23.6727,38.55114 74.0602,50.51158 116.164,41.35476 54.0203,-10.31179 104.4208,-53.87389 110.9357,-110.27278 0.7888,-32.83995 0.7757,-65.72269 4.9445,-98.36663 3.9298,-42.7466 9.9471,-89.084405 39.2166,-122.675002 17.104,-18.491716 51.2258,-26.9233518 69.4545,-5.555968 14.6931,19.194858 3.0296,45.294939 -10.7419,61.486039 -16.3416,25.138501 -48.7197,29.136431 -75.3811,36.237431 -26.4792,5.77658 -58.6276,2.75073 -76.1034,-20.51069 -9.6512,-10.713121 -20.4603,-22.768271 -20.6837,-38.053993" />
<path
- d="m 2254.6667,137.04023 c -3.9166,0.81691 -6.5582,5.39919 -5.219,9.18763 1.2777,3.63173 4.3682,6.64885 8.1357,7.58096 2.108,0.12035 4.1149,-1.67454 4.2375,-3.78089 0.7885,-3.73488 0.2701,-7.91813 -2.1144,-10.99661 -1.2461,-1.37634 -3.1464,-2.37225 -5.0398,-1.99109" />
+ d="m 2245.2696,122.42703 c -3.9166,0.81691 -6.5582,5.39919 -5.219,9.18763 1.2777,3.63173 4.3682,6.64885 8.1357,7.58096 2.108,0.12035 4.1149,-1.67454 4.2375,-3.78089 0.7885,-3.73488 0.2701,-7.91813 -2.1144,-10.99661 -1.2461,-1.37634 -3.1464,-2.37225 -5.0398,-1.99109" />
<path
- d="m 2228.9722,184.9569 c -29.9457,39.95653 -58.8628,80.7409 -86.118,122.56461 -5.4378,11.43956 -6.9218,27.24913 2.6137,36.94004 11.5344,8.50012 26.6093,3.95387 39.1614,0.62975 31.967,-8.46295 63.2786,-21.86206 88.264,-43.97857 15.2095,-12.48824 29.1196,-26.55137 41.4956,-41.85028" />
+ d="m 2219.5751,170.3437 c -29.9457,39.95653 -58.8628,80.7409 -86.118,122.56461 -5.4378,11.43956 -6.9218,27.24913 2.6137,36.94004 11.5344,8.50012 26.6093,3.95387 39.1614,0.62975 31.967,-8.46295 63.2786,-21.86206 88.264,-43.97857 15.2095,-12.48824 29.1196,-26.55137 41.4956,-41.85028" />
<path
- d="m 2496.7771,218.06883 c -3.3292,-19.2489 -24.4513,-30.55681 -42.8081,-28.63327 -39.0192,-1.47124 -74.6768,18.22839 -106.1126,39.27122 -27.4601,19.28281 -52.9628,45.12902 -62.0025,78.30592 -2.9108,24.00347 18.676,49.02117 43.417,46.57579 41.4005,-0.49369 78.4941,-23.55071 108.3115,-50.5202 26.5153,-22.3804 52.8121,-49.50782 59.1947,-84.99946" />
+ d="m 2487.38,203.45563 c -3.3292,-19.2489 -24.4513,-30.55681 -42.8081,-28.63327 -39.0192,-1.47124 -74.6768,18.22839 -106.1126,39.27122 -27.4601,19.28281 -52.9628,45.12902 -62.0025,78.30592 -2.9108,24.00347 18.676,49.02117 43.417,46.57579 41.4005,-0.49369 78.4941,-23.55071 108.3115,-50.5202 26.5153,-22.3804 52.8121,-49.50782 59.1947,-84.99946" />
<path
- d="m 2524.8056,241.2069 c -48.3542,24.84206 -95.4271,57.89871 -121.9801,106.67545 -38.548,57.86235 -85.0736,109.83278 -130.7587,162.02483 -14.3416,13.79585 -31.8449,28.78802 -52.8206,28.38924 -22.4201,-5.81296 -20.145,-35.44311 -3.7589,-46.92382 18.3472,-20.65863 39.7594,-38.46949 61.3752,-55.55681 37.3089,-27.01631 74.2659,-55.34905 116.5753,-74.2272 45.8819,-21.27356 92.5741,-41.44894 133.4511,-71.77058" />
+ d="m 2515.4085,226.5937 c -48.3542,24.84206 -95.4271,57.89871 -121.9801,106.67545 -38.548,57.86235 -85.0736,109.83278 -130.7587,162.02483 -14.3416,13.79585 -31.8449,28.78802 -52.8206,28.38924 -22.4201,-5.81296 -20.145,-35.44311 -3.7589,-46.92382 18.3472,-20.65863 39.7594,-38.46949 61.3752,-55.55681 37.3089,-27.01631 74.2659,-55.34905 116.5753,-74.2272 45.8819,-21.27356 92.5741,-41.44894 133.4511,-71.77058" />
<path
- d="m 2571.3333,191.2069 c -11.728,39.55572 -31.7885,76.05727 -54.1537,110.51619 -11.367,17.27415 -23.5479,34.0347 -36.8185,49.90047" />
+ d="m 2561.9362,176.5937 c -11.728,39.55572 -31.7885,76.05727 -54.1537,110.51619 -11.367,17.27415 -23.5479,34.0347 -36.8185,49.90047" />
<path
- d="m 2481.0556,349.54023 c 39.4203,-54.93792 84.2673,-108.82208 144.2119,-142.13528 20.4555,-10.53089 43.6781,-13.18946 66.1233,-16.24748 15.4075,-2.13385 35.1588,8.90133 33.4692,26.24623 -2.9508,16.37726 -14.16,29.73489 -22.9962,43.3486 -13.3021,19.00229 -30.5436,36.66009 -36.611,59.58253 -4.3581,18.38699 14.1449,34.91044 31.9547,29.10574 16.8023,-4.83584 31.073,-15.60156 46.3125,-23.86514 23.356,-14.17855 45.5509,-30.69352 63.9244,-51.0352" />
+ d="m 2471.6585,334.92703 c 39.4203,-54.93792 84.2673,-108.82208 144.2119,-142.13528 20.4555,-10.53089 43.6781,-13.18946 66.1233,-16.24748 15.4075,-2.13385 35.1588,8.90133 33.4692,26.24623 -2.9508,16.37726 -14.16,29.73489 -22.9962,43.3486 -13.3021,19.00229 -30.5436,36.66009 -36.611,59.58253 -4.3581,18.38699 14.1449,34.91044 31.9547,29.10574 16.8023,-4.83584 31.073,-15.60156 46.3125,-23.86514 23.356,-14.17855 45.5509,-30.69352 63.9244,-51.0352" />
<path
- d="m 2954.6667,291.2069 c 22.3825,-18.04222 43.6601,-40.96167 49.1836,-70.14766 1.6596,-16.7076 -14.1662,-31.70685 -30.5059,-31.31677 -38.4972,-6.9588 -76.9683,9.1156 -108.0208,30.84253 -27.6063,19.08076 -55.1974,41.48489 -69.2262,72.82154 -7.1903,18.94072 -2.0574,44.40278 17.325,53.92146 22.3966,12.66022 50.5757,7.55107 71.8376,-5.02642 25.3952,-13.7463 46.7256,-33.50699 69.4067,-51.09468" />
+ d="m 2945.2696,276.5937 c 22.3825,-18.04222 43.6601,-40.96167 49.1836,-70.14766 1.6596,-16.7076 -14.1662,-31.70685 -30.5059,-31.31677 -38.4972,-6.9588 -76.9683,9.1156 -108.0208,30.84253 -27.6063,19.08076 -55.1974,41.48489 -69.2262,72.82154 -7.1903,18.94072 -2.0574,44.40278 17.325,53.92146 22.3966,12.66022 50.5757,7.55107 71.8376,-5.02642 25.3952,-13.7463 46.7256,-33.50699 69.4067,-51.09468" />
<path
- d="m 3041.4722,235.65134 c -34.9663,24.39777 -159.9904,94.46573 -91.1404,111.19476 49.5078,12.02932 120.689,-54.55505 178.2367,-101.75128 57.5477,-47.19623 164.1423,-136.34884 176.2724,-205.706174 12.1301,-69.357335 -35.8274,25.038279 -57.6617,62.402284 -21.8343,37.36401 -53.1817,114.5822 -93.4244,175.68115 -55.9422,84.93494 14.2268,97.70016 78.695,54.07139 43.4593,-29.41104 56.0463,-39.23804 79.8558,-64.64213" />
+ d="m 3032.0751,221.03814 c -34.9663,24.39777 -159.9904,94.46573 -91.1404,111.19476 49.5078,12.02932 120.689,-54.55505 178.2367,-101.75128 57.5477,-47.19623 164.1423,-136.348841 176.2724,-205.706175 12.1301,-69.357335 -35.8274,25.038279 -57.6617,62.402284 -21.8343,37.364011 -53.1817,114.582201 -93.4244,175.681151 -55.9422,84.93494 14.2268,97.70016 78.695,54.07139 43.4593,-29.41104 56.0463,-39.23804 79.8558,-64.64213" />
<path
- d="m 3128.9722,178.01245 c 51.3284,2.8018 102.806,4.27265 154.1667,1.38889" />
+ d="m 3119.5751,163.39925 c 51.3284,2.8018 102.806,4.27265 154.1667,1.38889" />
<path
- d="m 3368.5556,180.79023 c -26.0554,38.94967 -53.443,76.90675 -75.3826,118.80876 -8.2374,15.73252 -12.8945,40.55439 6.2938,47.64921 25.3545,6.43589 34.5616,-2.95338 49.294,-7.34667 48.0292,-19.31164 87.8533,-54.50776 122.854,-93.37814 15.42,-20.923 30.5124,-42.09003 46.9408,-62.26134" />
+ d="m 3359.1585,166.17703 c -26.0554,38.94967 -53.443,76.90675 -75.3826,118.80876 -8.2374,15.73252 -12.8945,40.55439 6.2938,47.64921 25.3545,6.43589 34.5616,-2.95338 49.294,-7.34667 48.0292,-19.31164 87.8533,-54.50776 122.854,-93.37814 15.42,-20.923 30.5124,-42.09003 46.9408,-62.26134" />
<path
- d="m 3520.6389,183.56801 c -31.3786,34.96488 -59.3857,72.92099 -84.9995,112.24284 -6.288,13.61689 -16.1644,29.28735 -9.8599,44.58789 7.0942,13.41865 25.2642,10.69636 37.6171,7.93765 31.8778,-9.70921 58.1068,-31.49347 83.8755,-51.77583 20.5616,-16.72078 38.3203,-36.60992 53.5974,-58.18739 14.5478,-17.73424 29.2159,-35.93086 39.6787,-56.3568 4.934,-18.95097 -28.1547,-19.20088 -17.7187,-0.12487 9.5405,17.82935 32.3392,18.53167 50.1021,19.48194 16.3122,-3.37266 23.3898,15.5346 12.9603,26.5127 -6.8718,8.02389 -13.7478,15.769 -19.1588,24.9829 -16.8576,24.69747 -36.847,48.68268 -44.6449,78.10881 -3.0723,19.33042 19.5849,33.62972 36.7818,27.38476 35.6706,-8.34057 67.9833,-26.49985 99.2689,-44.93349" />
+ d="m 3511.2418,168.95481 c -31.3786,34.96488 -59.3857,72.92099 -84.9995,112.24284 -6.288,13.61689 -16.1644,29.28735 -9.8599,44.58789 7.0942,13.41865 25.2642,10.69636 37.6171,7.93765 31.8778,-9.70921 58.1068,-31.49347 83.8755,-51.77583 20.5616,-16.72078 38.3203,-36.60992 53.5974,-58.18739 14.5478,-17.73424 29.2159,-35.93086 39.6787,-56.3568 4.934,-18.95097 -28.1547,-19.20088 -17.7187,-0.12487 9.5405,17.82935 32.3392,18.53167 50.1021,19.48194 16.3122,-3.37266 23.3898,15.5346 12.9603,26.5127 -6.8718,8.02389 -13.7478,15.769 -19.1588,24.9829 -16.8576,24.69747 -36.847,48.68268 -44.6449,78.10881 -3.0723,19.33042 19.5849,33.62972 36.7818,27.38476 35.6706,-8.34057 67.9833,-26.49985 99.2689,-44.93349" />
<path
- d="m 3772.7222,231.48467 c 33.1817,22.33062 74.828,35.62344 114.8149,27.5851 15.6821,-3.20582 30.2525,-10.71137 43.1524,-19.942 17.3248,-14.2012 16.9209,-44.79145 -2.1675,-57.28603 -13.4925,-8.89012 -30.6833,-5.87659 -45.6599,-3.46265 -33.5763,7.00049 -61.9142,28.29846 -85.8989,51.8761 -25.4017,22.73023 -42.112,57.70516 -36.9155,92.17467 6.3894,18.1743 25.3211,28.36102 43.6991,29.78005 26.397,2.30348 52.8197,-3.96515 77.6246,-12.547 39.816,-14.49663 75.2011,-38.73414 108.0175,-65.12268" />
+ d="m 3763.3251,216.87147 c 33.1817,22.33062 74.828,35.62344 114.8149,27.5851 15.6821,-3.20582 30.2525,-10.71137 43.1524,-19.942 17.3248,-14.2012 16.9209,-44.79145 -2.1675,-57.28603 -13.4925,-8.89012 -30.6833,-5.87659 -45.6599,-3.46265 -33.5763,7.00049 -61.9142,28.29846 -85.8989,51.8761 -25.4017,22.73023 -42.112,57.70516 -36.9155,92.17467 6.3894,18.1743 25.3211,28.36102 43.6991,29.78005 26.397,2.30348 52.8197,-3.96515 77.6246,-12.547 39.816,-14.49663 75.2011,-38.73414 108.0175,-65.12268" />
+ <path
+ d="m 127.96633,989.9893 q -30.652774,0 -60.833949,-8.48849 -29.709599,-8.96003 -49.515998,-23.57904 l 12.732685,-75.45295 h 2.829486 q 20.749561,15.09059 44.800188,23.57904 24.050628,8.48846 46.686518,8.48846 44.32861,0 44.32861,-32.0675 0,-12.26111 -6.60214,-20.27798 -6.13055,-8.48846 -22.1643,-15.56217 L 91.183006,824.46436 Q 57.700762,809.37377 39.309106,783.43682 21.38903,757.49987 21.38903,723.07446 q 0,-31.59592 14.619009,-54.70339 15.09059,-23.57904 41.970703,-36.31173 27.351698,-12.73268 63.663428,-12.73268 26.88012,0 53.28865,7.07371 26.40853,7.07372 42.91386,18.39166 l -12.2611,71.20872 h -2.82949 Q 208.13508,705.62597 187.8571,699.967 q -19.8064,-6.13056 -39.14121,-6.13056 -41.49913,0 -41.49913,28.29486 0,11.31794 6.60214,19.33482 7.07371,8.01687 22.1643,14.61901 l 42.44228,19.33482 q 40.55597,18.39165 58.47604,42.91386 17.92008,24.05063 17.92008,59.89078 0,33.95383 -16.03376,59.4192 -15.56217,24.99379 -43.85702,38.66963 -28.29486,13.67588 -66.96449,13.67588 z"/>
+ <path
+ d="m 355.73912,985.27346 q -33.95383,0 -53.76023,-18.86324 -19.8064,-18.86323 -19.8064,-50.45916 0,-66.96449 89.1288,-74.98136 l 58.00446,-5.18739 v -2.35791 q 0,-16.50533 -9.9032,-23.57905 -9.43162,-7.54529 -30.18118,-7.54529 -20.74956,0 -43.85703,5.18739 -23.10747,4.71581 -36.78331,12.73268 h -3.30107 l 12.2611,-66.96449 q 41.49913,-16.97691 87.71406,-16.97691 106.10571,0 106.10571,103.27622 v 73.56663 q 0,19.8064 2.82948,37.25489 3.30107,17.4485 8.48846,27.3517 v 3.77264 h -76.39611 q -7.07371,-16.03375 -8.48846,-35.36857 h -3.30106 q -8.96004,17.92008 -30.18118,28.76644 -21.22115,10.37478 -48.57284,10.37478 z m 6.13055,-76.86769 q 0,19.33482 23.10747,19.33482 19.8064,0 32.0675,-11.31795 12.26111,-11.31794 12.26111,-28.76643 v -5.65897 l -38.19806,3.30106 q -29.23802,2.82949 -29.23802,23.10747 z"/>
+ <path
+ d="M 565.59215,981.50081 V 741.9377 h 76.39611 v 41.9707 h 3.30107 q 8.48845,-22.63588 26.88011,-34.89699 18.86324,-12.73268 43.38544,-12.73268 51.40233,0 70.26556,44.32861 h 1.88633 q 10.84636,-22.16431 30.18118,-33.01067 19.33482,-11.31794 45.27177,-11.31794 41.49912,0 63.19184,27.35169 22.16431,26.88012 22.16431,75.92453 V 981.50081 H 863.6313 V 847.10025 q 0,-39.14122 -30.18118,-39.14122 -15.56217,0 -24.99379,11.78952 -8.96004,11.31795 -8.96004,30.65276 v 131.0995 H 714.61172 V 847.57183 q 0,-39.6128 -30.18118,-39.6128 -15.56217,0 -24.99379,11.78952 -8.96003,11.78953 -8.96003,32.53909 v 129.21317 z"/>
+ <path
+ d="M 1001.8042,1099.396 V 741.9377 h 80.6403 v 35.36857 h 3.7726 q 22.1643,-41.02754 70.2656,-41.02754 31.1243,0 54.2318,15.56217 23.1075,15.56217 35.8402,43.85703 12.7326,27.82327 12.7326,66.02133 0,37.72647 -12.7326,66.02133 -12.7327,28.29485 -35.8402,43.85702 -23.1075,15.56219 -54.2318,15.56219 -42.9139,0 -66.0213,-33.01068 h -3.7727 V 1099.396 Z m 125.9121,-183.91652 q 21.2211,0 33.4822,-14.14742 12.2611,-14.61901 12.2611,-39.14122 0,-25.46537 -12.2611,-39.6128 -11.7895,-14.61901 -33.4822,-14.61901 -20.7496,0 -33.0107,14.61901 -12.2611,14.14743 -12.2611,39.14122 0,24.52221 12.2611,39.14121 12.2611,14.61901 33.0107,14.61901 z"/>
+ <path
+ d="M 1302.2008,981.50081 V 613.66769 h 84.8846 v 367.83312 z"/>
+ <path
+ d="m 1557.797,987.1598 q -58.9477,0 -93.3731,-33.48226 -33.9538,-33.48225 -33.9538,-91.95828 0,-39.6128 16.0338,-67.43608 16.5053,-28.29485 44.8002,-42.91386 28.7664,-15.09059 65.0781,-15.09059 55.6466,0 84.413,33.01066 29.238,32.53909 29.238,92.90145 v 12.73268 l -153.7354,15.09059 q 5.659,16.97692 19.8064,24.05063 14.619,7.07371 35.8402,7.07371 24.0506,0 46.2149,-5.65897 22.6359,-6.13055 33.9539,-12.2611 h 3.301 l -12.2611,66.96449 q -14.1474,6.13055 -37.7265,11.31794 -23.579,5.65899 -47.6296,5.65899 z m -2.8295,-188.63239 q -15.5622,0 -26.8801,9.43162 -10.8464,9.43162 -14.619,32.0675 l 79.2256,-7.54529 q -3.3011,-17.92008 -13.2043,-25.93695 -9.9032,-8.01688 -24.5222,-8.01688 z"/>
+ <path
+ d="m 1912.4242,989.9893 q -30.6527,0 -60.8339,-8.48849 -29.7096,-8.96003 -49.516,-23.57904 l 12.7327,-75.45295 h 2.8295 q 20.7495,15.09059 44.8002,23.57904 24.0506,8.48846 46.6865,8.48846 44.3286,0 44.3286,-32.0675 0,-12.26111 -6.6022,-20.27798 -6.1305,-8.48846 -22.1643,-15.56217 l -49.0444,-22.16431 q -33.4822,-15.09059 -51.8739,-41.02754 -17.9201,-25.93695 -17.9201,-60.36236 0,-31.59592 14.6191,-54.70339 15.0905,-23.57904 41.9707,-36.31173 27.3517,-12.73268 63.6634,-12.73268 26.8801,0 53.2886,7.07371 26.4086,7.07372 42.9139,18.39166 l -12.2611,71.20872 h -2.8295 q -14.619,-10.37478 -34.897,-16.03375 -19.8064,-6.13056 -39.1412,-6.13056 -41.4991,0 -41.4991,28.29486 0,11.31794 6.6021,19.33482 7.0737,8.01687 22.1643,14.61901 l 42.4423,19.33482 q 40.556,18.39165 58.476,42.91386 17.9201,24.05063 17.9201,59.89078 0,33.95383 -16.0337,59.4192 -15.5622,24.99379 -43.8571,38.66963 -28.2948,13.67588 -66.9645,13.67588 z"/>
+ <path
+ d="m 2124.6348,714.11442 q -23.1075,0 -37.2549,-13.67584 -14.1474,-14.14743 -14.1474,-35.36857 0,-21.22114 14.1474,-34.89699 14.1474,-14.14743 37.2549,-14.14743 23.1075,0 37.2549,14.14743 14.1474,13.67585 14.1474,34.89699 0,21.22114 -14.1474,35.36857 -14.1474,13.67584 -37.2549,13.67584 z m -42.4423,267.38639 V 741.9377 h 84.8846 v 239.56311 z"/>
+ <path
+ d="m 2329.7719,1105.055 q -27.8233,0 -53.7602,-6.6021 -25.937,-6.1306 -41.9707,-16.5053 l 14.1474,-66.493 h 3.3011 q 13.2042,8.0169 30.6527,12.7327 17.9201,5.1874 34.897,5.1874 31.5959,0 48.5729,-17.4485 16.9769,-17.4485 16.9769,-49.98756 v -17.44849 h -3.7727 q -23.1074,33.01066 -66.0213,33.01066 -31.1243,0 -54.2318,-15.09059 -23.1075,-15.56217 -35.8402,-42.91386 -12.7326,-27.82328 -12.7326,-64.60659 0,-37.25489 12.7326,-64.60659 12.7327,-27.35169 35.8402,-42.44228 23.1075,-15.56217 54.2318,-15.56217 24.9938,0 44.8002,11.31794 19.8064,11.31794 29.238,30.65276 h 3.3011 q 0.9431,-10.37478 3.301,-20.27798 2.3579,-9.9032 5.1874,-16.03375 h 80.1688 v 3.77265 q -6.1306,11.31794 -8.9601,29.7096 -2.3579,18.39165 -2.3579,34.89699 v 154.67854 q 0,67.43612 -35.8401,103.74782 -35.3686,36.3117 -101.8615,36.3117 z m 11.7895,-194.29133 q 20.7496,0 33.0107,-14.14742 12.2611,-14.14743 12.2611,-37.72648 0,-23.57905 -12.2611,-37.72647 -12.2611,-14.14743 -33.0107,-14.14743 -21.6927,0 -33.9538,14.14743 -11.7895,13.67584 -11.7895,38.19805 0,23.57905 12.2611,37.72648 12.2611,13.67584 33.4822,13.67584 z"/>
+ <path
+ d="M 2523.1198,981.50081 V 741.9377 h 76.3961 v 41.9707 h 3.301 q 8.4885,-22.63588 27.8233,-34.89699 19.3348,-12.73268 46.6865,-12.73268 40.556,0 63.6635,27.35169 23.579,27.3517 23.579,75.92453 v 141.94586 h -84.8846 V 849.45815 q 0,-41.49912 -33.9538,-41.49912 -17.4485,0 -27.8233,12.2611 -9.9032,12.26111 -9.9032,33.95383 v 127.32685 z"/>
+ <path
+ d="m 2875.8613,985.27346 q -33.9538,0 -53.7602,-18.86324 -19.8064,-18.86323 -19.8064,-50.45916 0,-66.96449 89.1288,-74.98136 l 58.0044,-5.18739 v -2.35791 q 0,-16.50533 -9.9032,-23.57905 -9.4316,-7.54529 -30.1812,-7.54529 -20.7495,0 -43.857,5.18739 -23.1075,4.71581 -36.7833,12.73268 h -3.3011 l 12.2611,-66.96449 q 41.4991,-16.97691 87.7141,-16.97691 106.1057,0 106.1057,103.27622 v 73.56663 q 0,19.8064 2.8295,37.25489 3.301,17.4485 8.4884,27.3517 v 3.77264 h -76.3961 q -7.0737,-16.03375 -8.4884,-35.36857 h -3.3011 q -8.96,17.92008 -30.1812,28.76644 -21.2211,10.37478 -48.5728,10.37478 z m 6.1305,-76.86769 q 0,19.33482 23.1075,19.33482 19.8064,0 32.0675,-11.31795 12.2611,-11.31794 12.2611,-28.76643 v -5.65897 l -38.198,3.30106 q -29.2381,2.82949 -29.2381,23.10747 z"/>
+ <path
+ d="M 3060.7205,807.95903 V 741.9377 h 40.5559 v -67.90765 h 84.8846 v 67.90765 h 58.9476 l -10.8464,66.02133 H 3186.161 V 863.134 q 0,50.93074 44.8002,50.93074 h 14.1474 l -10.8464,68.85082 h -35.3685 q -45.7434,0 -71.6803,-26.88012 -25.937,-26.88011 -25.937,-74.98136 v -73.09505 z"/>
+ <path
+ d="m 3394.1277,987.1598 q -54.7034,0 -85.8278,-30.65278 -31.1243,-31.12434 -31.1243,-86.77089 V 741.9377 h 84.8846 v 129.68476 q 0,21.22114 8.4884,32.53908 8.4885,11.31794 23.5791,11.31794 15.0905,0 23.579,-11.31794 8.4885,-11.31794 8.4885,-32.53908 V 741.9377 h 84.8845 v 127.79843 q 0,55.64655 -31.1243,86.77089 -31.1244,30.65278 -85.8277,30.65278 z"/>
+ <path
+ d="M 3562.4816,981.50081 V 741.9377 h 76.3961 v 46.68651 h 3.3011 q 16.5053,-52.34548 65.0781,-52.34548 14.1475,0 23.1075,5.65897 v 83.94141 h -3.3011 q -12.7327,-5.18739 -27.8232,-5.18739 -24.9938,0 -38.6697,16.50533 -13.2042,16.50533 -13.2042,44.32861 v 99.97515 z"/>
+ <path
+ d="m 3877.0254,987.1598 q -58.9477,0 -93.3731,-33.48226 -33.9538,-33.48225 -33.9538,-91.95828 0,-39.6128 16.0338,-67.43608 16.5053,-28.29485 44.8001,-42.91386 28.7665,-15.09059 65.0782,-15.09059 55.6466,0 84.413,33.01066 29.238,32.53909 29.238,92.90145 v 12.73268 l -153.7354,15.09059 q 5.659,16.97692 19.8064,24.05063 14.619,7.07371 35.8402,7.07371 24.0506,0 46.2149,-5.65897 22.6359,-6.13055 33.9538,-12.2611 h 3.3011 l -12.2611,66.96449 q -14.1474,6.13055 -37.7265,11.31794 -23.579,5.65899 -47.6296,5.65899 z m -2.8295,-188.63239 q -15.5622,0 -26.8801,9.43162 -10.8464,9.43162 -14.6191,32.0675 l 79.2256,-7.54529 q -3.301,-17.92008 -13.2042,-25.93695 -9.9032,-8.01688 -24.5222,-8.01688 z"/>
</svg>
diff --git a/mkdoc b/mkdoc
deleted file mode 100755
index 8c082c3..0000000
--- a/mkdoc
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/bash
-
-# https://github.com/jimmyfrasche/autoreadme
-autoreadme -f -template README.md.template
-# Improve the appearance of the markdown document with features unavailable in godoc
-cat README.md | tr '\n' '\v' | sed \
- -e 's/\v##\([^\v]*\)/\v## \1\v\v/g' \
- -e 's/\v• /* /g' \
- -e 's/\(http:\/\/www\.google\.com\/fonts\/\)/[Google Fonts](\1)/g' \
- -e 's/\(http:\/\/dejavu-fonts\.org\/\)/[DejaVu Fonts](\1)/g' \
- -e 's/draw2d.package.(\(https:\/\/github\.com\/llgcode\/draw2d\))/[draw2d](\1) package/g' \
- -e 's/FPDF.library.(\(http:\/\/www\.fpdf\.org\/\))/[FPDF](\1) library/g' \
- -e 's/original.FPDF.library/original [FPDF](http:\/\/www.fpdf.org\/) library/g' \
- -e 's/\(Effective.Go\)/[\1](https:\/\/golang.org\/doc\/effective_go.html)/g' \
- -e 's/\(fpdf_test.go\)/[\1](https:\/\/github.com\/jung-kurt\/gofpdf\/blob\/master\/fpdf_test.go)/g' \
- -e 's/golint.(\(https:\/\/github\.com\/golang\/lint\))/[golint](\1)/g' \
- -e 's/go.vet.(\(https:\/\/godoc\.org\/golang\.org\/x\/tools\/cmd\/vet\))/[go vet](\1)/g' \
- -e 's/test.coverage.(\(https:\/\/blog\.golang\.org\/cover\))/[test coverage](\1)/g' \
- -e 's/Pull.requests.(\(https:\/\/help\.github\.com\/articles\/using\-pull\-requests\/\))/[Pull requests](\1)/g' \
- -e 's/Your change should\v/Your change should\v\v/g' \
- -e 's/issue 109/[issue 109](https:\/\/github.com\/jung-kurt\/gofpdf\/issues\/109)/g' \
- | tr '\v' '\n' > _0
-mv _0 README.md
diff --git a/pdf/reference/Fpdf_SVGBasicWrite.pdf b/pdf/reference/Fpdf_SVGBasicWrite.pdf
index bc05a2b..b6cc82a 100644
--- a/pdf/reference/Fpdf_SVGBasicWrite.pdf
+++ b/pdf/reference/Fpdf_SVGBasicWrite.pdf
@@ -7,335 +7,884 @@
/Contents 4 0 R>>
endobj
4 0 obj
-<</Length 13115>>
+<</Length 30276>>
stream
0 J
0 j
0.57 w
-BT /F0 16.00 Tf ET
+BT /Fd08375f64eb9861c6eae4dfcfdbd3500fbdbe33e 16.00 Tf ET
0.000 G
0.000 g
-BT 31.19 800.74 Td (This example renders a simple ) Tj ET
-q 0.000 0.000 0.502 rg BT 230.70 800.74 Td (SVG) Tj ET 230.70 799.14 32.00 -0.80 re f Q
-BT 262.70 800.74 Td ( \(scalable vector graphics\) image that contains) Tj ET
-BT 31.18 784.74 Td (only basic path commands without any styling, color fill, reflection or endpoint) Tj ET
-BT 31.18 768.74 Td (closures. In particular, the type of vector graphic returned from a ) Tj ET
-q 0.000 0.000 0.502 rg BT 450.17 768.74 Td (jSignature) Tj ET 450.17 767.14 65.78 -0.80 re f Q
-BT 515.95 768.74 Td ( web) Tj ET
-BT 31.18 752.74 Td (control is supported and is used in this example.) Tj ET
+BT /Fd08375f64eb9861c6eae4dfcfdbd3500fbdbe33e 16.00 Tf ET
+BT 31.19 800.74 Td (This example renders a simple )Tj ET
+BT /Fd08375f64eb9861c6eae4dfcfdbd3500fbdbe33e 16.00 Tf ET
+q 0.000 0.000 0.502 rg BT 230.70 800.74 Td (SVG)Tj ET 230.70 799.14 32.00 -0.80 re f Q
+BT /Fd08375f64eb9861c6eae4dfcfdbd3500fbdbe33e 16.00 Tf ET
+BT 262.70 800.74 Td ( \(scalable vector graphics\) image that contains)Tj ET
+BT 31.18 784.74 Td (only basic path commands without any styling, color fill, reflection or endpoint)Tj ET
+BT 31.18 768.74 Td (closures. In particular, the type of vector graphic returned from a )Tj ET
+BT /Fd08375f64eb9861c6eae4dfcfdbd3500fbdbe33e 16.00 Tf ET
+q 0.000 0.000 0.502 rg BT 450.17 768.74 Td (jSignature)Tj ET 450.17 767.14 65.78 -0.80 re f Q
+BT /Fd08375f64eb9861c6eae4dfcfdbd3500fbdbe33e 16.00 Tf ET
+BT 515.95 768.74 Td ( web)Tj ET
+BT 31.18 752.74 Td (control is supported and is used in this example.)Tj ET
1 J
0.71 w
0.000 0.000 0.502 RG
-173.14 728.26 m
-176.69201 726.39095 182.10238 728.53851 183.84896 730.80536 c S
-183.85 730.81 m
-185.59553 733.07220 184.58495 734.47986 182.68888 734.91049 c S
-182.69 734.91 m
-180.79282 735.34111 179.70744 734.16862 178.61086 732.56810 c S
-178.61 732.57 m
-177.51427 730.96757 177.03169 729.05904 176.76941 726.25412 c S
-176.77 726.25 m
-176.50713 723.44920 176.58763 718.92532 175.59231 716.02576 c S
-175.59 716.03 m
-174.59698 713.12621 172.70888 711.78580 169.93096 710.97133 c S
-169.93 710.97 m
-167.15304 710.15686 163.10183 710.49922 160.99777 712.68222 c S
-161.00 712.68 m
-158.89370 714.86523 159.25220 718.65958 161.04160 720.24991 c S
-161.04 720.25 m
-162.83099 721.84024 164.57017 721.79421 164.81549 718.92486 c S
-164.82 718.92 m
-165.06081 716.05552 159.34783 711.36114 157.59405 711.67243 c S
-157.59 711.67 m
-155.84027 711.98373 156.94420 711.67243 156.61927 711.67243 c S
-194.42 717.62 m
-195.55336 718.57545 196.53975 719.83734 196.71861 721.35310 c S
-196.72 721.35 m
-196.82446 722.07726 196.58118 722.91283 195.89534 723.27141 c S
-195.90 723.27 m
-194.29350 724.28299 192.26361 723.95615 190.57449 723.35079 c S
-190.57 723.35 m
-188.48355 722.55908 186.56863 721.33744 184.85714 719.90832 c S
-184.86 719.91 m
-183.75668 718.95525 182.71431 717.88298 182.01721 716.59503 c S
-182.02 716.60 m
-181.27049 714.82491 182.43659 712.43836 184.40396 712.18734 c S
-184.40 712.19 m
-185.88681 711.92596 187.32423 712.55186 188.58566 713.26658 c S
-188.59 713.27 m
-190.25962 714.11983 191.79288 715.22377 193.18879 716.47757 c S
-193.19 716.48 m
-193.60290 716.83039 194.01304 717.18786 194.42040 717.54843 c S
-199.35 720.53 m
-196.54236 718.91546 192.97248 716.48071 191.52980 714.77466 c S
-191.53 714.77 m
-190.08712 713.06861 191.65325 712.50117 193.05058 712.37366 c S
-193.05 712.37 m
-194.44790 712.24614 195.89422 712.78453 197.56822 713.70532 c S
-197.57 713.71 m
-199.24222 714.62611 201.44780 716.46597 202.73492 717.96366 c S
-202.73 717.96 m
-204.02203 719.46135 205.40992 720.91076 205.82992 722.02588 c S
-205.83 722.03 m
-206.24992 723.14099 206.31152 723.46716 205.66702 723.86598 c S
-197.34 712.34 m
-201.53970 715.84331 205.14769 720.18427 210.14205 722.62966 c S
-210.14 722.63 m
-211.66595 723.65683 215.03478 724.77732 215.41016 722.05536 c S
-215.41 722.06 m
-215.56246 719.73171 213.64299 718.07070 212.48553 716.26895 c S
-212.49 716.27 m
-211.68434 715.21492 210.02152 712.93076 209.77854 712.65527 c S
-209.78 712.66 m
-212.49367 716.83123 216.42339 720.09449 220.58985 722.74578 c S
-220.59 722.75 m
-222.11202 723.74785 225.98680 723.99924 225.05321 721.15944 c S
-225.05 721.16 m
-224.59796 719.01691 222.96208 717.46923 221.42602 716.06033 c S
-221.43 716.06 m
-219.84594 714.63332 220.58200 712.11502 222.92551 712.60418 c S
-222.93 712.60 m
-224.90790 712.72647 226.45016 714.14554 228.13027 715.04406 c S
-228.13 715.04 m
-231.73885 717.86466 234.44484 721.90966 238.75494 723.78135 c S
-238.75 723.78 m
-240.92664 724.63139 243.74468 725.41728 245.70339 723.68346 c S
-245.70 723.68 m
-247.32271 722.17600 246.40020 719.70592 245.20379 718.24469 c S
-245.20 718.24 m
-243.91773 716.33636 242.04581 714.92493 239.91289 714.07804 c S
-239.91 714.08 m
-237.50533 712.64078 234.30210 712.77113 232.08008 714.50451 c S
-232.08 714.50 m
-232.00346 714.55375 231.92079 714.59171 231.83970 714.63264 c S
-237.53 725.94 m
-236.16664 722.49110 234.75181 719.00201 232.45219 716.05907 c S
-232.45 716.06 m
-230.44053 712.94864 229.16906 709.39055 226.81651 706.49471 c S
-226.82 706.49 m
-225.13530 704.16637 223.36673 701.86107 221.16026 700.00071 c S
-221.16 700.00 m
-219.78331 699.56298 219.74355 701.47050 220.12388 702.32728 c S
-220.12 702.33 m
-221.03094 704.89014 222.75501 707.03352 224.00539 709.42369 c S
-224.01 709.42 m
-225.56584 712.15913 227.82633 714.34097 230.06657 716.51012 c S
-232.03 714.35 m
-234.97123 711.68212 239.53495 711.46073 243.00452 713.18561 c S
-243.00 713.19 m
-248.64064 715.57527 253.44019 719.45575 258.25868 723.14675 c S
-258.26 723.15 m
-260.98511 725.35221 263.61742 727.85352 265.20744 731.02457 c S
-265.21 731.02 m
-265.58109 732.17969 266.00169 733.72429 265.04456 734.69963 c S
-265.04 734.70 m
-263.28737 735.36357 261.88150 733.34147 260.61139 732.40457 c S
-260.61 732.40 m
-257.62787 729.49504 255.24533 726.01787 253.13898 722.43949 c S
-253.14 722.44 m
-251.85716 720.04012 250.56984 718.16982 249.95083 714.95719 c S
-249.95 714.96 m
-249.60668 713.17113 251.17742 712.12890 252.67159 712.39514 c S
-252.67 712.40 m
-254.59704 712.48556 256.36031 713.38919 258.13335 714.05752 c S
-258.13 714.06 m
-259.56564 714.74830 260.82323 715.73671 262.07316 716.70648 c S
-263.25 720.83 m
-266.45830 718.32194 269.24179 718.19770 272.84620 719.05054 c S
-272.85 719.05 m
-273.90124 719.39462 274.66655 720.32105 274.97709 721.36491 c S
-274.98 721.36 m
-275.41570 722.28065 274.95660 723.33824 274.06315 723.76115 c S
-274.06 723.76 m
-272.68466 724.63544 270.90412 724.50736 269.47476 723.82657 c S
-269.47 723.83 m
-267.11353 722.80474 265.27331 720.93322 263.49705 719.12908 c S
-263.50 719.13 m
-262.51271 717.95853 261.89445 716.43859 261.87150 714.90564 c S
-261.87 714.91 m
-261.92482 714.00566 262.63090 713.30406 263.46867 713.07181 c S
-263.47 713.07 m
-265.49308 712.22637 267.82843 711.79548 269.96169 712.48022 c S
-269.96 712.48 m
-271.38589 712.99418 272.77993 713.60559 274.12454 714.29924 c S
-274.12 714.30 m
-275.73324 715.24381 277.04723 716.59074 278.37100 717.88463 c S
-282.40 711.90 m
-284.42511 711.68139 286.87452 711.71014 288.24351 713.48277 c S
-288.24 713.48 m
-289.77356 714.89601 291.29688 716.88360 290.76238 719.09920 c S
-290.76 719.10 m
-290.46995 720.66673 288.38862 721.80129 287.07511 720.65649 c S
-287.08 720.66 m
-284.83080 719.06805 284.85744 715.69051 286.16454 713.50810 c S
-286.16 713.51 m
-287.83794 710.78294 291.39981 709.93746 294.37610 710.58475 c S
-294.38 710.58 m
-298.19476 711.31369 301.75755 714.39307 302.21808 718.37987 c S
-302.22 718.38 m
-302.27384 720.70131 302.27291 723.02577 302.56760 725.33335 c S
-302.57 725.33 m
-302.84540 728.35509 303.27076 731.63068 305.33980 734.00518 c S
-305.34 734.01 m
-306.54888 735.31235 308.96093 735.90837 310.24950 734.39793 c S
-310.25 734.40 m
-311.28815 733.04105 310.46366 731.19605 309.49016 730.05151 c S
-309.49 730.05 m
-308.33498 728.27449 306.04620 727.99188 304.16152 727.48991 c S
-304.16 727.49 m
-302.28972 727.08157 300.01717 727.29546 298.78181 728.93980 c S
-298.78 728.94 m
-298.09957 729.69710 297.33548 730.54928 297.31969 731.62981 c S
-315.29 727.51 m
-315.00973 727.44850 314.82299 727.12458 314.91766 726.85678 c S
-314.92 726.86 m
-315.00798 726.60006 315.22645 726.38678 315.49277 726.32089 c S
-315.49 726.32 m
-315.64178 726.31238 315.78365 726.43926 315.79232 726.58816 c S
-315.79 726.59 m
-315.84805 726.85217 315.81141 727.14788 315.64285 727.36550 c S
-315.64 727.37 m
-315.55476 727.46279 315.42043 727.53319 315.28659 727.50625 c S
-313.47 724.12 m
-311.35342 721.29454 309.30928 718.41152 307.38263 715.45503 c S
-307.38 715.46 m
-306.99823 714.64637 306.89333 713.52880 307.56739 712.84376 c S
-307.57 712.84 m
-308.38275 712.24289 309.44839 712.56426 310.33569 712.79924 c S
-310.34 712.80 m
-312.59541 713.39748 314.80881 714.34466 316.57502 715.90806 c S
-316.58 715.91 m
-317.65017 716.79085 318.63346 717.78496 319.50832 718.86643 c S
-332.40 721.78 m
-332.16589 723.13908 330.67278 723.93843 329.37515 723.80245 c S
-329.38 723.80 m
-326.61691 723.90645 324.09629 722.51390 321.87411 721.02639 c S
-321.87 721.03 m
-319.93298 719.66330 318.13021 717.83625 317.49119 715.49099 c S
-317.49 715.49 m
-317.28543 713.79420 318.81139 712.02572 320.56032 712.19858 c S
-320.56 712.20 m
-323.48689 712.23348 326.10902 713.86336 328.21679 715.76982 c S
-328.22 715.77 m
-330.09114 717.35188 331.95005 719.26950 332.40123 721.77838 c S
-334.38 720.14 m
-330.96442 718.38670 327.63686 716.04994 325.75985 712.60194 c S
-325.76 712.60 m
-323.03491 708.51169 319.74605 704.83793 316.51659 701.14850 c S
-316.52 701.15 m
-315.50279 700.17328 314.26549 699.11349 312.78273 699.14168 c S
-312.78 699.14 m
-311.19787 699.55260 311.35870 701.64714 312.51702 702.45870 c S
-312.52 702.46 m
-313.81397 703.91905 315.32759 705.17809 316.85560 706.38598 c S
-316.86 706.39 m
-319.49294 708.29575 322.10541 710.29857 325.09624 711.63306 c S
-325.10 711.63 m
-328.33960 713.13687 331.64025 714.56306 334.52982 716.70648 c S
-337.67 723.68 m
-336.84252 720.88107 335.42446 718.30079 333.84347 715.86491 c S
-333.84 715.86 m
-333.03995 714.64381 332.17889 713.45902 331.24079 712.33748 c S
-331.29 712.48 m
-334.07649 716.36828 337.24670 720.17732 341.48414 722.53221 c S
-341.48 722.53 m
-342.93013 723.27663 344.57172 723.46456 346.15836 723.68073 c S
-346.16 723.68 m
-347.24751 723.83157 348.64372 723.05150 348.52428 721.82540 c S
-348.52 721.83 m
-348.31569 720.66770 347.52332 719.72346 346.89869 718.76111 c S
-346.90 718.76 m
-345.95837 717.41785 344.73958 716.16963 344.31068 714.54926 c S
-344.31 714.55 m
-344.00261 713.24949 345.31058 712.08146 346.56954 712.49179 c S
-346.57 712.49 m
-347.75729 712.83364 348.76607 713.59466 349.84334 714.17881 c S
-349.84 714.18 m
-351.49437 715.18108 353.06331 716.34851 354.36212 717.78645 c S
-364.77 716.61 m
-366.35139 717.88369 367.85549 719.50385 368.24594 721.56699 c S
-368.25 721.57 m
-368.36326 722.74804 367.24454 723.80833 366.08950 723.78076 c S
-366.09 723.78 m
-363.36815 724.27267 360.64865 723.13638 358.45357 721.60052 c S
-358.45 721.60 m
-356.50210 720.25171 354.55170 718.66798 353.56001 716.45281 c S
-353.56 716.45 m
-353.05173 715.11390 353.41457 713.31400 354.78470 712.64113 c S
-354.78 712.64 m
-356.36791 711.74619 358.35987 712.10735 359.86286 712.99644 c S
-359.86 713.00 m
-361.65803 713.96816 363.16587 715.36503 364.76918 716.60830 c S
-370.91 720.54 m
-368.43366 718.81082 359.59578 713.85776 364.46275 712.67519 c S
-364.46 712.68 m
-367.96243 711.82485 372.99419 716.53166 377.06220 719.86793 c S
-377.06 719.87 m
-381.13021 723.20421 388.66532 729.50635 389.52279 734.40918 c S
-389.52 734.41 m
-390.38026 739.31201 386.99017 732.63924 385.44672 729.99800 c S
-385.45 730.00 m
-383.90327 727.35676 381.68734 721.89825 378.84260 717.57920 c S
-378.84 717.58 m
-374.88808 711.57520 379.84829 710.67284 384.40551 713.75693 c S
-384.41 713.76 m
-387.47762 715.83598 388.36739 716.53064 390.05047 718.32644 c S
-377.09 724.61 m
-380.71911 724.41189 384.35803 724.30792 387.98869 724.51177 c S
-394.03 724.41 m
-392.18491 721.66026 390.24889 718.97709 388.69800 716.01507 c S
-388.70 716.02 m
-388.11570 714.90294 387.78649 713.14830 389.14290 712.64677 c S
-389.14 712.65 m
-390.93520 712.19182 391.58604 712.85554 392.62746 713.16610 c S
-392.63 713.17 m
-396.02262 714.53123 398.83776 717.01922 401.31194 719.76695 c S
-401.31 719.77 m
-402.40197 721.24598 403.46885 722.74227 404.63016 724.16817 c S
-404.78 724.22 m
-402.55929 721.74558 400.57949 719.06249 398.76886 716.28285 c S
-398.77 716.28 m
-398.32437 715.32028 397.62621 714.21254 398.07187 713.13095 c S
-398.07 713.13 m
-398.57336 712.18240 399.85778 712.37483 400.73100 712.56985 c S
-400.73 712.57 m
-402.98443 713.25618 404.83854 714.79610 406.66011 716.22985 c S
-406.66 716.23 m
-408.11360 717.41183 409.36895 718.81778 410.44888 720.34308 c S
-410.45 720.34 m
-411.47726 721.59671 412.51414 722.88301 413.25375 724.32691 c S
-413.25 724.33 m
-413.60253 725.66655 411.26351 725.68421 412.00122 724.33574 c S
-412.00 724.34 m
-412.67563 723.07539 414.28726 723.02575 415.54291 722.95857 c S
-415.54 722.96 m
-416.69601 723.19698 417.19632 721.86044 416.45907 721.08440 c S
-416.46 721.08 m
-415.97330 720.51720 415.48724 719.96970 415.10474 719.31838 c S
-415.10 719.32 m
-413.91309 717.57253 412.50005 715.87703 411.94882 713.79691 c S
-411.95 713.80 m
-411.73164 712.43046 413.33326 711.41965 414.54890 711.86110 c S
-414.55 711.86 m
-417.07044 712.45069 419.35460 713.73436 421.56616 715.03742 c S
-422.60 720.83 m
-424.94264 719.25149 427.88660 718.31183 430.71325 718.88005 c S
-430.71 718.88 m
-431.82181 719.10667 432.85178 719.63723 433.76367 720.28974 c S
-433.76 720.29 m
-434.98835 721.29361 434.95979 723.45602 433.61045 724.33926 c S
-433.61 724.34 m
-432.65667 724.96769 431.44146 724.75467 430.38277 724.58403 c S
-430.38 724.58 m
-428.00929 724.08917 426.00610 722.58363 424.31063 720.91694 c S
-424.31 720.92 m
-422.51500 719.31015 421.33376 716.83779 421.70110 714.40116 c S
-421.70 714.40 m
-422.15276 713.11643 423.49103 712.39634 424.79016 712.29603 c S
-424.79 712.30 m
-426.65615 712.13320 428.52395 712.57632 430.27740 713.18297 c S
-430.28 713.18 m
-433.09197 714.20773 435.59332 715.92106 437.91309 717.78645 c S
+172.56 729.26 m
+176.12859 727.37498 181.56609 729.53330 183.32142 731.81151 c S
+183.32 731.81 m
+185.07675 734.08972 184.06110 735.50444 182.15553 735.93722 c S
+182.16 735.94 m
+180.24996 736.37000 179.15914 735.19163 178.05706 733.58309 c S
+178.06 733.58 m
+176.95498 731.97454 176.46998 730.05644 176.20638 727.23746 c S
+176.21 727.24 m
+175.94279 724.41849 176.02369 719.87193 175.02338 716.95784 c S
+175.02 716.96 m
+174.02307 714.04375 172.12550 712.69662 169.33366 711.87807 c S
+169.33 711.88 m
+166.54182 711.05951 162.47030 711.40359 160.35569 713.59754 c S
+160.36 713.60 m
+158.24107 715.79148 158.60137 719.60485 160.39973 721.20315 c S
+160.40 721.20 m
+162.19810 722.80145 163.94600 722.75520 164.19254 719.87147 c S
+164.19 719.87 m
+164.43909 716.98774 158.69748 712.26983 156.93491 712.58268 c S
+156.93 712.58 m
+155.17233 712.89554 156.28179 712.58268 155.95524 712.58268 c S
+193.95 718.56 m
+195.08449 719.52030 196.07583 720.78852 196.25558 722.31187 c S
+196.26 722.31 m
+196.36196 723.03967 196.11746 723.87942 195.42818 724.23980 c S
+195.43 724.24 m
+193.81831 725.25646 191.77825 724.92797 190.08066 724.31958 c S
+190.08 724.32 m
+187.97924 723.52390 186.05472 722.29614 184.33465 720.85985 c S
+184.33 720.86 m
+183.22868 719.90201 182.18108 718.82436 181.48048 717.52995 c S
+181.48 717.53 m
+180.73003 715.75096 181.90197 713.35245 183.87920 713.10017 c S
+183.88 713.10 m
+185.36948 712.83748 186.81411 713.46652 188.08186 714.18482 c S
+188.08 714.18 m
+189.76421 715.04235 191.30516 716.15183 192.70807 717.41191 c S
+192.71 717.41 m
+193.12425 717.76649 193.53644 718.12575 193.94585 718.48814 c S
+198.90 721.49 m
+196.07844 719.86201 192.49067 717.41507 191.04076 715.70047 c S
+191.04 715.70 m
+189.59085 713.98586 191.16483 713.41558 192.56916 713.28742 c S
+192.57 713.29 m
+193.97349 713.15927 195.42706 713.70036 197.10945 714.62576 c S
+197.11 714.63 m
+198.79183 715.55117 201.00848 717.40025 202.30205 718.90544 c S
+202.30 718.91 m
+203.59561 720.41064 204.99046 721.86732 205.41256 722.98803 c S
+205.41 722.99 m
+205.83467 724.10873 205.89658 724.43654 205.24884 724.83735 c S
+196.88 713.26 m
+201.10084 716.77447 204.72691 721.13719 209.74630 723.59484 c S
+209.75 723.59 m
+211.27784 724.62715 214.66356 725.75326 215.04082 723.01765 c S
+215.04 723.02 m
+215.19389 720.68236 213.26479 719.01302 212.10153 717.20225 c S
+212.10 717.20 m
+211.29633 716.14293 209.62517 713.84732 209.38097 713.57045 c S
+209.38 713.57 m
+212.10971 717.76734 216.05913 721.04696 220.24647 723.71153 c S
+220.25 723.71 m
+221.77628 724.71863 225.67048 724.97128 224.73220 722.11724 c S
+224.73 722.12 m
+224.27467 719.96397 222.63059 718.40854 221.08683 716.99257 c S
+221.09 716.99 m
+219.49883 715.55841 220.23858 713.02749 222.59385 713.51910 c S
+222.59 713.52 m
+224.58617 713.64200 226.13616 715.06819 227.82469 715.97121 c S
+227.82 715.97 m
+231.45136 718.80595 234.17092 722.87123 238.50263 724.75230 c S
+238.50 724.75 m
+240.68520 725.60660 243.51738 726.39642 245.48590 724.65392 c S
+245.49 724.65 m
+247.11333 723.13890 246.18620 720.65644 244.98380 719.18788 c S
+244.98 719.19 m
+243.69129 717.26999 241.80998 715.85148 239.66638 715.00035 c S
+239.67 715.00 m
+237.24675 713.55589 234.02746 713.68689 231.79430 715.42895 c S
+231.79 715.43 m
+231.71730 715.47845 231.63421 715.51660 231.55272 715.55773 c S
+237.27 726.92 m
+235.90135 723.45558 234.47942 719.94900 232.16828 716.99131 c S
+232.17 716.99 m
+230.14653 713.86528 228.86869 710.28936 226.50435 707.37901 c S
+226.50 707.38 m
+224.81470 705.03899 223.03727 702.72215 220.81975 700.85245 c S
+220.82 700.85 m
+219.43589 700.41254 219.39593 702.32962 219.77817 703.19069 c S
+219.78 703.19 m
+220.68977 705.76640 222.42249 707.92052 223.67913 710.32267 c S
+223.68 710.32 m
+225.24740 713.07182 227.51923 715.26460 229.77069 717.44462 c S
+231.74 715.27 m
+234.69994 712.59242 239.28654 712.36992 242.77351 714.10344 c S
+242.77 714.10 m
+248.43787 716.50509 253.26148 720.40501 258.10412 724.11451 c S
+258.10 724.11 m
+260.84422 726.33103 263.48972 728.84488 265.08772 732.03182 c S
+265.09 732.03 m
+265.46324 733.19273 265.88595 734.74508 264.92402 735.72530 c S
+264.92 735.73 m
+263.15802 736.39257 261.74510 734.36034 260.46863 733.41874 c S
+260.47 733.42 m
+257.47016 730.49463 255.07567 727.00002 252.95876 723.40371 c S
+252.96 723.40 m
+251.67051 720.99231 250.37674 719.11264 249.75463 715.88391 c S
+249.75 715.88 m
+249.40876 714.08889 250.98737 713.04144 252.48903 713.30901 c S
+252.49 713.31 m
+254.42413 713.39988 256.19624 714.30805 257.97817 714.97973 c S
+257.98 714.98 m
+259.41764 715.67396 260.68153 716.66733 261.93773 717.64196 c S
+263.12 721.79 m
+266.34484 719.26553 269.14228 719.14066 272.76476 719.99777 c S
+272.76 720.00 m
+273.82509 720.34358 274.59424 721.27465 274.90634 722.32374 c S
+274.91 722.32 m
+275.34714 723.24408 274.88574 724.30697 273.98781 724.73200 c S
+273.99 724.73 m
+272.60242 725.61067 270.81295 725.48194 269.37642 724.79774 c S
+269.38 724.80 m
+267.00336 723.77079 265.15391 721.88990 263.36875 720.07671 c S
+263.37 720.08 m
+262.37948 718.90029 261.75811 717.37273 261.73505 715.83210 c S
+261.74 715.83 m
+261.78864 714.92761 262.49826 714.22249 263.34023 713.98907 c S
+263.34 713.99 m
+265.37479 713.13940 267.72184 712.70635 269.86579 713.39452 c S
+269.87 713.39 m
+271.29714 713.91105 272.69816 714.52553 274.04952 715.22266 c S
+274.05 715.22 m
+275.66628 716.17196 276.98685 717.52565 278.31726 718.82602 c S
+282.36 712.81 m
+284.40171 712.59169 286.86340 712.62058 288.23925 714.40209 c S
+288.24 714.40 m
+289.77697 715.82242 291.30792 717.81997 290.77075 720.04668 c S
+290.77 720.05 m
+290.47686 721.62207 288.38509 722.76231 287.06499 721.61177 c S
+287.06 721.61 m
+284.80944 720.01538 284.83621 716.62090 286.14986 714.42755 c S
+286.15 714.43 m
+287.83165 711.68873 291.41137 710.83902 294.40258 711.48955 c S
+294.40 711.49 m
+298.24039 712.22214 301.82103 715.31696 302.28387 719.32375 c S
+302.28 719.32 m
+302.33991 721.65682 302.33898 723.99293 302.63515 726.31208 c S
+302.64 726.31 m
+302.91434 729.34896 303.34183 732.64097 305.42124 735.02737 c S
+305.42 735.03 m
+306.63637 736.34109 309.06052 736.94011 310.35555 735.42209 c S
+310.36 735.42 m
+311.39940 734.05841 310.57078 732.20417 309.59241 731.05389 c S
+309.59 731.05 m
+308.43144 729.26796 306.13118 728.98393 304.23705 728.47945 c S
+304.24 728.48 m
+302.35587 728.06906 300.07192 728.28403 298.83038 729.93660 c S
+298.83 729.94 m
+298.14472 730.69770 297.37680 731.55415 297.36093 732.64010 c S
+315.42 728.50 m
+315.13964 728.43783 314.95197 728.11229 315.04711 727.84314 c S
+315.05 727.84 m
+315.13788 727.58513 315.35744 727.37078 315.62510 727.30456 c S
+315.63 727.30 m
+315.77486 727.29601 315.91744 727.42353 315.92615 727.57317 c S
+315.93 727.57 m
+315.98217 727.83851 315.94534 728.13571 315.77593 728.35441 c S
+315.78 728.35 m
+315.68741 728.45219 315.55240 728.52295 315.41789 728.49587 c S
+313.59 725.09 m
+311.46500 722.25303 309.41062 719.35555 307.47431 716.38424 c S
+307.47 716.38 m
+307.08799 715.57153 306.98256 714.44836 307.65999 713.75988 c S
+307.66 713.76 m
+308.47944 713.15600 309.55042 713.47898 310.44217 713.71514 c S
+310.44 713.72 m
+312.71322 714.31638 314.93772 715.26830 316.71277 716.83954 c S
+316.71 716.84 m
+317.79331 717.72675 318.78154 718.72585 319.66078 719.81274 c S
+332.62 722.74 m
+332.38180 724.10681 330.88121 724.91016 329.57707 724.77351 c S
+329.58 724.77 m
+326.80500 724.87803 324.27175 723.47849 322.03843 721.98353 c S
+322.04 721.98 m
+320.08756 720.61361 318.27576 718.77740 317.63354 716.42039 c S
+317.63 716.42 m
+317.42675 714.71509 318.96036 712.93774 320.71805 713.11147 c S
+320.72 713.11 m
+323.65930 713.14654 326.29456 714.78460 328.41290 716.70061 c S
+328.41 716.70 m
+330.29665 718.29060 332.16487 720.21783 332.61832 722.73929 c S
+334.61 721.10 m
+331.17430 719.33060 327.83007 716.98214 325.94364 713.51685 c S
+325.94 713.52 m
+323.20505 709.40609 319.89970 705.71392 316.65405 702.00600 c S
+316.65 702.01 m
+315.63517 701.02589 314.39167 699.96079 312.90148 699.98912 c S
+312.90 699.99 m
+311.30867 700.40210 311.47030 702.50713 312.63443 703.32277 c S
+312.63 703.32 m
+313.93789 704.79043 315.45909 706.05578 316.99476 707.26973 c S
+316.99 707.27 m
+319.64532 709.18907 322.27089 711.20194 325.27671 712.54311 c S
+325.28 712.54 m
+328.53633 714.05446 331.85352 715.48780 334.75757 717.64196 c S
+337.92 724.65 m
+337.08187 721.83748 335.65670 719.24427 334.06779 716.79618 c S
+334.07 716.80 m
+333.26023 715.56896 332.39486 714.37823 331.45206 713.25106 c S
+331.50 713.40 m
+334.30197 717.30207 337.48807 721.13020 341.74676 723.49689 c S
+341.75 723.50 m
+343.19999 724.24505 344.84981 724.43392 346.44440 724.65118 c S
+346.44 724.65 m
+347.53901 724.80277 348.94222 724.01879 348.82218 722.78655 c S
+348.82 722.79 m
+348.61255 721.62304 347.81620 720.67407 347.18845 719.70690 c S
+347.19 719.71 m
+346.24341 718.35690 345.01851 717.10243 344.58746 715.47393 c S
+344.59 715.47 m
+344.27785 714.16765 345.59237 712.99376 346.85764 713.40615 c S
+346.86 713.41 m
+348.05134 713.74971 349.06519 714.51454 350.14786 715.10162 c S
+350.15 715.10 m
+351.80716 716.10892 353.38397 717.28220 354.68929 718.72735 c S
+365.15 717.54 m
+366.73865 718.82508 368.25029 720.45336 368.64270 722.52684 c S
+368.64 722.53 m
+368.76060 723.71381 367.63628 724.77942 366.47545 724.75170 c S
+366.48 724.75 m
+363.74046 725.24608 361.00733 724.10410 358.80124 722.56053 c S
+358.80 722.56 m
+356.83999 721.20497 354.87981 719.61329 353.88315 717.38702 c S
+353.88 717.39 m
+353.37233 716.04140 353.73699 714.23248 355.11399 713.55624 c S
+355.11 713.56 m
+356.70513 712.65681 358.70707 713.01978 360.21760 713.91333 c S
+360.22 713.91 m
+362.02177 714.88992 363.53716 716.29379 365.14851 717.54329 c S
+371.32 721.49 m
+368.83136 719.75686 359.94918 714.77896 364.84054 713.59047 c S
+364.84 713.59 m
+368.35776 712.73586 373.41474 717.46627 377.50315 720.81926 c S
+377.50 720.82 m
+381.59155 724.17226 389.16443 730.50600 390.02620 735.43340 c S
+390.03 735.43 m
+390.88797 740.36081 387.48089 733.65459 385.92970 731.00011 c S
+385.93 731.00 m
+384.37851 728.34563 382.15147 722.85976 379.29248 718.51906 c S
+379.29 718.52 m
+375.31813 712.48497 380.30320 711.57808 384.88327 714.67763 c S
+384.88 714.68 m
+387.97078 716.76710 388.86501 717.46525 390.55652 719.27005 c S
+377.53 725.59 m
+381.17839 725.38600 384.83555 725.28150 388.48441 725.48638 c S
+394.55 725.39 m
+392.70166 722.62057 390.75594 719.92396 389.19727 716.94708 c S
+389.20 716.95 m
+388.61205 715.82939 388.28120 714.06595 389.64440 713.56191 c S
+389.64 713.56 m
+391.44568 713.10468 392.09979 713.77172 393.14644 714.08384 c S
+393.15 714.08 m
+396.55861 715.45581 399.38786 717.95628 401.87444 720.71777 c S
+401.87 720.72 m
+402.96994 722.20422 404.04216 723.70801 405.20929 725.14105 c S
+405.36 725.19 m
+403.12805 722.70632 401.13832 720.00978 399.31862 717.21621 c S
+399.32 717.22 m
+398.87189 716.24881 398.17024 715.13552 398.61813 714.04852 c S
+398.62 714.05 m
+399.12213 713.09521 400.41300 713.28861 401.29059 713.48460 c S
+401.29 713.48 m
+403.55531 714.17437 405.41872 715.72201 407.24942 717.16295 c S
+407.25 717.16 m
+408.71020 718.35085 409.97184 719.76385 411.05718 721.29680 c S
+411.06 721.30 m
+412.09071 722.55670 413.13279 723.84946 413.87611 725.30059 c S
+413.88 725.30 m
+414.22664 726.64694 411.87589 726.66470 412.61730 725.30947 c S
+412.62 725.31 m
+413.29510 724.04280 414.91480 723.99291 416.17675 723.92540 c S
+416.18 723.93 m
+417.33562 724.16500 417.83844 722.82176 417.09749 722.04183 c S
+417.10 722.04 m
+416.60929 721.47179 416.12080 720.92154 415.73638 720.26695 c S
+415.74 720.27 m
+414.53875 718.51235 413.11863 716.80835 412.56464 714.71781 c S
+412.56 714.72 m
+412.34637 713.34451 413.95602 712.32863 415.17776 712.77230 c S
+415.18 712.77 m
+417.71193 713.36484 420.00754 714.65494 422.23019 715.96454 c S
+423.27 721.79 m
+425.62360 720.19973 428.58231 719.25536 431.42312 719.82643 c S
+431.42 719.83 m
+432.53724 720.05419 433.57238 720.58741 434.48883 721.24319 c S
+434.49 721.24 m
+435.71965 722.25209 435.69096 724.42534 434.33485 725.31300 c S
+434.33 725.31 m
+433.37629 725.94459 432.15499 725.73050 431.09100 725.55900 c S
+431.09 725.56 m
+428.70561 725.06166 426.69238 723.54857 424.98842 721.87353 c S
+424.99 721.87 m
+423.18378 720.25869 421.99662 717.77394 422.36580 715.32509 c S
+422.37 715.33 m
+422.81973 714.03392 424.16471 713.31022 425.47035 713.20941 c S
+425.47 713.21 m
+427.34569 713.04576 429.22286 713.49111 430.98509 714.10079 c S
+430.99 714.10 m
+433.81377 715.13069 436.32766 716.85261 438.65906 718.72735 c S
+165.00 666.86 m
+162.81903 666.86099 160.67485 667.46404 v S
+160.67 667.46 m
+158.56417 668.10060 157.15705 669.13919 v S
+157.16 669.14 m 158.06 674.50 l S
+158.06 674.50 m 158.26 674.50 l S
+158.26 674.50 m
+159.73677 673.42756 161.44541 672.82450 v S
+161.45 672.82 m
+163.15406 672.22145 164.76220 672.22145 v S
+164.76 672.22 m
+167.91147 672.22145 167.91147 674.49965 v S
+167.91 674.50 m
+167.91147 675.37072 167.44243 675.94027 v S
+167.44 675.94 m
+167.00689 676.54332 165.86779 677.04587 v S
+165.87 677.05 m 162.38 678.62 l S
+162.38 678.62 m
+160.00479 679.69259 158.69818 681.53525 v S
+158.70 681.54 m
+157.42507 683.37791 157.42507 685.82362 v S
+157.43 685.82 m
+157.42507 688.06831 158.46366 689.70996 v S
+158.46 689.71 m
+159.53575 691.38510 161.44541 692.28968 v S
+161.45 692.29 m
+163.38858 693.19425 165.96830 693.19425 v S
+165.97 693.19 m
+167.87797 693.19425 169.75413 692.69171 v S
+169.75 692.69 m
+171.63029 692.18917 172.80289 691.38510 v S
+172.80 691.39 m 171.93 686.33 l S
+171.93 686.33 m 171.73 686.33 l S
+171.73 686.33 m
+170.69221 687.06323 169.25158 687.46526 v S
+169.25 687.47 m
+167.84446 687.90080 166.47085 687.90080 v S
+166.47 687.90 m
+163.52259 687.90080 163.52259 685.89063 v S
+163.52 685.89 m
+163.52259 685.08656 163.99163 684.51701 v S
+163.99 684.52 m
+164.49418 683.94746 165.56627 683.47842 v S
+165.57 683.48 m 168.58 682.10 l S
+168.58 682.10 m
+171.46278 680.79819 172.73588 679.05604 v S
+172.74 679.06 m
+174.00899 677.34739 174.00899 674.80117 v S
+174.01 674.80 m
+174.00899 672.38897 172.86990 670.57981 v S
+172.87 670.58 m
+171.76430 668.80416 169.75413 667.83258 v S
+169.75 667.83 m
+167.74396 666.86099 164.99672 666.86099 v S
+165.00 666.86 m 165.00 666.86 l S
+181.18 667.20 m
+178.76635 667.19602 177.35922 668.53614 v S
+177.36 668.54 m
+175.95210 669.87625 175.95210 672.12094 v S
+175.95 672.12 m
+175.95210 676.87835 182.28415 677.44790 v S
+182.28 677.45 m 186.41 677.82 l S
+186.41 677.82 m 186.41 677.98 l S
+186.41 677.98 m
+186.40500 679.15655 185.70144 679.65909 v S
+185.70 679.66 m
+185.03138 680.19514 183.55726 680.19514 v S
+183.56 680.20 m
+182.08313 680.19514 180.44149 679.82661 v S
+180.44 679.83 m
+178.79985 679.49158 177.82827 678.92203 v S
+177.83 678.92 m 177.59 678.92 l S
+177.59 678.92 m 178.46 683.68 l S
+178.46 683.68 m
+181.41307 684.88554 184.69636 684.88554 v S
+184.70 684.89 m
+192.23450 684.88554 192.23450 677.54841 v S
+192.23 677.55 m 192.23 672.32 l S
+192.23 672.32 m
+192.23450 670.91484 192.43552 669.67523 v S
+192.44 669.68 m
+192.67004 668.43563 193.03857 667.73207 v S
+193.04 667.73 m 193.04 667.46 l S
+193.04 667.46 m 187.61 667.46 l S
+187.61 667.46 m
+187.10856 668.60314 187.00805 669.97676 v S
+187.01 669.98 m 186.77 669.98 l S
+186.77 669.98 m
+186.13698 668.70365 184.62935 667.93308 v S
+184.63 667.93 m
+183.12172 667.19602 181.17855 667.19602 v S
+181.18 667.20 m 181.18 667.20 l S
+181.61 672.66 m
+181.61409 671.28337 183.25573 671.28337 v S
+183.26 671.28 m
+184.66285 671.28337 185.53393 672.08744 v S
+185.53 672.09 m
+186.40500 672.89151 186.40500 674.13112 v S
+186.41 674.13 m 186.41 674.53 l S
+186.41 674.53 m 183.69 674.30 l S
+183.69 674.30 m
+181.61409 674.09761 181.61409 672.65699 v S
+181.61 672.66 m 181.61 672.66 l S
+196.09 667.46 m 196.09 684.48 l S
+196.09 684.48 m 201.51 684.48 l S
+201.51 684.48 m 201.51 681.50 l S
+201.51 681.50 m 201.75 681.50 l S
+201.75 681.50 m
+202.35234 683.10989 203.65895 683.98096 v S
+203.66 683.98 m
+204.99907 684.88554 206.74121 684.88554 v S
+206.74 684.89 m
+210.39303 684.88554 211.73314 681.73627 v S
+211.73 681.74 m 211.87 681.74 l S
+211.87 681.74 m
+212.63772 683.31091 214.01134 684.08147 v S
+214.01 684.08 m
+215.38496 684.88554 217.22762 684.88554 v S
+217.23 684.89 m
+220.17587 684.88554 221.71700 682.94237 v S
+221.72 682.94 m
+223.29164 681.03271 223.29164 677.54841 v S
+223.29 677.55 m 223.29 667.46 l S
+223.29 667.46 m 217.26 667.46 l S
+217.26 667.46 m 217.26 677.01 l S
+217.26 677.01 m
+217.26112 679.79310 215.11693 679.79310 v S
+215.12 679.79 m
+214.01134 679.79310 213.34128 678.95553 v S
+213.34 678.96 m
+212.70473 678.15146 212.70473 676.77784 v S
+212.70 676.78 m 212.70 667.46 l S
+212.70 667.46 m 206.67 667.46 l S
+206.67 667.46 m 206.67 676.98 l S
+206.67 676.98 m
+206.67421 679.79310 204.53002 679.79310 v S
+204.53 679.79 m
+203.42443 679.79310 202.75437 678.95553 v S
+202.75 678.96 m
+202.11782 678.11796 202.11782 676.64383 v S
+202.12 676.64 m 202.12 667.46 l S
+202.12 667.46 m 196.09 667.46 l S
+227.08 659.09 m 227.08 684.48 l S
+227.08 684.48 m 232.81 684.48 l S
+232.81 684.48 m 232.81 681.97 l S
+232.81 681.97 m 233.07 681.97 l S
+233.07 681.97 m
+234.64908 684.88554 238.06638 684.88554 v S
+238.07 684.89 m
+240.27757 684.88554 241.91921 683.77995 v S
+241.92 683.78 m
+243.56085 682.67435 244.46543 680.66418 v S
+244.47 680.66 m
+245.37001 678.68751 245.37001 675.97377 v S
+245.37 675.97 m
+245.37001 673.29354 244.46543 671.28337 v S
+244.47 671.28 m
+243.56085 669.27320 241.91921 668.16760 v S
+241.92 668.17 m
+240.27757 667.06201 238.06638 667.06201 v S
+238.07 667.06 m
+235.01762 667.06201 233.37598 669.40721 v S
+233.38 669.41 m 233.11 669.41 l S
+233.11 669.41 m 233.11 659.09 l S
+233.11 659.09 m 227.08 659.09 l S
+242.05 672.15 m
+243.56085 672.15445 244.43192 673.15953 v S
+244.43 673.16 m
+245.30300 674.19812 245.30300 675.94027 v S
+245.30 675.94 m
+245.30300 677.74943 244.43192 678.75451 v S
+244.43 678.75 m
+243.59435 679.79310 242.05322 679.79310 v S
+242.05 679.79 m
+240.57909 679.79310 239.70802 678.75451 v S
+239.71 678.75 m
+238.83694 677.74943 238.83694 675.97377 v S
+238.84 675.97 m
+238.83694 674.23162 239.70802 673.19304 v S
+239.71 673.19 m
+240.57909 672.15445 242.05322 672.15445 v S
+242.05 672.15 m 242.05 672.15 l S
+248.42 667.46 m 248.42 693.60 l S
+248.42 693.60 m 254.45 693.60 l S
+254.45 693.60 m 254.45 667.46 l S
+254.45 667.46 m 248.42 667.46 l S
+266.58 667.06 m
+262.38939 667.06201 259.94368 669.44071 v S
+259.94 669.44 m
+257.53147 671.81942 257.53147 675.97377 v S
+257.53 675.97 m
+257.53147 678.78802 258.67057 680.76469 v S
+258.67 680.76 m
+259.84317 682.77486 261.85335 683.81345 v S
+261.85 683.81 m
+263.89702 684.88554 266.47674 684.88554 v S
+266.48 684.89 m
+270.43008 684.88554 272.47376 682.54034 v S
+272.47 682.54 m
+274.55093 680.22864 274.55093 675.94027 v S
+274.55 675.94 m 274.55 675.04 l S
+274.55 675.04 m 263.63 673.96 l S
+263.63 673.96 m
+264.03103 672.75750 265.03612 672.25496 v S
+265.04 672.25 m
+266.07470 671.75241 267.58234 671.75241 v S
+267.58 671.75 m
+269.29098 671.75241 270.86562 672.15445 v S
+270.87 672.15 m
+272.47376 672.58998 273.27783 673.02552 v S
+273.28 673.03 m 273.51 673.03 l S
+273.51 673.03 m 272.64 668.27 l S
+272.64 668.27 m
+271.63619 667.83258 269.96104 667.46404 v S
+269.96 667.46 m
+268.28590 667.06201 266.57725 667.06201 v S
+266.58 667.06 m 266.58 667.06 l S
+266.38 680.46 m
+265.27064 680.46316 264.46657 679.79310 v S
+264.47 679.79 m
+263.69600 679.12305 263.42798 677.51491 v S
+263.43 677.51 m 269.06 678.05 l S
+269.06 678.05 m
+268.82195 679.32406 268.11838 679.89361 v S
+268.12 679.89 m
+267.41482 680.46316 266.37624 680.46316 v S
+266.38 680.46 m 266.38 680.46 l S
+291.77 666.86 m
+289.59362 666.86099 287.44943 667.46404 v S
+287.45 667.46 m
+285.33875 668.10060 283.93163 669.13919 v S
+283.93 669.14 m 284.84 674.50 l S
+284.84 674.50 m 285.04 674.50 l S
+285.04 674.50 m
+286.51135 673.42756 288.22000 672.82450 v S
+288.22 672.82 m
+289.92865 672.22145 291.53679 672.22145 v S
+291.54 672.22 m
+294.68606 672.22145 294.68606 674.49965 v S
+294.69 674.50 m
+294.68606 675.37072 294.21701 675.94027 v S
+294.22 675.94 m
+293.78148 676.54332 292.64238 677.04587 v S
+292.64 677.05 m 289.16 678.62 l S
+289.16 678.62 m
+286.77938 679.69259 285.47276 681.53525 v S
+285.47 681.54 m
+284.19965 683.37791 284.19965 685.82362 v S
+284.20 685.82 m
+284.19965 688.06831 285.23825 689.70996 v S
+285.24 689.71 m
+286.31033 691.38510 288.22000 692.28968 v S
+288.22 692.29 m
+290.16317 693.19425 292.74289 693.19425 v S
+292.74 693.19 m
+294.65255 693.19425 296.52871 692.69171 v S
+296.53 692.69 m
+298.40488 692.18917 299.57747 691.38510 v S
+299.58 691.39 m 298.71 686.33 l S
+298.71 686.33 m 298.51 686.33 l S
+298.51 686.33 m
+297.46679 687.06323 296.02617 687.46526 v S
+296.03 687.47 m
+294.61905 687.90080 293.24543 687.90080 v S
+293.25 687.90 m
+290.29718 687.90080 290.29718 685.89063 v S
+290.30 685.89 m
+290.29718 685.08656 290.76622 684.51701 v S
+290.77 684.52 m
+291.26876 683.94746 292.34085 683.47842 v S
+292.34 683.48 m 295.36 682.10 l S
+295.36 682.10 m
+298.23736 680.79819 299.51047 679.05604 v S
+299.51 679.06 m
+300.78358 677.34739 300.78358 674.80117 v S
+300.78 674.80 m
+300.78358 672.38897 299.64448 670.57981 v S
+299.64 670.58 m
+298.53889 668.80416 296.52871 667.83258 v S
+296.53 667.83 m
+294.51854 666.86099 291.77130 666.86099 v S
+291.77 666.86 m 291.77 666.86 l S
+306.85 686.46 m
+305.20589 686.46018 304.20081 687.43176 v S
+304.20 687.43 m
+303.19573 688.43685 303.19573 689.94448 v S
+303.20 689.94 m
+303.19573 691.45210 304.20081 692.42369 v S
+304.20 692.42 m
+305.20589 693.42877 306.84754 693.42877 v S
+306.85 693.43 m
+308.48918 693.42877 309.49427 692.42369 v S
+309.49 692.42 m
+310.49935 691.45210 310.49935 689.94448 v S
+310.50 689.94 m
+310.49935 688.43685 309.49427 687.43176 v S
+309.49 687.43 m
+308.48918 686.46018 306.84754 686.46018 v S
+306.85 686.46 m 306.85 686.46 l S
+303.83 667.46 m 303.83 684.48 l S
+303.83 684.48 m 309.86 684.48 l S
+309.86 684.48 m 309.86 667.46 l S
+309.86 667.46 m 303.83 667.46 l S
+321.42 658.69 m
+319.44458 658.68629 317.60192 659.15533 v S
+317.60 659.16 m
+315.75926 659.59087 314.62016 660.32793 v S
+314.62 660.33 m 315.63 665.05 l S
+315.63 665.05 m 315.86 665.05 l S
+315.86 665.05 m
+316.79785 664.48229 318.03745 664.14726 v S
+318.04 664.15 m
+319.31057 663.77873 320.51667 663.77873 v S
+320.52 663.78 m
+322.76136 663.77873 323.96747 665.01834 v S
+323.97 665.02 m
+325.17357 666.25794 325.17357 668.56964 v S
+325.17 668.57 m 325.17 669.81 l S
+325.17 669.81 m 324.91 669.81 l S
+324.91 669.81 m
+323.26391 667.46404 320.21514 667.46404 v S
+320.22 667.46 m
+318.00396 667.46404 316.36231 668.53614 v S
+316.36 668.54 m
+314.72067 669.64173 313.81609 671.58490 v S
+313.82 671.58 m
+312.91152 673.56157 312.91152 676.17479 v S
+312.91 676.17 m
+312.91152 678.82152 313.81609 680.76469 v S
+313.82 680.76 m
+314.72067 682.70785 316.36231 683.77995 v S
+316.36 683.78 m
+318.00396 684.88554 320.21514 684.88554 v S
+320.22 684.89 m
+321.99080 684.88554 323.39792 684.08147 v S
+323.40 684.08 m
+324.80504 683.27740 325.47510 681.90378 v S
+325.48 681.90 m 325.71 681.90 l S
+325.71 681.90 m
+325.77662 682.64085 325.94413 683.34441 v S
+325.94 683.34 m
+326.11165 684.04797 326.31267 684.48351 v S
+326.31 684.48 m 332.01 684.48 l S
+332.01 684.48 m 332.01 684.22 l S
+332.01 684.22 m
+331.57262 683.41141 331.37160 682.10480 v S
+331.37 682.10 m
+331.20409 680.79819 331.20409 679.62559 v S
+331.20 679.63 m 331.20 668.64 l S
+331.20 668.64 m
+331.20409 663.84573 328.65787 661.26601 v S
+328.66 661.27 m
+326.14515 658.68629 321.42125 658.68629 v S
+321.42 658.69 m 321.42 658.69 l S
+322.26 672.49 m
+323.73295 672.48948 324.60402 673.49456 v S
+324.60 673.49 m
+325.47510 674.49965 325.47510 676.17479 v S
+325.48 676.17 m
+325.47510 677.84994 324.60402 678.85502 v S
+324.60 678.86 m
+323.73295 679.86011 322.25882 679.86011 v S
+322.26 679.86 m
+320.71769 679.86011 319.84661 678.85502 v S
+319.85 678.86 m
+319.00904 677.88344 319.00904 676.14129 v S
+319.01 676.14 m
+319.00904 674.46615 319.88012 673.46106 v S
+319.88 673.46 m
+320.75119 672.48948 322.25882 672.48948 v S
+322.26 672.49 m 322.26 672.49 l S
+335.16 667.46 m 335.16 684.48 l S
+335.16 684.48 m 340.58 684.48 l S
+340.58 684.48 m 340.58 681.50 l S
+340.58 681.50 m 340.82 681.50 l S
+340.82 681.50 m
+341.42244 683.10989 342.79606 683.98096 v S
+342.80 683.98 m
+344.16968 684.88554 346.11284 684.88554 v S
+346.11 684.89 m
+348.99409 684.88554 350.63574 682.94237 v S
+350.64 682.94 m
+352.31088 680.99921 352.31088 677.54841 v S
+352.31 677.55 m 352.31 667.46 l S
+352.31 667.46 m 346.28 667.46 l S
+346.28 667.46 m 346.28 676.84 l S
+346.28 676.84 m
+346.28036 679.79310 343.86815 679.79310 v S
+343.87 679.79 m
+342.62855 679.79310 341.89148 678.92203 v S
+341.89 678.92 m
+341.18792 678.05095 341.18792 676.50982 v S
+341.19 676.51 m 341.19 667.46 l S
+341.19 667.46 m 335.16 667.46 l S
+360.22 667.20 m
+357.80528 667.19602 356.39816 668.53614 v S
+356.40 668.54 m
+354.99104 669.87625 354.99104 672.12094 v S
+354.99 672.12 m
+354.99104 676.87835 361.32308 677.44790 v S
+361.32 677.45 m 365.44 677.82 l S
+365.44 677.82 m 365.44 677.98 l S
+365.44 677.98 m
+365.44393 679.15655 364.74037 679.65909 v S
+364.74 679.66 m
+364.07032 680.19514 362.59619 680.19514 v S
+362.60 680.20 m
+361.12207 680.19514 359.48042 679.82661 v S
+359.48 679.83 m
+357.83878 679.49158 356.86720 678.92203 v S
+356.87 678.92 m 356.63 678.92 l S
+356.63 678.92 m 357.50 683.68 l S
+357.50 683.68 m
+360.45200 684.88554 363.73529 684.88554 v S
+363.74 684.89 m
+371.27344 684.88554 371.27344 677.54841 v S
+371.27 677.55 m 371.27 672.32 l S
+371.27 672.32 m
+371.27344 670.91484 371.47445 669.67523 v S
+371.47 669.68 m
+371.70897 668.43563 372.07750 667.73207 v S
+372.08 667.73 m 372.08 667.46 l S
+372.08 667.46 m 366.65 667.46 l S
+366.65 667.46 m
+366.14749 668.60314 366.04699 669.97676 v S
+366.05 669.98 m 365.81 669.98 l S
+365.81 669.98 m
+365.17591 668.70365 363.66828 667.93308 v S
+363.67 667.93 m
+362.16065 667.19602 360.21749 667.19602 v S
+360.22 667.20 m 360.22 667.20 l S
+360.65 672.66 m
+360.65302 671.28337 362.29466 671.28337 v S
+362.29 671.28 m
+363.70178 671.28337 364.57286 672.08744 v S
+364.57 672.09 m
+365.44393 672.89151 365.44393 674.13112 v S
+365.44 674.13 m 365.44 674.53 l S
+365.44 674.53 m 362.73 674.30 l S
+362.73 674.30 m
+360.65302 674.09761 360.65302 672.65699 v S
+360.65 672.66 m 360.65 672.66 l S
+373.35 679.79 m 373.35 684.48 l S
+373.35 684.48 m 376.23 684.48 l S
+376.23 684.48 m 376.23 689.31 l S
+376.23 689.31 m 382.26 689.31 l S
+382.26 689.31 m 382.26 684.48 l S
+382.26 684.48 m 386.45 684.48 l S
+386.45 684.48 m 385.68 679.79 l S
+385.68 679.79 m 382.26 679.79 l S
+382.26 679.79 m 382.26 675.87 l S
+382.26 675.87 m
+382.26234 672.25496 385.44512 672.25496 v S
+385.45 672.25 m 386.45 672.25 l S
+386.45 672.25 m 385.68 667.36 l S
+385.68 667.36 m 383.17 667.36 l S
+383.17 667.36 m
+379.91714 667.36353 378.07448 669.27320 v S
+378.07 669.27 m
+376.23182 671.18286 376.23182 674.60016 v S
+376.23 674.60 m 376.23 679.79 l S
+376.23 679.79 m 373.35 679.79 l S
+397.04 667.06 m
+393.15074 667.06201 390.93955 669.23970 v S
+390.94 669.24 m
+388.72836 671.45089 388.72836 675.40423 v S
+388.73 675.40 m 388.73 684.48 l S
+388.73 684.48 m 394.76 684.48 l S
+394.76 684.48 m 394.76 675.27 l S
+394.76 675.27 m
+394.75888 673.76258 395.36193 672.95852 v S
+395.36 672.96 m
+395.96498 672.15445 397.03708 672.15445 v S
+397.04 672.15 m
+398.10916 672.15445 398.71222 672.95852 v S
+398.71 672.96 m
+399.31527 673.76258 399.31527 675.27021 v S
+399.32 675.27 m 399.32 684.48 l S
+399.32 684.48 m 405.35 684.48 l S
+405.35 684.48 m 405.35 675.40 l S
+405.35 675.40 m
+405.34578 671.45089 403.13460 669.23970 v S
+403.13 669.24 m
+400.92340 667.06201 397.03708 667.06201 v S
+397.04 667.06 m 397.04 667.06 l S
+409.00 667.46 m 409.00 684.48 l S
+409.00 684.48 m 414.43 684.48 l S
+414.43 684.48 m 414.43 681.17 l S
+414.43 681.17 m 414.66 681.17 l S
+414.66 681.17 m
+415.83215 684.88554 419.28295 684.88554 v S
+419.28 684.89 m
+420.28804 684.88554 420.92459 684.48351 v S
+420.92 684.48 m 420.92 678.52 l S
+420.92 678.52 m 420.69 678.52 l S
+420.69 678.52 m
+419.78549 678.88853 418.71340 678.88853 v S
+418.71 678.89 m
+416.93775 678.88853 415.96616 677.71592 v S
+415.97 677.72 m
+415.02809 676.54332 415.02809 674.56665 v S
+415.03 674.57 m 415.03 667.46 l S
+415.03 667.46 m 409.00 667.46 l S
+431.34 667.06 m
+427.15607 667.06201 424.71036 669.44071 v S
+424.71 669.44 m
+422.29816 671.81942 422.29816 675.97377 v S
+422.30 675.97 m
+422.29816 678.78802 423.43726 680.76469 v S
+423.44 680.76 m
+424.60986 682.77486 426.62003 683.81345 v S
+426.62 683.81 m
+428.66371 684.88554 431.24343 684.88554 v S
+431.24 684.89 m
+435.19677 684.88554 437.24044 682.54034 v S
+437.24 682.54 m
+439.31762 680.22864 439.31762 675.94027 v S
+439.32 675.94 m 439.32 675.04 l S
+439.32 675.04 m 428.40 673.96 l S
+428.40 673.96 m
+428.79772 672.75750 429.80280 672.25496 v S
+429.80 672.25 m
+430.84139 671.75241 432.34902 671.75241 v S
+432.35 671.75 m
+434.05767 671.75241 435.63230 672.15445 v S
+435.63 672.15 m
+437.24044 672.58998 438.04451 673.02552 v S
+438.04 673.03 m 438.28 673.03 l S
+438.28 673.03 m 437.41 668.27 l S
+437.41 668.27 m
+436.40287 667.83258 434.72772 667.46404 v S
+434.73 667.46 m
+433.05258 667.06201 431.34394 667.06201 v S
+431.34 667.06 m 431.34 667.06 l S
+431.14 680.46 m
+430.03732 680.46316 429.23326 679.79310 v S
+429.23 679.79 m
+428.46269 679.12305 428.19466 677.51491 v S
+428.19 677.51 m 433.82 678.05 l S
+433.82 678.05 m
+433.58863 679.32406 432.88507 679.89361 v S
+432.89 679.89 m
+432.18151 680.46316 431.14292 680.46316 v S
+431.14 680.46 m 431.14 680.46 l S
endstream
endobj
@@ -357,15 +906,17 @@ endobj
<<
/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
/Font <<
-/F0 5 0 R
+/Fd08375f64eb9861c6eae4dfcfdbd3500fbdbe33e 5 0 R
>>
/XObject <<
>>
+/ColorSpace <<
+>>
>>
endobj
6 0 obj
<<
-/Producer (FPDF 1.7)
+/Producer (
/CreationDate (D:20000101000000)
>>
endobj
@@ -378,13 +929,13 @@ endobj
xref
0 8
0000000000 65535 f
-0000013550 00000 n
-0000013735 00000 n
+0000030711 00000 n
+0000030896 00000 n
0000000009 00000 n
0000000384 00000 n
-0000013637 00000 n
-0000013839 00000 n
-0000013914 00000 n
+0000030798 00000 n
+0000031057 00000 n
+0000031142 00000 n
trailer
<<
/Size 8
@@ -392,5 +943,5 @@ trailer
/Info 6 0 R
>>
startxref
-13963
+31191
%%EOF
diff --git a/svgbasic.go b/svgbasic.go
index cc35073..f75d69f 100644
--- a/svgbasic.go
+++ b/svgbasic.go
@@ -31,7 +31,11 @@ func init() {
pathCmdSub = strings.NewReplacer(",", " ",
"L", " L ", "l", " l ",
"C", " C ", "c", " c ",
- "M", " M ", "m", " m ")
+ "M", " M ", "m", " m ",
+ "H", " H ", "h", " h ",
+ "V", " V ", "v", " v ",
+ "Q", " Q ", "q", " q ",
+ "Z", " Z ", "z", " z ")
}
// SVGBasicSegmentType describes a single curve or position segment
@@ -79,6 +83,29 @@ func absolutizePath(segs []SVGBasicSegmentType) {
segPtr.Cmd = 'C'
x = segPtr.Arg[4]
y = segPtr.Arg[5]
+ case 'Q':
+ x = seg.Arg[2]
+ y = seg.Arg[3]
+ case 'q':
+ adjust(0, x, y)
+ adjust(2, x, y)
+ segPtr.Cmd = 'Q'
+ x = segPtr.Arg[2]
+ y = segPtr.Arg[3]
+ case 'H':
+ x = seg.Arg[0]
+ case 'h':
+ segPtr.Arg[0] += x
+ segPtr.Cmd = 'H'
+ x += seg.Arg[0]
+ case 'V':
+ y = seg.Arg[0]
+ case 'v':
+ segPtr.Arg[0] += y
+ segPtr.Cmd = 'V'
+ y += seg.Arg[0]
+ case 'z':
+ segPtr.Cmd = 'Z'
}
}
}
@@ -127,10 +154,16 @@ func pathParse(pathStr string) (segs []SVGBasicSegmentType, err error) {
setup(2)
case 'C', 'c': // Absolute/relative Bézier curve: cx0, cy0, cx1, cy1, x1, y1
setup(6)
+ case 'H', 'h': // Absolute/relative horizontal line to: x
+ setup(1)
case 'L', 'l': // Absolute/relative lineto: x, y
setup(2)
+ case 'Q', 'q': // Absolute/relative quadratic curve: x0, y0, x1, y1
+ setup(4)
+ case 'V', 'v': // Absolute/relative vertical line to: y
+ setup(1)
case 'Z', 'z': // closepath instruction (takes no arguments)
- break
+ segs = append(segs, seg)
default:
err = fmt.Errorf("expecting SVG path command at position %d, got %s", j, str)
}
@@ -168,7 +201,8 @@ type SVGBasicType struct {
// information generated by jSignature, is supported. The returned path data
// includes only the commands 'M' (absolute moveto: x, y), 'L' (absolute
// lineto: x, y), 'C' (absolute cubic Bézier curve: cx0, cy0, cx1, cy1,
-// x1,y1) and 'Z' (closepath).
+// x1,y1), 'Q' (absolute quadratic Bézier curve: x0, y0, x1, y1) and 'Z'
+// (closepath).
func SVGBasicParse(buf []byte) (sig SVGBasicType, err error) {
type pathType struct {
D string `xml:"d,attr"`
diff --git a/svgwrite.go b/svgwrite.go
index 7e455fb..398a6da 100644
--- a/svgwrite.go
+++ b/svgwrite.go
@@ -29,8 +29,18 @@ func (f *Fpdf) SVGBasicWrite(sb *SVGBasicType, scale float64) {
var cx0, cy0, cx1, cy1 float64
var path []SVGBasicSegmentType
var seg SVGBasicSegmentType
+ var startX, startY float64
+ sval := func(origin float64, arg int) float64 {
+ return origin + scale*seg.Arg[arg]
+ }
+ xval := func(arg int) float64 {
+ return sval(originX, arg)
+ }
+ yval := func(arg int) float64 {
+ return sval(originY, arg)
+ }
val := func(arg int) (float64, float64) {
- return originX + scale*seg.Arg[arg], originY + scale*seg.Arg[arg+1]
+ return xval(arg), yval(arg + 1)
}
for j := 0; j < len(sb.Segments) && f.Ok(); j++ {
path = sb.Segments[j]
@@ -39,6 +49,7 @@ func (f *Fpdf) SVGBasicWrite(sb *SVGBasicType, scale float64) {
switch seg.Cmd {
case 'M':
x, y = val(0)
+ startX, startY = x, y
f.SetXY(x, y)
case 'L':
newX, newY = val(0)
@@ -50,8 +61,22 @@ func (f *Fpdf) SVGBasicWrite(sb *SVGBasicType, scale float64) {
newX, newY = val(4)
f.CurveCubic(x, y, cx0, cy0, newX, newY, cx1, cy1, "D")
x, y = newX, newY
+ case 'Q':
+ cx0, cy0 = val(0)
+ newX, newY = val(2)
+ f.Curve(x, y, cx0, cy0, newX, newY, "D")
+ x, y = newX, newY
+ case 'H':
+ newX = xval(0)
+ f.Line(x, y, newX, y)
+ x = newX
+ case 'V':
+ newY = yval(0)
+ f.Line(x, y, x, newY)
+ y = newY
case 'Z':
- f.Line(x, y, originX, originY)
+ f.Line(x, y, startX, startY)
+ x, y = startX, startY
default:
f.SetErrorf("Unexpected path command '%c'", seg.Cmd)
}
diff --git a/template.go b/template.go
index 31204c2..c0d3933 100644
--- a/template.go
+++ b/template.go
@@ -84,7 +84,18 @@ func (f *Fpdf) UseTemplateScaled(t Template, corner PointType, size SizeType) {
for _, tt := range t.Templates() {
f.templates[tt.ID()] = tt
}
+
+ // Create a list of existing image SHA-1 hashes.
+ existingImages := map[string]bool{}
+ for _, image := range f.images {
+ existingImages[image.i] = true
+ }
+
+ // Add each template image to $f, unless already present.
for name, ti := range t.Images() {
+ if _, found := existingImages[ti.i]; found {
+ continue
+ }
name = sprintf("t%s-%s", t.ID(), name)
f.images[name] = ti
}
diff --git a/template_impl.go b/template_impl.go
index c5d7be8..c1e2dff 100644
--- a/template_impl.go
+++ b/template_impl.go
@@ -296,4 +296,8 @@ func (t *Tpl) loadParamsFromFpdf(f *Fpdf) {
t.Fpdf.fontSizePt = f.fontSizePt
t.Fpdf.fontStyle = f.fontStyle
t.Fpdf.ws = f.ws
+
+ for key, value := range f.images {
+ t.Fpdf.images[key] = value
+ }
}
diff --git a/utf8fontfile.go b/utf8fontfile.go
index 964e919..4d90f28 100644
--- a/utf8fontfile.go
+++ b/utf8fontfile.go
@@ -377,7 +377,7 @@ func (utf *utf8FontFile) parseHHEATable() int {
}
func (utf *utf8FontFile) parseOS2Table() int {
- weightType := 0
+ var weightType int
scale := 1000.0 / float64(utf.fontElementSize)
if _, OK := utf.tableDescriptions["OS/2"]; OK {
utf.SeekTable("OS/2")
@@ -831,9 +831,9 @@ func (utf *utf8FontFile) getSymbols(originalSymbolIdx int, start *int, symbolSet
}
func (utf *utf8FontFile) parseHMTXTable(numberOfHMetrics, numSymbols int, symbolToChar map[int][]int, scale float64) {
+ var widths int
start := utf.SeekTable("hmtx")
arrayWidths := 0
- widths := 0
var arr []int
utf.CharWidths = make([]int, 256*256)
charCount := 0
@@ -863,8 +863,6 @@ func (utf *utf8FontFile) parseHMTXTable(numberOfHMetrics, numSymbols int, symbol
}
}
}
- data := utf.getRange(start+numberOfHMetrics*4, numSymbols*2)
- arr = unpackUint16Array(data)
diff := numSymbols - numberOfHMetrics
for pos := 0; pos < diff; pos++ {
symbol := pos + numberOfHMetrics
@@ -949,7 +947,7 @@ func (utf *utf8FontFile) generateSCCSDictionaries(runeCmapPosition int, symbolCh
for i := 0; i < segmentSize; i++ {
positions = append(positions, utf.readUint16())
}
- symbol := 0
+ var symbol int
for n := 0; n < segmentSize; n++ {
completePosition := completers[n] + 1
for char := beginners[n]; char < completePosition; char++ {
@@ -1140,3 +1138,16 @@ func keySortArrayRangeMap(s map[int][]int) []int {
sort.Ints(keys)
return keys
}
+
+// UTF8CutFont is a utility function that generates a TrueType font composed
+// only of the runes included in cutset. The rune glyphs are copied from This
+// function is demonstrated in ExampleUTF8CutFont().
+func UTF8CutFont(inBuf []byte, cutset string) (outBuf []byte) {
+ f := newUTF8Font(&fileReader{readerPosition: 0, array: inBuf})
+ runes := map[int]int{}
+ for i, r := range cutset {
+ runes[i] = int(r)
+ }
+ outBuf = f.GenerateСutFont(runes)
+ return
+}
diff --git a/util.go b/util.go
index e96cdd8..351d319 100644
--- a/util.go
+++ b/util.go
@@ -344,7 +344,7 @@ func (pa *untypedKeyMap) getIndex(key interface{}) int {
//Put key=>value in PHP Array
func (pa *untypedKeyMap) put(key interface{}, value int) {
if key == nil {
- i := 0
+ var i int
for n := 0; ; n++ {
i = pa.getIndex(n)
if i < 0 {
@@ -419,14 +419,8 @@ func arrayMerge(arr1, arr2 *untypedKeyMap) *untypedKeyMap {
answer.valueSet = arr1.valueSet[:]
for i := 0; i < len(arr2.keySet); i++ {
if arr2.keySet[i] == "interval" {
- u := 0
- u = u + 1
if arr1.getIndex("interval") < 0 {
answer.put("interval", arr2.valueSet[i])
- } else {
-
- u := 0
- u = u + 1
}
} else {
answer.put(nil, arr2.valueSet[i])
@@ -450,3 +444,19 @@ func remove(arr []int, key int) []int {
}
return append(arr[:n], arr[n+1:]...)
}
+
+func isChinese(rune2 rune) bool {
+ // chinese unicode: 4e00-9fa5
+ if rune2 >= rune(0x4e00) && rune2 <= rune(0x9fa5) {
+ return true
+ }
+ return false
+}
+
+// Condition font family string to PDF name compliance. See section 5.3 (Names)
+// in https://resources.infosecinstitute.com/pdf-file-format-basic-structure/
+func fontFamilyEscape(familyStr string) (escStr string) {
+ escStr = strings.Replace(familyStr, " ", "#20", -1)
+ // Additional replacements can take place here
+ return
+}