1
2 /******************************************************************************
3 * MODULE : rubber.cpp
4 * DESCRIPTION: boxes whose dimensions are (partially) set by the user.
5 * - empty and plain boxes
6 * - parenthesis boxes
7 * - overline and underline like boxes
8 * COPYRIGHT : (C) 1999 Joris van der Hoeven
9 *******************************************************************************
10 * This software falls under the GNU general public license version 3 or later.
11 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
12 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
13 ******************************************************************************/
14
15 #include "boxes.hpp"
16
17 /*****************************************************************************/
18 // Bracket types from ../math-mode/math-macros.hpp
19 /*****************************************************************************/
20
21 #define Lbracket 1011
22 #define Lcrochet 1012
23 #define Langular 1013
24 #define Laccolade 1014
25 #define Rbracket 1021
26 #define Rcrochet 1022
27 #define Rangular 1023
28 #define Raccolade 1024
29 #define Voidbr 1030
30 #define Absolute 1031
31
32 /*****************************************************************************/
33 // Empty boxes
34 /*****************************************************************************/
35
36 struct empty_box_rep: public box_rep {
empty_box_repempty_box_rep37 empty_box_rep (path ip, int x1b, int y1b, int x2b, int y2b): box_rep (ip) {
38 x3=x4=y3=y4=0; x1= x1b; y1=y1b; x2=x2b; y2=y2b; }
operator treeempty_box_rep39 operator tree () { return "empty"; }
displayempty_box_rep40 void display (renderer ren) { (void) ren; }
41 };
42
43 struct dummy_box_rep: public box_rep {
dummy_box_repdummy_box_rep44 dummy_box_rep (path ip, int x1b, int y1b, int x2b, int y2b): box_rep (ip) {
45 x3=x4=y3=y4=0; x1= x1b; y1=y1b; x2=x2b; y2=y2b; }
operator treedummy_box_rep46 operator tree () { return "dummy"; }
displaydummy_box_rep47 void display (renderer ren) { (void) ren; }
find_box_pathdummy_box_rep48 path find_box_path (SI x, SI y, SI delta, bool force, bool& found) {
49 bool dummy; found= false;
50 return box_rep::find_box_path (x, y, delta, force, dummy); }
51 };
52
53 struct marker_box_rep: public box_rep {
54 int pos;
55 box ref;
marker_box_repmarker_box_rep56 marker_box_rep (path ip2, int x1b, int y1b, int x2b, int y2b, box ref2):
57 box_rep (is_accessible (ip2)? ip2->next: ip2),
58 pos (is_accessible (ip2)? ip2->item: 0), ref (ref2) {
59 x3= x4= y3= y4= 0; x1= x1b; y1= y1b; x2= x2b; y2= y2b; }
operator treemarker_box_rep60 operator tree () { return "marker"; }
displaymarker_box_rep61 void display (renderer ren) { (void) ren; }
find_box_pathmarker_box_rep62 path find_box_path (SI x, SI y, SI delta, bool force) {
63 (void) x; (void) y; (void) delta; (void) force; return path (0); }
find_lipmarker_box_rep64 path find_lip () {
65 return is_accessible (ip)? descend (ip, pos): ip; }
find_ripmarker_box_rep66 path find_rip () {
67 return is_accessible (ip)? descend (ip, pos): ip; }
find_right_box_pathmarker_box_rep68 path find_right_box_path () {
69 return path (0); }
find_box_pathmarker_box_rep70 path find_box_path (path p, bool& found) {
71 found= !is_nil (p) && is_accessible (ip);
72 return path (0); }
find_tree_pathmarker_box_rep73 path find_tree_path (path bp) {
74 if (is_accessible (ip)) return reverse (descend (ip, pos));
75 else return reverse (descend_decode (ip, 0)); }
find_cursormarker_box_rep76 cursor find_cursor (path bp) {
77 (void) bp; return cursor (0, 0, 0, y1, y2); }
find_selectionmarker_box_rep78 selection find_selection (path lbp, path rbp) {
79 return selection (rectangles (),
80 find_tree_path (lbp), find_tree_path (rbp)); }
sub_lo_basemarker_box_rep81 SI sub_lo_base (int level) { return min (y1, ref->sub_lo_base (level)); }
sub_hi_limmarker_box_rep82 SI sub_hi_lim (int level) { return ref->sub_hi_lim (level); }
sup_lo_limmarker_box_rep83 SI sup_lo_lim (int level) { return ref->sup_lo_lim (level); }
sup_lo_basemarker_box_rep84 SI sup_lo_base (int level) { return ref->sup_lo_base (level); }
sup_hi_limmarker_box_rep85 SI sup_hi_lim (int level) { return max (y2, ref->sup_hi_lim (level)); }
86 };
87
88 /*****************************************************************************/
89 // Brackets
90 /*****************************************************************************/
91
92 struct bracket_box_rep: public box_rep {
93 int br_type;
94 pencil pen;
95
96 bracket_box_rep (path ip, int br_type2, pencil pen, SI y1b, SI y2b);
operator treebracket_box_rep97 operator tree () { return "bracket"; }
98 void display (renderer ren);
99 };
100
101 SI
bracket_width(int br_type,SI height,SI penw)102 bracket_width (int br_type, SI height, SI penw) {
103 switch (br_type) {
104 case Lbracket:
105 case Rbracket:
106 case Lcrochet:
107 case Rcrochet:
108 case Laccolade:
109 case Raccolade:
110 case Langular:
111 case Rangular:
112 {
113 SI ref_size = penw/2;
114 double factor= sqrt (((double) height) / ((double) ref_size));
115 if (factor<2) factor=2;
116 factor=factor*1.412;
117 return (2*penw) + ((SI) (((double) height)/factor));
118 }
119 case Absolute:
120 return 2*penw;
121 case Voidbr:
122 default:
123 return 0;
124 }
125 }
126
bracket_box_rep(path ip,int br_type2,pencil pen2,SI y1b,SI y2b)127 bracket_box_rep::bracket_box_rep (path ip, int br_type2, pencil pen2,
128 SI y1b, SI y2b): box_rep (ip) {
129 br_type = br_type2;
130 pen = pen2;
131 x1 = x3 = 0;
132 x2 = x4 = bracket_width (br_type, y2b- y1b, pen->get_width ());
133 y1 = y3 = y1b;
134 y2 = y4 = y2b;
135 }
136
137 void
draw_bracket(renderer ren,int br_type,SI x,SI y,SI w,SI h,pencil pen)138 draw_bracket (renderer ren, int br_type, SI x, SI y, SI w, SI h, pencil pen) {
139 SI lw= pen->get_width ();
140 x+=lw; w-=2*lw;
141 y+=lw; h-=2*lw;
142 ren->set_pencil (pen);
143 switch (br_type) {
144 case Lbracket:
145 {
146 int i;
147 SI ww= (SI) (((double) w) / (1.0- sqrt (0.5)));
148 SI hh= (SI) (((double) h) / sqrt (2.0));
149 SI ox= x+ ww;
150 SI oy= y+ (h>>1);
151 ren->set_pencil (pen->set_width (ren->pixel));
152 for (i=0; i<lw; i+=ren->pixel)
153 ren->arc (ox-ww+i, oy-hh, ox+ww-i, oy+hh, 135<<6, 90<<6);
154 }
155 break;
156 case Rbracket:
157 {
158 int i;
159 SI ww= (SI) (((double) w) / (1.0- sqrt (0.5)));
160 SI hh= (SI) (((double) h) / sqrt (2.0));
161 SI ox= x+ w- ww;
162 SI oy= y+ (h>>1);
163 ren->set_pencil (pen->set_width (ren->pixel));
164 for (i=0; i<lw; i+=ren->pixel)
165 ren->arc (ox-ww+i, oy-hh, ox+ww-i, oy+hh, -(45<<6), 90<<6);
166 }
167 break;
168 case Lcrochet:
169 ren->line (x, y, x, y+h);
170 ren->line (x, y, x+w, y);
171 ren->line (x, y+h, x+w, y+h);
172 break;
173 case Rcrochet:
174 ren->line (x+w, y, x+w, y+h);
175 ren->line (x, y, x+w, y);
176 ren->line (x, y+h, x+w, y+h);
177 break;
178 case Laccolade:
179 case Raccolade:
180 {
181 SI d = w>>1;
182 SI ox= x+ (w>>1);
183 SI oy= y+ (h>>1);
184 // SI xx= x+ w;
185 SI yy= y+ h;
186 ren->line (ox, y+d-PIXEL, ox, oy-d);
187 ren->line (ox, oy+d-PIXEL, ox, yy-d);
188 if (br_type==Laccolade) {
189 ren->arc (ox, yy-w, ox+w, yy, 90<<6, 90<<6);
190 ren->arc (ox-w, oy, ox, oy+w, 270<<6, 90<<6);
191 ren->arc (ox-w, oy-w, ox, oy, 0, 90<<6);
192 ren->arc (ox, y, ox+w, y+w, 180<<6, 90<<6);
193 }
194 else {
195 ren->arc (ox-w, yy-w, ox, yy, 0, 90<<6);
196 ren->arc (ox, oy, ox+w, oy+w, 180<<6, 90<<6);
197 ren->arc (ox, oy-w, ox+w, oy, 90<<6, 90<<6);
198 ren->arc (ox-w, y, ox, y+w, 270<<6, 90<<6);
199 }
200 }
201 break;
202 case Langular:
203 ren->line (x, y+(h>>1), x+w, y);
204 ren->line (x, y+(h>>1), x+w, y+h);
205 break;
206 case Rangular:
207 ren->line (x+w, y+(h>>1), x, y);
208 ren->line (x+w, y+(h>>1), x, y+h);
209 break;
210 case Absolute:
211 ren->line (x, y, x, y+h);
212 break;
213 }
214 }
215
216 void
display(renderer ren)217 bracket_box_rep::display (renderer ren) {
218 draw_bracket (ren, br_type, 0, y1, x2, y2-y1, pen);
219 }
220
221 /*****************************************************************************/
222 // box construction routines
223 /*****************************************************************************/
224
225 box
empty_box(path ip,int x1,int y1,int x2,int y2)226 empty_box (path ip, int x1, int y1, int x2, int y2) {
227 return tm_new<empty_box_rep> (ip, x1, y1, x2, y2);
228 }
229
230 box
dummy_box(path ip,int x1,int y1,int x2,int y2)231 dummy_box (path ip, int x1, int y1, int x2, int y2) {
232 return tm_new<dummy_box_rep> (ip, x1, y1, x2, y2);
233 }
234
235 box
marker_box(path ip,int x1,int y1,int x2,int y2,box ref)236 marker_box (path ip, int x1, int y1, int x2, int y2, box ref) {
237 return tm_new<marker_box_rep> (ip, x1, y1, x2, y2, ref);
238 }
239
240 box
bracket_box(path ip,int br_type,pencil pen,SI y1,SI y2)241 bracket_box (path ip, int br_type, pencil pen, SI y1, SI y2) {
242 return tm_new<bracket_box_rep> (ip, br_type, pen, y1, y2);
243 }
244