// ImageToPdfDirect converts image to PDF using gpdf func ImageToPdfDirect(w io.Writer, r io.Reader) error { img, _, err := image.Decode(r) if err != nil { return err } ib := img.Bounds().Canon().Size() doc := pdf.New() canvas := doc.NewPage(pdf.A4Width, pdf.A4Height) canvas.Translate(pdf.Cm, canvas.CropBox().Max.Y-pdf.Cm) // TODO: A4 Portrait ratio vs. ib ratio ir := float32(ib.X) / float32(ib.Y) bb := canvas.CropBox() cbw, cbh := int(bb.Max.X-bb.Min.X), int(bb.Max.Y-bb.Min.Y) if ir > float32(cbw/cbh) { bb.Max.Y = bb.Min.Y + pdf.Unit(1.0/ir*float32(cbw)) } else { bb.Max.X = bb.Min.X + pdf.Unit(ir*float32(cbh)) } canvas.DrawImage(img, bb) if err = canvas.Close(); err != nil { return err } return doc.Encode(w) }
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) } }
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() }
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() }
// unit returns a pdf.Unit, converted from a vg.Length. func unit(l vg.Length) pdf.Unit { return pdf.Unit(l.Points()) * pdf.Pt }
func unit(f float64) pdf.Unit { return pdf.Unit(f) * pdf.Cm }
func (s StaffSpec) IndexOffset(index int) pdf.Unit { offset := pdf.Unit(s.StaffSpace() / 2) return pdf.Unit(index-1) * offset }
func (s StaffSpec) StaffSpace() pdf.Unit { return pdf.Unit(s.height / 4) }