Home | History | Annotate | Line # | Download | only in eqn
      1 /*	$NetBSD: over.cpp,v 1.1.1.1 2016/01/13 18:41:49 christos Exp $	*/
      2 
      3 // -*- C++ -*-
      4 /* Copyright (C) 1989, 1990, 1991, 1992, 2001, 2002
      5    Free Software Foundation, Inc.
      6      Written by James Clark (jjc (at) jclark.com)
      7 
      8 This file is part of groff.
      9 
     10 groff is free software; you can redistribute it and/or modify it under
     11 the terms of the GNU General Public License as published by the Free
     12 Software Foundation; either version 2, or (at your option) any later
     13 version.
     14 
     15 groff is distributed in the hope that it will be useful, but WITHOUT ANY
     16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
     17 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     18 for more details.
     19 
     20 You should have received a copy of the GNU General Public License along
     21 with groff; see the file COPYING.  If not, write to the Free Software
     22 Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
     23 
     24 #include "eqn.h"
     25 #include "pbox.h"
     26 
     27 class over_box : public box {
     28 private:
     29   int reduce_size;
     30   box *num;
     31   box *den;
     32 public:
     33   over_box(int small, box *, box *);
     34   ~over_box();
     35   void debug_print();
     36   int compute_metrics(int);
     37   void output();
     38   void check_tabs(int);
     39 };
     40 
     41 box *make_over_box(box *pp, box *qq)
     42 {
     43   return new over_box(0, pp, qq);
     44 }
     45 
     46 box *make_small_over_box(box *pp, box *qq)
     47 {
     48   return new over_box(1, pp, qq);
     49 }
     50 
     51 over_box::over_box(int is_small, box *pp, box *qq)
     52 : reduce_size(is_small), num(pp), den(qq)
     53 {
     54   spacing_type = INNER_TYPE;
     55 }
     56 
     57 over_box::~over_box()
     58 {
     59   delete num;
     60   delete den;
     61 }
     62 
     63 int over_box::compute_metrics(int style)
     64 {
     65   if (reduce_size) {
     66     style = script_style(style);
     67     printf(".nr " SIZE_FORMAT " \\n[.ps]\n", uid);
     68     set_script_size();
     69     printf(".nr " SMALL_SIZE_FORMAT " \\n[.ps]\n", uid);
     70   }
     71   int mark_uid = 0;
     72   int res = num->compute_metrics(style);
     73   if (res)
     74     mark_uid = num->uid;
     75   int r = den->compute_metrics(cramped_style(style));
     76   if (r && res)
     77     error("multiple marks and lineups");
     78   else {
     79     mark_uid = den->uid;
     80     res = r;
     81   }
     82   if (reduce_size)
     83     printf(".ps \\n[" SIZE_FORMAT "]u\n", uid);
     84   printf(".nr " WIDTH_FORMAT " (\\n[" WIDTH_FORMAT "]>?\\n[" WIDTH_FORMAT "]",
     85 	 uid, num->uid, den->uid);
     86   // allow for \(ru being wider than both the numerator and denominator
     87   if (!draw_flag)
     88     fputs(">?\\w" DELIMITER_CHAR "\\(ru" DELIMITER_CHAR, stdout);
     89   printf(")+%dM\n", null_delimiter_space*2 + over_hang*2);
     90   // 15b
     91   printf(".nr " SUP_RAISE_FORMAT " %dM\n",
     92 	 uid, (reduce_size ? num2 : num1));
     93   printf(".nr " SUB_LOWER_FORMAT " %dM\n",
     94 	 uid, (reduce_size ? denom2 : denom1));
     95 
     96   // 15d
     97   printf(".nr " SUP_RAISE_FORMAT " +(\\n[" DEPTH_FORMAT
     98 	 "]-\\n[" SUP_RAISE_FORMAT "]+%dM+(%dM/2)+%dM)>?0\n",
     99 	 uid, num->uid, uid, axis_height, default_rule_thickness,
    100 	 default_rule_thickness*(reduce_size ? 1 : 3));
    101   printf(".nr " SUB_LOWER_FORMAT " +(\\n[" HEIGHT_FORMAT
    102 	 "]-\\n[" SUB_LOWER_FORMAT "]-%dM+(%dM/2)+%dM)>?0\n",
    103 	 uid, den->uid, uid, axis_height, default_rule_thickness,
    104 	 default_rule_thickness*(reduce_size ? 1 : 3));
    105 
    106 
    107   printf(".nr " HEIGHT_FORMAT " \\n[" SUP_RAISE_FORMAT "]+\\n["
    108 	 HEIGHT_FORMAT "]\n",
    109 	 uid, uid, num->uid);
    110   printf(".nr " DEPTH_FORMAT " \\n[" SUB_LOWER_FORMAT "]+\\n["
    111 	 DEPTH_FORMAT "]\n",
    112 	 uid, uid, den->uid);
    113   if (res)
    114     printf(".nr " MARK_REG " +(\\n[" WIDTH_FORMAT "]-\\n["
    115 	   WIDTH_FORMAT "]/2)\n", uid, mark_uid);
    116   return res;
    117 }
    118 
    119 #define USE_Z
    120 
    121 void over_box::output()
    122 {
    123   if (reduce_size)
    124     printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid);
    125 #ifdef USE_Z
    126   printf("\\Z" DELIMITER_CHAR);
    127 #endif
    128   // move up to the numerator baseline
    129   printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
    130   // move across so that it's centered
    131   printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'",
    132 	 uid, num->uid);
    133 
    134   // print the numerator
    135   num->output();
    136 
    137 #ifdef USE_Z
    138   printf(DELIMITER_CHAR);
    139 #else
    140   // back again
    141   printf("\\h'-\\n[" WIDTH_FORMAT "]u'", num->uid);
    142   printf("\\h'-(\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u)'",
    143 	 uid, num->uid);
    144   // down again
    145   printf("\\v'\\n[" SUP_RAISE_FORMAT "]u'", uid);
    146 #endif
    147 #ifdef USE_Z
    148   printf("\\Z" DELIMITER_CHAR);
    149 #endif
    150   // move down to the denominator baseline
    151   printf("\\v'\\n[" SUB_LOWER_FORMAT "]u'", uid);
    152 
    153   // move across so that it's centered
    154   printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'",
    155 	 uid, den->uid);
    156 
    157   // print the the denominator
    158   den->output();
    159 
    160 #ifdef USE_Z
    161   printf(DELIMITER_CHAR);
    162 #else
    163   // back again
    164   printf("\\h'-\\n[" WIDTH_FORMAT "]u'", den->uid);
    165   printf("\\h'-(\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u)'",
    166 	 uid, den->uid);
    167   // up again
    168   printf("\\v'-\\n[" SUB_LOWER_FORMAT "]u'", uid);
    169 #endif
    170   if (reduce_size)
    171     printf("\\s[\\n[" SIZE_FORMAT "]u]", uid);
    172   // draw the line
    173   printf("\\h'%dM'", null_delimiter_space);
    174   printf("\\v'-%dM'", axis_height);
    175   fputs(draw_flag ? "\\D'l" : "\\l'", stdout);
    176   printf("\\n[" WIDTH_FORMAT "]u-%dM",
    177 	 uid, 2*null_delimiter_space);
    178   fputs(draw_flag ? " 0'" : "\\&\\(ru'", stdout);
    179   printf("\\v'%dM'", axis_height);
    180   printf("\\h'%dM'", null_delimiter_space);
    181 }
    182 
    183 void over_box::debug_print()
    184 {
    185   fprintf(stderr, "{ ");
    186   num->debug_print();
    187   if (reduce_size)
    188     fprintf(stderr, " } smallover { ");
    189   else
    190     fprintf(stderr, " } over { ");
    191   den->debug_print();
    192   fprintf(stderr, " }");
    193 }
    194 
    195 void over_box::check_tabs(int level)
    196 {
    197   num->check_tabs(level + 1);
    198   den->check_tabs(level + 1);
    199 }
    200