From a38b0349d60721d3a9b74c1748878da07d1af053 Mon Sep 17 00:00:00 2001 From: Lephenixnoir Date: Wed, 19 Jun 2019 11:52:09 -0400 Subject: [PATCH] expose display mode and inline mode --- README.md | 4 ++-- TODO.md | 1 - include/TeX/TeX.h | 6 ++++-- include/TeX/classes.h | 5 +++-- include/TeX/defs.h | 3 +++ include/TeX/env.h | 2 +- include/TeX/flow.h | 5 ++--- include/TeX/node.h | 5 ++--- src/TeX.c | 8 ++++---- src/TeX.y | 2 +- src/classes.c | 36 ++++++++++++++++++------------------ src/env.c | 13 +++++++------ src/flow.c | 6 +++--- src/node.c | 6 +++--- src/platform/cli.c | 2 +- src/platform/sdl2.c | 2 +- 16 files changed, 55 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index 6933648..8dbab28 100644 --- a/README.md +++ b/README.md @@ -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): diff --git a/TODO.md b/TODO.md index a02d4cc..88db834 100644 --- a/TODO.md +++ b/TODO.md @@ -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: diff --git a/include/TeX/TeX.h b/include/TeX/TeX.h index 5f2726b..8407950 100644 --- a/include/TeX/TeX.h +++ b/include/TeX/TeX.h @@ -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 */ diff --git a/include/TeX/classes.h b/include/TeX/classes.h index 107d9da..2d6fe82 100644 --- a/include/TeX/classes.h +++ b/include/TeX/classes.h @@ -26,8 +26,9 @@ struct TeX_Class #include 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) diff --git a/include/TeX/defs.h b/include/TeX/defs.h index 33cf822..41c23bf 100644 --- a/include/TeX/defs.h +++ b/include/TeX/defs.h @@ -20,4 +20,7 @@ typedef unsigned int uint; _a > _b ? _a : _b; \ }) +/* Attributes */ +#define TEX_UNUSED __attribute__((unused)) + #endif /* DEFS_H */ diff --git a/include/TeX/env.h b/include/TeX/env.h index 70347f4..9bbf5a7 100644 --- a/include/TeX/env.h +++ b/include/TeX/env.h @@ -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); diff --git a/include/TeX/flow.h b/include/TeX/flow.h index 0ba3bc4..9ad4648 100644 --- a/include/TeX/flow.h +++ b/include/TeX/flow.h @@ -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 diff --git a/include/TeX/node.h b/include/TeX/node.h index 1284ce6..efb866d 100644 --- a/include/TeX/node.h +++ b/include/TeX/node.h @@ -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. */ diff --git a/src/TeX.c b/src/TeX.c index 92a7843..2cc177a 100644 --- a/src/TeX.c +++ b/src/TeX.c @@ -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); diff --git a/src/TeX.y b/src/TeX.y index 380efe4..7210162 100644 --- a/src/TeX.y +++ b/src/TeX.y @@ -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) { } diff --git a/src/classes.c b/src/classes.c index e2beb29..d9bb742 100644 --- a/src/classes.c +++ b/src/classes.c @@ -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; } diff --git a/src/env.c b/src/env.c index 2f3ccea..3cabdb8 100644 --- a/src/env.c +++ b/src/env.c @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -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); diff --git a/src/flow.c b/src/flow.c index 530c7f2..e740aa1 100644 --- a/src/flow.c +++ b/src/flow.c @@ -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; diff --git a/src/node.c b/src/node.c index 6b26358..a93f4eb 100644 --- a/src/node.c +++ b/src/node.c @@ -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 */ diff --git a/src/platform/cli.c b/src/platform/cli.c index 70d3bc4..73a52f8 100644 --- a/src/platform/cli.c +++ b/src/platform/cli.c @@ -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); diff --git a/src/platform/sdl2.c b/src/platform/sdl2.c index d3d4a81..493af4b 100644 --- a/src/platform/sdl2.c +++ b/src/platform/sdl2.c @@ -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);