/* Copyright (C) 1989, 1990 Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.uucp)
This file is part of groff.
groff is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 1, or (at your option) any later
groff is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
You should have received a copy of the GNU General Public License along
with groff; see the file LICENSE. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
class sqrt_box
: public pointer_box
{
int compute_metrics(int style
);
box
*make_sqrt_box(box
*pp
)
sqrt_box::sqrt_box(box
*pp
) : pointer_box(pp
)
#define SQRT_CHAR "\\(sr"
#define RADICAL_EXTENSION_CHAR "\\(rn"
#define SQRT_CHAIN "\\[sr\\\\n[" INDEX_REG "]]"
#define BAR_CHAIN "\\[rn\\\\n[" INDEX_REG "]]"
int sqrt_box::compute_metrics(int style
)
int r
= p
->compute_metrics(cramped_style(style
));
printf(".nr " TEMP_REG
" \\n[" HEIGHT_FORMAT
"]+\\n[" DEPTH_FORMAT
p
->uid
, p
->uid
, default_rule_thickness
,
(style
> SCRIPT_STYLE
? x_height
: default_rule_thickness
));
printf(".nr " SIZE_FORMAT
" \\n[.s]\n", uid
);
printf(".ds " SQRT_STRING_FORMAT
" " SQRT_CHAR
"\n", uid
);
printf(".ds " BAR_STRING
" " RADICAL_EXTENSION_CHAR
"\n");
printf(".nr " SQRT_WIDTH_FORMAT
" \\w" DELIMITER_CHAR SQRT_CHAR DELIMITER_CHAR
"\n",
printf(".if \\n[rst]-\\n[rsb]-%dM<\\n[" TEMP_REG
"] \\{",
printf(".nr " INDEX_REG
" 0\n"
".ie c" SQRT_CHAIN
" \\{"
".ds " SQRT_STRING_FORMAT
" " SQRT_CHAIN
"\n"
".ie c" BAR_CHAIN
" .ds " BAR_STRING
" " BAR_CHAIN
"\n"
".el .ds " BAR_STRING
" " RADICAL_EXTENSION_CHAR
"\n"
" \\w" DELIMITER_CHAR SQRT_CHAIN DELIMITER_CHAR
"\n"
".if \\\\n[rst]-\\\\n[rsb]-%dM<\\n[" TEMP_REG
"] \\{"
".el .nr " INDEX_REG
" 0-1\n"
uid
, uid
, default_rule_thickness
);
printf(".if \\n[" INDEX_REG
"]<0 \\{");
// Determine the maximum point size
printf(".nr " MAX_SIZE_REG
" \\n[.s]\n");
printf(".ps \\n[" SIZE_FORMAT
"]\n", uid
);
// We define a macro that will increase the current point size
// until we get a radical sign that's tall enough or we reach
// the maximum point size.
printf(".de " TEMP_MACRO
"\n"
" \\w" DELIMITER_CHAR
"\\*[" SQRT_STRING_FORMAT
"]" DELIMITER_CHAR
"\n"
".if \\\\n[rst]-\\\\n[rsb]-%dM<\\n[" TEMP_REG
"]"
"&(\\\\n[.s]<\\n[" MAX_SIZE_REG
"]) \\{"
uid
, uid
, default_rule_thickness
);
printf(".nr " SMALL_SIZE_FORMAT
" \\n[.s]\n", uid
);
// set TEMP_REG to the amount by which the radical sign is too big
printf(".nr " TEMP_REG
" \\n[rst]-\\n[rsb]-%dM-\\n[" TEMP_REG
"]\n",
// If TEMP_REG is negative, the bottom of the radical sign should
// be -TEMP_REG above the bottom of p. If it's positive, the bottom
// of the radical sign should be TEMP_REG/2 below the bottom of p.
// This calculates the amount by which the baseline of the radical
printf(".nr " SUP_RAISE_FORMAT
" (-\\n[" TEMP_REG
"]>?(-\\n[" TEMP_REG
"]/2))"
"-\\n[rsb]-\\n[" DEPTH_FORMAT
"]\n", uid
, p
->uid
);
printf(".nr " HEIGHT_FORMAT
" \\n[" HEIGHT_FORMAT
"]"
">?(\\n[" SUP_RAISE_FORMAT
"]+\\n[rst])\n",
printf(".nr " DEPTH_FORMAT
" \\n[" DEPTH_FORMAT
"]"
">?(-\\n[" SUP_RAISE_FORMAT
"]-\\n[rsb])\n",
// Do this last, so we don't lose height and depth information on
// Remember that the width of the bar might be greater than the width of p.
printf(".nr " TEMP_REG
" "
">?\\w" DELIMITER_CHAR
"\\*[" BAR_STRING
"]" DELIMITER_CHAR
"\n",
printf(".as " SQRT_STRING_FORMAT
" "
"\\l'\\n[" TEMP_REG
"]u\\&\\*[" BAR_STRING
"]'\n",
printf(".nr " WIDTH_FORMAT
" \\n[" TEMP_REG
"]"
"+\\n[" SQRT_WIDTH_FORMAT
"]\n",
printf(".nr " MARK_REG
" +\\n[" SQRT_WIDTH_FORMAT
"]\n", uid
);
// the top of the bar might be higher than the top of the radical sign
printf(".nr " HEIGHT_FORMAT
" \\n[" HEIGHT_FORMAT
"]"
">?(\\n[" SUP_RAISE_FORMAT
"]+\\n[rst])\n",
// put a bit of extra space above the bar
printf(".nr " HEIGHT_FORMAT
" +%dM\n", uid
, default_rule_thickness
);
printf(".ps \\n[" SIZE_FORMAT
"]\n", uid
);
printf("\\Z" DELIMITER_CHAR
);
printf("\\s[\\n[" SMALL_SIZE_FORMAT
"]]", uid
);
printf("\\v'-\\n[" SUP_RAISE_FORMAT
"]u'", uid
);
printf("\\*[" SQRT_STRING_FORMAT
"]", uid
);
printf("\\s[\\n[" SIZE_FORMAT
"]]", uid
);
printf("\\Z" DELIMITER_CHAR
);
printf("\\h'\\n[" WIDTH_FORMAT
"]u-\\n[" WIDTH_FORMAT
"]u"
"+\\n[" SQRT_WIDTH_FORMAT
"]u/2u'",
printf("\\h'\\n[" WIDTH_FORMAT
"]u'", uid
);
void sqrt_box::debug_print()
fprintf(stderr
, "sqrt { ");
void sqrt_box::check_tabs(int level
)
p
->check_tabs(level
+ 1);