154 lines
5.1 KiB
C
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 */
|