LCOV - code coverage report
Current view: top level - preproc/eqn - box.cpp (source / functions) Hit Total Coverage
Test: GNU roff Lines: 216 355 60.8 %
Date: 2026-01-16 17:51:41 Functions: 45 75 60.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Copyright 1989-2023 Free Software Foundation, Inc.
       2             :      Written by James Clark (jjc@jclark.com)
       3             : 
       4             : This file is part of groff, the GNU roff typesetting system.
       5             : 
       6             : groff is free software; you can redistribute it and/or modify it under
       7             : the terms of the GNU General Public License as published by the Free
       8             : Software Foundation, either version 3 of the License, or
       9             : (at your option) any later version.
      10             : 
      11             : groff is distributed in the hope that it will be useful, but WITHOUT ANY
      12             : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13             : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14             : for more details.
      15             : 
      16             : You should have received a copy of the GNU General Public License
      17             : along with this program.  If not, see <http://www.gnu.org/licenses/>. */
      18             : 
      19             : #ifdef HAVE_CONFIG_H
      20             : #include <config.h>
      21             : #endif
      22             : 
      23             : #include <stdcountof.h>
      24             : 
      25             : #include <assert.h>
      26             : 
      27             : #include "eqn.h"
      28             : #include "pbox.h"
      29             : 
      30             : const char *current_roman_font;
      31             : 
      32             : char *gifont = 0 /* nullptr */;
      33             : char *grfont = 0 /* nullptr */;
      34             : char *gbfont = 0 /* nullptr */;
      35             : int gsize = 0;
      36             : 
      37             : int script_size_reduction = -1; // negative means reduce by a percentage
      38             : 
      39             : int positive_space = -1;
      40             : int negative_space = -1;
      41             : 
      42             : int minimum_size = 5;
      43             : 
      44             : static int fat_offset = 4;
      45             : static int over_hang = 0;
      46             : static int accent_width = 31;
      47             : static int delimiter_factor = 900;
      48             : static int delimiter_shortfall = 50;
      49             : 
      50             : static int null_delimiter_space = 12;
      51             : static int script_space = 5;
      52             : static int thin_space = 17;
      53             : static int half_space = 17;
      54             : static int medium_space = 22;
      55             : static int thick_space = 28;
      56             : static int full_space = 28;
      57             : 
      58             : static int num1 = 70;
      59             : static int num2 = 40;
      60             : // we don't use num3, because we don't have \atop
      61             : static int denom1 = 70;
      62             : static int denom2 = 36;
      63             : static int axis_height = 26;    // in 100ths of an em
      64             : static int sup1 = 42;
      65             : static int sup2 = 37;
      66             : static int sup3 = 28;
      67             : static int default_rule_thickness = 4;
      68             : static int sub1 = 20;
      69             : static int sub2 = 23;
      70             : static int sup_drop = 38;
      71             : static int sub_drop = 5;
      72             : static int x_height = 45;
      73             : static int big_op_spacing1 = 11;
      74             : static int big_op_spacing2 = 17;
      75             : static int big_op_spacing3 = 20;
      76             : static int big_op_spacing4 = 60;
      77             : static int big_op_spacing5 = 10;
      78             : 
      79             : // These are for piles and matrices.
      80             : 
      81             : static int baseline_sep = 140;          // = num1 + denom1
      82             : static int shift_down = 26;             // = axis_height
      83             : static int column_sep = 100;            // = em space
      84             : static int matrix_side_sep = 17;        // = thin space
      85             : 
      86             : static int body_height = 85;
      87             : static int body_depth = 35;
      88             : 
      89             : static int nroff = 0;           // should we grok ndefine or tdefine?
      90             : 
      91             : struct param {
      92             :   const char *name;
      93             :   int *ptr;
      94             : } default_param_table[] = {
      95             :   { "fat_offset", &fat_offset },
      96             :   { "over_hang", &over_hang },
      97             :   { "accent_width", &accent_width },
      98             :   { "delimiter_factor", &delimiter_factor },
      99             :   { "delimiter_shortfall", &delimiter_shortfall },
     100             :   { "null_delimiter_space", &null_delimiter_space },
     101             :   { "script_space", &script_space },
     102             :   { "thin_space", &thin_space },
     103             :   { "medium_space", &medium_space },
     104             :   { "thick_space", &thick_space },
     105             :   { "half_space", &half_space },
     106             :   { "full_space", &full_space },
     107             :   { "num1", &num1 },
     108             :   { "num2", &num2 },
     109             :   { "denom1", &denom1 },
     110             :   { "denom2", &denom2 },
     111             :   { "axis_height", &axis_height },
     112             :   { "sup1", &sup1 },
     113             :   { "sup2", &sup2 },
     114             :   { "sup3", &sup3 },
     115             :   { "default_rule_thickness", &default_rule_thickness },
     116             :   { "sub1", &sub1 },
     117             :   { "sub2", &sub2 },
     118             :   { "sup_drop", &sup_drop },
     119             :   { "sub_drop", &sub_drop },
     120             :   { "x_height", &x_height },
     121             :   { "big_op_spacing1", &big_op_spacing1 },
     122             :   { "big_op_spacing2", &big_op_spacing2 },
     123             :   { "big_op_spacing3", &big_op_spacing3 },
     124             :   { "big_op_spacing4", &big_op_spacing4 },
     125             :   { "big_op_spacing5", &big_op_spacing5 },
     126             :   { "minimum_size", &minimum_size },
     127             :   { "baseline_sep", &baseline_sep },
     128             :   { "shift_down", &shift_down },
     129             :   { "column_sep", &column_sep },
     130             :   { "matrix_side_sep", &matrix_side_sep },
     131             :   { "draw_lines", &draw_flag },
     132             :   { "body_height", &body_height },
     133             :   { "body_depth", &body_depth },
     134             :   { "nroff", &nroff },
     135             : };
     136             : 
     137             : struct param *param_table = 0 /* nullptr */;
     138             : 
     139             : // Use the size of default_param_table to iterate through both it and
     140             : // param_table, because the former is known constant to the compiler.
     141             : 
     142          22 : void set_param(const char *name, int value)
     143             : {
     144         798 :   for (size_t i = 0; i <= countof(default_param_table); i++)
     145         798 :     if (strcmp(param_table[i].name, name) == 0) {
     146          22 :       *(param_table[i].ptr) = value;
     147          22 :       return;
     148             :     }
     149           0 :   error("'set' primitive does not recognize parameter name '%1'", name);
     150             : }
     151             : 
     152           1 : void reset_param(const char *name)
     153             : {
     154           9 :   for (size_t i = 0; i < countof(default_param_table); i++)
     155           9 :     if (strcmp(param_table[i].name, name) == 0) {
     156           1 :       *param_table[i].ptr = *(default_param_table[i].ptr);
     157           1 :       return;
     158             :     }
     159           0 :   error("'reset' primitive does not recognize parameter name '%1'",
     160           0 :         name);
     161             : }
     162             : 
     163        1365 : int get_param(const char *name)
     164             : {
     165       21247 :   for (size_t i = 0; i < countof(default_param_table); i++)
     166       21247 :     if (strcmp(param_table[i].name, name) == 0)
     167        1365 :       return *(param_table[i].ptr);
     168           0 :   assert(0 == "attempted to access parameter not in table");
     169             :   fatal("internal error: unrecognized parameter name '%1'", name);
     170             : }
     171             : 
     172          59 : void init_param_table()
     173             : {
     174          59 :   param_table = new param[countof(default_param_table)];
     175        2419 :   for (size_t i = 0; i < countof(default_param_table); i++) {
     176        2360 :     param_table[i].name = default_param_table[i].name;
     177        2360 :     param_table[i].ptr = new int(*(default_param_table[i].ptr));
     178             :   }
     179          59 : }
     180             : 
     181          59 : void free_param_table()
     182             : {
     183          59 :   if (param_table != 0 /* nullptr */) {
     184        2419 :     for (size_t i = 0; i < countof(default_param_table); i++)
     185        2360 :       delete param_table[i].ptr;
     186          59 :     delete[] param_table;
     187          59 :     param_table = 0 /* nullptr */;
     188             :   }
     189          59 : }
     190             : 
     191         197 : int script_style(int style)
     192             : {
     193         197 :   return style > SCRIPT_STYLE ? style - 2 : style;
     194             : }
     195             : 
     196         182 : int cramped_style(int style)
     197             : {
     198         182 :   return (style & 1) ? style - 1 : style;
     199             : }
     200             : 
     201           4 : void set_space(int n)
     202             : {
     203           4 :   if (n < 0)
     204           0 :     negative_space = -n;
     205             :   else
     206           4 :     positive_space = n;
     207           4 : }
     208             : 
     209             : // Return 0 if the specified size is bad.
     210             : // The caller is responsible for giving the error message.
     211             : 
     212           3 : int set_gsize(const char *s)
     213             : {
     214           3 :   const char *p = (*s == '+' || *s == '-') ? s + 1 : s;
     215             :   char *end;
     216           3 :   long n = strtol(p, &end, 10);
     217           3 :   if (n <= 0 || *end != '\0' || n > INT_MAX)
     218           0 :     return 0;
     219           3 :   if (p > s) {
     220           2 :     if (!gsize)
     221           0 :       gsize = 10;
     222           2 :     if (*s == '+') {
     223           1 :       if (gsize > INT_MAX - n)
     224           0 :         return 0;
     225           1 :       gsize += int(n);
     226             :     }
     227             :     else {
     228           1 :       if (gsize - n <= 0)
     229           0 :         return 0;
     230           1 :       gsize -= int(n);
     231             :     }
     232             :   }
     233             :   else
     234           1 :     gsize = int(n);
     235           3 :   return 1;
     236             : }
     237             : 
     238           0 : void set_script_reduction(int n)
     239             : {
     240           0 :   script_size_reduction = n;
     241           0 : }
     242             : 
     243         368 : const char *get_gifont()
     244             : {
     245         368 :   return gifont ? gifont : "I";
     246             : }
     247             : 
     248         393 : const char *get_grfont()
     249             : {
     250         393 :   return grfont ? grfont : "R";
     251             : }
     252             : 
     253           0 : const char *get_gbfont()
     254             : {
     255           0 :   return gbfont ? gbfont : "B";
     256             : }
     257             : 
     258           0 : void set_gifont(const char *s)
     259             : {
     260           0 :   delete[] gifont;
     261           0 :   gifont = strsave(s);
     262           0 : }
     263             : 
     264           0 : void set_grfont(const char *s)
     265             : {
     266           0 :   delete[] grfont;
     267           0 :   grfont = strsave(s);
     268           0 : }
     269             : 
     270           0 : void set_gbfont(const char *s)
     271             : {
     272           0 :   delete[] gbfont;
     273           0 :   gbfont = strsave(s);
     274           0 : }
     275             : 
     276             : // this must be precisely 2 characters in length
     277             : #define COMPATIBLE_REG "0C"
     278             : 
     279        4066 : void start_string()
     280             : {
     281        4066 :   if (output_format == troff) {
     282        4066 :     printf(".nr " COMPATIBLE_REG " \\n(.C\n");
     283        4066 :     printf(".cp 0\n");
     284        4066 :     printf(".ds " LINE_STRING "\n");
     285             :   }
     286        4066 : }
     287             : 
     288         177 : void output_string()
     289             : {
     290         177 :   if (output_format == troff)
     291         177 :     printf("\\*(" LINE_STRING "\n");
     292           0 :   else if (output_format == mathml && !xhtml)
     293           0 :     putchar('\n');
     294         177 : }
     295             : 
     296        4065 : void restore_compatibility()
     297             : {
     298        4065 :   if (output_format == troff)
     299        4065 :     printf(".cp \\n(" COMPATIBLE_REG "\n");
     300        4065 : }
     301             : 
     302         298 : void do_text(const char *s)
     303             : {
     304         298 :   if (output_format == troff) {
     305         298 :     printf(".eo\n");
     306         298 :     printf(".as " LINE_STRING " \"%s\n", s);
     307         298 :     printf(".ec\n");
     308             :   }
     309           0 :   else if (output_format == mathml) {
     310           0 :     fputs(s, stdout);
     311           0 :     if (xhtml && strlen(s) > 0)
     312           0 :       printf("\n");
     313             :   }
     314         298 : }
     315             : 
     316           0 : void set_minimum_size(int n)
     317             : {
     318           0 :   minimum_size = n;
     319           0 : }
     320             : 
     321         181 : void set_script_size()
     322             : {
     323         181 :   if (minimum_size < 0)
     324           0 :     minimum_size = 0;
     325         181 :   if (script_size_reduction >= 0)
     326           0 :     printf(".ps \\n[.s]-%d>?%d\n", script_size_reduction, minimum_size);
     327             :   else
     328         181 :     printf(".ps (u;\\n[.ps]*7+5/10>?%dz)\n", minimum_size);
     329         181 : }
     330             : 
     331             : int box::next_uid = 0;
     332             : 
     333        1786 : box::box() : spacing_type(ORDINARY_TYPE), uid(next_uid++)
     334             : {
     335        1786 : }
     336             : 
     337        1786 : box::~box()
     338             : {
     339        1786 : }
     340             : 
     341         184 : void box::top_level()
     342             : {
     343         184 :   box *b = this;
     344         184 :   if (output_format == troff) {
     345             :     // debug_print();
     346             :     // putc('\n', stderr);
     347         184 :     printf(".nr " SAVED_FONT_REG " \\n[.f]\n");
     348         184 :     printf(".ft\n");
     349         184 :     printf(".nr " SAVED_PREV_FONT_REG " \\n[.f]\n");
     350         184 :     printf(".ft %s\n", get_gifont());
     351         184 :     printf(".nr " SAVED_SIZE_REG " \\n[.ps]\n");
     352         184 :     if (gsize > 0) {
     353             :       char buf[INT_DIGITS + 1];
     354         106 :       sprintf(buf, "%d", gsize);
     355         106 :       b = new size_box(strsave(buf), b);
     356             :     }
     357         184 :     current_roman_font = get_grfont();
     358             :     // This catches tabs used within \Z (which aren't allowed).
     359         184 :     b->diagnose_tab_stop_usage(0);
     360         184 :     int r = b->compute_metrics(DISPLAY_STYLE);
     361         184 :     printf(".ft \\n[" SAVED_PREV_FONT_REG "]\n");
     362         184 :     printf(".ft \\n[" SAVED_FONT_REG "]\n");
     363         184 :     printf(".nr " MARK_OR_LINEUP_FLAG_REG " %d\n", r);
     364         184 :     if (r == FOUND_MARK) {
     365           0 :       printf(".nr " SAVED_MARK_REG " \\n[" MARK_REG "]\n");
     366           0 :       printf(".nr " MARK_WIDTH_REG " 0\\n[" WIDTH_FORMAT "]\n", b->uid);
     367             :     }
     368         184 :     else if (r == FOUND_LINEUP)
     369           0 :       printf(".if r" SAVED_MARK_REG " .as1 " LINE_STRING " \\h'\\n["
     370             :              SAVED_MARK_REG "]u-\\n[" MARK_REG "]u'\n");
     371             :     else
     372         184 :       assert(r == FOUND_NOTHING);
     373             :     // If we use \R directly, the space will prevent it working in a
     374             :     // macro argument; so we hide it in a string instead.
     375         184 :     printf(".ds " SAVE_FONT_STRING " "
     376             :            "\\R'" SAVED_INLINE_FONT_REG " \\En[.f]'"
     377             :            "\\fP"
     378             :            "\\R'" SAVED_INLINE_PREV_FONT_REG " \\En[.f]'"
     379             :            "\\R'" SAVED_INLINE_SIZE_REG " \\En[.ps]'"
     380             :            "\\s0"
     381             :            "\\R'" SAVED_INLINE_PREV_SIZE_REG " \\En[.ps]'"
     382             :            "\n"
     383             :            ".ds " RESTORE_FONT_STRING " "
     384             :            "\\f[\\En[" SAVED_INLINE_PREV_FONT_REG "]]"
     385             :            "\\f[\\En[" SAVED_INLINE_FONT_REG "]]"
     386             :            "\\s'\\En[" SAVED_INLINE_PREV_SIZE_REG "]u'"
     387             :            "\\s'\\En[" SAVED_INLINE_SIZE_REG "]u'"
     388             :            "\n");
     389         184 :     printf(".as1 " LINE_STRING " \\&\\E*[" SAVE_FONT_STRING "]");
     390         184 :     printf("\\f[%s]", get_gifont());
     391         184 :     printf("\\s'\\En[" SAVED_SIZE_REG "]u'");
     392         184 :     current_roman_font = get_grfont();
     393         184 :     b->output();
     394         184 :     printf("\\E*[" RESTORE_FONT_STRING "]\n");
     395         184 :     if (r == FOUND_LINEUP)
     396           0 :       printf(".if r" SAVED_MARK_REG " .as1 " LINE_STRING " \\h'\\n["
     397             :              MARK_WIDTH_REG "]u-\\n[" SAVED_MARK_REG "]u-(\\n["
     398             :              WIDTH_FORMAT "]u-\\n[" MARK_REG "]u)'\n",
     399           0 :              b->uid);
     400         184 :     b->extra_space();
     401         184 :     if (!inline_flag)
     402          32 :       printf(".ne \\n[" HEIGHT_FORMAT "]u-%dM>?0+(\\n["
     403             :              DEPTH_FORMAT "]u-%dM>?0)\n",
     404          32 :              b->uid, body_height, b->uid, body_depth);
     405             :   }
     406           0 :   else if (output_format == mathml) {
     407           0 :     if (xhtml)
     408           0 :       printf(".MATHML ");
     409           0 :     printf("<math>");
     410           0 :     b->output();
     411           0 :     printf("</math>");
     412             :   }
     413         184 :   delete b;
     414         184 :   next_uid = 0;
     415         184 : }
     416             : 
     417             : // gpic defines this register so as to make geqn not produce '\x's
     418             : #define EQN_NO_EXTRA_SPACE_REG "0x"
     419             : 
     420         184 : void box::extra_space()
     421             : {
     422         184 :   printf(".if !r" EQN_NO_EXTRA_SPACE_REG " "
     423             :          ".nr " EQN_NO_EXTRA_SPACE_REG " 0\n");
     424         184 :   if (positive_space >= 0 || negative_space >= 0) {
     425           4 :     if (positive_space > 0)
     426           0 :       printf(".if !\\n[" EQN_NO_EXTRA_SPACE_REG "] "
     427             :              ".as1 " LINE_STRING " \\x'-%dM'\n", positive_space);
     428           4 :     if (negative_space > 0)
     429           0 :       printf(".if !\\n[" EQN_NO_EXTRA_SPACE_REG "] "
     430             :              ".as1 " LINE_STRING " \\x'%dM'\n", negative_space);
     431           4 :     positive_space = negative_space = -1;
     432             :   }
     433             :   else {
     434         180 :     printf(".if !\\n[" EQN_NO_EXTRA_SPACE_REG "] "
     435             :            ".if \\n[" HEIGHT_FORMAT "]>%dM .as1 " LINE_STRING
     436             :            " \\x'-(\\n[" HEIGHT_FORMAT
     437             :            "]u-%dM)'\n",
     438         180 :            uid, body_height, uid, body_height);
     439         180 :     printf(".if !\\n[" EQN_NO_EXTRA_SPACE_REG "] "
     440             :            ".if \\n[" DEPTH_FORMAT "]>%dM .as1 " LINE_STRING
     441             :            " \\x'\\n[" DEPTH_FORMAT
     442             :            "]u-%dM'\n",
     443         180 :            uid, body_depth, uid, body_depth);
     444             :   }
     445         184 : }
     446             : 
     447           0 : int box::compute_metrics(int)
     448             : {
     449           0 :   printf(".nr " WIDTH_FORMAT " 0\n", uid);
     450           0 :   printf(".nr " HEIGHT_FORMAT " 0\n", uid);
     451           0 :   printf(".nr " DEPTH_FORMAT " 0\n", uid);
     452           0 :   return FOUND_NOTHING;
     453             : }
     454             : 
     455           0 : void box::compute_subscript_kern()
     456             : {
     457           0 :   printf(".nr " SUB_KERN_FORMAT " 0\n", uid);
     458           0 : }
     459             : 
     460           0 : void box::compute_skew()
     461             : {
     462           0 :   printf(".nr " SKEW_FORMAT " 0\n", uid);
     463           0 : }
     464             : 
     465           0 : void box::output()
     466             : {
     467           0 : }
     468             : 
     469        1133 : void box::diagnose_tab_stop_usage(int)
     470             : {
     471        1133 : }
     472             : 
     473           0 : int box::is_char()
     474             : {
     475           0 :   return 0;
     476             : }
     477             : 
     478         244 : int box::left_is_italic()
     479             : {
     480         244 :   return 0;
     481             : }
     482             : 
     483         339 : int box::right_is_italic()
     484             : {
     485         339 :   return 0;
     486             : }
     487             : 
     488         143 : void box::hint(unsigned)
     489             : {
     490         143 : }
     491             : 
     492           0 : void box::handle_char_type(int, int)
     493             : {
     494           0 : }
     495             : 
     496             : 
     497         282 : box_list::box_list(box *pp)
     498             : {
     499         282 :   p = new box*[10];
     500        3102 :   for (int i = 0; i < 10; i++)
     501        2820 :     p[i] = 0;
     502         282 :   maxlen = 10;
     503         282 :   len = 1;
     504         282 :   p[0] = pp;
     505         282 : }
     506             : 
     507         823 : void box_list::append(box *pp)
     508             : {
     509         823 :   if (len + 1 > maxlen) {
     510          21 :     box **oldp = p;
     511          21 :     maxlen *= 2;
     512          21 :     p = new box*[maxlen];
     513          21 :     memcpy(p, oldp, sizeof(box*)*len);
     514          21 :     delete[] oldp;
     515             :   }
     516         823 :   p[len++] = pp;
     517         823 : }
     518             : 
     519         564 : box_list::~box_list()
     520             : {
     521        1240 :   for (int i = 0; i < len; i++)
     522         958 :     delete p[i];
     523         282 :   delete[] p;
     524         282 : }
     525             : 
     526         219 : void box_list::list_diagnose_tab_stop_usage(int level)
     527             : {
     528        1177 :   for (int i = 0; i < len; i++)
     529         958 :     p[i]->diagnose_tab_stop_usage(level);
     530         219 : }
     531             : 
     532             : 
     533         338 : pointer_box::pointer_box(box *pp) : p(pp)
     534             : {
     535         338 :   spacing_type = p->spacing_type;
     536         338 : }
     537             : 
     538         338 : pointer_box::~pointer_box()
     539             : {
     540         338 :   delete p;
     541         338 : }
     542             : 
     543           0 : int pointer_box::compute_metrics(int style)
     544             : {
     545           0 :   int r = p->compute_metrics(style);
     546           0 :   printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]\n", uid, p->uid);
     547           0 :   printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n", uid, p->uid);
     548           0 :   printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid);
     549           0 :   return r;
     550             : }
     551             : 
     552          32 : void pointer_box::compute_subscript_kern()
     553             : {
     554          32 :   p->compute_subscript_kern();
     555          32 :   printf(".nr " SUB_KERN_FORMAT " \\n[" SUB_KERN_FORMAT "]\n", uid,
     556          32 :          p->uid);
     557          32 : }
     558             : 
     559           0 : void pointer_box::compute_skew()
     560             : {
     561           0 :   p->compute_skew();
     562           0 :   printf(".nr " SKEW_FORMAT " 0\\n[" SKEW_FORMAT "]\n",
     563           0 :          uid, p->uid);
     564           0 : }
     565             : 
     566         163 : void pointer_box::diagnose_tab_stop_usage(int level)
     567             : {
     568         163 :   p->diagnose_tab_stop_usage(level);
     569         163 : }
     570             : 
     571         386 : int simple_box::compute_metrics(int)
     572             : {
     573         386 :   printf(".nr " WIDTH_FORMAT " 0\\w" DELIMITER_CHAR, uid);
     574         386 :   output();
     575         386 :   printf(DELIMITER_CHAR "\n");
     576         386 :   printf(".nr " HEIGHT_FORMAT " 0>?\\n[rst]\n", uid);
     577         386 :   printf(".nr " DEPTH_FORMAT " 0-\\n[rsb]>?0\n", uid);
     578         386 :   printf(".nr " SUB_KERN_FORMAT " 0-\\n[ssc]>?0\n", uid);
     579         386 :   printf(".nr " SKEW_FORMAT " 0\\n[skw]\n", uid);
     580         386 :   return FOUND_NOTHING;
     581             : }
     582             : 
     583         181 : void simple_box::compute_subscript_kern()
     584             : {
     585             :   // do nothing, we already computed it in do_metrics
     586         181 : }
     587             : 
     588           2 : void simple_box::compute_skew()
     589             : {
     590             :   // do nothing, we already computed it in do_metrics
     591           2 : }
     592             : 
     593         998 : int box::is_simple()
     594             : {
     595         998 :   return 0;
     596             : }
     597             : 
     598        3942 : int simple_box::is_simple()
     599             : {
     600        3942 :   return 1;
     601             : }
     602             : 
     603          26 : quoted_text_box::quoted_text_box(char *s) : text(s)
     604             : {
     605          26 : }
     606             : 
     607          52 : quoted_text_box::~quoted_text_box()
     608             : {
     609          26 :   free(text);
     610          52 : }
     611             : 
     612          52 : void quoted_text_box::output()
     613             : {
     614          52 :   if (text) {
     615          52 :     if (output_format == troff)
     616          52 :       fputs(text, stdout);
     617           0 :     else if (output_format == mathml) {
     618           0 :       fputs("<mtext>", stdout);
     619           0 :       fputs(text, stdout);
     620           0 :       fputs("</mtext>", stdout);
     621             :     }
     622             :   }
     623          52 : }
     624             : 
     625           0 : tab_box::tab_box() : disabled(false)
     626             : {
     627           0 : }
     628             : 
     629             : // We treat a tab_box as having width 0 for width computations.
     630             : 
     631           0 : void tab_box::output()
     632             : {
     633           0 :   if (!disabled)
     634           0 :     printf("\\t");
     635           0 : }
     636             : 
     637           0 : void tab_box::diagnose_tab_stop_usage(int level)
     638             : {
     639           0 :   if (level > 0) {
     640           0 :     error("tabs allowed only at outermost lexical level");
     641           0 :     disabled = true;
     642             :   }
     643           0 : }
     644             : 
     645          20 : half_space_box::half_space_box()
     646             : {
     647          20 :   spacing_type = SUPPRESS_TYPE;
     648          20 : }
     649             : 
     650          40 : void half_space_box::output()
     651             : {
     652          40 :   if (output_format == troff)
     653          40 :     printf("\\h'%dM'", half_space);
     654           0 :   else if (output_format == mathml)
     655           0 :     printf("<mtext>&ThinSpace;</mtext>");
     656             :   else
     657             :     assert("unimplemented output format");
     658          40 : }
     659             : 
     660          63 : full_space_box::full_space_box()
     661             : {
     662          63 :   spacing_type = SUPPRESS_TYPE;
     663          63 : }
     664             : 
     665         126 : void full_space_box::output()
     666             : {
     667         126 :   if (output_format == troff)
     668         126 :     printf("\\h'%dM'", full_space);
     669           0 :   else if (output_format == mathml)
     670           0 :     printf("<mtext>&ThickSpace;</mtext>");
     671             :   else
     672             :     assert("unimplemented output format");
     673         126 : }
     674             : 
     675           0 : thick_space_box::thick_space_box()
     676             : {
     677           0 :   spacing_type = SUPPRESS_TYPE;
     678           0 : }
     679             : 
     680           0 : void thick_space_box::output()
     681             : {
     682           0 :   if (output_format == troff)
     683           0 :     printf("\\h'%dM'", thick_space);
     684           0 :   else if (output_format == mathml)
     685           0 :     printf("<mtext>&ThickSpace;</mtext>");
     686             :   else
     687             :     assert("unimplemented output format");
     688           0 : }
     689             : 
     690           0 : thin_space_box::thin_space_box()
     691             : {
     692           0 :   spacing_type = SUPPRESS_TYPE;
     693           0 : }
     694             : 
     695           0 : void thin_space_box::output()
     696             : {
     697           0 :   if (output_format == troff)
     698           0 :     printf("\\h'%dM'", thin_space);
     699           0 :   else if (output_format == mathml)
     700           0 :     printf("<mtext>&ThinSpace;</mtext>");
     701             :   else
     702             :     assert("unimplemented output format");
     703           0 : }
     704             : 
     705           0 : void box_list::list_debug_print(const char *sep)
     706             : {
     707           0 :   p[0]->debug_print();
     708           0 :   for (int i = 1; i < len; i++) {
     709           0 :     fprintf(stderr, "%s", sep);
     710           0 :     p[i]->debug_print();
     711             :   }
     712           0 : }
     713             : 
     714           0 : void quoted_text_box::debug_print()
     715             : {
     716           0 :   fprintf(stderr, "\"%s\"", (text ? text : ""));
     717           0 : }
     718             : 
     719           0 : void half_space_box::debug_print()
     720             : {
     721           0 :   fprintf(stderr, "^");
     722           0 : }
     723             : 
     724           0 : void full_space_box::debug_print()
     725             : {
     726           0 :   fprintf(stderr, "~");
     727           0 : }
     728             : 
     729           0 : void thick_space_box::debug_print()
     730             : {
     731           0 :   fprintf(stderr, "~");
     732           0 : }
     733             : 
     734           0 : void thin_space_box::debug_print()
     735             : {
     736           0 :   fprintf(stderr, "^");
     737           0 : }
     738             : 
     739           0 : void tab_box::debug_print()
     740             : {
     741           0 :   fprintf(stderr, "<tab>");
     742           0 : }
     743             : 
     744             : // Local Variables:
     745             : // fill-column: 72
     746             : // mode: C++
     747             : // End:
     748             : // vim: set cindent noexpandtab shiftwidth=2 textwidth=72:

Generated by: LCOV version 1.14