func (f *Fpdf) SetFillColor(r, g, b int) {
	f.setFillColor(r, g, b)
}
SetFillColor defines the color used for all filling operations (filled
rectangles and cell backgrounds). It is expressed in RGB components (0
-255). The method can be called before the first page is created and the
value is retained from page to page.
package gofpdf
import (
	"bytes"
	"encoding/binary"
	"encoding/json"
	"fmt"
	"image"
	"image/color"
	"image/gif"
	"image/jpeg"
	"image/png"
	"io"
	"io/ioutil"
	"math"
	"os"
	"path"
	"sort"
	"strconv"
	"strings"
	"time"
)
var gl struct {
	catalogSort  bool
	noCompress   bool  
	creationDate time.Time
}
type fmtBuffer struct {
	bytes.Buffer
}
func (b *fmtBuffer) printf(fmtStr string, args ...interface{}) {
	b.Buffer.WriteString(fmt.Sprintf(fmtStr, args...))
}
func fpdfNew(orientationStr, unitStr, sizeStr, fontDirStr string, size SizeType) (f *Fpdf) {
	f = new(Fpdf)
	if orientationStr == "" {
		orientationStr = "p"
	} else {
		orientationStr = strings.ToLower(orientationStr)
	}
	if unitStr == "" {
		unitStr = "mm"
	}
	if sizeStr == "" {
		sizeStr = "A4"
	}
	if fontDirStr == "" {
		fontDirStr = "."
	}
	f.page = 0
	f.n = 2
	f.pages = make([]*bytes.Buffer, 0, 8)
	f.pages = append(f.pages, bytes.NewBufferString(""))  
	f.pageSizes = make(map[int]SizeType)
	f.pageBoxes = make(map[int]map[string]PageBox)
	f.defPageBoxes = make(map[string]PageBox)
	f.state = 0
	f.fonts = make(map[string]fontDefType)
	f.fontFiles = make(map[string]fontFileType)
	f.diffs = make([]string, 0, 8)
	f.templates = make(map[string]Template)
	f.templateObjects = make(map[string]int)
	f.images = make(map[string]*ImageInfoType)
	f.pageLinks = make([][]linkType, 0, 8)
	f.pageLinks = append(f.pageLinks, make([]linkType, 0, 0))  
	f.links = make([]intLinkType, 0, 8)
	f.links = append(f.links, intLinkType{})  
	f.aliasMap = make(map[string]string)
	f.inHeader = false
	f.inFooter = false
	f.lasth = 0
	f.fontFamily = ""
	f.fontStyle = ""
	f.SetFontSize(12)
	f.underline = false
	f.setDrawColor(0, 0, 0)
	f.setFillColor(0, 0, 0)
	f.setTextColor(0, 0, 0)
	f.colorFlag = false
	f.ws = 0
	f.fontpath = fontDirStr
	f.coreFonts = map[string]bool{
		"courier":      true,
		"helvetica":    true,
		"times":        true,
		"symbol":       true,
		"zapfdingbats": true,
	}
	switch unitStr {
	case "pt", "point":
		f.k = 1.0
	case "mm":
		f.k = 72.0 / 25.4
	case "cm":
		f.k = 72.0 / 2.54
	case "in", "inch":
		f.k = 72.0
	default:
		f.err = fmt.Errorf("incorrect unit %s", unitStr)
		return
	}
	f.unitStr = unitStr
	f.stdPageSizes = make(map[string]SizeType)
	f.stdPageSizes["a3"] = SizeType{841.89, 1190.55}
	f.stdPageSizes["a4"] = SizeType{595.28, 841.89}
	f.stdPageSizes["a5"] = SizeType{420.94, 595.28}
	f.stdPageSizes["a6"] = SizeType{297.64, 420.94}
	f.stdPageSizes["a2"] = SizeType{1190.55, 1683.78}
	f.stdPageSizes["a1"] = SizeType{1683.78, 2383.94}
	f.stdPageSizes["letter"] = SizeType{612, 792}
	f.stdPageSizes["legal"] = SizeType{612, 1008}
	f.stdPageSizes["tabloid"] = SizeType{792, 1224}
	if size.Wd > 0 && size.Ht > 0 {
		f.defPageSize = size
	} else {
		f.defPageSize = f.getpagesizestr(sizeStr)
		if f.err != nil {
			return
		}
	}
	f.curPageSize = f.defPageSize
	switch orientationStr {
	case "p", "portrait":
		f.defOrientation = "P"
		f.w = f.defPageSize.Wd
		f.h = f.defPageSize.Ht
	case "l", "landscape":
		f.defOrientation = "L"
		f.w = f.defPageSize.Ht
		f.h = f.defPageSize.Wd
	default:
		f.err = fmt.Errorf("incorrect orientation: %s", orientationStr)
		return
	}
	f.curOrientation = f.defOrientation
	f.wPt = f.w * f.k
	f.hPt = f.h * f.k
	margin := 28.35 / f.k
	f.SetMargins(margin, margin, margin)
	f.cMargin = margin / 10
	f.lineWidth = 0.567 / f.k
	f.SetAutoPageBreak(true, 2*margin)
	f.SetDisplayMode("default", "default")
	if f.err != nil {
		return
	}
	f.acceptPageBreak = func() bool {
		return f.autoPageBreak
	}
	f.SetCompression(!gl.noCompress)
	f.spotColorMap = make(map[string]spotColorType)
	f.blendList = make([]blendModeType, 0, 8)
	f.blendList = append(f.blendList, blendModeType{})  
	f.blendMap = make(map[string]int)
	f.blendMode = "Normal"
	f.alpha = 1
	f.gradientList = make([]gradientType, 0, 8)
	f.gradientList = append(f.gradientList, gradientType{})  
	f.pdfVersion = "1.3"
	f.layerInit()
	f.catalogSort = gl.catalogSort
	f.creationDate = gl.creationDate
	return
}
func NewCustom(init *InitType) (f *Fpdf) {
	return fpdfNew(init.OrientationStr, init.UnitStr, init.SizeStr, init.FontDirStr, init.Size)
}
func New(orientationStr, unitStr, sizeStr, fontDirStr string) (f *Fpdf) {
	return fpdfNew(orientationStr, unitStr, sizeStr, fontDirStr, SizeType{0, 0})
}
func (f *Fpdf) Ok() bool {
	return f.err == nil
}
func (f *Fpdf) Err() bool {
	return f.err != nil
}
func (f *Fpdf) ClearError() {
	f.err = nil
}
func (f *Fpdf) SetErrorf(fmtStr string, args ...interface{}) {
	if f.err == nil {
		f.err = fmt.Errorf(fmtStr, args...)
	}
}
func (f *Fpdf) String() string {
	return "Fpdf " + cnFpdfVersion
}
func (f *Fpdf) SetError(err error) {
	if f.err == nil && err != nil {
		f.err = err
	}
}
func (f *Fpdf) Error() error {
	return f.err
}
func (f *Fpdf) GetPageSize() (width, height float64) {
	width = f.w
	height = f.h
	return
}
func (f *Fpdf) GetMargins() (left, top, right, bottom float64) {
	left = f.lMargin
	top = f.tMargin
	right = f.rMargin
	bottom = f.bMargin
	return
}
func (f *Fpdf) SetMargins(left, top, right float64) {
	f.lMargin = left
	f.tMargin = top
	if right < 0 {
		right = left
	}
	f.rMargin = right
}
func (f *Fpdf) SetLeftMargin(margin float64) {
	f.lMargin = margin
	if f.page > 0 && f.x < margin {
		f.x = margin
	}
}
func (f *Fpdf) GetCellMargin() float64 {
	return f.cMargin
}
func (f *Fpdf) SetCellMargin(margin float64) {
	f.cMargin = margin
}
func (f *Fpdf) SetPageBoxRec(t string, pb PageBox) {
	switch strings.ToLower(t) {
	case "trim":
		fallthrough
	case "trimbox":
		t = "TrimBox"
	case "crop":
		fallthrough
	case "cropbox":
		t = "CropBox"
	case "bleed":
		fallthrough
	case "bleedbox":
		t = "BleedBox"
	case "art":
		fallthrough
	case "artbox":
		t = "ArtBox"
	default:
		f.err = fmt.Errorf("%s is not a valid page box type", t)
		return
	}
	pb.X = pb.X * f.k
	pb.Y = pb.Y * f.k
	pb.Wd = (pb.Wd * f.k) + pb.X
	pb.Ht = (pb.Ht * f.k) + pb.Y
	if f.page > 0 {
		f.pageBoxes[f.page][t] = pb
	}
	f.defPageBoxes[t] = pb
}
func (f *Fpdf) SetPageBox(t string, x, y, wd, ht float64) {
	f.SetPageBoxRec(t, PageBox{SizeType{Wd: wd, Ht: ht}, PointType{X: x, Y: y}})
}
func (f *Fpdf) SetPage(pageNum int) {
	if (pageNum > 0) && (pageNum < len(f.pages)) {
		f.page = pageNum
	}
}
func (f *Fpdf) SetFontLocation(fontDirStr string) {
	f.fontpath = fontDirStr
}
func (f *Fpdf) SetFontLoader(loader FontLoader) {
	f.fontLoader = loader
}
func (f *Fpdf) SetHeaderFuncMode(fnc func(), homeMode bool) {
	f.headerFnc = fnc
	f.headerHomeMode = homeMode
}
func (f *Fpdf) SetHeaderFunc(fnc func()) {
	f.headerFnc = fnc
}
func (f *Fpdf) SetFooterFunc(fnc func()) {
	f.footerFnc = fnc
	f.footerFncLpi = nil
}
func (f *Fpdf) SetFooterFuncLpi(fnc func(lastPage bool)) {
	f.footerFncLpi = fnc
	f.footerFnc = nil
}
func (f *Fpdf) SetTopMargin(margin float64) {
	f.tMargin = margin
}
func (f *Fpdf) SetRightMargin(margin float64) {
	f.rMargin = margin
}
func (f *Fpdf) GetAutoPageBreak() (auto bool, margin float64) {
	auto = f.autoPageBreak
	margin = f.bMargin
	return
}
func (f *Fpdf) SetAutoPageBreak(auto bool, margin float64) {
	f.autoPageBreak = auto
	f.bMargin = margin
	f.pageBreakTrigger = f.h - margin
}
func (f *Fpdf) SetDisplayMode(zoomStr, layoutStr string) {
	if f.err != nil {
		return
	}
	if layoutStr == "" {
		layoutStr = "default"
	}
	switch zoomStr {
	case "fullpage", "fullwidth", "real", "default":
		f.zoomMode = zoomStr
	default:
		f.err = fmt.Errorf("incorrect zoom display mode: %s", zoomStr)
		return
	}
	switch layoutStr {
	case "single", "continuous", "two", "default", "SinglePage", "OneColumn",
		"TwoColumnLeft", "TwoColumnRight", "TwoPageLeft", "TwoPageRight":
		f.layoutMode = layoutStr
	default:
		f.err = fmt.Errorf("incorrect layout display mode: %s", layoutStr)
		return
	}
}
func SetDefaultCompression(compress bool) {
	gl.noCompress = !compress
}
func (f *Fpdf) SetCompression(compress bool) {
	f.compress = compress
}
func (f *Fpdf) SetTitle(titleStr string, isUTF8 bool) {
	if isUTF8 {
		titleStr = utf8toutf16(titleStr)
	}
	f.title = titleStr
}
func (f *Fpdf) SetSubject(subjectStr string, isUTF8 bool) {
	if isUTF8 {
		subjectStr = utf8toutf16(subjectStr)
	}
	f.subject = subjectStr
}
func (f *Fpdf) SetAuthor(authorStr string, isUTF8 bool) {
	if isUTF8 {
		authorStr = utf8toutf16(authorStr)
	}
	f.author = authorStr
}
func (f *Fpdf) SetKeywords(keywordsStr string, isUTF8 bool) {
	if isUTF8 {
		keywordsStr = utf8toutf16(keywordsStr)
	}
	f.keywords = keywordsStr
}
func (f *Fpdf) SetCreator(creatorStr string, isUTF8 bool) {
	if isUTF8 {
		creatorStr = utf8toutf16(creatorStr)
	}
	f.creator = creatorStr
}
func (f *Fpdf) SetXmpMetadata(xmpStream []byte) {
	f.xmp = xmpStream
}
func (f *Fpdf) AliasNbPages(aliasStr string) {
	if aliasStr == "" {
		aliasStr = "{nb}"
	}
	f.aliasNbPagesStr = aliasStr
}
func (f *Fpdf) open() {
	f.state = 1
}
func (f *Fpdf) Close() {
	if f.err == nil {
		if f.clipNest > 0 {
			f.err = fmt.Errorf("clip procedure must be explicitly ended")
		} else if f.transformNest > 0 {
			f.err = fmt.Errorf("transformation procedure must be explicitly ended")
		}
	}
	if f.err != nil {
		return
	}
	if f.state == 3 {
		return
	}
	if f.page == 0 {
		f.AddPage()
		if f.err != nil {
			return
		}
	}
	f.inFooter = true
	if f.footerFnc != nil {
		f.footerFnc()
	} else if f.footerFncLpi != nil {
		f.footerFncLpi(true)
	}
	f.inFooter = false
	f.endpage()
	f.enddoc()
	return
}
func (f *Fpdf) PageSize(pageNum int) (wd, ht float64, unitStr string) {
	sz, ok := f.pageSizes[pageNum]
	if ok {
		sz.Wd, sz.Ht = sz.Wd/f.k, sz.Ht/f.k
	} else {
		sz = f.defPageSize  
	}
	return sz.Wd, sz.Ht, f.unitStr
}
func (f *Fpdf) AddPageFormat(orientationStr string, size SizeType) {
	if f.err != nil {
		return
	}
	if f.page != len(f.pages)-1 {
		f.page = len(f.pages) - 1
	}
	if f.state == 0 {
		f.open()
	}
	familyStr := f.fontFamily
	style := f.fontStyle
	if f.underline {
		style += "U"
	}
	fontsize := f.fontSizePt
	lw := f.lineWidth
	dc := f.color.draw
	fc := f.color.fill
	tc := f.color.text
	cf := f.colorFlag
	if f.page > 0 {
		f.inFooter = true
		if f.footerFnc != nil {
			f.footerFnc()
		} else if f.footerFncLpi != nil {
			f.footerFncLpi(false)  
		}
		f.inFooter = false
		f.endpage()
	}
	f.beginpage(orientationStr, size)
	f.outf("%d J", f.capStyle)
	f.outf("%d j", f.joinStyle)
	f.lineWidth = lw
	f.outf("%.2f w", lw*f.k)
	if len(f.dashArray) > 0 {
		f.outputDashPattern()
	}
	if familyStr != "" {
		f.SetFont(familyStr, style, fontsize)
		if f.err != nil {
			return
		}
	}
	f.color.draw = dc
	if dc.str != "0 G" {
		f.out(dc.str)
	}
	f.color.fill = fc
	if fc.str != "0 g" {
		f.out(fc.str)
	}
	f.color.text = tc
	f.colorFlag = cf
	if f.headerFnc != nil {
		f.inHeader = true
		f.headerFnc()
		f.inHeader = false
		if f.headerHomeMode {
			f.SetHomeXY()
		}
	}
	if f.lineWidth != lw {
		f.lineWidth = lw
		f.outf("%.2f w", lw*f.k)
	}
	if familyStr != "" {
		f.SetFont(familyStr, style, fontsize)
		if f.err != nil {
			return
		}
	}
	if f.color.draw.str != dc.str {
		f.color.draw = dc
		f.out(dc.str)
	}
	if f.color.fill.str != fc.str {
		f.color.fill = fc
		f.out(fc.str)
	}
	f.color.text = tc
	f.colorFlag = cf
	return
}
func (f *Fpdf) AddPage() {
	if f.err != nil {
		return
	}
	f.AddPageFormat(f.defOrientation, f.defPageSize)
	return
}
func (f *Fpdf) PageNo() int {
	return f.page
}
func colorComp(v int) (int, float64) {
	if v < 0 {
		v = 0
	} else if v > 255 {
		v = 255
	}
	return v, float64(v) / 255.0
}
func rgbColorValue(r, g, b int, grayStr, fullStr string) (clr colorType) {
	clr.ir, clr.r = colorComp(r)
	clr.ig, clr.g = colorComp(g)
	clr.ib, clr.b = colorComp(b)
	clr.mode = colorModeRGB
	clr.gray = clr.ir == clr.ig && clr.r == clr.b
	if len(grayStr) > 0 {
		if clr.gray {
			clr.str = sprintf("%.3f %s", clr.r, grayStr)
		} else {
			clr.str = sprintf("%.3f %.3f %.3f %s", clr.r, clr.g, clr.b, fullStr)
		}
	} else {
		clr.str = sprintf("%.3f %.3f %.3f", clr.r, clr.g, clr.b)
	}
	return
}
func (f *Fpdf) SetDrawColor(r, g, b int) {
	f.setDrawColor(r, g, b)
}
func (f *Fpdf) setDrawColor(r, g, b int) {
	f.color.draw = rgbColorValue(r, g, b, "G", "RG")
	if f.page > 0 {
		f.out(f.color.draw.str)
	}
}
func (f *Fpdf) GetDrawColor() (int, int, int) {
	return f.color.draw.ir, f.color.draw.ig, f.color.draw.ib
}