Example #1
0
File: vgpdf.go Project: zzn01/plot
// Approximate a circular arc using multiple
// cubic Bézier curves, one for each π/2 segment.
//
// This is from:
// 	http://hansmuller-flex.blogspot.com/2011/04/approximating-circular-arc-with-cubic.html
func arc(p *pdf.Path, comp vg.PathComp) {
	x0 := comp.X + comp.Radius*vg.Length(math.Cos(comp.Start))
	y0 := comp.Y + comp.Radius*vg.Length(math.Sin(comp.Start))
	p.Line(pdfPoint(x0, y0))

	a1 := comp.Start
	end := a1 + comp.Angle
	sign := 1.0
	if end < a1 {
		sign = -1.0
	}
	left := math.Abs(comp.Angle)

	// Square root of the machine epsilon for IEEE 64-bit floating
	// point values.  This is the equality threshold recommended
	// in Numerical Recipes, if I recall correctly—it's small enough.
	const epsilon = 1.4901161193847656e-08

	for left > epsilon {
		a2 := a1 + sign*math.Min(math.Pi/2, left)
		partialArc(p, comp.X, comp.Y, comp.Radius, a1, a2)
		left -= math.Abs(a2 - a1)
		a1 = a2
	}
}
Example #2
0
// Approximate a circular arc of fewer than π/2
// radians with cubic Bézier curve.
func partialArc(p *pdf.Path, x, y, r vg.Length, a1, a2 float64) {
	a := (a2 - a1) / 2
	x4 := r * vg.Length(math.Cos(a))
	y4 := r * vg.Length(math.Sin(a))
	x1 := x4
	y1 := -y4

	const k = 0.5522847498 // some magic constant
	f := k * vg.Length(math.Tan(a))
	x2 := x1 + f*y4
	y2 := y1 + f*x4
	x3 := x2
	y3 := -y2

	// Rotate and translate points into position.
	ar := a + a1
	sinar := vg.Length(math.Sin(ar))
	cosar := vg.Length(math.Cos(ar))
	x2r := x2*cosar - y2*sinar + x
	y2r := x2*sinar + y2*cosar + y
	x3r := x3*cosar - y3*sinar + x
	y3r := x3*sinar + y3*cosar + y
	x4 = r*vg.Length(math.Cos(a2)) + x
	y4 = r*vg.Length(math.Sin(a2)) + y
	p.Curve(pdfPoint(x2r, y2r), pdfPoint(x3r, y3r), pdfPoint(x4, y4))
}
Example #3
0
func traceCurve(a, b, c, d pdf.Point, canvas *pdf.Canvas) {
	path := new(pdf.Path)
	path.Move(a)
	path.Curve(b, c, d)

	canvas.Stroke(path)
}
Example #4
0
func Grid(canvas *pdf.Canvas, x, y, w, h, step float64) {
	canvas.Push()
	canvas.SetColor(0.75, 0.75, 0.75)
	canvas.Translate(unit(x), unit(y))

	rowCount := int(math.Floor(h / step))

	for row := 0; row < rowCount; row++ {
		bottom := float64(row) * step
		top := bottom + step

		start := 0.0
		if row%2 == 0 {
			start += step
		}
		for left := start; left < w; left += (2 * step) {
			right := left + step
			bottomLeft := point(left, bottom)
			topRight := point(right, top)
			path := new(pdf.Path)
			path.Rectangle(pdf.Rectangle{bottomLeft, topRight})
			canvas.Fill(path)
		}
	}

	canvas.Pop()
}
func main() {
	doc := pdf.New()
	canvas := doc.NewPage(pdf.USLetterWidth, pdf.USLetterHeight)
	canvas.Translate(500, 500)
	// canvas.SetColor(230, 100, 30)

	canvas.SetStrokeColor(20, 40, 60)
	path := new(pdf.Path)
	path.Move(pdf.Point{0, 0})
	path.Line(pdf.Point{0, 50})
	canvas.Stroke(path)

	text := new(pdf.Text)
	text.SetFont(pdf.Helvetica, 14)
	text.Text("Hello, World!")
	canvas.DrawText(text)

	canvas.Close()

	err := doc.Encode(os.Stdout)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}
