summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStani <spe.stani.be@gmail.com>2015-07-06 14:39:32 +0200
committerStani <spe.stani.be@gmail.com>2015-07-06 14:39:32 +0200
commitc58d8b0f8bf2b0e43c107adb8dee06fdc7b3deb6 (patch)
tree6eabda283cb230dff32875b361d77c06de0b6c71
parent74622e58a96b143400c19c7ff408f084bcf78918 (diff)
implemented ArcTo
-rw-r--r--fpdf.go138
1 files changed, 89 insertions, 49 deletions
diff --git a/fpdf.go b/fpdf.go
index 41d8c25..fafca6f 100644
--- a/fpdf.go
+++ b/fpdf.go
@@ -907,7 +907,7 @@ func (f *Fpdf) Circle(x, y, r float64, styleStr string) {
//
// See tutorial 11 for an example of this function.
func (f *Fpdf) Ellipse(x, y, rx, ry, degRotate float64, styleStr string) {
- f.Arc(x, y, rx, ry, degRotate, 0, 360, styleStr)
+ f.arc(x, y, rx, ry, degRotate, 0, 360, styleStr, false)
}
// Polygon draws a closed figure defined by a series of vertices specified by
@@ -1047,54 +1047,7 @@ func (f *Fpdf) CurveBezierCubic(x0, y0, cx0, cy0, cx1, cy1, x1, y1 float64, styl
//
// See tutorial 11 for an example of this function.
func (f *Fpdf) Arc(x, y, rx, ry, degRotate, degStart, degEnd float64, styleStr string) {
- x *= f.k
- y = (f.h - y) * f.k
- rx *= f.k
- ry *= f.k
- segments := int(degEnd-degStart) / 60
- if segments < 2 {
- segments = 2
- }
- angleStart := degStart * math.Pi / 180
- angleEnd := degEnd * math.Pi / 180
- angleTotal := angleEnd - angleStart
- dt := angleTotal / float64(segments)
- dtm := dt / 3
- if degRotate != 0 {
- a := -degRotate * math.Pi / 180
- f.outf("q %.5f %.5f %.5f %.5f %.5f %.5f cm", math.Cos(a), -1*math.Sin(a),
- math.Sin(a), math.Cos(a), x, y)
- x = 0
- y = 0
- }
- t := angleStart
- a0 := x + rx*math.Cos(t)
- b0 := y + ry*math.Sin(t)
- c0 := -rx * math.Sin(t)
- d0 := ry * math.Cos(t)
- f.point(a0/f.k, f.h-(b0/f.k))
- for j := 1; j <= segments; j++ {
- // Draw this bit of the total curve
- t = (float64(j) * dt) + angleStart
- a1 := x + rx*math.Cos(t)
- b1 := y + ry*math.Sin(t)
- c1 := -rx * math.Sin(t)
- d1 := ry * math.Cos(t)
- f.curve((a0+(c0*dtm))/f.k,
- f.h-((b0+(d0*dtm))/f.k),
- (a1-(c1*dtm))/f.k,
- f.h-((b1-(d1*dtm))/f.k),
- a1/f.k,
- f.h-(b1/f.k))
- a0 = a1
- b0 = b1
- c0 = c1
- d0 = d1
- }
- f.out(fillDrawOp(styleStr))
- if degRotate != 0 {
- f.out("Q")
- }
+ f.arc(x, y, rx, ry, degRotate, degStart, degEnd, styleStr, false)
}
// SetAlpha sets the alpha blending channel. The blending effect applies to
@@ -3558,3 +3511,90 @@ func (f *Fpdf) ClosePath() {
func (f *Fpdf) DrawPath(styleStr string) {
f.outf(fillDrawOp(styleStr))
}
+
+// ArcTo draws an elliptical arc centered at point (x, y). rx and ry specify its
+// horizontal and vertical radii. If the start of the arc is not at
+// the current position, a connecting line will be drawn.
+//
+// degRotate specifies the angle that the arc will be rotated. degStart and
+// degEnd specify the starting and ending angle of the arc. All angles are
+// specified in degrees and measured counter-clockwise from the 3 o'clock
+// position.
+//
+// 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 arc's
+// path. Filling uses the current fill color.
+//
+// See tutorial 30 for an example of this function.
+func (f *Fpdf) ArcTo(x, y, rx, ry, degRotate, degStart, degEnd float64) {
+ f.arc(x, y, rx, ry, degRotate, degStart, degEnd, "", true)
+}
+
+func (f *Fpdf) arc(x, y, rx, ry, degRotate, degStart, degEnd float64,
+ styleStr string, path bool) {
+ x *= f.k
+ y = (f.h - y) * f.k
+ rx *= f.k
+ ry *= f.k
+ segments := int(degEnd-degStart) / 60
+ if segments < 2 {
+ segments = 2
+ }
+ angleStart := degStart * math.Pi / 180
+ angleEnd := degEnd * math.Pi / 180
+ angleTotal := angleEnd - angleStart
+ dt := angleTotal / float64(segments)
+ dtm := dt / 3
+ if degRotate != 0 {
+ a := -degRotate * math.Pi / 180
+ f.outf("q %.5f %.5f %.5f %.5f %.5f %.5f cm",
+ math.Cos(a), -1*math.Sin(a),
+ math.Sin(a), math.Cos(a), x, y)
+ x = 0
+ y = 0
+ }
+ t := angleStart
+ a0 := x + rx*math.Cos(t)
+ b0 := y + ry*math.Sin(t)
+ c0 := -rx * math.Sin(t)
+ d0 := ry * math.Cos(t)
+ sx := a0 / f.k // start point of arc
+ sy := f.h - (b0 / f.k)
+ if path {
+ if f.x != sx || f.y != sy {
+ // Draw connecting line to start point
+ f.LineTo(sx, sy)
+ }
+ } else {
+ f.point(sx, sy)
+ }
+ for j := 1; j <= segments; j++ {
+ // Draw this bit of the total curve
+ t = (float64(j) * dt) + angleStart
+ a1 := x + rx*math.Cos(t)
+ b1 := y + ry*math.Sin(t)
+ c1 := -rx * math.Sin(t)
+ d1 := ry * math.Cos(t)
+ f.curve((a0+(c0*dtm))/f.k,
+ f.h-((b0+(d0*dtm))/f.k),
+ (a1-(c1*dtm))/f.k,
+ f.h-((b1-(d1*dtm))/f.k),
+ a1/f.k,
+ f.h-(b1/f.k))
+ a0 = a1
+ b0 = b1
+ c0 = c1
+ d0 = d1
+ if path {
+ f.x = a1 / f.k
+ f.y = f.h - (b1 / f.k)
+ }
+ }
+ if !path {
+ f.out(fillDrawOp(styleStr))
+ }
+ if degRotate != 0 {
+ f.out("Q")
+ }
+}