expose display mode and inline mode

This commit is contained in:
Lephenixnoir 2019-06-19 11:52:09 -04:00
parent 36d8defe3e
commit a38b0349d6
16 changed files with 55 additions and 51 deletions

View File

@ -71,11 +71,11 @@ Before using the library in a program, a configuration step is needed. The libra
The three rendering functions are available in fxlib; for monospaced fonts the fourth can be implemented trivially. In gint, the four can be defined as wrappers for `dpixel()`, `dline()`, `dsize()` and `dtext()`.
The type of formulae is `TeX_Env`. To parse and compute the size of a formula, use the `TeX_parse()` function, which returns a new formula object (or `NULL` if a critical error occurs).
The type of formulae is `TeX_Env`. To parse and compute the size of a formula, use the `TeX_parse()` function, which returns a new formula object (or `NULL` if a critical error occurs). The second parameter `display` is set to non-zero to use display mode (similar to `\[ .. \]` in LaTeX) or zero to use inline mode (similar to `$ .. $` in LaTeX).
```c
char *code = "\\frac{x_7}{\\left\\{\\frac{\\frac{2}{3}}{27}\\right\\}^2}";
struct TeX_Env *formula = TeX_parse(code);
struct TeX_Env *formula = TeX_parse(code, 1);
```
The size of the formula can be queried through `formula->width` and `formula->height`. To render, specify the location of the top-left corner and the drawing color (which will be passed to all primitives):

View File

@ -1,5 +1,4 @@
Pure TeX things:
* Add a parameter to resolve as inline style or display style
* Have a decent reference other than the source code
Things that require help from the font manager:

View File

@ -66,9 +66,10 @@ void TeX_intf_text(void (*draw_text)(char const *str, int x, int y,int color));
/* TeX_parse(): Parse a TeX formula
@formula TeX formula to parse
@display Use full-size display mode instead of inline mode (as in LaTeX)
Returns a dynamically-allocated TeX_Env object that can be used in further
calls to TeX_draw() and must be freed by a call to TeX_free(). */
struct TeX_Env *TeX_parse(char const *formula);
struct TeX_Env *TeX_parse(char const *formula, int display);
/* TeX_free(): Free an allocated TeX formula
Freed formulas become dangling and must not be used in any further call.
@ -94,9 +95,10 @@ void TeX_draw(struct TeX_Env *formula, int x, int y, int color);
Only use it if you're going to render the formula only once or if you're
very short on memory.
@formula Formula to render (textual form)
@display Use display mode instead of inline mode (as in LaTeX)
@x x coordinate of the left-side of the bounding box (included)
@y y coordinate of the top-size of the bounding box (included)
@color Requested color for the rendered pixels */
void TeX_interpret(char const *formula, int x, int y, int color);
void TeX_interpret(char const *formula, int display, int x, int y, int color);
#endif /* TEX_TEX */

View File

@ -26,8 +26,9 @@ struct TeX_Class
#include <TeX/interface.h>
void TeX_size(char const *str, int *width, int *height);
@node A node of the described class, for size calculation */
void (*layout)(struct TeX_Node *node);
@node A node of the described class, for size calculation
@display Whether we use full-size display instead of inline mode */
void (*layout)(struct TeX_Node *node, int display);
/* render()
This function must render the given node at the provided (x, y)

View File

@ -20,4 +20,7 @@ typedef unsigned int uint;
_a > _b ? _a : _b; \
})
/* Attributes */
#define TEX_UNUSED __attribute__((unused))
#endif /* DEFS_H */

View File

@ -31,7 +31,7 @@ struct TeX_Env
void (*add_break)(TeX_Env *env);
/* layout(): Compute environment layout */
void (*layout)(TeX_Env *env);
void (*layout)(TeX_Env *env, int display);
/* render(): Render environment */
void (*render)(TeX_Env *env, int x, int y, int color);

View File

