Nodes#
A node is the smallest piece of information. There are different kinds of node, for example a glyph node contains a single visual representation of a letter such as the letter “A”.
Each glyph can be stored in a linked list together with other nodes. These linked lists are also called “node list”. These node lists can be packed in a horizontal box (hbox) or a vertical box (vbox). These packed lists are nodes themselves and can be part of a linked list. So during typesetting, a page that is ready to be placed in the PDF contains a vertical list which contains a list of nodes, usually paragraphs with lines of text and images, each placed in a vertical or a horizontal list.
Common traits of nodes#
Nodes that take up some space usually have a width and a height but also a depth.
The height is the size of the box of the baseline and the depth below the base line. When placing nodes next to each other, the baseline of each node is taken for alignment.
Each node has methods to chain the nodes in a linked list
Method | Description |
---|---|
Next() Node |
Get the next node. |
Prev() Node |
Get the previous node. |
SetNext(Node) |
Set the next pointer of the current node so that it points to the given node. The prev pointer of the argument is not changed. |
SetPrev(Node) |
Set the prev pointer of the current node so that it points to the given node. The next pointer of the argument is not changed. |
GetID() int |
Return the internal id. Each node in the document has its own unique id. |
Type() Type |
Return the node type. |
Name() string |
Return a string representation of the node type. |
Copy() Node |
Create a deep copy of of the node. |
List of nodes#
Node | Description |
---|---|
Disc | A hyphenation point. This node should be surrounded by glyph nodes. |
Glue | The glue node is a space between other nodes which has a natural width, a stretchability and a shrinkability. |
Glyph | A glyph node contains information about a font and a code point (the font specific glyph id). |
HList | Horizontal lists contain a pointer to a node list which items are placed horizontally next to each other. |
Image | An image is a rectangular area that represents a PNG, JPEG or a PDF file. |
Kern | A kern is inserted between two glyphs or other nodes to bring them closer together or further apart. |
Lang | The lang node contains information about the language which is used to hyphenate words behind the lang node. |
Penalty | The penalty node (in the range -10000 to +10000 inserts a possible line break. The values +/- 10000 are considered to be infinity. The higher the value is, the more likely a line break will be inserted. |
Rule | A rule contains a black box. |
StartStop | A paired set of nodes that temporarily inserts a color change or a hyperlink. |
VList | Vertical lists contain a node list which items are stacked on top of each other. The first item is placed at the top the next item below the first and so on. |
There are a few helper functions that deal with node lists:
Node | Description |
---|---|
func CopyList(nl Node) Node |
Make a deep copy of the node at nl. That means if the node contains a list of other nodes, these nodes will be deep-copied as well. |
func InsertAfter(head, cur, insert Node) Node |
Inserts insert after cur at the list starting with head . |
func InsertBefore(head, cur, insert Node) Node |
Inserts insert before cur at the list starting with head. The (perhaps new) head is returned. |
func Tail(nl Node) Node |
Return the last element of the list at nl . |
Each node has the following additional fields:
Field | Type | Description |
---|---|---|
ID | int | An internal unique identifier which gets created when creating a node with the new function (NewGlyph() for example). |
Attributes | H | A hash (any/any) for user defined values. |
Disc#
Disc nodes are inserted during the hyphenation phase.
Glue#
A glue node is a vertical or horizontal space, depending on the surrounding box. In a vbox, the glue is a vertical space and otherwise it is a horizontal space. It consists of a fixed width portion and a (perhaps zero) shrinkability and stretchability. Each value of shrink or stretch can have different orders of infinity. The highest infinity wins.
type Glue struct {
Subtype GlueSubtype
Width bag.ScaledPoint // The natural width of the glue.
Stretch bag.ScaledPoint // The stretchability of the glue, where width plus stretch = maximum width.
Shrink bag.ScaledPoint // The shrinkability of the glue, where width minus shrink = minimum width.
StretchOrder GlueOrder // The order of infinity of stretching.
ShrinkOrder GlueOrder // The order of infinity of shrinking.
}
Glyph#
type Glyph struct {
Font *font.Font
// The font specific glyph id
Codepoint int
// A codepoint can contain more than one rune, for example a fi ligature
// contains f + i. Filling the components string is optional.
Components string
// The advance width of the box.
Width bag.ScaledPoint
// The height is the length above the base line.
Height bag.ScaledPoint
// The Depth is the length below the base line. For example the letter g has
// a depth > 0.
Depth bag.ScaledPoint
// Vertical displacement. Positive values move the glyph towards the top of
// the page.
YOffset bag.ScaledPoint
// This allows the glyph to be part of word hyphenation.
Hyphenate bool
}
The component of the glyph node is a textual representation of the glyph and does not have to be exact.
HList#
type HList struct {
Width bag.ScaledPoint
Height bag.ScaledPoint
Depth bag.ScaledPoint
Badness int
GlueSet float64 // The ratio of the glue. Positive means stretching, negative shrinking.
GlueSign uint8 // 0 = normal, 1 = stretching, 2 = shrinking
GlueOrder GlueOrder // The level of infinity
Shift bag.ScaledPoint // The displacement perpendicular to the progressing direction. Not used.
List Node // The list itself.
VAlign VerticalAlignment
}
Image#
Kern#
Lang#
Penalty#
Rule#
type Rule struct {
// PDF code that gets output before the rule.
Pre string
// PDF Code after drawing the rule.
Post string
// Hide makes the rule invisible, no colored area is drawn. Used to make Pre
// and Post appear in the output with the given dimensions.
Hide bool
Width bag.ScaledPoint
Height bag.ScaledPoint
Depth bag.ScaledPoint
}
Example code#
Let's assume that you have a node list where the field head
points to the first node of the list. You can now insert a new rule node:
r := node.NewRule()
r.Pre = "0.6 g"
r.Post = "0 g"
// wd, ht = 0.5pt, 2pt
r.Width = bag.ScaledPointFromFloat(0.5)
r.Height = bag.ScaledPointFromFloat(2)
head = node.InsertAfter(head, cur, r)
StartStop#
type StartStop struct {
Action ActionType
StartNode *StartStop
Position PDFDataOutput
ShipoutCallback StartStopFunc
// Value contains action specific contents
Value any
}