diff options
author | Kurt Jung <kurt.w.jung@gmail.com> | 2015-07-06 17:21:32 -0400 |
---|---|---|
committer | Kurt Jung <kurt.w.jung@gmail.com> | 2015-07-06 17:21:32 -0400 |
commit | 8cb193ab3b092002fea2d87dd180d0772cf32fe0 (patch) | |
tree | cfe55b858f720d5e313d5a09e98e2221ee59fdba | |
parent | bc7edcc6a96f0232c6bb4f358bde13e146842242 (diff) | |
parent | 19ef571c9c8f0ea66120545e7280c264829cd66b (diff) |
Stani Michiels' full support for fill styles and excellent tutorial to
demonstrate it.
-rw-r--r-- | fpdf.go | 32 | ||||
-rw-r--r-- | fpdf_test.go | 76 |
2 files changed, 103 insertions, 5 deletions
@@ -858,14 +858,26 @@ func (f *Fpdf) Line(x1, y1, x2, y2 float64) { f.outf("%.2f %.2f m %.2f %.2f l S", x1*f.k, (f.h-y1)*f.k, x2*f.k, (f.h-y2)*f.k) } +// fillDrawOp corrects path painting operators func fillDrawOp(styleStr string) (opStr string) { switch strings.ToUpper(styleStr) { + case "", "D": + // Stroke the path. + opStr = "S" case "F": + // fill the path, using the nonzero winding number rule opStr = "f" + case "F*": + // fill the path, using the even-odd rule + opStr = "f*" case "FD", "DF": + // fill and then stroke the path, using the nonzero winding number rule opStr = "B" + case "FD*", "DF*": + // fill and then stroke the path, using the even-odd rule + opStr = "B*" default: - opStr = "S" + opStr = styleStr } return } @@ -931,7 +943,7 @@ func (f *Fpdf) Polygon(points []PointType, styleStr string) { } } f.outf("%.5f %.5f l ", points[0].X*f.k, (f.h-points[0].Y)*f.k) - f.outf(fillDrawOp(styleStr)) + f.DrawPath(styleStr) } } @@ -966,7 +978,7 @@ func (f *Fpdf) Beziergon(points []PointType, styleStr string) { points = points[3:] } - f.outf(fillDrawOp(styleStr)) + f.DrawPath(styleStr) } // Outputs current point @@ -3507,8 +3519,18 @@ func (f *Fpdf) ClosePath() { // DrawPath actually draws the path on the page. // // 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, line width, and cap style centered on the +// outlined and filled. An empty string will be replaced with "D". +// Path-painting operators as defined in the PDF specification are also +// allowed: "S" (Stroke the path), "s" (Close and stroke the path), +// "f" (fill the path, using the nonzero winding number), "f*" +// (Fill the path, using the even-odd rule), "B" (Fill and then stroke +// the path, using the nonzero winding number rule), "B*" (Fill and +// then stroke the path, using the even-odd rule), "b" (Close, fill, +// and then stroke the path, using the nonzero winding number rule) and +// "b*" (Close, fill, and then stroke the path, using the even-odd +// rule). +// Drawing uses the current draw color, line width, and cap style +// centered on the // path. Filling uses the current fill color. // // See tutorial 30 for an example of this function. diff --git a/fpdf_test.go b/fpdf_test.go index 9ac1e18..3872331 100644 --- a/fpdf_test.go +++ b/fpdf_test.go @@ -26,6 +26,7 @@ import ( "net/http" "os" "path/filepath" + "strconv" "strings" "github.com/jung-kurt/gofpdf" @@ -1516,3 +1517,78 @@ func ExampleFpdf_tutorial31() { // Output: // Successfully generated pdf/tutorial31.pdf } + +// This example demonstrates the Path Drawing functions, such as: MoveTo, +// LineTo, CurveTo, ..., ClosePath and DrawPath. +func ExampleFpdf_tutorial32() { + pdf := gofpdf.New("P", "mm", "A4", "") + pdf.SetDrawColor(0xff, 0x00, 0x00) + pdf.SetFillColor(0x99, 0x99, 0x99) + pdf.SetFont("Helvetica", "", 15) + pdf.AddPage() + pdf.SetAlpha(1, "Multiply") + var ( + polygon = func(cx, cy, r, n, dir float64) { + da := 2 * math.Pi / n + pdf.MoveTo(cx+r, cy) + pdf.Text(cx+r, cy, "0") + i := 1 + for a := da; a < 2*math.Pi; a += da { + x, y := cx+r*math.Cos(dir*a), cy+r*math.Sin(dir*a) + pdf.LineTo(x, y) + pdf.Text(x, y, strconv.Itoa(i)) + i++ + } + pdf.ClosePath() + } + polygons = func(cx, cy, r, n, dir float64) { + d := 1.0 + for rf := r; rf > 0; rf -= 10 { + polygon(cx, cy, rf, n, d) + d *= dir + } + } + star = func(cx, cy, r, n float64) { + da := 4 * math.Pi / n + pdf.MoveTo(cx+r, cy) + for a := da; a < 4*math.Pi+da; a += da { + x, y := cx+r*math.Cos(a), cy+r*math.Sin(a) + pdf.LineTo(x, y) + } + pdf.ClosePath() + } + ) + // triangle + polygons(55, 45, 40, 3, 1) + pdf.DrawPath("B") + pdf.Text(15, 95, "B (same direction, non zero winding)") + + // square + polygons(155, 45, 40, 4, 1) + pdf.DrawPath("B*") + pdf.Text(115, 95, "B* (same direction, even odd)") + + // pentagon + polygons(55, 145, 40, 5, -1) + pdf.DrawPath("B") + pdf.Text(15, 195, "B (different direction, non zero winding)") + + // hexagon + polygons(155, 145, 40, 6, -1) + pdf.DrawPath("B*") + pdf.Text(115, 195, "B* (different direction, even odd)") + + // star + star(55, 245, 40, 5) + pdf.DrawPath("B") + pdf.Text(15, 290, "B (non zero winding)") + + // star + star(155, 245, 40, 5) + pdf.DrawPath("B*") + pdf.Text(115, 290, "B* (even odd)") + + pdf.OutputAndClose(docWriter(pdf, 32)) + // Output: + // Successfully generated pdf/tutorial32.pdf +} |