LCOV - code coverage report
Current view: top level - preproc/eqn - over.cpp (source / functions) Hit Total Coverage
Test: GNU roff Lines: 72 99 72.7 %
Date: 2026-01-16 17:51:41 Functions: 7 9 77.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Copyright 1989-2024 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 "eqn.h"
      24             : #include "pbox.h"
      25             : 
      26             : class over_box : public box {
      27             : private:
      28             :   int reduce_size;
      29             :   box *num;
      30             :   box *den;
      31             : public:
      32             :   over_box(int small, box *, box *);
      33             :   ~over_box();
      34             :   void debug_print();
      35             :   int compute_metrics(int);
      36             :   void output();
      37             :   void diagnose_tab_stop_usage(int);
      38             : };
      39             : 
      40          11 : box *make_over_box(box *pp, box *qq)
      41             : {
      42          11 :   return new over_box(0, pp, qq);
      43             : }
      44             : 
      45           0 : box *make_small_over_box(box *pp, box *qq)
      46             : {
      47           0 :   return new over_box(1, pp, qq);
      48             : }
      49             : 
      50          11 : over_box::over_box(int is_small, box *pp, box *qq)
      51          11 : : reduce_size(is_small), num(pp), den(qq)
      52             : {
      53          11 :   spacing_type = INNER_TYPE;
      54          11 : }
      55             : 
      56          22 : over_box::~over_box()
      57             : {
      58          11 :   delete num;
      59          11 :   delete den;
      60          22 : }
      61             : 
      62          11 : int over_box::compute_metrics(int style)
      63             : {
      64          11 :   if (reduce_size) {
      65           0 :     style = script_style(style);
      66           0 :     printf(".nr " SIZE_FORMAT " \\n[.ps]\n", uid);
      67           0 :     set_script_size();
      68           0 :     printf(".nr " SMALL_SIZE_FORMAT " \\n[.ps]\n", uid);
      69             :   }
      70          11 :   int mark_uid = 0;
      71          11 :   int res = num->compute_metrics(style);
      72          11 :   if (res)
      73           0 :     mark_uid = num->uid;
      74          11 :   int r = den->compute_metrics(cramped_style(style));
      75          11 :   if (r && res)
      76           0 :     error("multiple marks and lineups");
      77             :   else {
      78          11 :     mark_uid = den->uid;
      79          11 :     res = r;
      80             :   }
      81          11 :   if (reduce_size)
      82           0 :     printf(".ps \\n[" SIZE_FORMAT "]u\n", uid);
      83          11 :   printf(".nr " WIDTH_FORMAT " (\\n[" WIDTH_FORMAT "]>?\\n[" WIDTH_FORMAT "]",
      84          11 :          uid, num->uid, den->uid);
      85             :   // allow for \(ru being wider than both the numerator and denominator
      86          11 :   if (!draw_flag)
      87          11 :     fputs(">?\\w" DELIMITER_CHAR "\\(ru" DELIMITER_CHAR, stdout);
      88          11 :   printf(")+%dM\n", get_param("null_delimiter_space") * 2
      89          11 :          + get_param("over_hang") * 2);
      90             :   // 15b
      91          22 :   printf(".nr " SUP_RAISE_FORMAT " %dM\n",
      92          11 :          uid, (reduce_size ? get_param("num2") : get_param("num1")));
      93          22 :   printf(".nr " SUB_LOWER_FORMAT " %dM\n",
      94          22 :          uid, (reduce_size ? get_param("denom2")
      95          11 :                            : get_param("denom1")));
      96             : 
      97             :   // 15d
      98          11 :   printf(".nr " SUP_RAISE_FORMAT " +(\\n[" DEPTH_FORMAT
      99             :          "]-\\n[" SUP_RAISE_FORMAT "]+%dM+(%dM/2)+%dM)>?0\n",
     100          11 :          uid, num->uid, uid, get_param("axis_height"),
     101             :          get_param("default_rule_thickness"),
     102          11 :          get_param("default_rule_thickness") * (reduce_size ? 1 : 3));
     103          11 :   printf(".nr " SUB_LOWER_FORMAT " +(\\n[" HEIGHT_FORMAT
     104             :          "]-\\n[" SUB_LOWER_FORMAT "]-%dM+(%dM/2)+%dM)>?0\n",
     105          11 :          uid, den->uid, uid, get_param("axis_height"),
     106             :          get_param("default_rule_thickness"),
     107          11 :          get_param("default_rule_thickness") * (reduce_size ? 1 : 3));
     108             : 
     109             : 
     110          11 :   printf(".nr " HEIGHT_FORMAT " \\n[" SUP_RAISE_FORMAT "]+\\n["
     111             :          HEIGHT_FORMAT "]\n",
     112          11 :          uid, uid, num->uid);
     113          11 :   printf(".nr " DEPTH_FORMAT " \\n[" SUB_LOWER_FORMAT "]+\\n["
     114             :          DEPTH_FORMAT "]\n",
     115          11 :          uid, uid, den->uid);
     116          11 :   if (res)
     117           0 :     printf(".nr " MARK_REG " +(\\n[" WIDTH_FORMAT "]-\\n["
     118           0 :            WIDTH_FORMAT "]/2)\n", uid, mark_uid);
     119          11 :   return res;
     120             : }
     121             : 
     122             : #define USE_Z
     123             : 
     124          11 : void over_box::output()
     125             : {
     126          11 :   if (output_format == troff) {
     127          11 :     if (reduce_size)
     128           0 :       printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid);
     129             :   #ifdef USE_Z
     130          11 :     printf("\\Z" DELIMITER_CHAR);
     131             :   #endif
     132             :     // move up to the numerator baseline
     133          11 :     printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
     134             :     // move across so that it's centered
     135          11 :     printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'",
     136          11 :            uid, num->uid);
     137             : 
     138             :     // print the numerator
     139          11 :     num->output();
     140             : 
     141             :   #ifdef USE_Z
     142          11 :     printf(DELIMITER_CHAR);
     143             :   #else
     144             :     // back again
     145             :     printf("\\h'-\\n[" WIDTH_FORMAT "]u'", num->uid);
     146             :     printf("\\h'-(\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u)'",
     147             :            uid, num->uid);
     148             :     // down again
     149             :     printf("\\v'\\n[" SUP_RAISE_FORMAT "]u'", uid);
     150             :   #endif
     151             :   #ifdef USE_Z
     152          11 :     printf("\\Z" DELIMITER_CHAR);
     153             :   #endif
     154             :     // move down to the denominator baseline
     155          11 :     printf("\\v'\\n[" SUB_LOWER_FORMAT "]u'", uid);
     156             : 
     157             :     // move across so that it's centered
     158          11 :     printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'",
     159          11 :            uid, den->uid);
     160             : 
     161             :     // print the denominator
     162          11 :     den->output();
     163             : 
     164             :   #ifdef USE_Z
     165          11 :     printf(DELIMITER_CHAR);
     166             :   #else
     167             :     // back again
     168             :     printf("\\h'-\\n[" WIDTH_FORMAT "]u'", den->uid);
     169             :     printf("\\h'-(\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u)'",
     170             :            uid, den->uid);
     171             :     // up again
     172             :     printf("\\v'-\\n[" SUB_LOWER_FORMAT "]u'", uid);
     173             :   #endif
     174          11 :     if (reduce_size)
     175           0 :       printf("\\s[\\n[" SIZE_FORMAT "]u]", uid);
     176             :     // draw the line
     177          11 :     printf("\\h'%dM'", get_param("null_delimiter_space"));
     178          11 :     printf("\\v'-%dM'", get_param("axis_height"));
     179          11 :     fputs(draw_flag ? "\\D'l" : "\\l'", stdout);
     180          11 :     printf("\\n[" WIDTH_FORMAT "]u-%dM",
     181          11 :            uid, 2 * get_param("null_delimiter_space"));
     182          11 :     fputs(draw_flag ? " 0'" : "\\&\\(ru'", stdout);
     183          11 :     printf("\\v'%dM'", get_param("axis_height"));
     184          11 :     printf("\\h'%dM'", get_param("null_delimiter_space"));
     185             :   }
     186           0 :   else if (output_format == mathml) {
     187             :     // FIXME: passing a displaystyle attribute doesn't validate.
     188           0 :     printf("<mfrac>");
     189           0 :     num->output();
     190           0 :     den->output();
     191           0 :     printf("</mfrac>");
     192             :   }
     193          11 : }
     194             : 
     195           0 : void over_box::debug_print()
     196             : {
     197           0 :   fprintf(stderr, "{ ");
     198           0 :   num->debug_print();
     199           0 :   if (reduce_size)
     200           0 :     fprintf(stderr, " } smallover { ");
     201             :   else
     202           0 :     fprintf(stderr, " } over { ");
     203           0 :   den->debug_print();
     204           0 :   fprintf(stderr, " }");
     205           0 : }
     206             : 
     207          11 : void over_box::diagnose_tab_stop_usage(int level)
     208             : {
     209          11 :   num->diagnose_tab_stop_usage(level + 1);
     210          11 :   den->diagnose_tab_stop_usage(level + 1);
     211          11 : }
     212             : 
     213             : // Local Variables:
     214             : // fill-column: 72
     215             : // mode: C++
     216             : // End:
     217             : // vim: set cindent noexpandtab shiftwidth=2 textwidth=72:

Generated by: LCOV version 1.14