Example #6
0
func EngraveStaff(origin pdf.Point, width, height, lineWidth pdf.Unit, canvas *pdf.Canvas) {
	path := new(pdf.Path)

	noteHeight := pdf.Unit(height / 4)
	for i := 0; i < 5; i++ {
		path.Move(origin)
		path.Line(pdf.Point{origin.X + width, origin.Y})
		origin.Y = origin.Y + noteHeight
	}

	canvas.Push()
	canvas.SetLineWidth(lineWidth)
	canvas.Stroke(path)
	canvas.Pop()
}
Example #7
0
func main() {
	doc := pdf.New()
	canvas := doc.NewPage(pdf.A4Width, pdf.A4Height)

	path := new(pdf.Path)
	bottomLeft := pdf.Point{borderWidth, borderWidth}
	topRight := pdf.Point{pdf.A4Width - borderWidth, pdf.A4Height - borderWidth}

	path.Rectangle(pdf.Rectangle{bottomLeft, topRight})
	canvas.Stroke(path)

	staffOrigin := pdf.Point{bottomLeft.X + pdf.Unit(10), bottomLeft.Y + pdf.Unit(500)}

	largeStaff := engraving.NewStaffSpec(engraving.RastralZero)
	engraving.EngraveStaff(staffOrigin, 12*pdf.Cm, largeStaff.Height(), 0.1*pdf.Pt, canvas)

	engraving.EngraveSurrogateNoteHead(staffOrigin, largeStaff.StaffSpace(), canvas)

	nextNote := pdf.Point{}
	nextNote.X = pdf.Unit(staffOrigin.X + largeStaff.StaffSpace())
	nextNote.Y = pdf.Unit(staffOrigin.Y + largeStaff.IndexOffset(0))
	engraving.EngraveSurrogateNoteHead(nextNote, largeStaff.StaffSpace(), canvas)

	nextNote.X = pdf.Unit(staffOrigin.X + (2 * largeStaff.StaffSpace()))
	nextNote.Y = pdf.Unit(staffOrigin.Y + largeStaff.IndexOffset(7))
	engraving.EngraveSurrogateNoteHead(nextNote, largeStaff.StaffSpace(), canvas)

	nextNote.X = pdf.Unit(staffOrigin.X + (3 * largeStaff.StaffSpace()))
	nextNote.Y = pdf.Unit(staffOrigin.Y + largeStaff.IndexOffset(-1))
	engraving.EngraveSurrogateNoteHead(nextNote, largeStaff.StaffSpace(), canvas)

	nextNote.X = pdf.Unit(staffOrigin.X + (4 * largeStaff.StaffSpace()))
	nextNote.Y = pdf.Unit(staffOrigin.Y + largeStaff.IndexOffset(2))
	engraving.EngraveSurrogateNoteHead(nextNote, largeStaff.StaffSpace(), canvas)

	smallStaff := engraving.NewStaffSpec(engraving.RastralEight)
	staffOrigin.Y = staffOrigin.Y + 5*pdf.Cm
	engraving.EngraveStaff(staffOrigin, 12*pdf.Cm, smallStaff.Height(), 0.1*pdf.Pt, canvas)
	canvas.Close()

	err := doc.Encode(os.Stdout)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

}
Example #8
0
// Approximate a circular arc using multiple
// cubic Bézier curves, one for each π/2 segment.
//
// This is from:
// 	http://hansmuller-flex.blogspot.com/2011/04/approximating-circular-arc-with-cubic.html
func arc(p *pdf.Path, comp vg.PathComp) {
	x0 := comp.X + comp.Radius*vg.Length(math.Cos(comp.Start))
	y0 := comp.Y + comp.Radius*vg.Length(math.Sin(comp.Start))
	p.Line(pdfPoint(x0, y0))

	a1 := comp.Start
	end := a1 + comp.Angle
	sign := 1.0
	if end < a1 {
		sign = -1.0
	}
	left := math.Abs(comp.Angle)
	for left > 0 {
		a2 := a1 + sign*math.Min(math.Pi/2, left)
		partialArc(p, comp.X, comp.Y, comp.Radius, a1, a2)
		left -= math.Abs(a2 - a1)
		a1 = a2
	}
}
Example #9
0
// pdfPath returns a pdf.Path from a vg.Path.
func pdfPath(c *Canvas, path vg.Path) *pdf.Path {
	p := new(pdf.Path)
	for _, comp := range path {
		switch comp.Type {
		case vg.MoveComp:
			p.Move(pdfPoint(comp.X, comp.Y))
		case vg.LineComp:
			p.Line(pdfPoint(comp.X, comp.Y))
		case vg.ArcComp:
			arc(p, comp)
		case vg.CloseComp:
			p.Close()
		default:
			panic(fmt.Sprintf("Unknown path component type: %d\n", comp.Type))
		}
	}
	return p
}
Example #10
0
func main() {
	doc := pdf.New()
	canvas := doc.NewPage(pdf.A4Width, pdf.A4Height)

	path := new(pdf.Path)
	bottomLeft := pdf.Point{borderWidth, borderWidth}
	topRight := pdf.Point{pdf.A4Width - borderWidth, pdf.A4Height - borderWidth}

	path.Rectangle(pdf.Rectangle{bottomLeft, topRight})
	canvas.Stroke(path)

	left := 5 * pdf.Cm
	right := 15 * pdf.Cm
	top := 15 * pdf.Cm
	bottom := 10 * pdf.Cm

	curve := new(pdf.Path)
	a := pdf.Point{left, bottom}
	b := pdf.Point{left, top}
	c := pdf.Point{right, top}
	d := pdf.Point{right, bottom}
	curve.Move(a)
	curve.Curve(b, c, d)

	beneath := 5 * pdf.Cm
	e := pdf.Point{left, beneath}
	f := pdf.Point{right, beneath}

	curve.Curve(f, e, a)

	left = 6.5 * pdf.Cm
	right = 13.5 * pdf.Cm
	top = 13.5 * pdf.Cm
	bottom = 10 * pdf.Cm
	beneath = 6.5 * pdf.Cm

	a = pdf.Point{left, 9 * pdf.Cm}
	b = pdf.Point{left, top}
	c = pdf.Point{right, top}
	d = pdf.Point{right, 11 * pdf.Cm}
	curve.Move(d)
	curve.Curve(c, b, a)

	e = pdf.Point{left, beneath}
	f = pdf.Point{right, beneath}

	curve.Curve(e, f, d)

	canvas.FillStroke(curve)

	canvas.Close()

	file, err := os.Create("curves.pdf")
	if err != nil {
		log.Fatal(err)
	}

	err = doc.Encode(file)
	if err != nil {
		log.Fatal(err)
		os.Exit(1)
	}

	file.Close()
}
Example #11
0
func EngraveSurrogateNoteHead(origin pdf.Point, size pdf.Unit, canvas *pdf.Canvas) {
	outline := new(pdf.Path)

	topRight := pdf.Point{origin.X + size, origin.Y + size}
	outline.Rectangle(pdf.Rectangle{origin, topRight})

	mid := pdf.Point{origin.X + pdf.Unit(size/2), origin.Y + pdf.Unit(size/2)}
	midPoints := new(pdf.Path)
	midPoints.Move(pdf.Point{mid.X, origin.Y})
	midPoints.Line(pdf.Point{mid.X, origin.Y + size})
	midPoints.Move(pdf.Point{origin.X, mid.Y})
	midPoints.Line(pdf.Point{origin.X + size, mid.Y})

	canvas.Push()
	canvas.SetColor(0.6, 0.6, 0.6)
	canvas.Fill(outline)
	canvas.SetLineWidth(pdf.Unit(0.1))
	canvas.Stroke(midPoints)
	canvas.Pop()
}