@ -22,8 +22,7 @@ struct TeX_Flow
uint16_t width;
uint16_t height;
uint16_t line;
} __attribute__((packed, aligned(sizeof (void *))));
};
/* Possible subscript and superscript mode.
@ -63,7 +62,7 @@ void TeX_flow_free(struct TeX_Flow *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's metadata. */
void TeX_flow_layout(struct TeX_Flow *flow);
void TeX_flow_layout(struct TeX_Flow *flow, int display);
/* TeX_flow_render(): Render a flow and all its components
This function renders all horizontal objects in a flow. The layout of the

View File

@ -51,8 +51,7 @@ struct TeX_Node
/* Location within the flow, as x and baseline displacement */
uint16_t x;
int16_t l;
} __attribute__((packed, aligned(sizeof (void *))));
};
//---
// Node creation and destruction functions
@ -94,7 +93,7 @@ void TeX_node_free(struct TeX_Node *node);
/* TeX_node_layout(): Compute the layout of a node
This functions computes the layout of a node and its children, and stores
the results in the node's metadata. */
void TeX_node_layout(struct TeX_Node *node);
void TeX_node_layout(struct TeX_Node *node, int display);
/* TeX_node_render(): Render a node and its children
The node's layout must have been computed first. */

View File

@ -59,7 +59,7 @@ void TeX_free(struct TeX_Env *env)
//---
/* TeX_parse(): Parse a TeX formula */
struct TeX_Env *TeX_parse(char const *formula)
struct TeX_Env *TeX_parse(char const *formula, int display)
{
/* Provided by the parser. */
struct TeX_Env *parse(char const *str);
@ -67,7 +67,7 @@ struct TeX_Env *TeX_parse(char const *formula)
struct TeX_Env *env = parse(formula);
if(!env) return NULL;
env->layout(env);
env->layout(env, display);
return env;
}
@ -78,9 +78,9 @@ void TeX_draw(struct TeX_Env *formula, int x, int y, int color)
}
/* TeX_interpret(): Parse and render, in sequence */
void TeX_interpret(char const *formula, int x, int y, int color)
void TeX_interpret(char const *formula, int display, int x, int y, int color)
{
struct TeX_Env *env = TeX_parse(formula);
struct TeX_Env *env = TeX_parse(formula, display);
if(!env) return;
TeX_draw(env, x, y, color);

View File

@ -459,7 +459,7 @@ struct TeX_Env *parse(char const *str)
#ifndef TEX_PRINT
void yyerror(__attribute__((unused)) char const *error)
void yyerror(TEX_UNUSED char const *error)
{
}

View File

@ -26,7 +26,7 @@
// * flow: normal
//---
void text_layout(struct TeX_Node *node)
void text_layout(struct TeX_Node *node, TEX_UNUSED int display)
{
int w, h;
TeX_size((char const *)node->text, &w, &h);
@ -45,9 +45,9 @@ void text_render(struct TeX_Node const * node, int x, int y, int color)
// Environment nodes.
//---
void env_layout(struct TeX_Node *node)
void env_layout(struct TeX_Node *node, int display)
{
node->env->layout(node->env);
node->env->layout(node->env, display);
node->width = node->env->width;
node->height = node->env->height;
@ -82,7 +82,7 @@ void env_render(struct TeX_Node const * node, int x, int y, int color)
// TEX_FRACTION_MARGIN
//---
void frac_layout(struct TeX_Node *node)
void frac_layout(struct TeX_Node *node, TEX_UNUSED int display)
{
/* Drop the fraction if there are less than two arguments */
if(!args[1]) { node->hidden = 1; return; }
@ -150,7 +150,7 @@ void frac_render(struct TeX_Node const * node, int x, int y, int color)
// seems to resize the contents to make it smoother. Not possible here.
//---
void leftright_layout(struct TeX_Node *node)
void leftright_layout(struct TeX_Node *node, TEX_UNUSED int display)
{
int width, height;
TeX_size("#", &width, &height);
@ -276,7 +276,7 @@ void leftright_render(struct TeX_Node const * node, int x, int y, int color)
// >--< TEX_SUBSCRIPT_SPACING
//---
void supsubscript_layout(struct TeX_Node *node)
void supsubscript_layout(struct TeX_Node *node, TEX_UNUSED int display)
{
/* Invalidate node if no argument is provided */
if(!args[0]) { node->hidden = 1; return; }
@ -300,15 +300,15 @@ void supsubscript_render(struct TeX_Node const * node, int x, int y,
// Summation symbols are just nodes with a constant size and function.
//---
void sum_layout(struct TeX_Node *node)
void sum_layout(struct TeX_Node *node, TEX_UNUSED int display)
{
node->width = 9;
node->height = 9;
node->line = 4;
}
void sum_render(__attribute__((unused)) struct TeX_Node const * node, int x,
int y, int color)
void sum_render(TEX_UNUSED struct TeX_Node const * node, int x, int y,
int color)
{
TeX_line(x, y, x + 8, y, color);
TeX_line(x, y, x + 4, y + 4, color);
@ -324,15 +324,15 @@ void sum_render(__attribute__((unused)) struct TeX_Node const * node, int x,
// * flow: display mode when available
//---
void prod_layout(struct TeX_Node *node)
void prod_layout(struct TeX_Node *node, TEX_UNUSED int display)
{
node->width = 9;
node->height = 9;
node->line = 4;
}
void prod_render(__attribute__((unused)) struct TeX_Node const * node, int x,
int y, int color)
void prod_render(TEX_UNUSED struct TeX_Node const * node, int x, int y,
int color)
{
TeX_line(x, y, x + 8, y, color);
TeX_line(x + 1, y, x + 1, y + 8, color);
@ -347,7 +347,7 @@ void prod_render(__attribute__((unused)) struct TeX_Node const * node, int x,
// * flow: default
//---
void int_layout(struct TeX_Node *node)
void int_layout(struct TeX_Node *node, TEX_UNUSED int display)
{
node->width = 5;
node->height = TEX_INT_HEIGHT;
@ -389,7 +389,7 @@ void int_render(struct TeX_Node const * node, int x, int y, int color)
// TEX_VEC_MARGIN
//---
void vec_layout(struct TeX_Node *node)
void vec_layout(struct TeX_Node *node, TEX_UNUSED int display)
{
int arrow_height = 2 * TEX_VEC_ARROW_LENGTH + 1;
@ -423,7 +423,7 @@ void vec_render(struct TeX_Node const * node, int x, int y, int color)
// * flow: display mode when available
//---
void lim_layout(struct TeX_Node *node)
void lim_layout(struct TeX_Node *node, TEX_UNUSED int display)
{
int w, h;
TeX_size("lim", &w, &h);
@ -432,8 +432,8 @@ void lim_layout(struct TeX_Node *node)
node->line = h >> 1;
}
void lim_render(__attribute__((unused)) struct TeX_Node const * node, int x,
int y, int color)
void lim_render(TEX_UNUSED struct TeX_Node const * node, int x, int y,
int color)
{
TeX_text("lim", x, y, color);
}
@ -478,7 +478,7 @@ void lim_render(__attribute__((unused)) struct TeX_Node const * node, int x,
// ^
//---
void sqrt_layout(struct TeX_Node *node)
void sqrt_layout(struct TeX_Node *node, TEX_UNUSED int display)
{
/* Invalidate the node if no argument is present */
if(!args[0]) { node->hidden = 1; return; }

View File

@ -3,6 +3,7 @@
#include <TeX/env.h>
#include <TeX/vector.h>
#include <TeX/defs.h>
#include <stdlib.h>
#include <string.h>
@ -44,18 +45,18 @@ static void primary_add_node(struct TeX_Env *env, struct TeX_Node *node)
p->flow = TeX_flow_add_node(p->flow, node);
}
static void primary_add_separator(__attribute__((unused)) struct TeX_Env *env)
static void primary_add_separator(TEX_UNUSED struct TeX_Env *env)
{
}
static void primary_add_break(__attribute__((unused)) struct TeX_Env *env)
static void primary_add_break(TEX_UNUSED struct TeX_Env *env)
{
}
static void primary_layout(struct TeX_Env *env)
static void primary_layout(struct TeX_Env *env, int display)
{
struct TeX_Env_Primary *p = (void *)env;
TeX_flow_layout(p->flow);
TeX_flow_layout(p->flow, display);
env->width = p->flow->width;
env->height = p->flow->height;
@ -145,7 +146,7 @@ static void matrix_add_break(struct TeX_Env *env)
m->rows++;
}
static void matrix_layout(struct TeX_Env *env)
static void matrix_layout(struct TeX_Env *env, int display)
{
struct TeX_Env_Matrix *m = (void *)env;
@ -173,7 +174,7 @@ static void matrix_layout(struct TeX_Env *env)
struct TeX_Flow *f = m->elements[i];
if(!f) { col++; continue; }
TeX_flow_layout(f);
TeX_flow_layout(f, display);
/* Update the current row and column */
m->rowline[row] = max(m->rowline[row], f->line);

View File

@ -314,7 +314,7 @@ static void update(struct chunk *c, struct group *g, int *x, int *above,
}
/* TeX_flow_layout(): Calculate the layout of a flow */
void TeX_flow_layout(struct TeX_Flow *flow)
void TeX_flow_layout(struct TeX_Flow *flow, int display)
{
/* Current node and current chunk */
struct TeX_Node *node;
@ -331,7 +331,7 @@ void TeX_flow_layout(struct TeX_Flow *flow)
for(node = flow->first; node; node = node->next)
{
char const *class = TeX_class_of(node)->name;
TeX_node_layout(node);
TeX_node_layout(node, display);
if(!strcmp(class, "\\sup"))
{
@ -360,7 +360,7 @@ void TeX_flow_layout(struct TeX_Flow *flow)
int mode = TEX_CHUNK_INLINE;
int pref = TeX_class_of(node)->mode;
if((pref == TEX_FLOW_PREFER_DISPLAY && 1) ||
if((pref == TEX_FLOW_PREFER_DISPLAY && display) ||
pref == TEX_FLOW_DISPLAY)
{
mode = TEX_CHUNK_DISPLAY;

View File

@ -119,15 +119,15 @@ void TeX_node_free(struct TeX_Node *node)
//---
/* TeX_node_layout(): Compute the layout of a node */
void TeX_node_layout(struct TeX_Node *node)
void TeX_node_layout(struct TeX_Node *node, int display)
{
/* First compute the layout of the children */
if(!special(node))
for(int i = 0; i < TEX_NODE_MAX_CHILDREN && node->args[i]; i++)
TeX_flow_layout(node->args[i]);
TeX_flow_layout(node->args[i], display);
/* Then use the class' special layout computation function */
TeX_class_of(node)->layout(node);
TeX_class_of(node)->layout(node, display);
}
/* TeX_node_render(): Render a node and its children */

View File

@ -95,7 +95,7 @@ int main(void)
TeX_print_lex(formula);
printf("\n\e[36m<><><>\e[0m \e[1mParsing\e[0m\n\n");
struct TeX_Env *env = TeX_parse(formula);
struct TeX_Env *env = TeX_parse(formula, 1);
if(!env) puts("parsing error!");
else TeX_print_env(env, 0);
TeX_free(env);

View File

@ -184,7 +184,7 @@ int main(void)
"x&\\sqrt{y}&\\left[\\begin{matrix}\\end{matrix}\\right]"
"\\end{matrix}\\right\\}"; */
struct TeX_Env *env = TeX_parse(formula);
struct TeX_Env *env = TeX_parse(formula, 1);
if(!env) { puts("parsing error!"); return 1; }
TeX_print_env(env, 0);