Documentation
¶
Overview ¶
Package writer implements PDF writing infrastructure.
Package writer provides infrastructure for writing PDF files.
This package implements the low-level PDF writing functionality, including object management, cross-reference tables, and file structure.
Package writer provides PDF writing infrastructure for generating PDF files.
Package writer implements PDF writing infrastructure.
Package writer implements PDF writing infrastructure.
Index ¶
- func CompressStream(data []byte, level CompressionLevel) ([]byte, error)
- func CreateAcroFormDict(fieldRefs []int, fontObjNum int) string
- func CreateFontObjects(textOps []TextOp) (map[string]*fonts.Standard14Font, error)
- func DecompressStream(data []byte) ([]byte, error)
- func EscapePDFString(s string) string
- func EstimateCompressionRatio(data []byte) float64
- func ShouldCompress(data []byte) bool
- type BezierSegment
- type CMYK
- type ColorStopOp
- type CompressionLevel
- type ContentStreamWriter
- func (csw *ContentStreamWriter) BeginText()
- func (csw *ContentStreamWriter) Bytes() []byte
- func (csw *ContentStreamWriter) CloseAndStroke()
- func (csw *ContentStreamWriter) ClosePath()
- func (csw *ContentStreamWriter) Compress() ([]byte, error)deprecated
- func (csw *ContentStreamWriter) CompressedBytes() ([]byte, error)
- func (csw *ContentStreamWriter) ConcatMatrix(a, b, c, d, e, f float64)
- func (csw *ContentStreamWriter) CurveTo(x1, y1, x2, y2, x3, y3 float64)
- func (csw *ContentStreamWriter) EndPath()
- func (csw *ContentStreamWriter) EndText()
- func (csw *ContentStreamWriter) Fill()
- func (csw *ContentStreamWriter) FillAndStroke()
- func (csw *ContentStreamWriter) FillAndStrokeEvenOdd()
- func (csw *ContentStreamWriter) FillEvenOdd()
- func (csw *ContentStreamWriter) GetCompression() CompressionLevel
- func (csw *ContentStreamWriter) IsCompressed() bool
- func (csw *ContentStreamWriter) Len() int
- func (csw *ContentStreamWriter) LineTo(x, y float64)
- func (csw *ContentStreamWriter) MoveTextPosition(tx, ty float64)
- func (csw *ContentStreamWriter) MoveTextPositionSetLeading(tx, ty float64)
- func (csw *ContentStreamWriter) MoveTo(x, y float64)
- func (csw *ContentStreamWriter) MoveToNextLine()
- func (csw *ContentStreamWriter) Rectangle(x, y, width, height float64)
- func (csw *ContentStreamWriter) Reset()
- func (csw *ContentStreamWriter) RestoreState()
- func (csw *ContentStreamWriter) SaveState()
- func (csw *ContentStreamWriter) SetCompression(level CompressionLevel)
- func (csw *ContentStreamWriter) SetDashPattern(dashArray []float64, dashPhase float64)
- func (csw *ContentStreamWriter) SetFillColorCMYK(c, m, y, k float64)
- func (csw *ContentStreamWriter) SetFillColorGray(gray float64)
- func (csw *ContentStreamWriter) SetFillColorRGB(r, g, b float64)
- func (csw *ContentStreamWriter) SetFont(fontName string, size float64)
- func (csw *ContentStreamWriter) SetLeading(leading float64)
- func (csw *ContentStreamWriter) SetLineCap(style int)
- func (csw *ContentStreamWriter) SetLineJoin(style int)
- func (csw *ContentStreamWriter) SetLineWidth(width float64)
- func (csw *ContentStreamWriter) SetMiterLimit(limit float64)
- func (csw *ContentStreamWriter) SetStrokeColorCMYK(c, m, y, k float64)
- func (csw *ContentStreamWriter) SetStrokeColorGray(gray float64)
- func (csw *ContentStreamWriter) SetStrokeColorRGB(r, g, b float64)
- func (csw *ContentStreamWriter) SetTextMatrix(a, b, c, d, e, f float64)
- func (csw *ContentStreamWriter) ShowText(text string)
- func (csw *ContentStreamWriter) ShowTextNextLine(text string)
- func (csw *ContentStreamWriter) String() string
- func (csw *ContentStreamWriter) Stroke()
- type GradientOp
- type GradientType
- type GraphicsOp
- type IndirectObject
- type PageContent
- type PdfWriter
- func (w *PdfWriter) Close() error
- func (w *PdfWriter) Write(doc *document.Document) error
- func (w *PdfWriter) WriteAllAnnotations(page *document.Page) ([]*IndirectObject, []int, error)
- func (w *PdfWriter) WriteAnnotations(annotations []*document.LinkAnnotation) ([]*IndirectObject, []int, error)
- func (w *PdfWriter) WriteWithAllContent(doc *document.Document, textContents map[int][]TextOp, ...) error
- func (w *PdfWriter) WriteWithPageContent(doc *document.Document, pageContents map[int][]TextOp) error
- type Point
- type RGB
- type ResourceDictionary
- func (rd *ResourceDictionary) AddExtGState(objNum int) string
- func (rd *ResourceDictionary) AddFont(objNum int) string
- func (rd *ResourceDictionary) AddImage(objNum int) string
- func (rd *ResourceDictionary) Bytes() []byte
- func (rd *ResourceDictionary) HasResources() bool
- func (rd *ResourceDictionary) String() string
- type TextOp
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CompressStream ¶
func CompressStream(data []byte, level CompressionLevel) ([]byte, error)
CompressStream compresses data using zlib (FlateDecode in PDF terminology).
PDF's FlateDecode filter uses zlib compression, which includes:
- 2-byte zlib header
- Deflate-compressed data
- 4-byte Adler-32 checksum
This is different from raw deflate compression.
Parameters:
- data: Uncompressed data to compress
- level: Compression level (NoCompression, BestSpeed, DefaultCompression, BestCompression)
Returns:
- compressed: Compressed data (zlib format)
- error: Any error that occurred
Example:
content := []byte("BT /F1 12 Tf 100 700 Td (Hello) Tj ET")
compressed, err := CompressStream(content, DefaultCompression)
Reference: PDF 1.7 Specification, Section 7.4.4 (FlateDecode Filter).
func CreateAcroFormDict ¶
CreateAcroFormDict creates the AcroForm dictionary for the catalog.
The AcroForm dictionary is required when a document contains form fields. It includes:
- /Fields: Array of all form field references
- /NeedAppearances: true (let the PDF reader generate appearances)
- /DR: Default resources (fonts)
- /DA: Default appearance string
PDF structure:
<<
/Fields [101 0 R 102 0 R ...]
/NeedAppearances true
/DR <<
/Font <<
/Helv 5 0 R
/Cour 6 0 R
/TiRo 7 0 R
>>
>>
/DA (/Helv 12 Tf 0 g)
>>
Parameters:
- fieldRefs: Array of form field object numbers
- fontObjNum: Object number of Helvetica font (for default appearance)
Returns the AcroForm dictionary as a PDF object string.
func CreateFontObjects ¶
func CreateFontObjects(textOps []TextOp) (map[string]*fonts.Standard14Font, error)
CreateFontObjects creates PDF font objects for the fonts used in text operations.
Returns a map of font name -> *Standard14Font.
This allows the writer to create font objects and assign them object numbers.
func DecompressStream ¶
DecompressStream decompresses zlib data (FlateDecode filter).
This is the inverse of CompressStream, used for reading compressed streams.
Parameters:
- data: Compressed data (zlib format)
Returns:
- decompressed: Decompressed data
- error: Any error that occurred (invalid format, checksum mismatch, etc.)
Example:
decompressed, err := DecompressStream(compressed)
Reference: PDF 1.7 Specification, Section 7.4.4 (FlateDecode Filter).
func EscapePDFString ¶
EscapePDFString escapes a string for use in PDF literal strings.
PDF literal strings are enclosed in parentheses: (Hello World)
Escapes:
- \ → \\
- ( → \(
- ) → \)
- \n → \n (newline)
- \r → \r (carriage return)
- \t → \t (tab)
- \b → \b (backspace)
- \f → \f (form feed)
Unicode characters (including Cyrillic) are passed through as-is. The caller is responsible for encoding them appropriately (usually UTF-16BE for text strings in PDF).
Example:
EscapePDFString("Hello") // "Hello"
EscapePDFString("Price: $50 (USD)") // "Price: $50 \\(USD\\)"
EscapePDFString("Line1\nLine2") // "Line1\\nLine2"
EscapePDFString("C:\\path") // "C:\\\\path"
EscapePDFString("Привет") // "Привет" (unchanged)
Reference: PDF 1.7 Spec, Table 3 (Escape sequences in literal strings).
func EstimateCompressionRatio ¶
EstimateCompressionRatio estimates the compression ratio for given data.
This is useful for deciding whether to compress a stream:
- Ratio < 0.9: Good compression, use FlateDecode
- Ratio >= 0.9: Poor compression, store uncompressed
Parameters:
- data: Uncompressed data
Returns:
- ratio: Estimated compression ratio (compressed size / original size)
Note: This actually compresses the data to get an accurate estimate. For a fast heuristic, check if data contains repeated patterns.
func ShouldCompress ¶
ShouldCompress determines if data should be compressed based on size and content.
Heuristic:
- Data < 50 bytes: Don't compress (overhead not worth it)
- Data >= 50 bytes: Compress (likely worth it for text content)
For more precise control, use EstimateCompressionRatio.
Parameters:
- data: Uncompressed data
Returns:
- bool: true if compression is recommended
Types ¶
type BezierSegment ¶
BezierSegment represents a cubic Bézier curve segment.
type ColorStopOp ¶
ColorStopOp represents a color stop in a gradient.
type CompressionLevel ¶
type CompressionLevel int
CompressionLevel defines compression level for streams.
PDF uses FlateDecode filter, which is based on zlib (deflate with header and checksum).
Levels:
- NoCompression: Store data without compression (fastest, largest)
- BestSpeed: Fast compression with lower compression ratio
- DefaultCompression: Balanced speed and compression (recommended)
- BestCompression: Maximum compression (slowest, smallest)
Reference: PDF 1.7 Specification, Table 3.4 (Standard Filters).
const ( // NoCompression disables compression (level 0). NoCompression CompressionLevel = 0 // BestSpeed uses fastest compression (level 1). BestSpeed CompressionLevel = 1 // DefaultCompression uses default zlib compression (level -1). // This is the recommended setting for most use cases. DefaultCompression CompressionLevel = -1 // BestCompression uses maximum compression (level 9). BestCompression CompressionLevel = 9 )
type ContentStreamWriter ¶
type ContentStreamWriter struct {
// contains filtered or unexported fields
}
ContentStreamWriter builds PDF content streams.
A content stream is a sequence of PDF operators and operands that describe page content (text, graphics, images).
Example:
csw := NewContentStreamWriter()
csw.BeginText()
csw.SetFont("F1", 12)
csw.MoveTextPosition(100, 700)
csw.ShowText("Hello World")
csw.EndText()
content := csw.Bytes()
Reference: PDF 1.7 Specification, Section 8.2 (Content Streams and Resources).
Example (Combined) ¶
ExampleContentStreamWriter_combined demonstrates combining text and graphics.
package main
import (
"fmt"
"github.com/coregx/gxpdf/internal/writer"
)
func main() {
csw := writer.NewContentStreamWriter()
// Draw a filled rectangle.
csw.SaveState()
csw.SetFillColorRGB(0.9, 0.9, 1.0) // Light blue
csw.Rectangle(40.0, 40.0, 220.0, 80.0)
csw.Fill()
csw.RestoreState()
// Add text on top.
csw.BeginText()
csw.SetFont("Times-Roman", 14.0)
csw.MoveTextPosition(50.0, 60.0)
csw.ShowText("Inside Box")
csw.EndText()
// Verify content was created.
if csw.Len() > 0 {
fmt.Println("Content stream created successfully")
}
}
Output: Content stream created successfully
Example (Compression) ¶
ExampleContentStreamWriter_compression demonstrates content stream compression.
package main
import (
"fmt"
"github.com/coregx/gxpdf/internal/writer"
)
func main() {
csw := writer.NewContentStreamWriter()
// Create some content.
csw.BeginText()
csw.SetFont("Courier", 10.0)
csw.MoveTextPosition(50.0, 750.0)
csw.ShowText("This text will be compressed")
csw.EndText()
// Compress the content.
compressed, err := csw.Compress()
if err != nil {
fmt.Printf("Compression error: %v\n", err)
return
}
// Show that compression worked.
if len(compressed) > 0 && csw.Len() > 0 {
fmt.Println("Content stream compressed successfully")
}
}
Output: Content stream compressed successfully
Example (Rectangle) ¶
ExampleContentStreamWriter_rectangle demonstrates drawing a rectangle.
package main
import (
"fmt"
"github.com/coregx/gxpdf/internal/writer"
)
func main() {
csw := writer.NewContentStreamWriter()
// Save state, set stroke color, draw rectangle.
csw.SaveState()
csw.SetStrokeColorRGB(1.0, 0.0, 0.0) // Red
csw.SetLineWidth(2.0)
csw.Rectangle(50.0, 50.0, 200.0, 100.0)
csw.Stroke()
csw.RestoreState()
fmt.Println(csw.String())
}
Output: q 1.00 0.00 0.00 RG 2.00 w 50.00 50.00 200.00 100.00 re S Q
Example (SimpleText) ¶
ExampleContentStreamWriter_simpleText demonstrates creating a simple text content stream.
package main
import (
"fmt"
"github.com/coregx/gxpdf/internal/writer"
)
func main() {
csw := writer.NewContentStreamWriter()
// Create text content.
csw.BeginText()
csw.SetFont("Helvetica", 12.0)
csw.MoveTextPosition(100.0, 700.0)
csw.ShowText("Hello World")
csw.EndText()
// Get the content stream.
fmt.Println(csw.String())
}
Output: BT /Helvetica 12.00 Tf 100.00 700.00 Td (Hello World) Tj ET
func NewContentStreamWriter ¶
func NewContentStreamWriter() *ContentStreamWriter
NewContentStreamWriter creates a new content stream writer.
By default, compression is enabled with DefaultCompression level. Use SetCompression to change the compression level.
func (*ContentStreamWriter) BeginText ¶
func (csw *ContentStreamWriter) BeginText()
BeginText begins a text object (BT operator).
Reference: PDF 1.7 Spec, Section 9.4 (Text Objects).
func (*ContentStreamWriter) Bytes ¶
func (csw *ContentStreamWriter) Bytes() []byte
Bytes returns the accumulated content stream data.
func (*ContentStreamWriter) CloseAndStroke ¶
func (csw *ContentStreamWriter) CloseAndStroke()
CloseAndStroke closes and strokes the path (s operator).
Reference: PDF 1.7 Spec, Section 8.5.3 (Path-Painting Operators).
func (*ContentStreamWriter) ClosePath ¶
func (csw *ContentStreamWriter) ClosePath()
ClosePath closes the current subpath (h operator).
Reference: PDF 1.7 Spec, Section 8.5.2 (Path Construction Operators).
func (*ContentStreamWriter) Compress
deprecated
func (csw *ContentStreamWriter) Compress() ([]byte, error)
Compress compresses the content stream using Flate encoding.
Deprecated: Use CompressedBytes() instead, which uses the configured compression level.
Returns compressed bytes or error.
func (*ContentStreamWriter) CompressedBytes ¶
func (csw *ContentStreamWriter) CompressedBytes() ([]byte, error)
CompressedBytes returns the content stream compressed using the configured compression level.
If compression is disabled (NoCompression), returns uncompressed bytes.
Returns:
- compressed: Compressed bytes (or uncompressed if NoCompression)
- error: Any compression error
Example:
csw := NewContentStreamWriter()
csw.BeginText()
csw.ShowText("Hello")
csw.EndText()
compressed, err := csw.CompressedBytes()
func (*ContentStreamWriter) ConcatMatrix ¶
func (csw *ContentStreamWriter) ConcatMatrix(a, b, c, d, e, f float64)
ConcatMatrix modifies the current transformation matrix (cm operator).
Parameters:
- a, b, c, d, e, f: Matrix coefficients
Reference: PDF 1.7 Spec, Section 8.4.4 (Coordinate Systems).
func (*ContentStreamWriter) CurveTo ¶
func (csw *ContentStreamWriter) CurveTo(x1, y1, x2, y2, x3, y3 float64)
CurveTo appends a cubic Bezier curve (c operator).
Parameters:
- x1, y1: First control point
- x2, y2: Second control point
- x3, y3: End point
Reference: PDF 1.7 Spec, Section 8.5.2 (Path Construction Operators).
func (*ContentStreamWriter) EndPath ¶
func (csw *ContentStreamWriter) EndPath()
EndPath ends the path without filling or stroking (n operator).
Reference: PDF 1.7 Spec, Section 8.5.3 (Path-Painting Operators).
func (*ContentStreamWriter) EndText ¶
func (csw *ContentStreamWriter) EndText()
EndText ends a text object (ET operator).
Reference: PDF 1.7 Spec, Section 9.4 (Text Objects).
func (*ContentStreamWriter) Fill ¶
func (csw *ContentStreamWriter) Fill()
Fill fills the path (f operator).
Uses nonzero winding number rule.
Reference: PDF 1.7 Spec, Section 8.5.3 (Path-Painting Operators).
func (*ContentStreamWriter) FillAndStroke ¶
func (csw *ContentStreamWriter) FillAndStroke()
FillAndStroke fills and strokes the path (B operator).
Uses nonzero winding number rule.
Reference: PDF 1.7 Spec, Section 8.5.3 (Path-Painting Operators).
func (*ContentStreamWriter) FillAndStrokeEvenOdd ¶
func (csw *ContentStreamWriter) FillAndStrokeEvenOdd()
FillAndStrokeEvenOdd fills and strokes using even-odd rule (B* operator).
Reference: PDF 1.7 Spec, Section 8.5.3 (Path-Painting Operators).
func (*ContentStreamWriter) FillEvenOdd ¶
func (csw *ContentStreamWriter) FillEvenOdd()
FillEvenOdd fills the path using even-odd rule (f* operator).
Reference: PDF 1.7 Spec, Section 8.5.3 (Path-Painting Operators).
func (*ContentStreamWriter) GetCompression ¶
func (csw *ContentStreamWriter) GetCompression() CompressionLevel
GetCompression returns the current compression level.
func (*ContentStreamWriter) IsCompressed ¶
func (csw *ContentStreamWriter) IsCompressed() bool
IsCompressed returns true if compression is enabled.
Compression is disabled when level is NoCompression.
func (*ContentStreamWriter) Len ¶
func (csw *ContentStreamWriter) Len() int
Len returns the length of the accumulated content.
func (*ContentStreamWriter) LineTo ¶
func (csw *ContentStreamWriter) LineTo(x, y float64)
LineTo appends a straight line segment (l operator).
Parameters:
- x, y: End point coordinates
Reference: PDF 1.7 Spec, Section 8.5.2 (Path Construction Operators).
func (*ContentStreamWriter) MoveTextPosition ¶
func (csw *ContentStreamWriter) MoveTextPosition(tx, ty float64)
MoveTextPosition moves to the start of the next line (Td operator).
Parameters:
- tx: Horizontal translation
- ty: Vertical translation
Reference: PDF 1.7 Spec, Section 9.4.2 (Text-Positioning Operators).
func (*ContentStreamWriter) MoveTextPositionSetLeading ¶
func (csw *ContentStreamWriter) MoveTextPositionSetLeading(tx, ty float64)
MoveTextPositionSetLeading moves to next line and sets leading (TD operator).
Parameters:
- tx: Horizontal translation
- ty: Vertical translation (also sets leading to -ty)
Reference: PDF 1.7 Spec, Section 9.4.2 (Text-Positioning Operators).
func (*ContentStreamWriter) MoveTo ¶
func (csw *ContentStreamWriter) MoveTo(x, y float64)
MoveTo begins a new subpath (m operator).
Parameters:
- x, y: Starting point coordinates
Reference: PDF 1.7 Spec, Section 8.5.2 (Path Construction Operators).
func (*ContentStreamWriter) MoveToNextLine ¶
func (csw *ContentStreamWriter) MoveToNextLine()
MoveToNextLine moves to the start of the next line (T* operator).
Reference: PDF 1.7 Spec, Section 9.4.2 (Text-Positioning Operators).
func (*ContentStreamWriter) Rectangle ¶
func (csw *ContentStreamWriter) Rectangle(x, y, width, height float64)
Rectangle appends a rectangle (re operator).
Parameters:
- x, y: Lower-left corner
- width, height: Rectangle dimensions
Reference: PDF 1.7 Spec, Section 8.5.2 (Path Construction Operators).
func (*ContentStreamWriter) Reset ¶
func (csw *ContentStreamWriter) Reset()
Reset clears the content stream buffer.
func (*ContentStreamWriter) RestoreState ¶
func (csw *ContentStreamWriter) RestoreState()
RestoreState restores the graphics state (Q operator).
Reference: PDF 1.7 Spec, Section 8.4.2 (Graphics State Stack).
func (*ContentStreamWriter) SaveState ¶
func (csw *ContentStreamWriter) SaveState()
SaveState saves the graphics state (q operator).
Reference: PDF 1.7 Spec, Section 8.4.2 (Graphics State Stack).
func (*ContentStreamWriter) SetCompression ¶
func (csw *ContentStreamWriter) SetCompression(level CompressionLevel)
SetCompression sets the compression level for this content stream.
Parameters:
- level: Compression level (NoCompression, BestSpeed, DefaultCompression, BestCompression)
This affects the output of CompressedBytes() method.
Example:
csw := NewContentStreamWriter() csw.SetCompression(BestCompression) // Maximum compression // ... add content ... compressed, _ := csw.CompressedBytes()
func (*ContentStreamWriter) SetDashPattern ¶
func (csw *ContentStreamWriter) SetDashPattern(dashArray []float64, dashPhase float64)
SetDashPattern sets the line dash pattern (d operator).
Parameters:
- dashArray: Array of dash and gap lengths
- dashPhase: Starting offset into the pattern
Reference: PDF 1.7 Spec, Section 8.4.3 (Graphics State Parameters).
func (*ContentStreamWriter) SetFillColorCMYK ¶
func (csw *ContentStreamWriter) SetFillColorCMYK(c, m, y, k float64)
SetFillColorCMYK sets the fill color in CMYK (k operator).
Parameters:
- c, m, y, k: CMYK values (0.0 to 1.0)
Reference: PDF 1.7 Spec, Section 8.6.8 (Color Operators).
func (*ContentStreamWriter) SetFillColorGray ¶
func (csw *ContentStreamWriter) SetFillColorGray(gray float64)
SetFillColorGray sets the fill color in grayscale (g operator).
Parameters:
- gray: Grayscale value (0.0 = black, 1.0 = white)
Reference: PDF 1.7 Spec, Section 8.6.8 (Color Operators).
func (*ContentStreamWriter) SetFillColorRGB ¶
func (csw *ContentStreamWriter) SetFillColorRGB(r, g, b float64)
SetFillColorRGB sets the fill color in RGB (rg operator).
Parameters:
- r, g, b: RGB values (0.0 to 1.0)
Reference: PDF 1.7 Spec, Section 8.6.8 (Color Operators).
func (*ContentStreamWriter) SetFont ¶
func (csw *ContentStreamWriter) SetFont(fontName string, size float64)
SetFont sets the text font and size (Tf operator).
Parameters:
- fontName: Font resource name (e.g., "F1")
- size: Font size in points
Reference: PDF 1.7 Spec, Section 9.3 (Text State Parameters and Operators).
func (*ContentStreamWriter) SetLeading ¶
func (csw *ContentStreamWriter) SetLeading(leading float64)
SetLeading sets the text leading (TL operator).
Leading is the vertical distance between text lines.
Parameters:
- leading: Leading value in text space units
Reference: PDF 1.7 Spec, Section 9.3.5 (Text State Parameters).
func (*ContentStreamWriter) SetLineCap ¶
func (csw *ContentStreamWriter) SetLineCap(style int)
SetLineCap sets the line cap style (J operator).
Parameters:
- style: 0 = butt cap, 1 = round cap, 2 = projecting square cap
Reference: PDF 1.7 Spec, Section 8.4.3 (Graphics State Parameters).
func (*ContentStreamWriter) SetLineJoin ¶
func (csw *ContentStreamWriter) SetLineJoin(style int)
SetLineJoin sets the line join style (j operator).
Parameters:
- style: 0 = miter join, 1 = round join, 2 = bevel join
Reference: PDF 1.7 Spec, Section 8.4.3 (Graphics State Parameters).
func (*ContentStreamWriter) SetLineWidth ¶
func (csw *ContentStreamWriter) SetLineWidth(width float64)
SetLineWidth sets the line width (w operator).
Parameters:
- width: Line width in user space units
Reference: PDF 1.7 Spec, Section 8.4.3 (Graphics State Parameters).
func (*ContentStreamWriter) SetMiterLimit ¶
func (csw *ContentStreamWriter) SetMiterLimit(limit float64)
SetMiterLimit sets the miter limit (M operator).
Parameters:
- limit: Maximum ratio of miter length to line width
Reference: PDF 1.7 Spec, Section 8.4.3 (Graphics State Parameters).
func (*ContentStreamWriter) SetStrokeColorCMYK ¶
func (csw *ContentStreamWriter) SetStrokeColorCMYK(c, m, y, k float64)
SetStrokeColorCMYK sets the stroke color in CMYK (K operator).
Parameters:
- c, m, y, k: CMYK values (0.0 to 1.0)
Reference: PDF 1.7 Spec, Section 8.6.8 (Color Operators).
func (*ContentStreamWriter) SetStrokeColorGray ¶
func (csw *ContentStreamWriter) SetStrokeColorGray(gray float64)
SetStrokeColorGray sets the stroke color in grayscale (G operator).
Parameters:
- gray: Grayscale value (0.0 = black, 1.0 = white)
Reference: PDF 1.7 Spec, Section 8.6.8 (Color Operators).
func (*ContentStreamWriter) SetStrokeColorRGB ¶
func (csw *ContentStreamWriter) SetStrokeColorRGB(r, g, b float64)
SetStrokeColorRGB sets the stroke color in RGB (RG operator).
Parameters:
- r, g, b: RGB values (0.0 to 1.0)
Reference: PDF 1.7 Spec, Section 8.6.8 (Color Operators).
func (*ContentStreamWriter) SetTextMatrix ¶
func (csw *ContentStreamWriter) SetTextMatrix(a, b, c, d, e, f float64)
SetTextMatrix sets the text matrix (Tm operator).
The text matrix determines text positioning and scaling.
Parameters:
- a, b, c, d: Matrix coefficients for scaling/rotation
- e, f: Translation (horizontal, vertical)
Reference: PDF 1.7 Spec, Section 9.4.2 (Text-Positioning Operators).
func (*ContentStreamWriter) ShowText ¶
func (csw *ContentStreamWriter) ShowText(text string)
ShowText shows a text string (Tj operator).
Parameters:
- text: Text to display (will be escaped)
Reference: PDF 1.7 Spec, Section 9.4.3 (Text-Showing Operators).
func (*ContentStreamWriter) ShowTextNextLine ¶
func (csw *ContentStreamWriter) ShowTextNextLine(text string)
ShowTextNextLine moves to next line and shows text (' operator).
Equivalent to: T* followed by Tj.
Parameters:
- text: Text to display (will be escaped)
Reference: PDF 1.7 Spec, Section 9.4.3 (Text-Showing Operators).
func (*ContentStreamWriter) String ¶
func (csw *ContentStreamWriter) String() string
String returns the content stream as a string (for debugging).
func (*ContentStreamWriter) Stroke ¶
func (csw *ContentStreamWriter) Stroke()
Stroke strokes the path (S operator).
Reference: PDF 1.7 Spec, Section 8.5.3 (Path-Painting Operators).
type GradientOp ¶
type GradientOp struct {
Type GradientType
// ColorStops define the color transitions (minimum 2).
ColorStops []ColorStopOp
// Linear gradient coordinates
X1, Y1, X2, Y2 float64
// Radial gradient coordinates
X0, Y0, R0, R1 float64
// Extend flags
ExtendStart bool
ExtendEnd bool
}
GradientOp represents a gradient fill operation.
type GradientType ¶
type GradientType int
GradientType represents the type of gradient.
const ( // GradientTypeLinear is an axial gradient (ShadingType 2). GradientTypeLinear GradientType = 2 // GradientTypeRadial is a radial gradient (ShadingType 3). GradientTypeRadial GradientType = 3 )
type GraphicsOp ¶
type GraphicsOp struct {
Type int // 0=line, 1=rect, 2=circle, 5=polygon, 6=polyline, 7=ellipse, 8=bezier
// Common fields
X float64
Y float64
// Line fields
X2 float64
Y2 float64
// Rectangle fields
Width float64
Height float64
// Circle fields
Radius float64
// Ellipse fields
RX float64 // Horizontal radius
RY float64 // Vertical radius
// Polygon/Polyline fields
Vertices []Point
// Bezier fields
BezierSegs []BezierSegment
Closed bool // For Bezier curves
// Appearance
StrokeColor *RGB
StrokeColorCMYK *CMYK // If set, takes precedence over StrokeColor
FillColor *RGB
FillColorCMYK *CMYK // If set, takes precedence over FillColor
FillGradient *GradientOp // Gradient fill
StrokeWidth float64
Dashed bool
DashArray []float64
DashPhase float64
}
GraphicsOp represents a graphics drawing operation.
This is an infrastructure-level representation of graphics operations from the creator package.
type IndirectObject ¶
type IndirectObject struct {
// Number is the object number (must be positive).
Number int
// Generation is the generation number (usually 0).
Generation int
// Data contains the serialized object data (dictionary, array, etc.).
Data []byte
}
IndirectObject represents a PDF indirect object.
In PDF format, indirect objects are uniquely identified by: - Object number (positive integer) - Generation number (usually 0 for new objects)
Format in PDF file:
N G obj ... object data ... endobj
Example:
1 0 obj << /Type /Catalog /Pages 2 0 R >> endobj
func CreateContentStreamObject ¶
func CreateContentStreamObject(objNum int, content []byte, compress bool) *IndirectObject
CreateContentStreamObject creates a PDF stream object for content.
Format (uncompressed):
N 0 obj << /Length M >> stream ... content ... endstream endobj
Format (compressed):
N 0 obj << /Length M /Filter /FlateDecode >> stream ... compressed content ... endstream endobj
Parameters:
- objNum: Object number for this stream
- content: Stream content (uncompressed)
- compress: If true, compress the content using FlateDecode
Returns the IndirectObject ready to write.
func NewIndirectObject ¶
func NewIndirectObject(number, generation int, data []byte) *IndirectObject
NewIndirectObject creates a new indirect object.
Parameters:
- number: Object number (must be positive)
- generation: Generation number (usually 0)
- data: Serialized object data
Example:
catalogData := []byte("<< /Type /Catalog /Pages 2 0 R >>")
obj := NewIndirectObject(1, 0, catalogData)
func (*IndirectObject) String ¶
func (o *IndirectObject) String() string
String returns a string representation of the object (for debugging).
type PageContent ¶
type PageContent struct {
// TextOperations are the text drawing operations for this page.
TextOperations []TextOp
// GraphicsOperations are the graphics drawing operations for this page.
GraphicsOperations []GraphicsOp
// Resources tracks fonts and other resources used on this page.
Resources *ResourceDictionary
}
PageContent represents the content and resources for a single page.
This structure bridges the Creator API (which tracks text operations) with the Writer infrastructure (which generates PDF bytes).
type PdfWriter ¶
type PdfWriter struct {
// contains filtered or unexported fields
}
PdfWriter writes PDF documents to files.
This is the main infrastructure component for PDF file generation. It manages object numbering, cross-reference tables, and file structure.
Example:
doc := document.NewDocument()
doc.AddPage(document.A4)
writer, err := NewPdfWriter("output.pdf")
if err != nil {
return err
}
defer writer.Close()
err = writer.Write(doc)
func NewPdfWriter ¶
NewPdfWriter creates a new PDF writer for the specified file path.
The file will be created or truncated if it already exists.
Returns an error if the file cannot be created.
func (*PdfWriter) Close ¶
Close closes the writer and the underlying file.
It's safe to call Close multiple times.
func (*PdfWriter) Write ¶
Write writes a document to the PDF file.
This performs the following steps: 1. Write PDF header with version 2. Write catalog object 3. Write pages object tree 4. Write cross-reference table 5. Write trailer
Returns an error if: - Document validation fails. - Document has no pages. - Any write operation fails.
func (*PdfWriter) WriteAllAnnotations ¶
WriteAllAnnotations writes all annotations from a page and returns annotation objects.
This handles link, text, markup, and stamp annotations.
Returns:
- annotObjs: Array of annotation indirect objects
- annotRefs: Array of annotation object numbers (for /Annots array)
- error: Any error that occurred
func (*PdfWriter) WriteAnnotations ¶
func (w *PdfWriter) WriteAnnotations( annotations []*document.LinkAnnotation, ) ([]*IndirectObject, []int, error)
WriteAnnotations writes link annotations and returns annotation objects.
DEPRECATED: Use WriteAllAnnotations instead for pages, or writeLinkAnnotations for specific link annotations. This method is kept for backward compatibility.
For each annotation, creates an indirect object with the annotation dictionary.
Returns:
- annotObjs: Array of annotation indirect objects
- annotRefs: Array of annotation object numbers (for /Annots array)
- error: Any error that occurred
func (*PdfWriter) WriteWithAllContent ¶
func (w *PdfWriter) WriteWithAllContent( doc *document.Document, textContents map[int][]TextOp, graphicsContents map[int][]GraphicsOp, ) error
WriteWithAllContent writes a document with text and graphics content operations.
This is similar to WriteWithPageContent() but accepts both text and graphics operations.
Parameters:
- doc: The document to write
- textContents: Text operations for each page (indexed by page number)
- graphicsContents: Graphics operations for each page (indexed by page number)
Returns an error if validation or writing fails.
func (*PdfWriter) WriteWithPageContent ¶
func (w *PdfWriter) WriteWithPageContent(doc *document.Document, pageContents map[int][]TextOp) error
WriteWithPageContent writes a document with page content operations to the PDF file.
This is similar to Write() but accepts page-level content operations (text, graphics, etc.) that will be rendered as PDF content streams.
Parameters:
- doc: The document to write
- pageContents: Content operations for each page (indexed by page number)
Returns an error if validation or writing fails.
type ResourceDictionary ¶
type ResourceDictionary struct {
// contains filtered or unexported fields
}
ResourceDictionary manages PDF page resources (fonts, images, graphics states, etc.).
Resources are referenced in content streams by name (e.g., /F1 for fonts, /Im1 for images). This struct tracks resource names and their corresponding PDF object numbers.
PDF Dictionary Format:
/Resources << /Font << /F1 5 0 R /F2 6 0 R >> /XObject << /Im1 7 0 R >> /ExtGState << /GS1 8 0 R >> /ProcSet [/PDF /Text /ImageB /ImageC /ImageI] >>
Thread Safety: Not thread-safe. Caller must synchronize if needed.
Example ¶
ExampleResourceDictionary demonstrates basic usage of ResourceDictionary.
package main
import (
"fmt"
"github.com/coregx/gxpdf/internal/writer"
)
func main() {
// Create a new resource dictionary.
rd := writer.NewResourceDictionary()
// Add a font resource.
fontName := rd.AddFont(5) // Font object is at 5 0 R
fmt.Printf("Font name: %s\n", fontName)
// Add another font.
fontName2 := rd.AddFont(6) // Font object is at 6 0 R
fmt.Printf("Second font name: %s\n", fontName2)
// Add an image.
imageName := rd.AddImage(10) // Image object is at 10 0 R
fmt.Printf("Image name: %s\n", imageName)
// Get the PDF dictionary.
fmt.Println(rd.String())
}
Output: Font name: F1 Second font name: F2 Image name: Im1 << /Font << /F1 5 0 R /F2 6 0 R >> /XObject << /Im1 10 0 R >> /ProcSet [/PDF /Text /ImageB /ImageC /ImageI] >>
Example (Empty) ¶
ExampleResourceDictionary_empty demonstrates an empty resource dictionary.
package main
import (
"fmt"
"github.com/coregx/gxpdf/internal/writer"
)
func main() {
rd := writer.NewResourceDictionary()
// Check if dictionary has resources.
fmt.Printf("Has resources: %v\n", rd.HasResources())
// Empty dictionary outputs minimal syntax.
fmt.Println(rd.String())
}
Output: Has resources: false << >>
Example (Fonts) ¶
ExampleResourceDictionary_fonts demonstrates managing font resources.
package main
import (
"fmt"
"github.com/coregx/gxpdf/internal/writer"
)
func main() {
rd := writer.NewResourceDictionary()
// Add fonts for a multi-font document.
helvetica := rd.AddFont(5) // Object 5: Helvetica
times := rd.AddFont(6) // Object 6: Times-Roman
courier := rd.AddFont(7) // Object 7: Courier
fmt.Printf("Helvetica: %s, Times: %s, Courier: %s\n", helvetica, times, courier)
fmt.Println(rd.String())
}
Output: Helvetica: F1, Times: F2, Courier: F3 << /Font << /F1 5 0 R /F2 6 0 R /F3 7 0 R >> /ProcSet [/PDF /Text /ImageB /ImageC /ImageI] >>
Example (Images) ¶
ExampleResourceDictionary_images demonstrates managing image resources.
package main
import (
"fmt"
"github.com/coregx/gxpdf/internal/writer"
)
func main() {
rd := writer.NewResourceDictionary()
// Add images for a document with graphics.
logo := rd.AddImage(10) // Object 10: Company logo
photo := rd.AddImage(11) // Object 11: Product photo
diagram := rd.AddImage(12) // Object 12: Technical diagram
fmt.Printf("Logo: %s, Photo: %s, Diagram: %s\n", logo, photo, diagram)
fmt.Println(rd.String())
}
Output: Logo: Im1, Photo: Im2, Diagram: Im3 << /XObject << /Im1 10 0 R /Im2 11 0 R /Im3 12 0 R >> /ProcSet [/PDF /Text /ImageB /ImageC /ImageI] >>
Example (Mixed) ¶
ExampleResourceDictionary_mixed demonstrates combining different resource types.
package main
import (
"fmt"
"github.com/coregx/gxpdf/internal/writer"
)
func main() {
rd := writer.NewResourceDictionary()
// Real-world document with fonts, images, and graphics states.
rd.AddFont(5) // Helvetica
rd.AddFont(6) // Times-Roman
rd.AddImage(10) // Logo
rd.AddExtGState(15) // Transparency state
fmt.Printf("Has resources: %v\n", rd.HasResources())
fmt.Println(rd.String())
}
Output: Has resources: true << /Font << /F1 5 0 R /F2 6 0 R >> /XObject << /Im1 10 0 R >> /ExtGState << /GS1 15 0 R >> /ProcSet [/PDF /Text /ImageB /ImageC /ImageI] >>
func GenerateContentStream ¶
func GenerateContentStream(textOps []TextOp) (content []byte, resources *ResourceDictionary, err error)
GenerateContentStream generates a PDF content stream from text and graphics operations.
Graphics are drawn BEFORE text (so text appears on top).
Returns:
- content: The content stream bytes
- resources: The resource dictionary for fonts used
- error: Any error that occurred
Example content stream:
BT 0 0 0 rg /F1 24 Tf 100 700 Td (Hello World) Tj ET
func GenerateContentStreamWithGraphics ¶
func GenerateContentStreamWithGraphics(textOps []TextOp, graphicsOps []GraphicsOp) (content []byte, resources *ResourceDictionary, err error)
GenerateContentStreamWithGraphics generates a PDF content stream from text and graphics operations.
Graphics are drawn BEFORE text (so text appears on top).
Returns:
- content: The content stream bytes
- resources: The resource dictionary for fonts used
- error: Any error that occurred
func NewResourceDictionary ¶
func NewResourceDictionary() *ResourceDictionary
NewResourceDictionary creates a new empty resource dictionary.
func (*ResourceDictionary) AddExtGState ¶
func (rd *ResourceDictionary) AddExtGState(objNum int) string
AddExtGState adds a graphics state resource and returns its resource name.
Graphics states are named sequentially: GS1, GS2, GS3, etc.
Parameters:
- objNum: PDF object number of the ExtGState dictionary
Returns:
- Resource name (e.g., "GS1")
Example:
rd := NewResourceDictionary() name := rd.AddExtGState(15) // Returns "GS1" // In content stream: /GS1 gs (apply graphics state GS1)
func (*ResourceDictionary) AddFont ¶
func (rd *ResourceDictionary) AddFont(objNum int) string
AddFont adds a font resource and returns its resource name.
Fonts are named sequentially: F1, F2, F3, etc.
Parameters:
- objNum: PDF object number of the font dictionary
Returns:
- Resource name (e.g., "F1")
Example:
rd := NewResourceDictionary() name := rd.AddFont(5) // Returns "F1" // In content stream: /F1 12 Tf (set font F1 at 12pt)
func (*ResourceDictionary) AddImage ¶
func (rd *ResourceDictionary) AddImage(objNum int) string
AddImage adds an image XObject resource and returns its resource name.
Images are named sequentially: Im1, Im2, Im3, etc.
Parameters:
- objNum: PDF object number of the image XObject
Returns:
- Resource name (e.g., "Im1")
Example:
rd := NewResourceDictionary() name := rd.AddImage(10) // Returns "Im1" // In content stream: /Im1 Do (draw image Im1)
func (*ResourceDictionary) Bytes ¶
func (rd *ResourceDictionary) Bytes() []byte
Bytes returns the resource dictionary as PDF bytes.
Format:
<< /Font << /F1 5 0 R >> /XObject << /Im1 10 0 R >> /ProcSet [/PDF /Text /ImageB /ImageC /ImageI] >>
Returns empty dictionary if no resources are registered:
<< >>
Note: Resource names are sorted alphabetically for consistent output.
func (*ResourceDictionary) HasResources ¶
func (rd *ResourceDictionary) HasResources() bool
HasResources returns true if any resources are registered.
Use this to check if the resource dictionary is empty before writing.
func (*ResourceDictionary) String ¶
func (rd *ResourceDictionary) String() string
String returns the resource dictionary as a PDF string.
Convenience method for debugging and testing.
type TextOp ¶
type TextOp struct {
Text string // Text to display
X float64 // Horizontal position (points from left)
Y float64 // Vertical position (points from bottom)
Font string // Font name (e.g., "Helvetica")
Size float64 // Font size in points
Color RGB // Text color (RGB)
ColorCMYK *CMYK // Text color (CMYK, optional - takes precedence over RGB)
}
TextOp represents a text drawing operation.
This is an infrastructure-level representation of text operations from the creator package.