PageRenderTime 48ms CodeModel.GetById 8ms app.highlight 35ms RepoModel.GetById 2ms app.codeStats 0ms

/contrib/groff/src/preproc/eqn/sqrt.cpp

https://bitbucket.org/freebsd/freebsd-head/
C++ | 180 lines | 124 code | 20 blank | 36 comment | 1 complexity | 13f1f69c2a6255fc5e9f161f69a0835c MD5 | raw file
  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}