Documentation
¶
Overview ¶
Package printout is the document an engine produces and a renderer consumes: pages of absolutely-positioned marks in paint order.
Nothing in a printout is evaluable. Every expression has been evaluated, every box resolved to absolute coordinates, every string wrapped to lines, every barcode encoded to stripe widths, every font resolved to a specific file. A renderer needs no data, no template, and no expression evaluator.
Index ¶
- Constants
- type Barcode
- type Blob
- type Box
- type FontEntry
- type Header
- type Image
- type Line
- type Mark
- type Outline
- type Page
- type PageGeometry
- type Printout
- func (doc *Printout) AddWarning(kind, node string, record int, message string)
- func (doc *Printout) HasWarning(kind string) bool
- func (doc *Printout) Validate() error
- func (doc *Printout) WriteCBOR(writer io.Writer, dir string) error
- func (doc *Printout) WriteFile(path string) error
- func (doc *Printout) WriteNDJSON(writer io.Writer, dir string) error
- type Rectangle
- type ReportMeta
- type Text
- type Warning
- type Xref
Constants ¶
const ( WarnOverflow = "overflow" WarnGlyph = "glyph" WarnFont = "font" )
Warning kinds.
const Version = 1
Version is the format version this package reads and writes.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Barcode ¶
type Barcode struct {
Kind string `json:"kind"`
Box Box `json:"box"`
Type string `json:"type"`
Value string `json:"value"`
Module float64 `json:"module"`
Vertical bool `json:"vertical"`
// Ink is the bar colour. Always present, and "#000000" unless the
// template asked for another.
Ink string `json:"ink"`
// Paper is the fill painted behind the whole symbol, quiet zones
// included. Absent leaves whatever is underneath showing, which
// is what a template that says nothing about the background gets.
Paper *string `json:"paper,omitempty"`
// Stripes is a flat array for a 1-D type;
// Rows is an array of rows for a 2-D one.
// Exactly one is present. Both alternate light and dark
// starting with light, so index 0 is a light run in every case.
Stripes []int `json:"stripes,omitempty"`
Rows [][]int `json:"rows,omitempty"`
}
Barcode is encoded stripe geometry, in modules.
func NewBarcode ¶
func NewBarcode() *Barcode
NewBarcode builds a barcode mark with its kind set and black ink, which is what a template that names no colour means.
type Blob ¶
type Blob struct {
// Encoding is "base64" for binary, absent for literal text.
Encoding string `json:"encoding,omitempty"`
Content string `json:"content"`
}
Blob is a shared piece of content, stored once however many marks read it.
type Box ¶
type Box struct {
Left float64 `json:"x"`
Top float64 `json:"y"`
Width float64 `json:"width"`
Height float64 `json:"height"`
}
Box is an absolute rectangle, with the top-left corner at x, y measured from the top-left of the page. Y grows downward.
type FontEntry ¶
type FontEntry struct {
Name string `json:"name"`
Size int `json:"size"`
Bold bool `json:"bold"`
Italic bool `json:"italic"`
Underline bool `json:"underline"`
// Requested is the template's typeface. A font node that named
// a file or data instead has no typeface to record, so this is
// absent and ResolvedBy is "explicit".
Requested string `json:"requested,omitempty"`
// ResolvedFile is relative to the printout when the template named it,
// and absolute -- as opened -- when the engine found it on the host.
ResolvedFile string `json:"resolvedFile,omitempty"`
// ResolvedData names a header data entry, for an embedded font.
ResolvedData string `json:"resolvedData,omitempty"`
// ResolvedIndex is the face's position inside a font collection,
// absent for the ordinary single-face file. A .ttc holds several
// faces and the file name alone does not say which one was measured.
ResolvedIndex int `json:"resolvedIndex,omitempty"`
ResolvedFace string `json:"resolvedFace"`
ResolvedBy string `json:"resolvedBy"`
// contains filtered or unexported fields
}
FontEntry records a font that was actually measured, and how it was found.
func (FontEntry) ResolvedPath ¶
ResolvedPath returns a font entry's file as an absolute path, resolved against wherever the printout was read from.
func (*FontEntry) SetResolvedPath ¶
SetResolvedPath records where a template-named font was found. Provenance decides what the writer emits: a path the template named travels with the printout, one the engine discovered is written as it was opened.
type Header ¶
type Header struct {
SR int `json:"sr"`
Kind string `json:"kind"`
Report *ReportMeta `json:"report,omitempty"`
Built string `json:"built"`
Engine string `json:"engine"`
StrictFonts bool `json:"strictFonts"`
Pages int `json:"pages"`
GroupRuns map[string]int `json:"groupRuns,omitempty"`
GroupKeys map[string]int `json:"groupKeys,omitempty"`
Page PageGeometry `json:"page"`
Fonts []FontEntry `json:"fonts"`
Data map[string]*Blob `json:"data"`
Warnings []Warning `json:"warnings,omitempty"`
}
Header is the printout's first line.
type Image ¶
type Image struct {
Kind string `json:"kind"`
Box Box `json:"box"`
Type string `json:"type"`
Data string `json:"data,omitempty"`
// File appears only for embed=#false.
// The template named it, so it is written relative to the printout.
File string `json:"file,omitempty"`
Crop *Box `json:"crop,omitempty"`
// contains filtered or unexported fields
}
Image is a bitmap. Box is the final drawn rectangle and Crop names the source pixels that fill it, so a renderer needs no notion of fitting.
func (*Image) ResolvedPath ¶
ResolvedPath returns an image mark's file as an absolute path.
type Line ¶
type Line struct {
Kind string `json:"kind"`
Box Box `json:"box"`
Width float64 `json:"width"`
Dash string `json:"dash"`
Color string `json:"color"`
Backslant bool `json:"backslant"`
}
Line runs from the box's top-left corner to its bottom-right, or bottom-left to top-right when Backslant is set.
type Mark ¶
type Mark interface {
// MarkKind names the mark, matching its "kind" field.
MarkKind() string
}
Mark is one drawn thing.
type Outline ¶
type Outline struct {
Kind string `json:"kind"`
Title string `json:"title"`
Level int `json:"level"`
Name string `json:"name,omitempty"`
Closed bool `json:"closed"`
Left float64 `json:"x"`
Top float64 `json:"y"`
}
Outline is a document outline entry. It names a scroll position rather than a region, so it carries a point instead of a box.
type Page ¶
type Page struct {
Kind string `json:"kind"`
Number int `json:"number"`
Width float64 `json:"width,omitempty"`
Height float64 `json:"height,omitempty"`
// The margins are pointers because zero is a real margin:
// a page flush to the paper edge under a header that insets
// is an override, and an omitted number could not say so.
LeftMargin *float64 `json:"leftMargin,omitempty"`
RightMargin *float64 `json:"rightMargin,omitempty"`
TopMargin *float64 `json:"topMargin,omitempty"`
BottomMargin *float64 `json:"bottomMargin,omitempty"`
Marks []Mark `json:"marks"`
}
Page is one page of marks.
The size and the margins are the header's, except where this page overrides them: a subreport that paginates itself may run at a page size and inset of its own, and its pages carry the difference.
func (*Page) Geometry ¶
func (page *Page) Geometry(header PageGeometry) PageGeometry
Geometry is the page's size and margins: the header's, with whatever the page overrides applied.
func (*Page) SetGeometry ¶
func (page *Page) SetGeometry(want, header PageGeometry)
SetGeometry records what this page runs at, writing only the parts that differ from the document default.
type PageGeometry ¶
type PageGeometry struct {
Width float64 `json:"width"`
Height float64 `json:"height"`
LeftMargin float64 `json:"leftMargin"`
RightMargin float64 `json:"rightMargin"`
TopMargin float64 `json:"topMargin"`
BottomMargin float64 `json:"bottomMargin"`
}
PageGeometry is a page's size and margins, in points.
type Printout ¶
Printout is a whole document.
The in-memory structure is the primary artifact: the engine hands it to a renderer directly, and serializes only when asked.
func ReadNDJSON ¶
ReadNDJSON reads a printout back.
A relative path in the document resolves against dir, the directory the printout was read from; an absolute one is used as it stands. So a renderer needs no base directory and the header carries none.
func (*Printout) AddWarning ¶
AddWarning records a document warning in the header.
func (*Printout) HasWarning ¶
HasWarning reports whether the header carries a warning of a kind.
func (*Printout) Validate ¶
Validate checks the invariants of doc/printout.md#invariants. A valid printout satisfies all of them; the test suite asserts this on every printout it produces.
The numbers in the comments below are that list's numbering, so the checks read out of order: they are placed where the walk has what they need rather than in the order the document states them. Invariant 4 appears twice, once for an image's data and once for a font's.
func (*Printout) WriteCBOR ¶
WriteCBOR writes the same objects as a CBOR sequence, in the same order.
func (*Printout) WriteFile ¶
WriteFile writes the printout, choosing the encoding from the extension: .srp.cbor is CBOR, anything else NDJSON.
func (*Printout) WriteNDJSON ¶
WriteNDJSON writes the printout as one JSON object per line: the header, then one line per page.
dir is the directory the printout is being written to, which is what template-named paths are made relative to. An empty dir stands for the process's working directory, which is what a pipe or an in-memory hand-off gets.
type Rectangle ¶
type Rectangle struct {
Kind string `json:"kind"`
Box Box `json:"box"`
Width float64 `json:"width"`
Dash string `json:"dash"`
Stroke *string `json:"stroke,omitempty"`
Fill *string `json:"fill,omitempty"`
Radius float64 `json:"radius,omitempty"`
}
Rectangle is a box, stroked and filled independently. An absent Stroke means no outline is drawn regardless of Width; an absent Fill leaves the interior untouched.
func NewRectangle ¶
func NewRectangle() *Rectangle
NewRectangle builds a rectangle mark with its kind set.
type ReportMeta ¶
type ReportMeta struct {
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
Version string `json:"version,omitempty"`
Author string `json:"author,omitempty"`
}
ReportMeta is what the template's report node carried. Omitted fields are absent, not null.
type Text ¶
type Text struct {
Kind string `json:"kind"`
Box Box `json:"box"`
Font string `json:"font"`
Color string `json:"color"`
Align string `json:"align"`
Leading float64 `json:"leading"`
Lines []string `json:"lines"`
LastLineJustified bool `json:"lastLineJustified,omitempty"`
}
Text is wrapped text. A renderer must not re-wrap it.
type Warning ¶
type Warning struct {
// Kind is "overflow", "glyph", or "font".
Kind string `json:"kind"`
Node string `json:"node,omitempty"`
Record int `json:"record,omitempty"`
Message string `json:"message"`
}
Warning is a diagnostic about the document, recorded in the header so an affected printout is identifiable from the artifact.
type Xref ¶
type Xref struct {
Kind string `json:"kind"`
Box Box `json:"box"`
Type string `json:"type"`
Target string `json:"target"`
Caption string `json:"caption,omitempty"`
Marks []Mark `json:"marks"`
}
Xref is a link region. Its nested marks use page coordinates, so a renderer can flatten them recursively and draw in one pass; the box is purely a hit region.