func (gc *GraphicContext) Save() {
	gc.StackGraphicContext.Save()
	gc.pdf.TransformBegin()
}
Save saves the current context stack
(transformation, font, color,...).
package draw2dpdf
import (
	"bytes"
	"image"
	"image/color"
	"image/png"
	"log"
	"math"
	"os"
	"strconv"
	"github.com/golang/freetype/truetype"
	"github.com/jung-kurt/gofpdf"
	"github.com/llgcode/draw2d"
	"github.com/llgcode/draw2d/draw2dbase"
	"github.com/llgcode/draw2d/draw2dkit"
)
const (
	DPI  = 72
	c255 = 255.0 / 65535.0
)
var (
	caps = map[draw2d.LineCap]string{
		draw2d.RoundCap:  "round",
		draw2d.ButtCap:   "butt",
		draw2d.SquareCap: "square"}
	joins = map[draw2d.LineJoin]string{
		draw2d.RoundJoin: "round",
		draw2d.BevelJoin: "bevel",
		draw2d.MiterJoin: "miter",
	}
	imageCount uint32
	white      color.Color = color.RGBA{255, 255, 255, 255}
)
func NewPdf(orientationStr, unitStr, sizeStr string) *gofpdf.Fpdf {
	pdf := gofpdf.New(orientationStr, unitStr, sizeStr, draw2d.GetFontFolder())
	pdf.SetMargins(0, 0, 0)
	pdf.SetDrawColor(0, 0, 0)
	pdf.SetFillColor(255, 255, 255)
	pdf.SetLineCapStyle("round")
	pdf.SetLineJoinStyle("round")
	pdf.SetLineWidth(1)
	pdf.AddPage()
	return pdf
}
func rgb(c color.Color) (int, int, int) {
	r, g, b, _ := c.RGBA()
	return int(float64(r) * c255), int(float64(g) * c255), int(float64(b) * c255)
}
func clearRect(gc *GraphicContext, x1, y1, x2, y2 float64) {
	f := gc.Current.FillColor
	x, y := gc.pdf.GetXY()
	gc.SetFillColor(white)
	draw2dkit.Rectangle(gc, x1, y1, x2, y2)
	gc.Fill()
	gc.SetFillColor(f)
	gc.pdf.MoveTo(x, y)
}
type GraphicContext struct {
	*draw2dbase.StackGraphicContext
	pdf *gofpdf.Fpdf
	DPI int
}
func NewGraphicContext(pdf *gofpdf.Fpdf) *GraphicContext {
	gc := &GraphicContext{draw2dbase.NewStackGraphicContext(), pdf, DPI}
	gc.SetDPI(DPI)
	return gc
}
func (gc *GraphicContext) DrawImage(image image.Image) {
	name := strconv.Itoa(int(imageCount))
	imageCount++
	tp := "PNG"  
	b := &bytes.Buffer{}
	png.Encode(b, image)
	gc.pdf.RegisterImageReader(name, tp, b)
	bounds := image.Bounds()
	x0, y0 := float64(bounds.Min.X), float64(bounds.Min.Y)
	w, h := float64(bounds.Dx()), float64(bounds.Dy())
	gc.pdf.Image(name, x0, y0, w, h, false, tp, 0, "")
}
func (gc *GraphicContext) Clear() {
	width, height := gc.pdf.GetPageSize()
	clearRect(gc, 0, 0, width, height)
}
func (gc *GraphicContext) ClearRect(x1, y1, x2, y2 int) {
	clearRect(gc, float64(x1), float64(y1), float64(x2), float64(y2))
}
func (gc *GraphicContext) recalc() {
	gc.Current.Scale = 3 * float64(gc.DPI) / 72
}
func (gc *GraphicContext) SetDPI(dpi int) {
	gc.DPI = dpi
	gc.recalc()
}
func (gc *GraphicContext) GetDPI() int {
	return gc.DPI
}
func (gc *GraphicContext) GetStringBounds(s string) (left, top, right, bottom float64) {
	_, h := gc.pdf.GetFontSize()
	d := gc.pdf.GetFontDesc("", "")
	if d.Ascent == 0 {
		top = 0.81 * h
	} else {
		top = -float64(d.Ascent) * h / float64(d.Ascent-d.Descent)
	}
	return 0, top, gc.pdf.GetStringWidth(s), top + h
}
func (gc *GraphicContext) CreateStringPath(text string, x, y float64) (cursor float64) {
	left, top, right, bottom := gc.GetStringBounds(text)
	w := right - left
	h := bottom - top
	margin := gc.pdf.GetCellMargin()
	gc.pdf.MoveTo(x-left-margin, y+top)
	gc.pdf.CellFormat(w, h, text, "", 0, "BL", false, 0, "")
	return w
}
func (gc *GraphicContext) FillString(text string) (cursor float64) {
	return gc.FillStringAt(text, 0, 0)
}
func (gc *GraphicContext) FillStringAt(text string, x, y float64) (cursor float64) {
	return gc.CreateStringPath(text, x, y)
}
func (gc *GraphicContext) StrokeString(text string) (cursor float64) {
	return gc.StrokeStringAt(text, 0, 0)
}
func (gc *GraphicContext) StrokeStringAt(text string, x, y float64) (cursor float64) {
	return gc.CreateStringPath(text, x, y)
}
func (gc *GraphicContext) Stroke(paths ...*draw2d.Path) {
	_, _, _, alphaS := gc.Current.StrokeColor.RGBA()
	gc.draw("D", alphaS, paths...)
	gc.Current.Path.Clear()
}
func (gc *GraphicContext) Fill(paths ...*draw2d.Path) {
	style := "F"
	if gc.Current.FillRule != draw2d.FillRuleWinding {
		style += "*"
	}
	_, _, _, alphaF := gc.Current.FillColor.RGBA()
	gc.draw(style, alphaF, paths...)
	gc.Current.Path.Clear()
}
func (gc *GraphicContext) FillStroke(paths ...*draw2d.Path) {
	var rule string
	if gc.Current.FillRule != draw2d.FillRuleWinding {
		rule = "*"
	}
	_, _, _, alphaS := gc.Current.StrokeColor.RGBA()
	_, _, _, alphaF := gc.Current.FillColor.RGBA()
	if alphaS == alphaF {
		gc.draw("FD"+rule, alphaF, paths...)
	} else {
		gc.draw("F"+rule, alphaF, paths...)
		gc.draw("S", alphaS, paths...)
	}
	gc.Current.Path.Clear()
}
var logger = log.New(os.Stdout, "", log.Lshortfile)
const alphaMax = float64(0xFFFF)
func (gc *GraphicContext) draw(style string, alpha uint32, paths ...*draw2d.Path) {
	paths = append(paths, gc.Current.Path)
	for _, p := range paths {
		ConvertPath(p, gc.pdf)
	}
	a := float64(alpha) / alphaMax
	current, blendMode := gc.pdf.GetAlpha()
	if a != current {
		gc.pdf.SetAlpha(a, blendMode)
	}
	gc.pdf.DrawPath(style)
}
func (gc *GraphicContext) SetStrokeColor(c color.Color) {
	gc.StackGraphicContext.SetStrokeColor(c)
	gc.pdf.SetDrawColor(rgb(c))
}
func (gc *GraphicContext) SetFillColor(c color.Color) {
	gc.StackGraphicContext.SetFillColor(c)
	gc.pdf.SetFillColor(rgb(c))
	gc.pdf.SetTextColor(rgb(c))
}
func (gc *GraphicContext) SetFont(font *truetype.Font) {
}
func (gc *GraphicContext) SetFontData(fontData draw2d.FontData) {
	gc.StackGraphicContext.SetFontData(fontData)
	var style string
	if fontData.Style&draw2d.FontStyleBold != 0 {
		style += "B"
	}
	if fontData.Style&draw2d.FontStyleItalic != 0 {
		style += "I"
	}
	fn := draw2d.FontFileName(fontData)
	fn = fn[:len(fn)-4]
	size, _ := gc.pdf.GetFontSize()
	gc.pdf.AddFont(fontData.Name, style, fn+".json")
	gc.pdf.SetFont(fontData.Name, style, size)
}
func (gc *GraphicContext) SetFontSize(fontSize float64) {
	gc.StackGraphicContext.SetFontSize(fontSize)
	gc.recalc()
	gc.pdf.SetFontSize(fontSize * gc.Current.Scale)
}
func (gc *GraphicContext) SetLineDash(Dash []float64, DashOffset float64) {
	gc.StackGraphicContext.SetLineDash(Dash, DashOffset)
	gc.pdf.SetDashPattern(Dash, DashOffset)
}
func (gc *GraphicContext) SetLineWidth(LineWidth float64) {
	gc.StackGraphicContext.SetLineWidth(LineWidth)
	gc.pdf.SetLineWidth(LineWidth)
}
func (gc *GraphicContext) SetLineCap(Cap draw2d.LineCap) {
	gc.StackGraphicContext.SetLineCap(Cap)
	gc.pdf.SetLineCapStyle(caps[Cap])
}
func (gc *GraphicContext) SetLineJoin(Join draw2d.LineJoin) {
	gc.StackGraphicContext.SetLineJoin(Join)
	gc.pdf.SetLineJoinStyle(joins[Join])
}
func (gc *GraphicContext) Scale(sx, sy float64) {
	gc.StackGraphicContext.Scale(sx, sy)
	gc.pdf.TransformScale(sx*100, sy*100, 0, 0)
}
func (gc *GraphicContext) Rotate(angle float64) {
	gc.StackGraphicContext.Rotate(angle)
	gc.pdf.TransformRotate(-angle*180/math.Pi, 0, 0)
}
func (gc *GraphicContext) Translate(tx, ty float64) {
	gc.StackGraphicContext.Translate(tx, ty)
	gc.pdf.TransformTranslate(tx, ty)
}