square root and jumbo matrix example

This commit is contained in:
Lephenixnoir 2019-06-18 18:51:19 -04:00
parent 3d88e387cb
commit 51b7ba58ee
6 changed files with 111 additions and 39 deletions

View File

@ -15,24 +15,24 @@ This library is a customizable 2D math rendering tool for calculators. It can be
* Build formulae from TeX syntax or using the structural API
* Highly-customizable graphical and layout parameters
* Drawing is based on a few user-provided primitives (point, line, text size,
text)
* Drawing uses only a few user primitives (point, line, text size, text)
* Compatible with fxlib and gint
List of currently supported elements:
* Fractions (`\frac`)
* Subscripts and superscripts (`_` and `^`)
* Grouping parentheses, brackets and braces (`\left` and `\right`)
* Grouping parentheses, brackets, and braces (`\left` and `\right`)
* Grouping angle brackets, vertical lines, and dots (invisible)
* Sums, products and integrals (`\sum`, `\prod` and `\int`)
* Vectors (`\vec`) and limits (`\lim`)
* Square roots (`\sqrt`)
* Matrices (`\begin{matrix} ... \end{matrix}`)
Features that are partially implemented (and what is left to finish them):
* Support for inline style and display style (expose a parameter)
* Full fx-CG 50 support (suitable parenthesis styles)
* Theme that can decently port to fx-CG 50 (suitable parenthesis styles)
See the `TODO.md` file for more features to come.

33
TODO.md
View File

@ -1,33 +1,8 @@
* Support Unicode symbols (probably requires help from the font side, urgh)
Available blocks:
-> U+0020 .. U+007F (128) ASCII
-> U+00A0 .. U+00FF (96) Latin-1 Supplement
-> U+0100 .. U+017F (128) Latin Extended-A
-> U+0370 .. U+03FF (144) Greek
-> U+0400 .. U+047F (128) Cyrillic
-> U+2010 .. U+205F (80) General punctuation
-> U+2070 .. U+209F (48) Subscripts and superscripts
-> U+2160 .. U+217F (32) Roman numerals
-> U+2190 .. U+21FF (112) Arrows
-> U+2200 .. U+22FF (256) Mathematical operators
-> U+25A0 .. U+25FF (96) Geometric shapes
-> U+2800 .. U+28FF (256) Braille patterns
Other interesting blocks?
-> Finish cyrillic
-> IPA extenstions and Phonetic extensions
-> Currency symbols
-> Hiragana and Katakana
Other characters supported in FONTCHARACTER:
-> U+2139 Imaginary number
-> U+231F Fraction symbol
-> U+3010
-> U+3011
Pure TeX things:
* Add a parameter to resolve as inline style or display style
* Parametrize character-level and word-level spacing
* Be more generic in what nodes have display mode by default
Things that require help from the font manager:
* Parametrize character-level and word-level spacing
* Reduce horizontal spacing by using a proportional font
* Have a decent variable-height font system in gint (argh)
* Add square roots, and honor TEX_SQRT_SLANTED and TEX_SQRT_BAR_LENGTH
* Make more matrix tests

View File

@ -75,10 +75,18 @@
/* Extra height between argument and vector */
#define TEX_VEC_SPACING TEX_LAYOUT_SPACING
/* Make the vertical part of the square root symbol slanted at low heights */
/* Make the vertical part of the square root symbol slanted at small heights */
#define TEX_SQRT_SLANTED 1
/* Maximum height consider small */
#define TEX_SQRT_SLANT_MAX 10
/* Horizontal size occupied by the slanted part */
#define TEX_SQRT_SLANT_LENGTH 2
/* Length of the top-right bar of square roots (0 to disable) */
#define TEX_SQRT_BAR_LENGTH 0
/* Length of tip starting at the bottom left of the square root */
#define TEX_SQRT_TIP_LENGTH 2
/* Margin around argument */
#define TEX_SQRT_MARGIN TEX_LAYOUT_SPACING
/* Spacing between rows and columns in matrices */
#define TEX_MATRIX_COL_SPACING 4

View File

