1 /* $NetBSD: sqrt.cpp,v 1.1.1.1 2016/01/13 18:41:49 christos Exp $ */ 2 3 // -*- C++ -*- 4 /* Copyright (C) 1989, 1990, 1991, 1992, 2002, 2003 5 Free Software Foundation, Inc. 6 Written by James Clark (jjc@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 28 class sqrt_box : public pointer_box { 29 public: 30 sqrt_box(box *); 31 int compute_metrics(int style); 32 void output(); 33 void debug_print(); 34 void check_tabs(int); 35 }; 36 37 box *make_sqrt_box(box *pp) 38 { 39 return new sqrt_box(pp); 40 } 41 42 sqrt_box::sqrt_box(box *pp) : pointer_box(pp) 43 { 44 } 45 46 #define SQRT_CHAR "\\[sqrt]" 47 #define RADICAL_EXTENSION_CHAR "\\[sqrtex]" 48 49 #define SQRT_CHAIN "\\[sqrt\\\\n[" INDEX_REG "]]" 50 #define BAR_CHAIN "\\[sqrtex\\\\n[" INDEX_REG "]]" 51 52 int sqrt_box::compute_metrics(int style) 53 { 54 // 11 55 int r = p->compute_metrics(cramped_style(style)); 56 printf(".nr " TEMP_REG " \\n[" HEIGHT_FORMAT "]+\\n[" DEPTH_FORMAT 57 "]+%dM+(%dM/4)\n", 58 p->uid, p->uid, default_rule_thickness, 59 (style > SCRIPT_STYLE ? x_height : default_rule_thickness)); 60 printf(".nr " SIZE_FORMAT " \\n[.ps]\n", uid); 61 printf(".ds " SQRT_STRING_FORMAT " " SQRT_CHAR "\n", uid); 62 printf(".ds " BAR_STRING " " RADICAL_EXTENSION_CHAR "\n"); 63 printf(".nr " SQRT_WIDTH_FORMAT 64 " 0\\w" DELIMITER_CHAR SQRT_CHAR DELIMITER_CHAR "\n", 65 uid); 66 printf(".if \\n[rst]-\\n[rsb]-%dM<\\n[" TEMP_REG "] \\{", 67 default_rule_thickness); 68 69 printf(".nr " INDEX_REG " 0\n" 70 ".de " TEMP_MACRO "\n" 71 ".ie c" SQRT_CHAIN " \\{" 72 ".ds " SQRT_STRING_FORMAT " " SQRT_CHAIN "\n" 73 ".ie c" BAR_CHAIN " .ds " BAR_STRING " " BAR_CHAIN "\n" 74 ".el .ds " BAR_STRING " " RADICAL_EXTENSION_CHAR "\n" 75 ".nr " SQRT_WIDTH_FORMAT 76 " 0\\w" DELIMITER_CHAR SQRT_CHAIN DELIMITER_CHAR "\n" 77 ".if \\\\n[rst]-\\\\n[rsb]-%dM<\\n[" TEMP_REG "] \\{" 78 ".nr " INDEX_REG " +1\n" 79 "." TEMP_MACRO "\n" 80 ".\\}\\}\n" 81 ".el .nr " INDEX_REG " 0-1\n" 82 "..\n" 83 "." TEMP_MACRO "\n", 84 uid, uid, default_rule_thickness); 85 86 printf(".if \\n[" INDEX_REG "]<0 \\{"); 87 88 // Determine the maximum point size 89 printf(".ps 1000\n"); 90 printf(".nr " MAX_SIZE_REG " \\n[.ps]\n"); 91 printf(".ps \\n[" SIZE_FORMAT "]u\n", uid); 92 // We define a macro that will increase the current point size 93 // until we get a radical sign that's tall enough or we reach 94 // the maximum point size. 95 printf(".de " TEMP_MACRO "\n" 96 ".nr " SQRT_WIDTH_FORMAT 97 " 0\\w" DELIMITER_CHAR "\\*[" SQRT_STRING_FORMAT "]" DELIMITER_CHAR "\n" 98 ".if \\\\n[rst]-\\\\n[rsb]-%dM<\\n[" TEMP_REG "]" 99 "&(\\\\n[.ps]<\\n[" MAX_SIZE_REG "]) \\{" 100 ".ps +1\n" 101 "." TEMP_MACRO "\n" 102 ".\\}\n" 103 "..\n" 104 "." TEMP_MACRO "\n", 105 uid, uid, default_rule_thickness); 106 107 printf(".\\}\\}\n"); 108 109 printf(".nr " SMALL_SIZE_FORMAT " \\n[.ps]\n", uid); 110 // set TEMP_REG to the amount by which the radical sign is too big 111 printf(".nr " TEMP_REG " \\n[rst]-\\n[rsb]-%dM-\\n[" TEMP_REG "]\n", 112 default_rule_thickness); 113 // If TEMP_REG is negative, the bottom of the radical sign should 114 // be -TEMP_REG above the bottom of p. If it's positive, the bottom 115 // of the radical sign should be TEMP_REG/2 below the bottom of p. 116 // This calculates the amount by which the baseline of the radical 117 // should be raised. 118 printf(".nr " SUP_RAISE_FORMAT " (-\\n[" TEMP_REG "]>?(-\\n[" TEMP_REG "]/2))" 119 "-\\n[rsb]-\\n[" DEPTH_FORMAT "]\n", uid, p->uid); 120 printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]" 121 ">?(\\n[" SUP_RAISE_FORMAT "]+\\n[rst])\n", 122 uid, p->uid, uid); 123 printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]" 124 ">?(-\\n[" SUP_RAISE_FORMAT "]-\\n[rsb])\n", 125 uid, p->uid, uid); 126 // Do this last, so we don't lose height and depth information on 127 // the radical sign. 128 // Remember that the width of the bar might be greater than the width of p. 129 130 printf(".nr " TEMP_REG " " 131 "\\n[" WIDTH_FORMAT "]" 132 ">?\\w" DELIMITER_CHAR "\\*[" BAR_STRING "]" DELIMITER_CHAR "\n", 133 p->uid); 134 printf(".as " SQRT_STRING_FORMAT " " 135 "\\l'\\n[" TEMP_REG "]u\\&\\*[" BAR_STRING "]'\n", 136 uid); 137 printf(".nr " WIDTH_FORMAT " \\n[" TEMP_REG "]" 138 "+\\n[" SQRT_WIDTH_FORMAT "]\n", 139 uid, uid); 140 141 if (r) 142 printf(".nr " MARK_REG " +\\n[" SQRT_WIDTH_FORMAT "]\n", uid); 143 // the top of the bar might be higher than the top of the radical sign 144 printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]" 145 ">?(\\n[" SUP_RAISE_FORMAT "]+\\n[rst])\n", 146 uid, p->uid, uid); 147 // put a bit of extra space above the bar 148 printf(".nr " HEIGHT_FORMAT " +%dM\n", uid, default_rule_thickness); 149 printf(".ps \\n[" SIZE_FORMAT "]u\n", uid); 150 return r; 151 } 152 153 void sqrt_box::output() 154 { 155 printf("\\Z" DELIMITER_CHAR); 156 printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid); 157 printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid); 158 printf("\\*[" SQRT_STRING_FORMAT "]", uid); 159 printf("\\s[\\n[" SIZE_FORMAT "]u]", uid); 160 printf(DELIMITER_CHAR); 161 162 printf("\\Z" DELIMITER_CHAR); 163 printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u" 164 "+\\n[" SQRT_WIDTH_FORMAT "]u/2u'", 165 uid, p->uid, uid); 166 p->output(); 167 printf(DELIMITER_CHAR); 168 169 printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid); 170 } 171 172 void sqrt_box::debug_print() 173 { 174 fprintf(stderr, "sqrt { "); 175 p->debug_print(); 176 fprintf(stderr, " }"); 177 } 178 179 void sqrt_box::check_tabs(int level) 180 { 181 p->check_tabs(level + 1); 182 } 183