summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.hgignore1
-rw-r--r--doc.go4
-rw-r--r--fpdf.go82
-rw-r--r--fpdf_test.go9
-rw-r--r--util.go17
5 files changed, 74 insertions, 39 deletions
diff --git a/.hgignore b/.hgignore
index 6e433bb..7c36670 100644
--- a/.hgignore
+++ b/.hgignore
@@ -3,3 +3,4 @@ makefont/makefont
pdf/*.pdf
look
open
+pdf.txt
diff --git a/doc.go b/doc.go
index ebc0f1c..091cd5a 100644
--- a/doc.go
+++ b/doc.go
@@ -46,7 +46,9 @@ Features
• Page compression
-• Drawing support (lines, Bézier curves, arcs, ellipses) and clipping
+• Drawing support (lines, Bézier curves, arcs, ellipses)
+
+• Clipping
gofpdf has no dependencies other than the Go standard library. All tests pass
on Linux, Mac and Windows platforms. Like FPDF version 1.7, from which gofpdf
diff --git a/fpdf.go b/fpdf.go
index 3c3f709..b8422e2 100644
--- a/fpdf.go
+++ b/fpdf.go
@@ -87,7 +87,7 @@ func New(orientationStr, unitStr, sizeStr, fontDirStr string) (f *Fpdf) {
f.diffs = make([]string, 0, 8)
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)
+ f.pageLinks = append(f.pageLinks, make([]linkType, 0, 0)) // pageLinks[0] is unused (1-based)
f.links = make([]intLinkType, 0, 8)
f.links = append(f.links, intLinkType{}) // links[0] is unused (1-based)
f.inHeader = false
@@ -962,30 +962,34 @@ func (f *Fpdf) setClipActive() bool {
// Begins a rectangular clipping operation. The rectangle is of width w and
// height h. Its upper left corner is positioned at point (x, y). outline is
// true to draw a border with the current draw color and line width centered on
-// the rectangle's perimeter. After calling this method, all rendering
-// operations (for example, Image(), LinearGradient(), etc) will be clipped by
-// the specified rectangle. Call ClipEnd() to restore unclipped operations.
-
+// the rectangle's perimeter. Only the outer half of the border will be shown.
+// After calling this method, all rendering operations (for example, Image(),
+// LinearGradient(), etc) will be clipped by the specified rectangle. Call
+// ClipEnd() to restore unclipped operations.
+//
+// See tutorial 14 for an example of this function.
func (f *Fpdf) ClipRect(x, y, w, h float64, outline bool) {
if !f.setClipActive() {
return
}
- f.outf("q %.2f %.2f %.2f %.2f re W %s", x*f.k, (f.h-y)*f.k, w*f.k, -h*f.k, StrIf(outline, "S", "n"))
+ f.outf("q %.2f %.2f %.2f %.2f re W %s", x*f.k, (f.h-y)*f.k, w*f.k, -h*f.k, strIf(outline, "S", "n"))
}
// Begins a clipping operation in which rendering is confined to the character
// string specified by txtStr. The origin (x, y) is on the left of the first
// character at the baseline. The current font is used. outline is true to draw
// a border with the current draw color and line width centered on the
-// perimeters of the text characters. After calling this method, all rendering
-// operations (for example, Image(), LinearGradient(), etc) will be clipped.
-// Call ClipEnd() to restore unclipped operations.
-
+// perimeters of the text characters. Only the outer half of the border will be
+// shown. After calling this method, all rendering operations (for example,
+// Image(), LinearGradient(), etc) will be clipped. Call ClipEnd() to restore
+// unclipped operations.
+//
+// See tutorial 14 for an example of this function.
func (f *Fpdf) ClipText(x, y float64, txtStr string, outline bool) {
if !f.setClipActive() {
return
}
- f.outf("q BT %.2f %.2f Td %d Tr (%s) Tj ET", x*f.k, (f.h-y)*f.k, IntIf(outline, 5, 7), f.escape(txtStr))
+ f.outf("q BT %.2f %.2f Td %d Tr (%s) Tj ET", x*f.k, (f.h-y)*f.k, intIf(outline, 5, 7), f.escape(txtStr))
}
func (f *Fpdf) clipArc(x1, y1, x2, y2, x3, y3 float64) {
@@ -998,10 +1002,12 @@ func (f *Fpdf) clipArc(x1, y1, x2, y2, x3, y3 float64) {
// height h. Its upper left corner is positioned at point (x, y). The rounded
// corners of the rectangle are specified by radius r. outline is true to draw
// a border with the current draw color and line width centered on the
-// rectangle's perimeter. After calling this method, all rendering operations
-// (for example, Image(), LinearGradient(), etc) will be clipped by the
-// specified rectangle. Call ClipEnd() to restore unclipped operations.
-
+// rectangle's perimeter. Only the outer half of the border will be shown.
+// After calling this method, all rendering operations (for example, Image(),
+// LinearGradient(), etc) will be clipped by the specified rectangle. Call
+// ClipEnd() to restore unclipped operations.
+//
+// See tutorial 14 for an example of this function.
func (f *Fpdf) ClipRoundedRect(x, y, w, h, r float64, outline bool) {
if !f.setClipActive() {
return
@@ -1026,16 +1032,18 @@ func (f *Fpdf) ClipRoundedRect(x, y, w, h, r float64, outline bool) {
yc = y + r
f.outf("%.2f %.2f l", x*k, (hp-yc)*k)
f.clipArc(xc-r, yc-r*myArc, xc-r*myArc, yc-r, xc, yc-r)
- f.outf(" W %s", StrIf(outline, "S", "n"))
+ f.outf(" W %s", strIf(outline, "S", "n"))
}
// Begins an elliptical clipping operation. The ellipse is centered at (x, y).
// Its horizontal and vertical radii are specified by rx and ry. outline is
// true to draw a border with the current draw color and line width centered on
-// the ellipse's perimeter. After calling this method, all rendering operations
-// (for example, Image(), LinearGradient(), etc) will be clipped by the
-// specified ellipse. Call ClipEnd() to restore unclipped operations.
-
+// the ellipse's perimeter. Only the outer half of the border will be shown.
+// After calling this method, all rendering operations (for example, Image(),
+// LinearGradient(), etc) will be clipped by the specified ellipse. Call
+// ClipEnd() to restore unclipped operations.
+//
+// See tutorial 14 for an example of this function.
func (f *Fpdf) ClipEllipse(x, y, rx, ry float64, outline bool) {
if !f.setClipActive() {
return
@@ -1061,16 +1069,17 @@ func (f *Fpdf) ClipEllipse(x, y, rx, ry float64, outline bool) {
(x+lx)*k, (h-(y+ry))*k,
(x+rx)*k, (h-(y+ly))*k,
(x+rx)*k, (h-y)*k,
- StrIf(outline, "S", "n"))
+ strIf(outline, "S", "n"))
}
// Begins a circular clipping operation. The circle is centered at (x, y) and
// has radius r. outline is true to draw a border with the current draw color
-// and line width centered on the circle's perimeter. After calling this
-// method, all rendering operations (for example, Image(), LinearGradient(),
-// etc) will be clipped by the specified circle. Call ClipEnd() to restore
-// unclipped operations.
-
+// and line width centered on the circle's perimeter. Only the outer half of
+// the border will be shown. After calling this method, all rendering
+// operations (for example, Image(), LinearGradient(), etc) will be clipped by
+// the specified circle. Call ClipEnd() to restore unclipped operations.
+//
+// See tutorial 14 for an example of this function.
func (f *Fpdf) ClipCircle(x, y, r float64, outline bool) {
f.ClipEllipse(x, y, r, r, outline)
}
@@ -1080,10 +1089,12 @@ func (f *Fpdf) ClipCircle(x, y, r float64, outline bool) {
// the units established in New(). The last point in the slice will be
// implicitly joined to the first to close the polygon. outline is true to draw
// a border with the current draw color and line width centered on the
-// polygon's perimeter. After calling this method, all rendering operations
-// (for example, Image(), LinearGradient(), etc) will be clipped by the
-// specified polygon. Call ClipEnd() to restore unclipped operations.
-
+// polygon's perimeter. Only the outer half of the border will be shown. After
+// calling this method, all rendering operations (for example, Image(),
+// LinearGradient(), etc) will be clipped by the specified polygon. Call
+// ClipEnd() to restore unclipped operations.
+//
+// See tutorial 14 for an example of this function.
func (f *Fpdf) ClipPolygon(points []pointType, outline bool) {
if !f.setClipActive() {
return
@@ -1093,9 +1104,9 @@ func (f *Fpdf) ClipPolygon(points []pointType, outline bool) {
k := f.k
s.printf("q ")
for j, pt := range points {
- s.printf("%.2f %.2f %s ", pt.x*k, (h-pt.y)*k, StrIf(j == 0, "m", "l"))
+ s.printf("%.2f %.2f %s ", pt.x*k, (h-pt.y)*k, strIf(j == 0, "m", "l"))
}
- s.printf("h W %s", StrIf(outline, "S", "n"))
+ s.printf("h W %s", strIf(outline, "S", "n"))
f.out(s.String())
}
@@ -1103,7 +1114,8 @@ func (f *Fpdf) ClipPolygon(points []pointType, outline bool) {
// ClipRoundedRect(), ClipText(), ClipEllipse(), ClipCircle() or ClipPolygon().
// Only one clipping operation can be active at a time, and the document cannot
// be successfully output while a clipping operation is active.
-
+//
+// See tutorial 14 for an example of this function.
func (f *Fpdf) ClipEnd() {
if f.err == nil {
if f.clipActive {
@@ -1953,6 +1965,10 @@ func (f *Fpdf) Output(w io.Writer) error {
if err != nil {
f.err = err
}
+ dump("pdf.txt", f.stdpageSizes,
+ f.defPageSize,
+ f.curPageSize,
+ f.pageSizes)
return f.err
}
diff --git a/fpdf_test.go b/fpdf_test.go
index 2ccbde3..c27263e 100644
--- a/fpdf_test.go
+++ b/fpdf_test.go
@@ -777,7 +777,7 @@ func ExampleFpdf_tutorial13() {
// Successfully generated pdf/tutorial13.pdf
}
-// Clipping
+// Clipping examples
func ExampleFpdf_tutorial14() {
pdf := New("", "", "", FONT_DIR)
y := 10.0
@@ -785,8 +785,8 @@ func ExampleFpdf_tutorial14() {
pdf.SetFont("Helvetica", "", 24)
pdf.SetXY(0, y)
- pdf.ClipText(10, y+12, "Clipping operations", false)
- pdf.LinearGradient(0, y, 100, y+20, 0, 0, 0, 220, 220, 220, 0, 0, 1, 1)
+ pdf.ClipText(10, y+12, "Clipping examples", false)
+ pdf.RadialGradient(10, y, 100, 20, 128, 128, 160, 32, 32, 48, 0.25, 0.5, 0.25, 0.5, 0.2)
pdf.ClipEnd()
y += 12
@@ -819,7 +819,10 @@ func ExampleFpdf_tutorial14() {
pdf.ClipEnd()
y += 30
+ pdf.SetLineWidth(.1)
+ pdf.SetDrawColor(180, 180, 180)
pdf.ClipRoundedRect(10, y, 120, 20, 5, true)
+ pdf.RadialGradient(10, y, 120, 20, 255, 255, 255, 240, 240, 220, 0.25, 0.75, 0.25, 0.75, 0.5)
pdf.SetXY(5, y-5)
pdf.SetFont("Times", "", 12)
pdf.MultiCell(130, 5, lorem(), "", "", false)
diff --git a/util.go b/util.go
index b2202ca..823bf68 100644
--- a/util.go
+++ b/util.go
@@ -20,6 +20,8 @@ import (
"bytes"
"compress/zlib"
"fmt"
+ "github.com/davecgh/go-spew/spew"
+ // "io/ioutil"
"math"
"os"
"regexp"
@@ -204,7 +206,7 @@ func utf8toutf16(s string) string {
}
// Return a if cnd is true, otherwise b
-func IntIf(cnd bool, a, b int) int {
+func intIf(cnd bool, a, b int) int {
if cnd {
return a
} else {
@@ -213,10 +215,21 @@ func IntIf(cnd bool, a, b int) int {
}
// Return aStr if cnd is true, otherwise bStr
-func StrIf(cnd bool, aStr, bStr string) string {
+func strIf(cnd bool, aStr, bStr string) string {
if cnd {
return aStr
} else {
return bStr
}
}
+
+// Dump the internals of the specified values
+func dump(fileStr string, a ...interface{}) {
+ fl, err := os.OpenFile(fileStr, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600)
+ if err == nil {
+ fmt.Fprintf(fl, "----------------\n")
+ spew.Fdump(fl, a...)
+ fl.Close()
+ }
+ // ioutil.WriteFile(fileStr, []byte(spew.Sdump(a)), os.ModeAppend)
+}