diff options
-rw-r--r-- | .hgignore | 1 | ||||
-rw-r--r-- | doc.go | 4 | ||||
-rw-r--r-- | fpdf.go | 82 | ||||
-rw-r--r-- | fpdf_test.go | 9 | ||||
-rw-r--r-- | util.go | 17 |
5 files changed, 74 insertions, 39 deletions
@@ -3,3 +3,4 @@ makefont/makefont pdf/*.pdf look open +pdf.txt @@ -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 @@ -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) @@ -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) +} |