diff --git a/README.md b/README.md index 78cf152..6933648 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/TODO.md b/TODO.md index aac3dfc..b2119a1 100644 --- a/TODO.md +++ b/TODO.md @@ -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 diff --git a/include/TeX/config.h b/include/TeX/config.h index ba471f9..4877730 100644 --- a/include/TeX/config.h +++ b/include/TeX/config.h @@ -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 diff --git a/src/classes.c b/src/classes.c index 4893deb..5771cad 100644 --- a/src/classes.c +++ b/src/classes.c @@ -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 }, }; diff --git a/src/env.c b/src/env.c index 0603cae..2f3ccea 100644 --- a/src/env.c +++ b/src/env.c @@ -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; } diff --git a/src/platform/sdl2.c b/src/platform/sdl2.c index 0cfe847..6969fa1 100644 --- a/src/platform/sdl2.c +++ b/src/platform/sdl2.c @@ -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);