Documentation
¶
Overview ¶
Package pdf manages PDF document creation, page layout, and styling.
Index ¶
- Constants
- Variables
- func FontSupportsGlyph(fontData []byte, r rune) bool
- func HeadingLineHeight(fontSize float64) float64
- func HeadingSpaceAfter(level int) float64
- func HeadingSpaceBefore(level int) float64
- func LoadCustomEmojiFont(pdf *fpdf.Fpdf, archivePath string) ([]byte, error)
- func LoadCustomFonts(pdf *fpdf.Fpdf, archivePath string) ([]byte, error)
- func LoadCustomSymbolsFont(pdf *fpdf.Fpdf, archivePath string) ([]byte, error)
- func RegisterEmojiFont(pdf *fpdf.Fpdf) []byte
- func RegisterFonts(pdf *fpdf.Fpdf) []byte
- func RegisterSymbolsFont(pdf *fpdf.Fpdf) []byte
- func SubstituteUnsupportedGlyphs(bodyFont, symbolsFont, emojiFont []byte, text string) string
- type Document
- func (d *Document) BaseDir() string
- func (d *Document) BodyFontBytes() []byte
- func (d *Document) EmojiFontBytes() []byte
- func (d *Document) FooterCalls() int
- func (d *Document) PDF() *fpdf.Fpdf
- func (d *Document) Save(path string) error
- func (d *Document) SetBaseDir(dir string)
- func (d *Document) SymbolsFontBytes() []byte
- type DocumentOption
- type FontKind
- type TextSegment
Constants ¶
const ( FontBody = "NotoSans" FontCode = "NotoSansMono" FontSymbols = "NotoSansSymbols2" FontEmoji = "NotoEmoji" FontSizeBody = 11.0 FontSizeH1 = 24.0 FontSizeH2 = 20.0 FontSizeH3 = 16.0 FontSizeH4 = 14.0 FontSizeH5 = 12.0 FontSizeH6 = 11.0 FontSizeCoverTitle = 36.0 // Large title on cover page FontSizeCoverSubtitle = 18.0 // Subtitle below title FontSizeCoverMeta = 14.0 // Author, date, version CoverTitleY = 80.0 // Y position for title (from top, mm) CoverSpacing = 12.0 // Vertical spacing between cover elements CoverMetaSpace = 8.0 // Spacing between metadata fields LineHeight = 6.0 PageMargin = 20.0 BlockquoteIndent = 10.0 BlockquoteBar = 2.0 FontSizeCode = 9.0 CodeBlockPadding = 6.0 CodeBlockMarginV = 4.0 ListIndent = 7.0 // left margin increase per nesting level (LaTeX ~2.5em) ListLabelWidth = 5.0 // width of the label box (right-aligned labels) ListLabelSep = 2.0 // gap between label box and text (LaTeX \labelsep ≈ 5pt) ListBulletSize = 2.0 ListItemSpacing = 2.0 TableCellPadding = 3.0 TableBorderWidth = 0.3 FontSizeTable = 10.0 ImageMarginV = 4.0 SVGRenderScale = 2.0 CodeContinuationIndicator = " →" // → shows code wraps to next line (falls back to "->" if unsupported) // Heading spacing (LaTeX article.cls inspired, ~1.5:1 before:after ratio). // LaTeX \section uses 3.5ex/2.3ex (~1.52:1), CSS uses 1:1 symmetric. // We use ~1.4–1.5:1 as a balanced professional compromise. // Before: space above heading (proximity break from previous content). // After: space below heading (closer to its own content). HeadingBeforeH1 = 14.0 // ~40pt HeadingBeforeH2 = 12.0 // ~34pt HeadingBeforeH3 = 10.0 // ~28pt HeadingBeforeH4 = 8.0 // ~23pt HeadingBeforeH5 = 6.0 // ~17pt HeadingBeforeH6 = 5.0 // ~14pt HeadingAfterH1 = 10.0 // ~28pt (ratio 1.40:1) HeadingAfterH2 = 8.0 // ~23pt (ratio 1.50:1) HeadingAfterH3 = 6.5 // ~18pt (ratio 1.54:1) HeadingAfterH4 = 5.5 // ~16pt (ratio 1.45:1) HeadingAfterH5 = 4.0 // ~11pt (ratio 1.50:1) HeadingAfterH6 = 3.5 // ~10pt (ratio 1.43:1) // Heading line height multiplier (tighter than body text for visual impact). HeadingLeading = 1.25 )
Variables ¶
var ( // ListBulletChars are the UTF-8 bullet characters by nesting depth. ListBulletChars = []rune{'•', '‣', '⁃'} ColorText = fpdf.RGBType{R: 20, G: 20, B: 20} ColorLink = fpdf.RGBType{R: 20, G: 90, B: 200} ColorBlockquote = fpdf.RGBType{R: 230, G: 230, B: 230} ColorCodeFill = fpdf.RGBType{R: 240, G: 240, B: 240} ColorCodeBlockBG = fpdf.RGBType{R: 245, G: 245, B: 245} ColorCodeBlockBorder = fpdf.RGBType{R: 220, G: 220, B: 220} ColorTableHeader = fpdf.RGBType{R: 240, G: 240, B: 240} ColorTableBorder = fpdf.RGBType{R: 180, G: 180, B: 180} )
Functions ¶
func FontSupportsGlyph ¶ added in v0.0.3
FontSupportsGlyph checks whether the given TTF font data contains a glyph for the specified rune. It uses golang.org/x/image/font/sfnt to parse the font's cmap table. A GlyphIndex of 0 means the .notdef (missing) glyph.
func HeadingLineHeight ¶ added in v0.0.3
HeadingLineHeight returns the line height (mm) for multi-line headings. It uses a tighter leading (1.25×) than body text for visual impact.
func HeadingSpaceAfter ¶ added in v0.0.3
HeadingSpaceAfter returns the vertical space (mm) to insert below a heading.
func HeadingSpaceBefore ¶ added in v0.0.3
HeadingSpaceBefore returns the vertical space (mm) to insert above a heading.
func LoadCustomEmojiFont ¶ added in v0.0.3
LoadCustomEmojiFont reads a zip or tar.gz archive and registers the first TTF found as the emoji fallback font family. Returns the font bytes.
func LoadCustomFonts ¶ added in v0.0.3
LoadCustomFonts reads a zip or tar.gz archive from path, extracts all .ttf files, and registers them as the body font family on the PDF document. It maps filename patterns (Regular, Bold, Italic, BoldItalic) to fpdf styles. Returns the regular font bytes (for glyph detection) or an error.
func LoadCustomSymbolsFont ¶ added in v0.0.3
LoadCustomSymbolsFont reads a zip or tar.gz archive and registers the first TTF found as the symbols fallback font family. Returns the font bytes.
func RegisterEmojiFont ¶ added in v0.0.3
RegisterEmojiFont registers the embedded Noto Emoji font as the third-tier fallback font family for rendering emoji glyphs that neither the body nor symbols font supports. It returns the emoji font bytes for glyph detection.
func RegisterFonts ¶
RegisterFonts registers the embedded Noto Sans font families with the PDF document. After registration, FontBody and FontCode constants can be used with SetFont as usual. It returns the regular body font bytes for glyph detection.
func RegisterSymbolsFont ¶ added in v0.0.3
RegisterSymbolsFont registers the embedded Noto Sans Symbols 2 font as a fallback font family for rendering glyphs the body font doesn't support. It returns the symbols font bytes for glyph detection.
func SubstituteUnsupportedGlyphs ¶ added in v0.0.3
SubstituteUnsupportedGlyphs replaces runes that neither the body nor symbols font can render with ASCII text equivalents from the substitution table. Runes renderable by the symbols font are kept as-is (they will be rendered via font fallback). This function is used for text measurement where we need a flat string rather than segmented output.
Types ¶
type Document ¶
type Document struct {
// contains filtered or unexported fields
}
func NewDocument ¶
func NewDocument(opts ...DocumentOption) (*Document, error)
func (*Document) BodyFontBytes ¶ added in v0.0.3
BodyFontBytes returns the raw TTF bytes of the regular body font, used for glyph detection (e.g. checking if bullet characters exist).
func (*Document) EmojiFontBytes ¶ added in v0.0.3
EmojiFontBytes returns the raw TTF bytes of the emoji fallback font, used for glyph detection when neither the body nor symbols font has a glyph.
func (*Document) FooterCalls ¶
func (*Document) SetBaseDir ¶
func (*Document) SymbolsFontBytes ¶ added in v0.0.3
SymbolsFontBytes returns the raw TTF bytes of the symbols fallback font, used for glyph detection when the body font lacks a glyph.
type DocumentOption ¶ added in v0.0.3
type DocumentOption func(*documentConfig)
DocumentOption configures Document creation.
func WithCustomEmojiFont ¶ added in v0.0.3
func WithCustomEmojiFont(archivePath string) DocumentOption
WithCustomEmojiFont returns an option that loads an emoji fallback font from a zip or tar.gz archive instead of the default embedded Noto Emoji.
func WithCustomFont ¶ added in v0.0.3
func WithCustomFont(archivePath string) DocumentOption
WithCustomFont returns an option that loads fonts from a zip or tar.gz archive instead of the default embedded Noto Sans.
func WithCustomSymbolsFont ¶ added in v0.0.3
func WithCustomSymbolsFont(archivePath string) DocumentOption
WithCustomSymbolsFont returns an option that loads a symbols fallback font from a zip or tar.gz archive instead of the default embedded Noto Sans Symbols 2.
type FontKind ¶ added in v0.0.3
type FontKind int
FontKind indicates which font family a text segment should be rendered with.
const ( // FontKindBody means the segment should be rendered with the body font. FontKindBody FontKind = iota // FontKindSymbols means the segment should be rendered with the symbols fallback font. FontKindSymbols // FontKindEmoji means the segment should be rendered with the emoji fallback font. FontKindEmoji )
type TextSegment ¶ added in v0.0.3
TextSegment is a contiguous run of text that should be rendered with a single font family. The renderer switches fonts between segments.
func SegmentText ¶ added in v0.0.3
func SegmentText(bodyFont, symbolsFont, emojiFont []byte, text string) []TextSegment
SegmentText splits text into segments tagged with the font that can render them. It checks each rune against the body font first, then the symbols font, and falls back to text substitution if neither font has the glyph.
Adjacent runes using the same font are coalesced into a single segment.