summaryrefslogtreecommitdiff
path: root/fpdf.go
diff options
context:
space:
mode:
Diffstat (limited to 'fpdf.go')
-rw-r--r--fpdf.go104
1 files changed, 92 insertions, 12 deletions
diff --git a/fpdf.go b/fpdf.go
index 8361d3c..a650d6d 100644
--- a/fpdf.go
+++ b/fpdf.go
@@ -36,6 +36,7 @@ import (
"math"
"os"
"path"
+ "strconv"
"strings"
"time"
)
@@ -312,6 +313,17 @@ func (f *Fpdf) SetFontLocation(fontDirStr string) {
f.fontpath = fontDirStr
}
+// SetFontLoader sets a loader used to read font files (.json and .z) from an
+// arbitrary source. If a font loader has been specified, it is used to load
+// the named font resources when AddFont() is called. If this operation fails,
+// an attempt is made to load the resources from the configured font directory
+// (see SetFontLocation()).
+//
+// See tutorial 29 for an example of this method.
+func (f *Fpdf) SetFontLoader(loader FontLoader) {
+ f.fontLoader = loader
+}
+
// SetHeaderFunc sets the function that lets the application render the page
// header. The specified function is automatically called by AddPage() and
// should not be called directly by the application. The implementation in Fpdf
@@ -565,6 +577,10 @@ func (f *Fpdf) AddPageFormat(orientationStr string, size SizeType) {
// Set line width
f.lineWidth = lw
f.outf("%.2f w", lw*f.k)
+ // Set dash pattern
+ if len(f.dashArray) > 0 {
+ f.outputDashPattern()
+ }
// Set font
if familyStr != "" {
f.SetFont(familyStr, style, fontsize)
@@ -775,6 +791,44 @@ func (f *Fpdf) SetLineCapStyle(styleStr string) {
}
}
+// SetDashPattern sets the dash pattern that is used to draw lines. The
+// dashArray elements are numbers that specify the lengths, in units
+// established in New(), of alternating dashes and gaps. The dash phase
+// specifies the distance into the dash pattern at which to start the dash. The
+// dash pattern is retained from page to page. Call this method with an empty
+// array to restore solid line drawing.
+//
+// See tutorial 28 for an example of this function.
+func (f *Fpdf) SetDashPattern(dashArray []float64, dashPhase float64) {
+ scaled := make([]float64, len(dashArray))
+ for i, value := range dashArray {
+ scaled[i] = value * f.k
+ }
+ dashPhase *= f.k
+ if !slicesEqual(scaled, f.dashArray) || dashPhase != f.dashPhase {
+ f.dashArray = scaled
+ f.dashPhase = dashPhase
+ if f.page > 0 {
+ f.outputDashPattern()
+ }
+ }
+}
+
+func (f *Fpdf) outputDashPattern() {
+ var buf bytes.Buffer
+ buf.WriteByte('[')
+ for i, value := range f.dashArray {
+ if i > 0 {
+ buf.WriteByte(' ')
+ }
+ buf.WriteString(strconv.FormatFloat(value, 'f', 2, 64))
+ }
+ buf.WriteString("] ")
+ buf.WriteString(strconv.FormatFloat(f.dashPhase, 'f', 2, 64))
+ buf.WriteString(" d")
+ f.outbuf(&buf)
+}
+
// Line draws a line between points (x1, y1) and (x2, y2) using the current
// draw color, line width and cap style.
func (f *Fpdf) Line(x1, y1, x2, y2 float64) {
@@ -1319,8 +1373,19 @@ func (f *Fpdf) AddFont(familyStr, styleStr, fileStr string) {
if fileStr == "" {
fileStr = strings.Replace(familyStr, " ", "", -1) + strings.ToLower(styleStr) + ".json"
}
- fileStr = path.Join(f.fontpath, fileStr)
+ if f.fontLoader != nil {
+ reader, err := f.fontLoader.Open(fileStr)
+ if err == nil {
+ f.AddFontFromReader(familyStr, styleStr, reader)
+ if closer, ok := reader.(io.Closer); ok {
+ closer.Close()
+ }
+ return
+ }
+ }
+
+ fileStr = path.Join(f.fontpath, fileStr)
file, err := os.Open(fileStr)
if err != nil {
f.err = err
@@ -2932,7 +2997,7 @@ func (f *Fpdf) putfonts() {
f.newobj()
info.n = f.n
f.fontFiles[file] = info
- font, err := ioutil.ReadFile(path.Join(f.fontpath, file))
+ font, err := f.loadFontFile(file)
if err != nil {
f.err = err
return
@@ -3032,6 +3097,20 @@ func (f *Fpdf) putfonts() {
return
}
+func (f *Fpdf) loadFontFile(name string) ([]byte, error) {
+ if f.fontLoader != nil {
+ reader, err := f.fontLoader.Open(name)
+ if err == nil {
+ data, err := ioutil.ReadAll(reader)
+ if closer, ok := reader.(io.Closer); ok {
+ closer.Close()
+ }
+ return data, err
+ }
+ }
+ return ioutil.ReadFile(path.Join(f.fontpath, name))
+}
+
func (f *Fpdf) putimages() {
for _, img := range f.images {
f.putimage(img)
@@ -3385,16 +3464,17 @@ func (f *Fpdf) enddoc() {
}
// Path Drawing
+//
// Create a "path" by moving a virtual stylus around the page, then draw it or
// fill it in. The main advantage of using the path drawing routines rather
// than multiple Fpdf.Line is that PDF creates nice line joins at the angles,
// rather than just overlaying the lines.
+
+// MoveTo moves the stylus to (x, y) without drawing the path from the previous
+// point. Paths must start with a MoveTo to set the original stylus location or
+// the result is undefined.
//
-// MoveTo moves the stylus to (x, y) without drawing the path from the
-// previous point. Paths must start with a MoveTo to set the original stylus
-// location or the result is undefined.
-//
-// See tutorial 29 for an example of this function.
+// See tutorial 30 for an example of this function.
func (f *Fpdf) MoveTo(x, y float64) {
f.point(x, y) // rename?
}
@@ -3403,7 +3483,7 @@ func (f *Fpdf) MoveTo(x, y float64) {
// becomes the new stylus location. Note that this only creates the line in
// the path; it does not actually draw the line on the page.
//
-// See tutorial 29 for an example of this function.
+// See tutorial 30 for an example of this function.
func (f *Fpdf) LineTo(x, y float64) {
f.outf("%.2f %.2f l", x*f.k, (f.h-y)*f.k)
}
@@ -3415,7 +3495,7 @@ func (f *Fpdf) LineTo(x, y float64) {
// point. At the end point, the curve is tangent to the straight line between
// the end point and the control point.
//
-// See tutorial 29 for an example of this function.
+// See tutorial 30 for an example of this function.
func (f *Fpdf) CurveTo(cx, cy, x, y float64) {
f.outf("%.5f %.5f %.5f %.5f v", cx*f.k, (f.h-cy)*f.k, x*f.k, (f.h-y)*f.k)
}
@@ -3428,7 +3508,7 @@ func (f *Fpdf) CurveTo(cx, cy, x, y float64) {
// the curve is tangent to the straight line between the end point and the
// control point (cx1, cy1).
//
-// See tutorial 29 for examples of this function.
+// See tutorial 30 for examples of this function.
func (f *Fpdf) CurveBezierCubicTo(cx0, cy0, cx1, cy1, x, y float64) {
f.curve(cx0, cy0, cx1, cy1, x, y) // rename?
}
@@ -3437,7 +3517,7 @@ func (f *Fpdf) CurveBezierCubicTo(cx0, cy0, cx1, cy1, x, y float64) {
// (if not the same) and mark the path as closed so the first and last lines
// join nicely.
//
-// See tutorial 29 for an example of this function.
+// See tutorial 30 for an example of this function.
func (f *Fpdf) ClosePath() {
f.outf("h")
}
@@ -3449,7 +3529,7 @@ func (f *Fpdf) ClosePath() {
// the current draw color, line width, and cap style centered on the
// path. Filling uses the current fill color.
//
-// See tutorial 29 for an example of this function.
+// See tutorial 30 for an example of this function.
func (f *Fpdf) DrawPath(styleStr string) {
f.outf(fillDrawOp(styleStr))
}