@ -382,7 +382,7 @@ void int_render(struct TeX_Node const * node, int x, int y, int color)
// TEX_VEC_MARGIN:
// Horizontal margin around the argument.
//
// ------> ] related to TEX_VEC_ARROW_LENGTH
// ------> ] 2 * TEX_VEC_ARROW_LENGTH + 1
// ] TEX_VEC_SPACING
// 1
// |_| |_|
@ -438,6 +438,83 @@ void lim_render(__attribute__((unused)) struct TeX_Node const * node, int x,
TeX_text("lim", x, y, color);
}
//---
// Square roots
// * args: 1 (<1 invalidate, >1 ignore)
// * flow: normal
//
// Graphical parameters:
//
// TEX_SQRT_SLANTED:
// Makes the vertical part of the square root slanted when it is small.
// TEX_SQRT_SLANT_MAX:
// Maximum height consider small
// TEX_SQRT_SLANT_LENGTH:
// Horizontal size occupied by the slanted part.
// TEX_SQRT_BAR_LENGTH:
// Length of the top-right bar marking the end of the argument (or 0)
// TEX_SQRT_TIP_LENGTH:
// Length of tip starting at the bottom left of the square root
// TEX_SQRT_MARGIN:
// Margin around argument
//
// If TEX_SQRT_SLANTED != 0 and height(1) <= TEX_SQRT_SLANT_MAX:
//
// TEX_SQRT_TIP_LENGTH
// | _______ v
// | / | | TEX_SQRT_BAR_LENGTH
// | v / 1 ^
// +-->| \/
// ^ <->
// TEX_SQRT_SLANT_LENGTH
//
// All other cases:
//
// TEX_SQRT_TIP_LENGTH
// | _______ v
// | | | | TEX_SQRT_BAR_LENGTH
// | v | 1 ^
// +-->| \|
// ^
//---
void sqrt_layout(struct TeX_Node *node)
{
/* Invalidate the node if no argument is present */
if(!args[0]) { node->hidden = 1; return; }
int slanted = TEX_SQRT_SLANTED && h(0) <= TEX_SQRT_SLANT_MAX;
node->width = w(0) + 2 * TEX_SQRT_MARGIN + TEX_SQRT_TIP_LENGTH;
node->width += (TEX_SQRT_BAR_LENGTH > 0);
node->width += (slanted ? TEX_SQRT_SLANT_LENGTH : 1);
node->height = h(0) + TEX_SQRT_MARGIN + 1;
node->line = l(0) + TEX_SQRT_MARGIN + 1;
}
void sqrt_render(struct TeX_Node const * node, int x, int y, int color)
{
int slanted = TEX_SQRT_SLANTED && h(0) <= TEX_SQRT_SLANT_MAX;
int w = node->width;
int h = node->height;
int tip = TEX_SQRT_TIP_LENGTH;
TeX_line(x, y + h - tip - 1, x + tip, y + h - 1, color);
int bar_length = (slanted ? TEX_SQRT_SLANT_LENGTH : 1);
TeX_line(x + tip + bar_length - 1, y, x + tip, y + h - 1, color);
int base = tip + bar_length;
TeX_line(x + base, y, x + w - 1, y, color);
TeX_line(x + w - 1, y, x + w - 1, y + TEX_SQRT_BAR_LENGTH, color);
TeX_flow_render(args[0],
x + base + TEX_SQRT_MARGIN,
y + 1 + TEX_SQRT_MARGIN,
color);
}
//---
// The class table and lookup functions
//---
@ -467,6 +544,9 @@ static struct TeX_Class const class_table[] = {
{ "vec", vec_layout, vec_render },
{ "lim", lim_layout, lim_render },
/* Square root */
{ "sqrt", sqrt_layout, sqrt_render },
/* NULL terminator */
{ NULL },
};

View File

@ -194,8 +194,8 @@ static void matrix_layout(struct TeX_Env *env)
env->width += m->colwidth[j];
}
env->width += TEX_MATRIX_COL_SPACING * (m->cols - 1);
env->height += TEX_MATRIX_ROW_SPACING * (m->rows - 1);
env->width += TEX_MATRIX_COL_SPACING * max(m->cols - 1, 0);
env->height += TEX_MATRIX_ROW_SPACING * max(m->rows - 1, 0);
env->line = env->height >> 1;
}

View File

@ -169,12 +169,21 @@ int main(void)
char const * formula =
"\\frac{x^7\\left[X,Y\\right]+3\\left|\\frac{A}{B}\\right>}"
"{\\left\\{\\frac{a_k+b_k}{k!}\\right\\}^5}"
" + \\int_a^b\\frac{\\left(b-t\\right)^{n+1}}{n!}dt"
" + \\int_a^b\\frac{\\left(b-t\\right)^{n+1}}{n!\\sqrt{n^3}}dt"
" + \\left(\\begin{matrix}"
"\\frac{1}{2}&5\\\\"
"\\frac{1}{2}&\\sqrt{5}\\\\"
"-1&a+b"
"\\end{matrix}\\right)";
/* Much harder matrix test.
formula = "\\left\\{\\begin{matrix}"
"\\frac{-1}{ab}+7&\\sum_{i=1}^{k+\\int f} \\frac{in}{4!}\\\\"
"\\left(\\begin{matrix}"
"cos(t)&-sin(t)\\\\sin(t)&cos(t)"
"\\end{matrix}\\right)\\\\"
"x&y&\\left[\\begin{matrix}\\end{matrix}\\right]"
"\\end{matrix}\\right\\}"; */
struct TeX_Env *env = TeX_parse(formula);
if(!env) { puts("parsing error!"); return 1; }
TeX_print_env(env, 0);