TeX/include/TeX/structure.h

154 lines
5.1 KiB
C

//---
// structure: Recursive node/flow data structure
//---
#ifndef TEX_STRUCTURE
#define TEX_STRUCTURE
#include <TeX/defs.h>
#include <stddef.h>
#include <stdint.h>
/* Maximum number of command arguments allowed by the library (each node has
exactly this number of children; memory usage is better if this is small) */
#define TEX_MAX_CHILDREN 2
/* A special class number for nodes that contain plain text. Class numbers from
1 onwards are used by TeX_Class. See also the class array in nodes.c. */
#define TEX_NODECLASS_TEXT 0
//---
// Data structures
// The structure mixes linked lists (text flow along a line, TeX_Flow) and
// trees (arguments to commands, TeX_Node) in a mutually-recursive way.
//---
/* TeX_Flow
This object represents a horizontal line of nodes following the flow of the
text; each node can be a plain string or a functional node. All share the
same base line when rendered. */
struct TeX_Flow
{
/* Pointer to first and last elements of the line */
struct TeX_Node *first;
struct TeX_Node *last;
uint16_t width;
uint16_t height;
uint16_t line;
} __attribute__((packed, aligned(sizeof (void *))));
/* TeX_Node
Here's the main deal. TeX_Flow objects handle the flow and TeX_Node objects
handle the content and its structure. */
struct TeX_Node
{
/* Pointer to next element in the flow */
struct TeX_Node *next;
union {
/* Plain text content encoded as UTF-8 */
uint8_t *text;
/* Functional arguments */
struct TeX_Flow *args[TEX_MAX_CHILDREN];
};
/* Invalid or hidden node */
uint hidden :1;
/* Node class identifier */
uint type :7;
/* Class variant or fixed argument */
uint subtype :8;
/* Size and placement */
uint16_t width;
uint16_t height;
uint16_t line;
/* Location withing flow, as x and baseline displacement */
uint16_t x;
int16_t l;
} __attribute__((packed, aligned(sizeof (void *))));
//---
// Class nodes
// These are the nodes that have arguments, and specific size-calculation
// and rendering methods. Most interesting nodes (fractions, sums,
// matrices...) fall into this category.
//---
/* TeX_Class
A class of nodes (ie. "\name{arg}{arg}..."): function name, size-calculation
method, rendering method. */
struct TeX_Class
{
/* Most of the time this name appears in the formula using the "\name"
notation, but some classes (superscript, parentheses, matrices...)
have special syntax and their names are hardcoded. To avoid
conflicts, built-in class names start with a backslash. */
const char *name;
/* size()
This function must calculate the width, height and base line of the
node and store the results in the structure fields. It is allowed to
access the .width, .height and .line fields of its children because
they will have had their size calculated beforehand.
This TeX module provides classes with a primitive function that
calculates the size of raw strings:
void text_size(const char *str, int *width, int *height);
@node A node of the described class, for size calculation */
void (*size)(struct TeX_Node *node);
/* render()
This function must render the given node at the provided (x, y)
coordinates. The (x, y) point is the top-left corner of the bounding
box of the expression and is inside the box (ie. it can be drawn
to). This function must honor the size estimates provided by
calculate_size() and not draw outside the bounding box.
This TeX module provides two primitive functions for rendering:
void pixel(int x, int y, int color);
void text(const char *str, int x, int y, int color);
@node A node of the described class, for rendering
@x Horizontal coordinate of the requested rendering position
@y Vertical coordinate of the requested rendering position
@color Requested rendering color */
void (*render)(struct TeX_Node const * node, int x, int y, int color);
};
/* class_find() - Find a class using a command name
@name Command name
Returns a positive class id representing the requested TeX_Class object (if
a class with this name is found in the table, a negative number otherwise.
This function never returns 0, which is reserved for TEX_NODECLASS_TEXT. */
int class_find(const char *name);
/* Class table. This is an array that can be indexed by class_id - 1 where
class_id is an id returned by class_find(). It is terminated by a class
with a NULL command name. Be careful because the first element in this array
has class id 1. */
extern struct TeX_Class TeX_table[];
//---
// Recursive size computation
//---
/* size_node() - Calculate the size of node
This function handles all node classes (including text) and computes the
size of the children in advance, as required by the class' calculate_size()
method. Modifies the node structure. */
void size_node(struct TeX_Node *node);
/* size_flow() - Calculate the size of a flow
This function calculates the size taken by nodes sharing the same baseline.
It heeds for special size and alignment exceptions such as parenthesis-type
characters and subscripts/superscripts. Modifies the flow structure. */
void size_flow(struct TeX_Flow *flow);
#endif /* TEX_STRUCTURE */