sqrt.cpp revision 151497
1// -*- C++ -*- 2/* Copyright (C) 1989, 1990, 1991, 1992, 2002, 2003 3 Free Software Foundation, Inc. 4 Written by James Clark (jjc@jclark.com) 5 6This file is part of groff. 7 8groff is free software; you can redistribute it and/or modify it under 9the terms of the GNU General Public License as published by the Free 10Software Foundation; either version 2, or (at your option) any later 11version. 12 13groff is distributed in the hope that it will be useful, but WITHOUT ANY 14WARRANTY; without even the implied warranty of MERCHANTABILITY or 15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16for more details. 17 18You should have received a copy of the GNU General Public License along 19with groff; see the file COPYING. If not, write to the Free Software 20Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */ 21 22#include "eqn.h" 23#include "pbox.h" 24 25 26class sqrt_box : public pointer_box { 27public: 28 sqrt_box(box *); 29 int compute_metrics(int style); 30 void output(); 31 void debug_print(); 32 void check_tabs(int); 33}; 34 35box *make_sqrt_box(box *pp) 36{ 37 return new sqrt_box(pp); 38} 39 40sqrt_box::sqrt_box(box *pp) : pointer_box(pp) 41{ 42} 43 44#define SQRT_CHAR "\\[sqrt]" 45#define RADICAL_EXTENSION_CHAR "\\[sqrtex]" 46 47#define SQRT_CHAIN "\\[sqrt\\\\n[" INDEX_REG "]]" 48#define BAR_CHAIN "\\[sqrtex\\\\n[" INDEX_REG "]]" 49 50int sqrt_box::compute_metrics(int style) 51{ 52 // 11 53 int r = p->compute_metrics(cramped_style(style)); 54 printf(".nr " TEMP_REG " \\n[" HEIGHT_FORMAT "]+\\n[" DEPTH_FORMAT 55 "]+%dM+(%dM/4)\n", 56 p->uid, p->uid, default_rule_thickness, 57 (style > SCRIPT_STYLE ? x_height : default_rule_thickness)); 58 printf(".nr " SIZE_FORMAT " \\n[.ps]\n", uid); 59 printf(".ds " SQRT_STRING_FORMAT " " SQRT_CHAR "\n", uid); 60 printf(".ds " BAR_STRING " " RADICAL_EXTENSION_CHAR "\n"); 61 printf(".nr " SQRT_WIDTH_FORMAT 62 " 0\\w" DELIMITER_CHAR SQRT_CHAR DELIMITER_CHAR "\n", 63 uid); 64 printf(".if \\n[rst]-\\n[rsb]-%dM<\\n[" TEMP_REG "] \\{", 65 default_rule_thickness); 66 67 printf(".nr " INDEX_REG " 0\n" 68 ".de " TEMP_MACRO "\n" 69 ".ie c" SQRT_CHAIN " \\{" 70 ".ds " SQRT_STRING_FORMAT " " SQRT_CHAIN "\n" 71 ".ie c" BAR_CHAIN " .ds " BAR_STRING " " BAR_CHAIN "\n" 72 ".el .ds " BAR_STRING " " RADICAL_EXTENSION_CHAR "\n" 73 ".nr " SQRT_WIDTH_FORMAT 74 " 0\\w" DELIMITER_CHAR SQRT_CHAIN DELIMITER_CHAR "\n" 75 ".if \\\\n[rst]-\\\\n[rsb]-%dM<\\n[" TEMP_REG "] \\{" 76 ".nr " INDEX_REG " +1\n" 77 "." TEMP_MACRO "\n" 78 ".\\}\\}\n" 79 ".el .nr " INDEX_REG " 0-1\n" 80 "..\n" 81 "." TEMP_MACRO "\n", 82 uid, uid, default_rule_thickness); 83 84 printf(".if \\n[" INDEX_REG "]<0 \\{"); 85 86 // Determine the maximum point size 87 printf(".ps 1000\n"); 88 printf(".nr " MAX_SIZE_REG " \\n[.ps]\n"); 89 printf(".ps \\n[" SIZE_FORMAT "]u\n", uid); 90 // We define a macro that will increase the current point size 91 // until we get a radical sign that's tall enough or we reach 92 // the maximum point size. 93 printf(".de " TEMP_MACRO "\n" 94 ".nr " SQRT_WIDTH_FORMAT 95 " 0\\w" DELIMITER_CHAR "\\*[" SQRT_STRING_FORMAT "]" DELIMITER_CHAR "\n" 96 ".if \\\\n[rst]-\\\\n[rsb]-%dM<\\n[" TEMP_REG "]" 97 "&(\\\\n[.ps]<\\n[" MAX_SIZE_REG "]) \\{" 98 ".ps +1\n" 99 "." TEMP_MACRO "\n" 100 ".\\}\n" 101 "..\n" 102 "." TEMP_MACRO "\n", 103 uid, uid, default_rule_thickness); 104 105 printf(".\\}\\}\n"); 106 107 printf(".nr " SMALL_SIZE_FORMAT " \\n[.ps]\n", uid); 108 // set TEMP_REG to the amount by which the radical sign is too big 109 printf(".nr " TEMP_REG " \\n[rst]-\\n[rsb]-%dM-\\n[" TEMP_REG "]\n", 110 default_rule_thickness); 111 // If TEMP_REG is negative, the bottom of the radical sign should 112 // be -TEMP_REG above the bottom of p. If it's positive, the bottom 113 // of the radical sign should be TEMP_REG/2 below the bottom of p. 114 // This calculates the amount by which the baseline of the radical 115 // should be raised. 116 printf(".nr " SUP_RAISE_FORMAT " (-\\n[" TEMP_REG "]>?(-\\n[" TEMP_REG "]/2))" 117 "-\\n[rsb]-\\n[" DEPTH_FORMAT "]\n", uid, p->uid); 118 printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]" 119 ">?(\\n[" SUP_RAISE_FORMAT "]+\\n[rst])\n", 120 uid, p->uid, uid); 121 printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]" 122 ">?(-\\n[" SUP_RAISE_FORMAT "]-\\n[rsb])\n", 123 uid, p->uid, uid); 124 // Do this last, so we don't lose height and depth information on 125 // the radical sign. 126 // Remember that the width of the bar might be greater than the width of p. 127 128 printf(".nr " TEMP_REG " " 129 "\\n[" WIDTH_FORMAT "]" 130 ">?\\w" DELIMITER_CHAR "\\*[" BAR_STRING "]" DELIMITER_CHAR "\n", 131 p->uid); 132 printf(".as " SQRT_STRING_FORMAT " " 133 "\\l'\\n[" TEMP_REG "]u\\&\\*[" BAR_STRING "]'\n", 134 uid); 135 printf(".nr " WIDTH_FORMAT " \\n[" TEMP_REG "]" 136 "+\\n[" SQRT_WIDTH_FORMAT "]\n", 137 uid, uid); 138 139 if (r) 140 printf(".nr " MARK_REG " +\\n[" SQRT_WIDTH_FORMAT "]\n", uid); 141 // the top of the bar might be higher than the top of the radical sign 142 printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]" 143 ">?(\\n[" SUP_RAISE_FORMAT "]+\\n[rst])\n", 144 uid, p->uid, uid); 145 // put a bit of extra space above the bar 146 printf(".nr " HEIGHT_FORMAT " +%dM\n", uid, default_rule_thickness); 147 printf(".ps \\n[" SIZE_FORMAT "]u\n", uid); 148 return r; 149} 150 151void sqrt_box::output() 152{ 153 printf("\\Z" DELIMITER_CHAR); 154 printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid); 155 printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid); 156 printf("\\*[" SQRT_STRING_FORMAT "]", uid); 157 printf("\\s[\\n[" SIZE_FORMAT "]u]", uid); 158 printf(DELIMITER_CHAR); 159 160 printf("\\Z" DELIMITER_CHAR); 161 printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u" 162 "+\\n[" SQRT_WIDTH_FORMAT "]u/2u'", 163 uid, p->uid, uid); 164 p->output(); 165 printf(DELIMITER_CHAR); 166 167 printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid); 168} 169 170void sqrt_box::debug_print() 171{ 172 fprintf(stderr, "sqrt { "); 173 p->debug_print(); 174 fprintf(stderr, " }"); 175} 176 177void sqrt_box::check_tabs(int level) 178{ 179 p->check_tabs(level + 1); 180} 181