codeberg.org/go-pdf/fpdf@v0.11.1/def.go (about)

     1  // Copyright ©2023 The go-pdf Authors. All rights reserved.
     2  // Use of this source code is governed by a MIT-style
     3  // license that can be found in the LICENSE file.
     4  
     5  /*
     6   * Copyright (c) 2013-2014 Kurt Jung (Gmail: kurt.w.jung)
     7   *
     8   * Permission to use, copy, modify, and distribute this software for any
     9   * purpose with or without fee is hereby granted, provided that the above
    10   * copyright notice and this permission notice appear in all copies.
    11   *
    12   * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
    13   * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
    14   * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
    15   * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
    16   * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
    17   * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
    18   * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
    19   */
    20  
    21  package fpdf
    22  
    23  import (
    24  	"bytes"
    25  	"crypto/sha1"
    26  	"encoding/binary"
    27  	"encoding/gob"
    28  	"encoding/json"
    29  	"fmt"
    30  	"io"
    31  	"math"
    32  	"strconv"
    33  	"time"
    34  )
    35  
    36  // Version of FPDF from which this package is derived
    37  const (
    38  	cnFpdfVersion = "1.7"
    39  )
    40  
    41  type blendModeType struct {
    42  	strokeStr, fillStr, modeStr string
    43  	objNum                      int
    44  }
    45  
    46  type gradientType struct {
    47  	tp                int // 2: linear, 3: radial
    48  	clr1Str, clr2Str  string
    49  	x1, y1, x2, y2, r float64
    50  	objNum            int
    51  }
    52  
    53  const (
    54  	// OrientationPortrait represents the portrait orientation.
    55  	OrientationPortrait = "portrait"
    56  
    57  	// OrientationLandscape represents the landscape orientation.
    58  	OrientationLandscape = "landscape"
    59  )
    60  
    61  const (
    62  	// UnitPoint represents the size unit point
    63  	UnitPoint = "pt"
    64  	// UnitMillimeter represents the size unit millimeter
    65  	UnitMillimeter = "mm"
    66  	// UnitCentimeter represents the size unit centimeter
    67  	UnitCentimeter = "cm"
    68  	// UnitInch represents the size unit inch
    69  	UnitInch = "inch"
    70  )
    71  
    72  const (
    73  	// PageSizeA3 represents DIN/ISO A3 page size
    74  	PageSizeA3 = "A3"
    75  	// PageSizeA4 represents DIN/ISO A4 page size
    76  	PageSizeA4 = "A4"
    77  	// PageSizeA5 represents DIN/ISO A5 page size
    78  	PageSizeA5 = "A5"
    79  	// PageSizeLetter represents US Letter page size
    80  	PageSizeLetter = "Letter"
    81  	// PageSizeLegal represents US Legal page size
    82  	PageSizeLegal = "Legal"
    83  )
    84  
    85  const (
    86  	// BorderNone set no border
    87  	BorderNone = ""
    88  	// BorderFull sets a full border
    89  	BorderFull = "1"
    90  	// BorderLeft sets the border on the left side
    91  	BorderLeft = "L"
    92  	// BorderTop sets the border at the top
    93  	BorderTop = "T"
    94  	// BorderRight sets the border on the right side
    95  	BorderRight = "R"
    96  	// BorderBottom sets the border on the bottom
    97  	BorderBottom = "B"
    98  )
    99  
   100  const (
   101  	// LineBreakNone disables linebreak
   102  	LineBreakNone = 0
   103  	// LineBreakNormal enables normal linebreak
   104  	LineBreakNormal = 1
   105  	// LineBreakBelow enables linebreak below
   106  	LineBreakBelow = 2
   107  )
   108  
   109  const (
   110  	// AlignLeft left aligns the cell
   111  	AlignLeft = "L"
   112  	// AlignRight right aligns the cell
   113  	AlignRight = "R"
   114  	// AlignCenter centers the cell
   115  	AlignCenter = "C"
   116  	// AlignTop aligns the cell to the top
   117  	AlignTop = "T"
   118  	// AlignBottom aligns the cell to the bottom
   119  	AlignBottom = "B"
   120  	// AlignMiddle aligns the cell to the middle
   121  	AlignMiddle = "M"
   122  	// AlignBaseline aligns the cell to the baseline
   123  	AlignBaseline = "B"
   124  )
   125  
   126  type colorMode int
   127  
   128  const (
   129  	colorModeRGB colorMode = iota
   130  	colorModeSpot
   131  )
   132  
   133  type colorType struct {
   134  	r, g, b    float64
   135  	ir, ig, ib int
   136  	mode       colorMode
   137  	spotStr    string // name of current spot color
   138  	gray       bool
   139  	str        string
   140  }
   141  
   142  // SpotColorType specifies a named spot color value
   143  type spotColorType struct {
   144  	id, objID int
   145  	val       cmykColorType
   146  }
   147  
   148  // cmykColorType specifies an ink-based CMYK color value
   149  type cmykColorType struct {
   150  	c, m, y, k byte // 0% to 100%
   151  }
   152  
   153  // SizeType fields Wd and Ht specify the horizontal and vertical extents of a
   154  // document element such as a page.
   155  type SizeType struct {
   156  	Wd, Ht float64
   157  }
   158  
   159  // PointType fields X and Y specify the horizontal and vertical coordinates of
   160  // a point, typically used in drawing.
   161  type PointType struct {
   162  	X, Y float64
   163  }
   164  
   165  // XY returns the X and Y components of the receiver point.
   166  func (p PointType) XY() (float64, float64) {
   167  	return p.X, p.Y
   168  }
   169  
   170  // ImageInfoType contains size, color and other information about an image.
   171  // Changes to this structure should be reflected in its GobEncode and GobDecode
   172  // methods.
   173  type ImageInfoType struct {
   174  	data  []byte  // Raw image data
   175  	smask []byte  // Soft Mask, an 8bit per-pixel transparency mask
   176  	n     int     // Image object number
   177  	w     float64 // Width
   178  	h     float64 // Height
   179  	cs    string  // Color space
   180  	pal   []byte  // Image color palette
   181  	bpc   int     // Bits Per Component
   182  	f     string  // Image filter
   183  	dp    string  // DecodeParms
   184  	trns  []int   // Transparency mask
   185  	scale float64 // Document scale factor
   186  	dpi   float64 // Dots-per-inch found from image file (png only)
   187  	i     string  // SHA-1 checksum of the above values.
   188  }
   189  
   190  type idEncoder struct {
   191  	w   io.Writer
   192  	buf []byte
   193  	err error
   194  }
   195  
   196  func newIDEncoder(w io.Writer) *idEncoder {
   197  	return &idEncoder{
   198  		w:   w,
   199  		buf: make([]byte, 8),
   200  	}
   201  }
   202  
   203  func (enc *idEncoder) i64(v int64) {
   204  	if enc.err != nil {
   205  		return
   206  	}
   207  	binary.LittleEndian.PutUint64(enc.buf, uint64(v))
   208  	_, enc.err = enc.w.Write(enc.buf)
   209  }
   210  
   211  func (enc *idEncoder) f64(v float64) {
   212  	if enc.err != nil {
   213  		return
   214  	}
   215  	binary.LittleEndian.PutUint64(enc.buf, math.Float64bits(v))
   216  	_, enc.err = enc.w.Write(enc.buf)
   217  }
   218  
   219  func (enc *idEncoder) str(v string) {
   220  	if enc.err != nil {
   221  		return
   222  	}
   223  	_, enc.err = enc.w.Write([]byte(v))
   224  }
   225  
   226  func (enc *idEncoder) bytes(v []byte) {
   227  	if enc.err != nil {
   228  		return
   229  	}
   230  	_, enc.err = enc.w.Write(v)
   231  }
   232  
   233  func generateImageID(info *ImageInfoType) (string, error) {
   234  	sha := sha1.New()
   235  	enc := newIDEncoder(sha)
   236  	enc.bytes(info.data)
   237  	enc.bytes(info.smask)
   238  	enc.i64(int64(info.n))
   239  	enc.f64(info.w)
   240  	enc.f64(info.h)
   241  	enc.str(info.cs)
   242  	enc.bytes(info.pal)
   243  	enc.i64(int64(info.bpc))
   244  	enc.str(info.f)
   245  	enc.str(info.dp)
   246  	for _, v := range info.trns {
   247  		enc.i64(int64(v))
   248  	}
   249  	enc.f64(info.scale)
   250  	enc.f64(info.dpi)
   251  	enc.str(info.i)
   252  
   253  	return fmt.Sprintf("%x", sha.Sum(nil)), nil
   254  }
   255  
   256  // GobEncode encodes the receiving image to a byte slice.
   257  func (info *ImageInfoType) GobEncode() (buf []byte, err error) {
   258  	fields := []interface{}{info.data, info.smask, info.n, info.w, info.h, info.cs,
   259  		info.pal, info.bpc, info.f, info.dp, info.trns, info.scale, info.dpi}
   260  	w := new(bytes.Buffer)
   261  	encoder := gob.NewEncoder(w)
   262  	for j := 0; j < len(fields) && err == nil; j++ {
   263  		err = encoder.Encode(fields[j])
   264  	}
   265  	if err == nil {
   266  		buf = w.Bytes()
   267  	}
   268  	return
   269  }
   270  
   271  // GobDecode decodes the specified byte buffer (generated by GobEncode) into
   272  // the receiving image.
   273  func (info *ImageInfoType) GobDecode(buf []byte) (err error) {
   274  	fields := []interface{}{&info.data, &info.smask, &info.n, &info.w, &info.h,
   275  		&info.cs, &info.pal, &info.bpc, &info.f, &info.dp, &info.trns, &info.scale, &info.dpi}
   276  	r := bytes.NewBuffer(buf)
   277  	decoder := gob.NewDecoder(r)
   278  	for j := 0; j < len(fields) && err == nil; j++ {
   279  		err = decoder.Decode(fields[j])
   280  	}
   281  
   282  	info.i, err = generateImageID(info)
   283  	return
   284  }
   285  
   286  // PointConvert returns the value of pt, expressed in points (1/72 inch), as a
   287  // value expressed in the unit of measure specified in New(). Since font
   288  // management in Fpdf uses points, this method can help with line height
   289  // calculations and other methods that require user units.
   290  func (f *Fpdf) PointConvert(pt float64) (u float64) {
   291  	return pt / f.k
   292  }
   293  
   294  // PointToUnitConvert is an alias for PointConvert.
   295  func (f *Fpdf) PointToUnitConvert(pt float64) (u float64) {
   296  	return pt / f.k
   297  }
   298  
   299  // UnitToPointConvert returns the value of u, expressed in the unit of measure
   300  // specified in New(), as a value expressed in points (1/72 inch). Since font
   301  // management in Fpdf uses points, this method can help with setting font sizes
   302  // based on the sizes of other non-font page elements.
   303  func (f *Fpdf) UnitToPointConvert(u float64) (pt float64) {
   304  	return u * f.k
   305  }
   306  
   307  // Extent returns the width and height of the image in the units of the Fpdf
   308  // object.
   309  func (info *ImageInfoType) Extent() (wd, ht float64) {
   310  	return info.Width(), info.Height()
   311  }
   312  
   313  // Width returns the width of the image in the units of the Fpdf object.
   314  func (info *ImageInfoType) Width() float64 {
   315  	return info.w / (info.scale * info.dpi / 72)
   316  }
   317  
   318  // Height returns the height of the image in the units of the Fpdf object.
   319  func (info *ImageInfoType) Height() float64 {
   320  	return info.h / (info.scale * info.dpi / 72)
   321  }
   322  
   323  // SetDpi sets the dots per inch for an image. PNG images MAY have their dpi
   324  // set automatically, if the image specifies it. DPI information is not
   325  // currently available automatically for JPG and GIF images, so if it's
   326  // important to you, you can set it here. It defaults to 72 dpi.
   327  func (info *ImageInfoType) SetDpi(dpi float64) {
   328  	info.dpi = dpi
   329  }
   330  
   331  type fontFileType struct {
   332  	length1, length2 int64
   333  	n                int
   334  	embedded         bool
   335  	content          []byte
   336  	fontType         string
   337  }
   338  
   339  type linkType struct {
   340  	x, y, wd, ht float64
   341  	link         int    // Auto-generated internal link ID or...
   342  	linkStr      string // ...application-provided external link string
   343  }
   344  
   345  type intLinkType struct {
   346  	page int
   347  	y    float64
   348  }
   349  
   350  // outlineType is used for a sidebar outline of bookmarks
   351  type outlineType struct {
   352  	text                                   string
   353  	level, parent, first, last, next, prev int
   354  	y                                      float64
   355  	p                                      int
   356  }
   357  
   358  // InitType is used with NewCustom() to customize an Fpdf instance.
   359  // OrientationStr, UnitStr, SizeStr and FontDirStr correspond to the arguments
   360  // accepted by New(). If the Wd and Ht fields of Size are each greater than
   361  // zero, Size will be used to set the default page size rather than SizeStr. Wd
   362  // and Ht are specified in the units of measure indicated by UnitStr.
   363  type InitType struct {
   364  	OrientationStr string
   365  	UnitStr        string
   366  	SizeStr        string
   367  	Size           SizeType
   368  	FontDirStr     string
   369  }
   370  
   371  // FontLoader is used to read fonts (JSON font specification and zlib compressed font binaries)
   372  // from arbitrary locations (e.g. files, zip files, embedded font resources).
   373  //
   374  // Open provides an io.Reader for the specified font file (.json or .z). The file name
   375  // never includes a path. Open returns an error if the specified file cannot be opened.
   376  type FontLoader interface {
   377  	Open(name string) (io.Reader, error)
   378  }
   379  
   380  // Pdf defines the interface used for various methods. It is implemented by the
   381  // main FPDF instance as well as templates.
   382  type Pdf interface {
   383  	AddFont(familyStr, styleStr, fileStr string)
   384  	AddFontFromBytes(familyStr, styleStr string, jsonFileBytes, zFileBytes []byte)
   385  	AddFontFromReader(familyStr, styleStr string, r io.Reader)
   386  	AddLayer(name string, visible bool) (layerID int)
   387  	AddLink() int
   388  	AddPage()
   389  	AddPageFormat(orientationStr string, size SizeType)
   390  	AddSpotColor(nameStr string, c, m, y, k byte)
   391  	AliasNbPages(aliasStr string)
   392  	ArcTo(x, y, rx, ry, degRotate, degStart, degEnd float64)
   393  	Arc(x, y, rx, ry, degRotate, degStart, degEnd float64, styleStr string)
   394  	BeginLayer(id int)
   395  	Beziergon(points []PointType, styleStr string)
   396  	Bookmark(txtStr string, level int, y float64)
   397  	CellFormat(w, h float64, txtStr, borderStr string, ln int, alignStr string, fill bool, link int, linkStr string)
   398  	Cellf(w, h float64, fmtStr string, args ...interface{})
   399  	Cell(w, h float64, txtStr string)
   400  	Circle(x, y, r float64, styleStr string)
   401  	ClearError()
   402  	ClipCircle(x, y, r float64, outline bool)
   403  	ClipEllipse(x, y, rx, ry float64, outline bool)
   404  	ClipEnd()
   405  	ClipPolygon(points []PointType, outline bool)
   406  	ClipRect(x, y, w, h float64, outline bool)
   407  	ClipRoundedRect(x, y, w, h, r float64, outline bool)
   408  	ClipText(x, y float64, txtStr string, outline bool)
   409  	Close()
   410  	ClosePath()
   411  	CreateTemplateCustom(corner PointType, size SizeType, fn func(*Tpl)) Template
   412  	CreateTemplate(fn func(*Tpl)) Template
   413  	CurveBezierCubicTo(cx0, cy0, cx1, cy1, x, y float64)
   414  	CurveBezierCubic(x0, y0, cx0, cy0, cx1, cy1, x1, y1 float64, styleStr string)
   415  	CurveCubic(x0, y0, cx0, cy0, x1, y1, cx1, cy1 float64, styleStr string)
   416  	CurveTo(cx, cy, x, y float64)
   417  	Curve(x0, y0, cx, cy, x1, y1 float64, styleStr string)
   418  	DrawPath(styleStr string)
   419  	Ellipse(x, y, rx, ry, degRotate float64, styleStr string)
   420  	EndLayer()
   421  	Err() bool
   422  	Error() error
   423  	GetAlpha() (alpha float64, blendModeStr string)
   424  	GetAuthor() string
   425  	GetAutoPageBreak() (auto bool, margin float64)
   426  	GetCatalogSort() bool
   427  	GetCellMargin() float64
   428  	GetCompression() bool
   429  	GetConversionRatio() float64
   430  	GetCreationDate() time.Time
   431  	GetCreator() string
   432  	GetDisplayMode() (zoomStr, layoutStr string)
   433  	GetDrawColor() (int, int, int)
   434  	GetDrawSpotColor() (name string, c, m, y, k byte)
   435  	GetFillColor() (int, int, int)
   436  	GetFillSpotColor() (name string, c, m, y, k byte)
   437  	GetFontDesc(familyStr, styleStr string) FontDescType
   438  	GetFontFamily() string
   439  	GetFontLoader() FontLoader
   440  	GetFontLocation() string
   441  	GetFontSize() (ptSize, unitSize float64)
   442  	GetFontStyle() string
   443  	GetImageInfo(imageStr string) (info *ImageInfoType)
   444  	GetJavascript() string
   445  	GetKeywords() string
   446  	GetLang() string
   447  	GetLineCapStyle() string
   448  	GetLineJoinStyle() string
   449  	GetLineWidth() float64
   450  	GetMargins() (left, top, right, bottom float64)
   451  	GetModificationDate() time.Time
   452  	GetPageSize() (width, height float64)
   453  	GetPageSizeStr(sizeStr string) (size SizeType)
   454  	GetProducer() string
   455  	GetStringWidth(s string) float64
   456  	GetSubject() string
   457  	GetTextColor() (int, int, int)
   458  	GetTextSpotColor() (name string, c, m, y, k byte)
   459  	GetTitle() string
   460  	GetUnderlineThickness() float64
   461  	GetWordSpacing() float64
   462  	GetX() float64
   463  	GetXmpMetadata() []byte
   464  	GetXY() (float64, float64)
   465  	GetY() float64
   466  	HTMLBasicNew() (html HTMLBasicType)
   467  	Image(imageNameStr string, x, y, w, h float64, flow bool, tp string, link int, linkStr string)
   468  	ImageOptions(imageNameStr string, x, y, w, h float64, flow bool, options ImageOptions, link int, linkStr string)
   469  	ImageTypeFromMime(mimeStr string) (tp string)
   470  	LinearGradient(x, y, w, h float64, r1, g1, b1, r2, g2, b2 int, x1, y1, x2, y2 float64)
   471  	LineTo(x, y float64)
   472  	Line(x1, y1, x2, y2 float64)
   473  	LinkString(x, y, w, h float64, linkStr string)
   474  	Link(x, y, w, h float64, link int)
   475  	Ln(h float64)
   476  	MoveTo(x, y float64)
   477  	MultiCell(w, h float64, txtStr, borderStr, alignStr string, fill bool)
   478  	Ok() bool
   479  	OpenLayerPane()
   480  	OutputAndClose(w io.WriteCloser) error
   481  	OutputFileAndClose(fileStr string) error
   482  	Output(w io.Writer) error
   483  	PageCount() int
   484  	PageNo() int
   485  	PageSize(pageNum int) (wd, ht float64, unitStr string)
   486  	PointConvert(pt float64) (u float64)
   487  	PointToUnitConvert(pt float64) (u float64)
   488  	Polygon(points []PointType, styleStr string)
   489  	RadialGradient(x, y, w, h float64, r1, g1, b1, r2, g2, b2 int, x1, y1, x2, y2, r float64)
   490  	RawWriteBuf(r io.Reader)
   491  	RawWriteStr(str string)
   492  	Rect(x, y, w, h float64, styleStr string)
   493  	RegisterAlias(alias, replacement string)
   494  	RegisterImage(fileStr, tp string) (info *ImageInfoType)
   495  	RegisterImageOptions(fileStr string, options ImageOptions) (info *ImageInfoType)
   496  	RegisterImageOptionsReader(imgName string, options ImageOptions, r io.Reader) (info *ImageInfoType)
   497  	RegisterImageReader(imgName, tp string, r io.Reader) (info *ImageInfoType)
   498  	SetAcceptPageBreakFunc(fnc func() bool)
   499  	SetAlpha(alpha float64, blendModeStr string)
   500  	SetAuthor(authorStr string, isUTF8 bool)
   501  	SetAutoPageBreak(auto bool, margin float64)
   502  	SetCatalogSort(flag bool)
   503  	SetCellMargin(margin float64)
   504  	SetCompression(compress bool)
   505  	SetCreationDate(tm time.Time)
   506  	SetCreator(creatorStr string, isUTF8 bool)
   507  	SetDashPattern(dashArray []float64, dashPhase float64)
   508  	SetDisplayMode(zoomStr, layoutStr string)
   509  	SetLang(lang string)
   510  	SetDrawColor(r, g, b int)
   511  	SetDrawSpotColor(nameStr string, tint byte)
   512  	SetError(err error)
   513  	SetErrorf(fmtStr string, args ...interface{})
   514  	SetFillColor(r, g, b int)
   515  	SetFillSpotColor(nameStr string, tint byte)
   516  	SetFont(familyStr, styleStr string, size float64)
   517  	SetFontLoader(loader FontLoader)
   518  	SetFontLocation(fontDirStr string)
   519  	SetFontSize(size float64)
   520  	SetFontStyle(styleStr string)
   521  	SetFontUnitSize(size float64)
   522  	SetFooterFunc(fnc func())
   523  	SetFooterFuncLpi(fnc func(lastPage bool))
   524  	SetHeaderFunc(fnc func())
   525  	SetHeaderFuncMode(fnc func(), homeMode bool)
   526  	SetHomeXY()
   527  	SetJavascript(script string)
   528  	SetKeywords(keywordsStr string, isUTF8 bool)
   529  	SetLeftMargin(margin float64)
   530  	SetLineCapStyle(styleStr string)
   531  	SetLineJoinStyle(styleStr string)
   532  	SetLineWidth(width float64)
   533  	SetLink(link int, y float64, page int)
   534  	SetMargins(left, top, right float64)
   535  	SetPageBoxRec(t string, pb PageBox)
   536  	SetPageBox(t string, x, y, wd, ht float64)
   537  	SetPage(pageNum int)
   538  	SetProtection(actionFlag byte, userPassStr, ownerPassStr string)
   539  	SetRightMargin(margin float64)
   540  	SetSubject(subjectStr string, isUTF8 bool)
   541  	SetTextColor(r, g, b int)
   542  	SetTextSpotColor(nameStr string, tint byte)
   543  	SetTitle(titleStr string, isUTF8 bool)
   544  	SetTopMargin(margin float64)
   545  	SetUnderlineThickness(thickness float64)
   546  	SetXmpMetadata(xmpStream []byte)
   547  	SetX(x float64)
   548  	SetXY(x, y float64)
   549  	SetY(y float64)
   550  	SplitLines(txt []byte, w float64) [][]byte
   551  	String() string
   552  	SVGBasicWrite(sb *SVGBasicType, scale float64)
   553  	Text(x, y float64, txtStr string)
   554  	TransformBegin()
   555  	TransformEnd()
   556  	TransformMirrorHorizontal(x float64)
   557  	TransformMirrorLine(angle, x, y float64)
   558  	TransformMirrorPoint(x, y float64)
   559  	TransformMirrorVertical(y float64)
   560  	TransformRotate(angle, x, y float64)
   561  	TransformScale(scaleWd, scaleHt, x, y float64)
   562  	TransformScaleX(scaleWd, x, y float64)
   563  	TransformScaleXY(s, x, y float64)
   564  	TransformScaleY(scaleHt, x, y float64)
   565  	TransformSkew(angleX, angleY, x, y float64)
   566  	TransformSkewX(angleX, x, y float64)
   567  	TransformSkewY(angleY, x, y float64)
   568  	Transform(tm TransformMatrix)
   569  	TransformTranslate(tx, ty float64)
   570  	TransformTranslateX(tx float64)
   571  	TransformTranslateY(ty float64)
   572  	UnicodeTranslatorFromDescriptor(cpStr string) (rep func(string) string)
   573  	UnitToPointConvert(u float64) (pt float64)
   574  	UseTemplateScaled(t Template, corner PointType, size SizeType)
   575  	UseTemplate(t Template)
   576  	WriteAligned(width, lineHeight float64, textStr, alignStr string)
   577  	Writef(h float64, fmtStr string, args ...interface{})
   578  	Write(h float64, txtStr string)
   579  	WriteLinkID(h float64, displayStr string, linkID int)
   580  	WriteLinkString(h float64, displayStr, targetStr string)
   581  }
   582  
   583  // PageBox defines the coordinates and extent of the various page box types
   584  type PageBox struct {
   585  	SizeType
   586  	PointType
   587  }
   588  
   589  // Fpdf is the principal structure for creating a single PDF document
   590  type Fpdf struct {
   591  	isCurrentUTF8    bool                       // is current font used in utf-8 mode
   592  	isRTL            bool                       // is is right to left mode enabled
   593  	page             int                        // current page number
   594  	n                int                        // current object number
   595  	offsets          []int                      // array of object offsets
   596  	templates        map[string]Template        // templates used in this document
   597  	templateObjects  map[string]int             // template object IDs within this document
   598  	importedObjs     map[string][]byte          // imported template objects (gofpdi)
   599  	importedObjPos   map[string]map[int]string  // imported template objects hashes and their positions (gofpdi)
   600  	importedTplObjs  map[string]string          // imported template names and IDs (hashed) (gofpdi)
   601  	importedTplIDs   map[string]int             // imported template ids hash to object id int (gofpdi)
   602  	buffer           fmtBuffer                  // buffer holding in-memory PDF
   603  	pages            []*bytes.Buffer            // slice[page] of page content; 1-based
   604  	state            int                        // current document state
   605  	compress         bool                       // compression flag
   606  	k                float64                    // scale factor (number of points in user unit)
   607  	defOrientation   string                     // default orientation
   608  	curOrientation   string                     // current orientation
   609  	stdPageSizes     map[string]SizeType        // standard page sizes
   610  	defPageSize      SizeType                   // default page size
   611  	defPageBoxes     map[string]PageBox         // default page size
   612  	curPageSize      SizeType                   // current page size
   613  	pageSizes        map[int]SizeType           // used for pages with non default sizes or orientations
   614  	pageBoxes        map[int]map[string]PageBox // used to define the crop, trim, bleed and art boxes
   615  	unitStr          string                     // unit of measure for all rendered objects except fonts
   616  	wPt, hPt         float64                    // dimensions of current page in points
   617  	w, h             float64                    // dimensions of current page in user unit
   618  	lMargin          float64                    // left margin
   619  	tMargin          float64                    // top margin
   620  	rMargin          float64                    // right margin
   621  	bMargin          float64                    // page break margin
   622  	cMargin          float64                    // cell margin
   623  	x, y             float64                    // current position in user unit
   624  	lasth            float64                    // height of last printed cell
   625  	lineWidth        float64                    // line width in user unit
   626  	fontpath         string                     // path containing fonts
   627  	fontLoader       FontLoader                 // used to load font files from arbitrary locations
   628  	coreFonts        map[string]bool            // array of core font names
   629  	fonts            map[string]fontDefType     // array of used fonts
   630  	fontFiles        map[string]fontFileType    // array of font files
   631  	diffs            []string                   // array of encoding differences
   632  	fontFamily       string                     // current font family
   633  	fontStyle        string                     // current font style
   634  	underline        bool                       // underlining flag
   635  	strikeout        bool                       // strike out flag
   636  	currentFont      fontDefType                // current font info
   637  	fontSizePt       float64                    // current font size in points
   638  	fontSize         float64                    // current font size in user unit
   639  	ws               float64                    // word spacing
   640  	images           map[string]*ImageInfoType  // array of used images
   641  	aliasMap         map[string]string          // map of alias->replacement
   642  	pageLinks        [][]linkType               // pageLinks[page][link], both 1-based
   643  	links            []intLinkType              // array of internal links
   644  	attachments      []Attachment               // slice of content to embed globally
   645  	pageAttachments  [][]annotationAttach       // 1-based array of annotation for file attachments (per page)
   646  	outlines         []outlineType              // array of outlines
   647  	outlineRoot      int                        // root of outlines
   648  	autoPageBreak    bool                       // automatic page breaking
   649  	acceptPageBreak  func() bool                // returns true to accept page break
   650  	pageBreakTrigger float64                    // threshold used to trigger page breaks
   651  	inHeader         bool                       // flag set when processing header
   652  	headerFnc        func()                     // function provided by app and called to write header
   653  	headerHomeMode   bool                       // set position to home after headerFnc is called
   654  	inFooter         bool                       // flag set when processing footer
   655  	footerFnc        func()                     // function provided by app and called to write footer
   656  	footerFncLpi     func(bool)                 // function provided by app and called to write footer with last page flag
   657  	zoomMode         string                     // zoom display mode
   658  	layoutMode       string                     // layout display mode
   659  	nXMP             int                        // XMP object number
   660  	xmp              []byte                     // XMP metadata
   661  	producer         string                     // producer
   662  	title            string                     // title
   663  	subject          string                     // subject
   664  	author           string                     // author
   665  	lang             string                     // lang
   666  	keywords         string                     // keywords
   667  	creator          string                     // creator
   668  	creationDate     time.Time                  // override for document CreationDate value
   669  	modDate          time.Time                  // override for document ModDate value
   670  	aliasNbPagesStr  string                     // alias for total number of pages
   671  	pdfVersion       pdfVersion                 // PDF version number
   672  	fontDirStr       string                     // location of font definition files
   673  	capStyle         int                        // line cap style: butt 0, round 1, square 2
   674  	joinStyle        int                        // line segment join style: miter 0, round 1, bevel 2
   675  	dashArray        []float64                  // dash array
   676  	dashPhase        float64                    // dash phase
   677  	blendList        []blendModeType            // slice[idx] of alpha transparency modes, 1-based
   678  	blendMap         map[string]int             // map into blendList
   679  	blendMode        string                     // current blend mode
   680  	alpha            float64                    // current transpacency
   681  	gradientList     []gradientType             // slice[idx] of gradient records
   682  	clipNest         int                        // Number of active clipping contexts
   683  	transformNest    int                        // Number of active transformation contexts
   684  	err              error                      // Set if error occurs during life cycle of instance
   685  	protect          protectType                // document protection structure
   686  	layer            layerRecType               // manages optional layers in document
   687  	catalogSort      bool                       // sort resource catalogs in document
   688  	nJs              int                        // JavaScript object number
   689  	javascript       *string                    // JavaScript code to include in the PDF
   690  	colorFlag        bool                       // indicates whether fill and text colors are different
   691  	color            struct {
   692  		// Composite values of colors
   693  		draw, fill, text colorType
   694  	}
   695  	spotColorMap           map[string]spotColorType // Map of named ink-based colors
   696  	userUnderlineThickness float64                  // A custom user underline thickness multiplier.
   697  
   698  	fmt struct {
   699  		buf []byte       // buffer used to format numbers.
   700  		col bytes.Buffer // buffer used to build color strings.
   701  	}
   702  }
   703  
   704  const (
   705  	pdfVers1_3 = pdfVersion(uint16(1)<<8 | uint16(3))
   706  	pdfVers1_4 = pdfVersion(uint16(1)<<8 | uint16(4))
   707  	pdfVers1_5 = pdfVersion(uint16(1)<<8 | uint16(5))
   708  )
   709  
   710  type pdfVersion uint16
   711  
   712  func pdfVersionFrom(maj, min uint) pdfVersion {
   713  	if min > 255 {
   714  		panic(fmt.Errorf("fpdf: invalid PDF version %d.%d", maj, min))
   715  	}
   716  	return pdfVersion(uint16(maj)<<8 | uint16(min))
   717  }
   718  
   719  func (v pdfVersion) String() string {
   720  	maj := int64(byte(v >> 8))
   721  	min := int64(byte(v))
   722  	return strconv.FormatInt(maj, 10) + "." + strconv.FormatInt(min, 10)
   723  }
   724  
   725  type encType struct {
   726  	uv   int
   727  	name string
   728  }
   729  
   730  type encListType [256]encType
   731  
   732  type fontBoxType struct {
   733  	Xmin, Ymin, Xmax, Ymax int
   734  }
   735  
   736  // Font flags for FontDescType.Flags as defined in the pdf specification.
   737  const (
   738  	// FontFlagFixedPitch is set if all glyphs have the same width (as
   739  	// opposed to proportional or variable-pitch fonts, which have
   740  	// different widths).
   741  	FontFlagFixedPitch = 1 << 0
   742  	// FontFlagSerif is set if glyphs have serifs, which are short
   743  	// strokes drawn at an angle on the top and bottom of glyph stems.
   744  	// (Sans serif fonts do not have serifs.)
   745  	FontFlagSerif = 1 << 1
   746  	// FontFlagSymbolic is set if font contains glyphs outside the
   747  	// Adobe standard Latin character set. This flag and the
   748  	// Nonsymbolic flag shall not both be set or both be clear.
   749  	FontFlagSymbolic = 1 << 2
   750  	// FontFlagScript is set if glyphs resemble cursive handwriting.
   751  	FontFlagScript = 1 << 3
   752  	// FontFlagNonsymbolic is set if font uses the Adobe standard
   753  	// Latin character set or a subset of it.
   754  	FontFlagNonsymbolic = 1 << 5
   755  	// FontFlagItalic is set if glyphs have dominant vertical strokes
   756  	// that are slanted.
   757  	FontFlagItalic = 1 << 6
   758  	// FontFlagAllCap is set if font contains no lowercase letters;
   759  	// typically used for display purposes, such as for titles or
   760  	// headlines.
   761  	FontFlagAllCap = 1 << 16
   762  	// SmallCap is set if font contains both uppercase and lowercase
   763  	// letters. The uppercase letters are similar to those in the
   764  	// regular version of the same typeface family. The glyphs for the
   765  	// lowercase letters have the same shapes as the corresponding
   766  	// uppercase letters, but they are sized and their proportions
   767  	// adjusted so that they have the same size and stroke weight as
   768  	// lowercase glyphs in the same typeface family.
   769  	SmallCap = 1 << 18
   770  	// ForceBold determines whether bold glyphs shall be painted with
   771  	// extra pixels even at very small text sizes by a conforming
   772  	// reader. If the ForceBold flag is set, features of bold glyphs
   773  	// may be thickened at small text sizes.
   774  	ForceBold = 1 << 18
   775  )
   776  
   777  // FontDescType (font descriptor) specifies metrics and other
   778  // attributes of a font, as distinct from the metrics of individual
   779  // glyphs (as defined in the pdf specification).
   780  type FontDescType struct {
   781  	// The maximum height above the baseline reached by glyphs in this
   782  	// font (for example for "S"). The height of glyphs for accented
   783  	// characters shall be excluded.
   784  	Ascent int
   785  	// The maximum depth below the baseline reached by glyphs in this
   786  	// font. The value shall be a negative number.
   787  	Descent int
   788  	// The vertical coordinate of the top of flat capital letters,
   789  	// measured from the baseline (for example "H").
   790  	CapHeight int
   791  	// A collection of flags defining various characteristics of the
   792  	// font. (See the FontFlag* constants.)
   793  	Flags int
   794  	// A rectangle, expressed in the glyph coordinate system, that
   795  	// shall specify the font bounding box. This should be the smallest
   796  	// rectangle enclosing the shape that would result if all of the
   797  	// glyphs of the font were placed with their origins coincident
   798  	// and then filled.
   799  	FontBBox fontBoxType
   800  	// The angle, expressed in degrees counterclockwise from the
   801  	// vertical, of the dominant vertical strokes of the font. (The
   802  	// 9-o’clock position is 90 degrees, and the 3-o’clock position
   803  	// is –90 degrees.) The value shall be negative for fonts that
   804  	// slope to the right, as almost all italic fonts do.
   805  	ItalicAngle int
   806  	// The thickness, measured horizontally, of the dominant vertical
   807  	// stems of glyphs in the font.
   808  	StemV int
   809  	// The width to use for character codes whose widths are not
   810  	// specified in a font dictionary’s Widths array. This shall have
   811  	// a predictable effect only if all such codes map to glyphs whose
   812  	// actual widths are the same as the value of the MissingWidth
   813  	// entry. (Default value: 0.)
   814  	MissingWidth int
   815  }
   816  
   817  type fontDefType struct {
   818  	Tp           string        // "Core", "TrueType", ...
   819  	Name         string        // "Courier-Bold", ...
   820  	Desc         FontDescType  // Font descriptor
   821  	Up           int           // Underline position
   822  	Ut           int           // Underline thickness
   823  	Cw           []int         // Character width by ordinal
   824  	Enc          string        // "cp1252", ...
   825  	Diff         string        // Differences from reference encoding
   826  	File         string        // "Redressed.z"
   827  	Size1, Size2 int           // Type1 values
   828  	OriginalSize int           // Size of uncompressed font file
   829  	N            int           // Set by font loader
   830  	DiffN        int           // Position of diff in app array, set by font loader
   831  	i            string        // 1-based position in font list, set by font loader, not this program
   832  	utf8File     *utf8FontFile // UTF-8 font
   833  	usedRunes    map[int]int   // Array of used runes
   834  }
   835  
   836  // generateFontID generates a font Id from the font definition
   837  func generateFontID(fdt fontDefType) (string, error) {
   838  	// file can be different if generated in different instance
   839  	fdt.File = ""
   840  	b, err := json.Marshal(&fdt)
   841  	return fmt.Sprintf("%x", sha1.Sum(b)), err
   842  }
   843  
   844  type fontInfoType struct {
   845  	Data               []byte
   846  	File               string
   847  	OriginalSize       int
   848  	FontName           string
   849  	Bold               bool
   850  	IsFixedPitch       bool
   851  	UnderlineThickness int
   852  	UnderlinePosition  int
   853  	Widths             []int
   854  	Size1, Size2       uint32
   855  	Desc               FontDescType
   856  }