1 
2 /******************************************************************************
3 * MODULE     : env_semantics.cpp
4 * DESCRIPTION: attaching numerical values to the environment variables
5 * COPYRIGHT  : (C) 1999  Joris van der Hoeven
6 *******************************************************************************
7 * This software falls under the GNU general public license version 3 or later.
8 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
9 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
10 ******************************************************************************/
11 
12 #include "env.hpp"
13 #include "page_type.hpp"
14 #include "typesetter.hpp"
15 #include "Boxes/construct.hpp"
16 #include "analyze.hpp"
17 
18 /******************************************************************************
19 * Retrieving the page size
20 ******************************************************************************/
21 
22 /*static*/ hashmap<string,int> default_var_type (Env_User);
23 
24 /*static*/ void
initialize_default_var_type()25 initialize_default_var_type () {
26   if (N(default_var_type) != 0) return;
27   hashmap<string,int>& var_type= default_var_type;
28 
29   var_type (DPI)                = Env_Fixed;
30   var_type (ZOOM_FACTOR)        = Env_Zoom;
31   var_type (PREAMBLE)           = Env_Preamble;
32   var_type (SAVE_AUX)           = Env_Fixed;
33   var_type (MODE)               = Env_Mode;
34   var_type (INFO_FLAG)          = Env_Info_Level;
35 
36   var_type (FONT)               = Env_Font;
37   var_type (FONT_FAMILY)        = Env_Font;
38   var_type (FONT_SERIES)        = Env_Font;
39   var_type (FONT_SHAPE)         = Env_Font;
40   var_type (FONT_SIZE)          = Env_Font_Size;
41   var_type (FONT_BASE_SIZE)     = Env_Font_Size;
42   var_type (MAGNIFICATION)      = Env_Magnification;
43   var_type (MAGNIFY)            = Env_Magnify;
44   var_type (COLOR)              = Env_Color;
45   var_type (OPACITY)            = Env_Color;
46   var_type (NO_PATTERNS)        = Env_Pattern_Mode;
47   var_type (LANGUAGE)           = Env_Language;
48 
49   var_type (MATH_LANGUAGE)      = Env_Language;
50   var_type (MATH_FONT)          = Env_Font;
51   var_type (MATH_FONT_FAMILY)   = Env_Font;
52   var_type (MATH_FONT_SERIES)   = Env_Font;
53   var_type (MATH_FONT_SHAPE)    = Env_Font;
54   var_type (MATH_LEVEL)         = Env_Index_Level;
55   var_type (MATH_DISPLAY)       = Env_Display_Style;
56   var_type (MATH_CONDENSED)     = Env_Math_Condensed;
57   var_type (MATH_VPOS)          = Env_Vertical_Pos;
58 
59   var_type (PROG_LANGUAGE)      = Env_Language;
60   var_type (PROG_FONT)          = Env_Font;
61   var_type (PROG_FONT_FAMILY)   = Env_Font;
62   var_type (PROG_FONT_SERIES)   = Env_Font;
63   var_type (PROG_FONT_SHAPE)    = Env_Font;
64 
65   var_type (PAR_MODE)           = Env_Paragraph;
66   var_type (PAR_FLEXIBILITY)    = Env_Paragraph;
67   var_type (PAR_HYPHEN)         = Env_Paragraph;
68   var_type (PAR_SPACING)        = Env_Paragraph;
69   var_type (PAR_KERNING_STRETCH)= Env_Paragraph;
70   var_type (PAR_KERNING_MARGIN) = Env_Paragraph;
71   var_type (PAR_HYPHEN)         = Env_Paragraph;
72   var_type (PAR_WIDTH)          = Env_Paragraph;
73   var_type (PAR_LEFT)           = Env_Paragraph;
74   var_type (PAR_RIGHT)          = Env_Paragraph;
75   var_type (PAR_FIRST)          = Env_Paragraph;
76   var_type (PAR_NO_FIRST)       = Env_Paragraph;
77   var_type (PAR_SEP)            = Env_Paragraph;
78   var_type (PAR_HOR_SEP)        = Env_Paragraph;
79   var_type (PAR_VER_SEP)        = Env_Paragraph;
80   var_type (PAR_LINE_SEP)       = Env_Paragraph;
81   var_type (PAR_PAR_SEP)        = Env_Paragraph;
82 
83   var_type (PAGE_TYPE)          = Env_Fixed;
84   var_type (PAGE_BREAKING)      = Env_Fixed;
85   var_type (PAGE_FLEXIBILITY)   = Env_Fixed;
86   var_type (PAGE_FIRST)         = Env_Fixed;
87   var_type (PAGE_WIDTH)         = Env_Page_Extents;
88   var_type (PAGE_HEIGHT)        = Env_Page_Extents;
89   var_type (PAGE_WIDTH_MARGIN)  = Env_Page;
90   var_type (PAGE_SCREEN_MARGIN) = Env_Page;
91   var_type (PAGE_NR)            = Env_Page;
92   var_type (PAGE_THE_PAGE)      = Env_Page;
93   var_type (PAGE_ODD)           = Env_Page;
94   var_type (PAGE_EVEN)          = Env_Page;
95   var_type (PAGE_RIGHT)         = Env_Page;
96   var_type (PAGE_TOP)           = Env_Page;
97   var_type (PAGE_BOT)           = Env_Page;
98   var_type (PAGE_USER_HEIGHT)   = Env_Page;
99   var_type (PAGE_ODD_SHIFT)     = Env_Page;
100   var_type (PAGE_EVEN_SHIFT)    = Env_Page;
101   var_type (PAGE_SHRINK)        = Env_Page;
102   var_type (PAGE_EXTEND)        = Env_Page;
103   var_type (PAGE_HEAD_SEP)      = Env_Page;
104   var_type (PAGE_FOOT_SEP)      = Env_Page;
105   var_type (PAGE_ODD_HEADER)    = Env_Page;
106   var_type (PAGE_ODD_FOOTER)    = Env_Page;
107   var_type (PAGE_EVEN_HEADER)   = Env_Page;
108   var_type (PAGE_EVEN_FOOTER)   = Env_Page;
109   var_type (PAGE_THIS_HEADER)   = Env_Page;
110   var_type (PAGE_THIS_FOOTER)   = Env_Page;
111   var_type (PAGE_FNOTE_SEP)     = Env_Page;
112   var_type (PAGE_FNOTE_BARLEN)  = Env_Page;
113   var_type (PAGE_FLOAT_SEP)     = Env_Page;
114   var_type (PAGE_MNOTE_SEP)     = Env_Page;
115   var_type (PAGE_MNOTE_WIDTH)   = Env_Page;
116 
117   var_type (POINT_STYLE)        = Env_Point_Style;
118   var_type (LINE_WIDTH)         = Env_Line_Width;
119   var_type (DASH_STYLE)         = Env_Dash_Style;
120   var_type (DASH_STYLE_UNIT)    = Env_Dash_Style_Unit;
121   var_type (FILL_COLOR)         = Env_Fill_Color;
122   var_type (ARROW_BEGIN)        = Env_Line_Arrows;
123   var_type (ARROW_END)          = Env_Line_Arrows;
124   var_type (ARROW_LENGTH)       = Env_Line_Arrows;
125   var_type (ARROW_HEIGHT)       = Env_Line_Arrows;
126   var_type (TEXT_AT_HALIGN)     = Env_Text_At_Halign;
127   var_type (TEXT_AT_VALIGN)     = Env_Text_At_Valign;
128   var_type (GR_FRAME)           = Env_Frame;
129   var_type (GR_GEOMETRY)        = Env_Geometry;
130   var_type (GR_GRID)            = Env_Grid;
131   var_type (GR_GRID_ASPECT)     = Env_Grid_Aspect;
132   var_type (GR_EDIT_GRID)       = Env_Grid;
133   var_type (GR_EDIT_GRID_ASPECT)= Env_Grid_Aspect;
134 
135   var_type (SRC_STYLE)          = Env_Src_Style;
136   var_type (SRC_SPECIAL)        = Env_Src_Special;
137   var_type (SRC_COMPACT)        = Env_Src_Compact;
138   var_type (SRC_CLOSE)          = Env_Src_Close;
139 }
140 
141 /******************************************************************************
142 * Retrieving the page size
143 ******************************************************************************/
144 
145 #define get_page_par(which) \
146   (get_string (which) == "auto"? \
147    as_length (page_get_feature (page_type, which, page_landscape)): \
148    get_length (which))
149 
150 void
update_page_pars()151 edit_env_rep::update_page_pars () {
152   page_type         = get_string (PAGE_TYPE);
153   page_landscape    = (get_string (PAGE_ORIENTATION) == "landscape");
154   page_automatic    = (get_string (PAGE_MEDIUM) == "automatic");
155   string width_flag = get_string (PAGE_WIDTH_MARGIN);
156   string height_flag= get_string (PAGE_HEIGHT_MARGIN);
157   bool   screen_flag= get_bool   (PAGE_SCREEN_MARGIN);
158 
159   if (page_automatic) {
160     page_width        = get_length (PAGE_SCREEN_WIDTH);
161     page_height       = get_length (PAGE_SCREEN_HEIGHT);
162     page_odd_margin   = get_length (PAGE_SCREEN_LEFT);
163     page_right_margin = get_length (PAGE_SCREEN_RIGHT);
164     page_even_margin  = page_odd_margin;
165     page_top_margin   = get_length (PAGE_SCREEN_TOP);
166     page_bottom_margin= get_length (PAGE_SCREEN_BOT);
167     page_user_width   = page_width - page_odd_margin - page_right_margin;
168     page_user_height  = page_height - page_top_margin - page_bottom_margin;
169   }
170   else {
171     page_width  = get_page_par (PAGE_WIDTH);
172     page_height = get_page_par (PAGE_HEIGHT);
173 
174     if (width_flag == "false") {
175       page_odd_margin   = get_page_par (PAGE_ODD);
176       page_even_margin  = get_page_par (PAGE_EVEN);
177       page_right_margin = get_page_par (PAGE_RIGHT);
178       page_user_width   = page_width - page_odd_margin - page_right_margin;
179     }
180     else if (width_flag == "true") {
181       page_user_width   = get_page_par (PAR_WIDTH);
182       SI odd_sh         = get_length (PAGE_ODD_SHIFT);
183       SI even_sh        = get_length (PAGE_EVEN_SHIFT);
184       page_odd_margin   = ((page_width - page_user_width) >> 1) + odd_sh;
185       page_even_margin  = ((page_width - page_user_width) >> 1) + even_sh;
186       page_right_margin = page_width - page_odd_margin - page_user_width;
187     }
188     else {
189       page_odd_margin   = get_page_par (PAGE_ODD);
190       page_even_margin  = get_page_par (PAGE_EVEN);
191       page_user_width   = get_page_par (PAR_WIDTH);
192       page_right_margin = page_width - page_odd_margin - page_user_width;
193     }
194 
195     if (height_flag == "false") {
196       page_top_margin   = get_page_par (PAGE_TOP);
197       page_bottom_margin= get_page_par (PAGE_BOT);
198       page_user_height  = page_height - page_top_margin - page_bottom_margin;
199     }
200     else if (height_flag == "true") {
201       page_user_height  = get_length (PAGE_USER_HEIGHT);
202       page_top_margin   = (page_height - page_user_width) >> 1;
203       page_bottom_margin= page_top_margin;
204     }
205     else {
206       page_user_height  = get_length (PAGE_USER_HEIGHT);
207       page_top_margin   = get_page_par (PAGE_TOP);
208       page_bottom_margin= page_height - page_top_margin - page_user_height;
209     }
210 
211     if (page_type == "user") {
212       if (get_string (PAGE_EVEN) == "auto" &&
213           get_string (PAGE_ODD ) != "auto")
214         page_even_margin= page_odd_margin;
215       if (get_string (PAGE_ODD ) == "auto" &&
216           get_string (PAGE_EVEN) != "auto")
217         page_odd_margin= page_even_margin;
218     }
219 
220     if (screen_flag) {
221       page_odd_margin   = get_length (PAGE_SCREEN_LEFT);
222       page_right_margin = get_length (PAGE_SCREEN_RIGHT);
223       page_top_margin   = get_length (PAGE_SCREEN_TOP);
224       page_bottom_margin= get_length (PAGE_SCREEN_BOT);
225       page_even_margin  = page_odd_margin;
226       page_width = page_user_width + page_odd_margin + page_right_margin;
227       page_height= page_user_height + page_top_margin + page_bottom_margin;
228     }
229   }
230 }
231 
232 void
get_page_pars(SI & w,SI & h,SI & width,SI & height,SI & odd,SI & even,SI & top,SI & bot)233 edit_env_rep::get_page_pars (SI& w, SI& h, SI& width, SI& height,
234 			     SI& odd, SI& even, SI& top, SI& bot)
235 {
236   w     = page_user_width;
237   h     = page_user_height;
238   width = page_width;
239   height= page_height;
240   odd   = page_odd_margin;
241   even  = page_even_margin;
242   top   = page_top_margin;
243   bot   = page_bottom_margin;
244 
245   int nr_cols= get_int (PAR_COLUMNS);
246   if (nr_cols > 1) {
247     SI col_sep= get_length (PAR_COLUMNS_SEP);
248     w= ((w+col_sep) / nr_cols) - col_sep;
249   }
250 
251   /*
252   cout << "w     = " << (w/PIXEL) << "\n";
253   cout << "h     = " << (h/PIXEL) << "\n";
254   cout << "width = " << (width/PIXEL) << "\n";
255   cout << "height= " << (height/PIXEL) << "\n";
256   cout << "odd   = " << (odd/PIXEL) << "\n";
257   cout << "even  = " << (even/PIXEL) << "\n";
258   cout << "top   = " << (top/PIXEL) << "\n";
259   cout << "bot   = " << (bot/PIXEL) << "\n";
260   cout << "cols  = " << nr_cols << "\n";
261   */
262 }
263 
264 /******************************************************************************
265 * Retrieving ornament parameters
266 ******************************************************************************/
267 
268 static tree
tuplify(tree t)269 tuplify (tree t) {
270   array<string> a= tokenize (t->label, ",");
271   tree r (TUPLE, N(a));
272   for (int i=0; i<N(a); i++)
273     r[i]= a[i];
274   return r;
275 }
276 
277 ornament_parameters
get_ornament_parameters()278 edit_env_rep::get_ornament_parameters () {
279   tree  shape = read (ORNAMENT_SHAPE);
280   tree  tst   = read (ORNAMENT_TITLE_STYLE);
281   tree  bg    = read (ORNAMENT_COLOR);
282   tree  xc    = read (ORNAMENT_EXTRA_COLOR);
283   tree  sunny = read (ORNAMENT_SUNNY_COLOR);
284   tree  shadow= read (ORNAMENT_SHADOW_COLOR);
285   int   a     = alpha;
286   tree  w     = read (ORNAMENT_BORDER);
287   tree  ext   = read (ORNAMENT_SWELL);
288   tree  xpad  = read (ORNAMENT_HPADDING);
289   tree  ypad  = read (ORNAMENT_VPADDING);
290 
291   array<brush> border;
292   if (is_func (sunny, TUPLE)) {
293     for (int i=0; i<N(sunny); i++)
294       border << brush (sunny[i], a);
295   }
296   else {
297     border << brush (sunny, a);
298     border << brush (shadow, a);
299   }
300   if (N(border) == 1) border << border[0];
301   if (N(border) == 2) border << border[1] << border[0];
302 
303   SI lw, bw, rw, tw;
304   if (is_atomic (w) && occurs (",", w->label))
305     w= tuplify (w);
306   if (is_func (w, TUPLE, 4)) {
307     lw= ((as_length (w[0]) >> 1) << 1);
308     bw= ((as_length (w[1]) >> 1) << 1);
309     rw= ((as_length (w[2]) >> 1) << 1);
310     tw= ((as_length (w[3]) >> 1) << 1);
311   }
312   else lw= bw= rw= tw= ((as_length (w) >> 1) << 1);
313 
314   double lx, bx, rx, tx;
315   if (is_atomic (ext) && occurs (",", ext->label))
316     ext= tuplify (ext);
317   if (is_func (ext, TUPLE, 4)) {
318     lx= as_double (ext[0]);
319     bx= as_double (ext[1]);
320     rx= as_double (ext[2]);
321     tx= as_double (ext[3]);
322   }
323   else lx= bx= rx= tx= as_double (ext);
324 
325   SI lpad, rpad;
326   if (is_atomic (xpad) && occurs (",", xpad->label))
327     xpad= tuplify (xpad);
328   if (is_func (xpad, TUPLE, 2)) {
329     lpad= as_length (xpad[0]);
330     rpad= as_length (xpad[1]);
331   }
332   else lpad= rpad= as_length (xpad);
333 
334   SI bpad, tpad;
335   if (is_atomic (ypad) && occurs (",", ypad->label))
336     ypad= tuplify (ypad);
337   if (is_func (ypad, TUPLE, 2)) {
338     bpad= as_length (ypad[0]);
339     tpad= as_length (ypad[1]);
340   }
341   else bpad= tpad= as_length (ypad);
342 
343   return ornament_parameters (shape, tst,
344                               lw, bw, rw, tw,
345 			      lx, bx, rx, tx,
346 			      lpad, bpad, rpad, tpad,
347                               brush (bg, a), brush (xc, a), border);
348 }
349 
350 /******************************************************************************
351 * Updating the environment from the variables
352 ******************************************************************************/
353 
354 void
update_font()355 edit_env_rep::update_font () {
356   fn_size= (int) (((double) get_int (FONT_BASE_SIZE)) *
357 		  get_double (FONT_SIZE) + 0.5);
358   switch (mode) {
359   case 0:
360   case 1:
361     fn= smart_font (get_string (FONT), get_string (FONT_FAMILY),
362                     get_string (FONT_SERIES), get_string (FONT_SHAPE),
363                     script (fn_size, index_level), (int) (magn*dpi));
364     break;
365   case 2:
366     fn= smart_font (get_string (MATH_FONT), get_string (MATH_FONT_FAMILY),
367                     get_string (MATH_FONT_SERIES), get_string (MATH_FONT_SHAPE),
368                     get_string (FONT), get_string (FONT_FAMILY),
369                     get_string (FONT_SERIES), "mathitalic",
370                     script (fn_size, index_level), (int) (magn*dpi));
371     break;
372   case 3:
373     fn= smart_font (get_string (PROG_FONT), get_string (PROG_FONT_FAMILY),
374                     get_string (PROG_FONT_SERIES), get_string (PROG_FONT_SHAPE),
375                     get_string (FONT), get_string (FONT_FAMILY) * "-tt",
376                     get_string (FONT_SERIES), get_string (FONT_SHAPE),
377                     script (fn_size, index_level), (int) (magn*dpi));
378     break;
379   }
380 }
381 
382 int
decode_alpha(string s)383 decode_alpha (string s) {
384   if (N(s) == 0) return 255;
385   else if (s[N(s)-1] == '%') {
386     // mg: be careful to avoid rounding problems for the conversion from double to int : (int)(2.55*100.0)=254
387     double p = as_double (s (0, N(s)-1));
388     if (p<0.0) p = 0.0;
389     if (p>100.0) p = 100.0;
390     return ((int) (255.0 * p))/100;
391   }
392   else {
393     double p = as_double (s);
394     if (p<0.0) p = 0.0;
395     if (p>1.0) p = 1.0;
396     return ((int) (255.0 * p));
397   }
398 }
399 
400 void
update_color()401 edit_env_rep::update_color () {
402   alpha= decode_alpha (get_string (OPACITY));
403   tree pc= env [COLOR];
404   tree fc= env [FILL_COLOR];
405   if (pc == "none") pen= pencil (false);
406   else pen= pencil (pc, alpha, get_length (LINE_WIDTH));
407   if (fc == "none") fill_brush= brush (false);
408   else fill_brush= brush (fc, alpha);
409 }
410 
411 void
update_pattern_mode()412 edit_env_rep::update_pattern_mode () {
413   no_patterns= (get_string (NO_PATTERNS) == "true");
414   if (no_patterns) {
415     tree c= env[COLOR];
416     if (is_func (c, PATTERN, 4)) env (COLOR)= exec (c);
417     c= env[BG_COLOR];
418     if (is_func (c, PATTERN, 4)) env (BG_COLOR)= exec (c);
419     c= env[FILL_COLOR];
420     if (is_func (c, PATTERN, 4)) env (FILL_COLOR)= exec (c);
421     c= env[ORNAMENT_COLOR];
422     if (is_func (c, PATTERN, 4)) env (ORNAMENT_COLOR)= exec (c);
423     c= env[ORNAMENT_EXTRA_COLOR];
424     if (is_func (c, PATTERN, 4)) env (ORNAMENT_EXTRA_COLOR)= exec (c);
425     update_color ();
426   }
427 }
428 
429 void
update_mode()430 edit_env_rep::update_mode () {
431   string s= get_string (MODE);
432   if (s == "text") mode=1;
433   else if (s == "math") mode=2;
434   else if (s == "prog") mode=3;
435   else mode=0;
436   if (mode == 2) mode_op= OP_SYMBOL;
437   else mode_op= OP_TEXT;
438 }
439 
440 void
update_info_level()441 edit_env_rep::update_info_level () {
442   string s= get_string (INFO_FLAG);
443   if (s == "none") info_level= INFO_NONE;
444   else if (s == "minimal") info_level= INFO_MINIMAL;
445   else if (s == "short") info_level= INFO_SHORT;
446   else if (s == "detailed") info_level= INFO_DETAILED;
447   else if (s == "paper") info_level= INFO_PAPER;
448   else if (s == "short-paper") info_level= INFO_SHORT_PAPER;
449   else info_level= INFO_MINIMAL;
450 }
451 
452 void
update_language()453 edit_env_rep::update_language () {
454   switch (mode) {
455   case 0:
456   case 1:
457     lan= text_language (get_string (LANGUAGE));
458     break;
459   case 2:
460     lan= math_language (get_string (MATH_LANGUAGE));
461     break;
462   case 3:
463     lan= prog_language (get_string (PROG_LANGUAGE));
464     break;
465   }
466   hl_lan= lan->hl_lan;
467 }
468 
469 void
update_geometry()470 edit_env_rep::update_geometry () {
471   tree t= env [GR_GEOMETRY];
472   gw= as_length ("1par");
473   gh= as_length ("0.6par");
474   gvalign= as_string ("center");
475   if (is_tuple (t, "geometry", 2) || is_tuple (t, "geometry", 3)) {
476     if (is_length (as_string (t[1]))) gw= as_length (t[1]);
477     if (is_length (as_string (t[2]))) gh= as_length (t[2]);
478     if (is_tuple (t, "geometry", 3))
479       gvalign= as_string (t[3]);
480   }
481   update_frame ();
482 }
483 
484 void
update_frame()485 edit_env_rep::update_frame () {
486   tree t= env [GR_FRAME];
487   SI yinc= gvalign == "top"    ? - gh
488 	 : gvalign == "bottom" ? 0
489          : gvalign == "axis" ? - (gh/2) + as_length ("1yfrac")
490 	 : - gh / 2;
491   if (is_tuple (t, "scale", 2) && is_func (t[2], TUPLE, 2)) {
492     SI magn= as_length (t[1]);
493     SI x   = as_length (t[2][0]);
494     SI y   = as_length (t[2][1]);
495     fr= scaling (magn, point (x, y + yinc));
496   }
497   else {
498     SI cm   = as_length (string ("1cm"));
499     SI par  = as_length (string ("1par"));
500     SI yfrac= as_length (string ("1yfrac"));
501     fr= scaling (cm, point (par >> 1, yfrac + yinc));
502   }
503   point p0= fr (as_point (tuple ("0par", "0par")));
504   if (gvalign == "top") {
505     clip_lim1= fr [point (p0[0], p0[1] - gh)];
506     clip_lim2= fr [point (p0[0] + gw, p0[1])];
507   }
508   else if (gvalign == "bottom") {
509     clip_lim1= fr [point (p0[0], p0[1])];
510     clip_lim2= fr [point (p0[0] + gw, p0[1] + gh)];
511   }
512   else if (gvalign == "axis") {
513     clip_lim1= fr [point (p0[0], p0[1] - (gh/2) + as_length ("1yfrac"))];
514     clip_lim2= fr [point (p0[0] + gw, p0[1] + (gh/2) + as_length ("1yfrac"))];
515   }
516   else {
517     clip_lim1= fr [point (p0[0], p0[1] - gh/2)];
518     clip_lim2= fr [point (p0[0] + gw, p0[1] + gh/2)];
519   }
520 }
521 
522 void
update_src_style()523 edit_env_rep::update_src_style () {
524   string s= as_string (env [SRC_STYLE]);
525   if (s == "angular") src_style= STYLE_ANGULAR;
526   else if (s == "scheme") src_style= STYLE_SCHEME;
527   else if (s == "latex") src_style= STYLE_LATEX;
528   else if (s == "functional") src_style= STYLE_FUNCTIONAL;
529 }
530 
531 void
update_src_special()532 edit_env_rep::update_src_special () {
533   string s= as_string (env [SRC_SPECIAL]);
534   if (s == "raw") src_special= SPECIAL_RAW;
535   else if (s == "format") src_special= SPECIAL_FORMAT;
536   else if (s == "normal") src_special= SPECIAL_NORMAL;
537   else if (s == "maximal") src_special= SPECIAL_MAXIMAL;
538 }
539 
540 void
update_src_compact()541 edit_env_rep::update_src_compact () {
542   string s= as_string (env [SRC_COMPACT]);
543   if (s == "all") src_compact= COMPACT_ALL;
544   else if (s == "inline args") src_compact= COMPACT_INLINE_ARGS;
545   else if (s == "normal") src_compact= COMPACT_INLINE_START;
546   else if (s == "inline") src_compact= COMPACT_INLINE;
547   else if (s == "none") src_compact= COMPACT_NONE;
548 }
549 
550 void
update_src_close()551 edit_env_rep::update_src_close () {
552   string s= as_string (env [SRC_CLOSE]);
553   if (s == "minimal") src_close= CLOSE_MINIMAL;
554   else if (s == "compact") src_close= CLOSE_COMPACT;
555   else if (s == "long") src_close= CLOSE_LONG;
556   else if (s == "repeat") src_close= CLOSE_REPEAT;
557 }
558 
559 void
update_dash_style()560 edit_env_rep::update_dash_style () {
561   tree t= env [DASH_STYLE];
562   dash_style= array<bool> (0);
563   if (is_string (t)) {
564     string s= as_string (t);
565     if (N(s) > 0 && (s[0] == '0' || s[0] == '1')) {
566       int i, n= N(s);
567       dash_style= array<bool> (n);
568       for (i=0; i<n; i++)
569         dash_style[i]= (s[i] != '0');
570     }
571   }
572 }
573 
574 void
decompose_length(string s,double & x,string & un)575 decompose_length (string s, double& x, string& un) {
576   int i;
577   for (i=0; i<N(s); i++)
578     if ((s[i]>='a') && (s[i]<='z')) break;
579   x = as_double (s (0, i));
580   un= s (i, N(s));
581 }
582 
583 tree
decode_arrow(tree t,string l,string h)584 edit_env_rep::decode_arrow (tree t, string l, string h) {
585   if (is_string (t)) {
586     string s= t->label;
587     if (s == "" || s == "none") return "";
588     double lx, hx;
589     string lun, hun;
590     decompose_length (l, lx, lun);
591     decompose_length (h, hx, hun);
592     if (s == "<less>")
593       return tree (LINE,
594                    tree (_POINT, l, h),
595                    tree (_POINT, "0" * lun, "0" * hun),
596                    tree (_POINT, l, as_string (-hx) * hun));
597     if (s == "<gtr>")
598       return tree (LINE,
599                    tree (_POINT, as_string (-lx) * lun, h),
600                    tree (_POINT, "0" * lun, "0" * hun),
601                    tree (_POINT, as_string (-lx) * lun,
602                                  as_string (-hx) * hun));
603     if (s == "<less>|")
604       return tree (WITH, FILL_COLOR, tree (VALUE, COLOR),
605                    LINE_WIDTH, "0ln",
606                    tree (CLINE,
607                          tree (_POINT, l, h),
608                          tree (_POINT, "0" * lun, "0" * hun),
609                          tree (_POINT, l, as_string (-hx) * hun)));
610     if (s == "|<gtr>")
611       return tree (WITH, FILL_COLOR, tree (VALUE, COLOR),
612                    LINE_WIDTH, "0ln",
613                    tree (CLINE,
614                          tree (_POINT, as_string (-lx) * lun, h),
615                          tree (_POINT, "0" * lun, "0" * hun),
616                          tree (_POINT, as_string (-lx) * lun,
617                                as_string (-hx) * hun)));
618     if (s == "<gtr>")
619       return tree (LINE,
620                    tree (_POINT, as_string (-lx) * lun, h),
621                    tree (_POINT, "0" * lun, "0" * hun),
622                    tree (_POINT, as_string (-lx) * lun,
623                                  as_string (-hx) * hun));
624     if (s == "<less><less>")
625       return tree (GR_GROUP,
626                    tree (LINE,
627                          tree (_POINT, l, h),
628                          tree (_POINT, "0" * lun, "0" * hun),
629                          tree (_POINT, l, as_string (-hx) * hun)),
630                    tree (LINE,
631                          tree (_POINT, as_string (0 * lx) * lun, h),
632                          tree (_POINT, as_string (-lx) * lun, "0" * hun),
633                          tree (_POINT, as_string (0 * lx) * lun,
634                                as_string (-hx) * hun)));
635     if (s == "<gtr><gtr>")
636       return tree (GR_GROUP,
637                    tree (LINE,
638                          tree (_POINT, as_string (-lx) * lun, h),
639                          tree (_POINT, "0" * lun, "0" * hun),
640                          tree (_POINT, as_string (-lx) * lun,
641                                as_string (-hx) * hun)),
642                    tree (LINE,
643                          tree (_POINT, as_string (0 * lx) * lun, h),
644                          tree (_POINT, as_string (lx) * lun, "0" * hun),
645                          tree (_POINT, as_string (0 * lx) * lun,
646                                as_string (-hx) * hun)));
647     if (s == "|")
648       return tree (LINE,
649                    tree (_POINT, "0" * lun, h),
650                    tree (_POINT, "0" * lun, as_string (-hx) * hun));
651     if (s == "o")
652       return tree (WITH, FILL_COLOR, tree (VALUE, COLOR),
653                    LINE_WIDTH, "0ln",
654                    tree (CARC,
655                          tree (_POINT, "0" * lun, h),
656                          tree (_POINT, l, "0" * hun),
657                          tree (_POINT, "0" * lun, as_string (-hx) * hun)));
658     return "";
659   }
660   else return t;
661 }
662 
663 void
update_line_arrows()664 edit_env_rep::update_line_arrows () {
665   line_arrows= array<tree> (2);
666   string l= get_string (ARROW_LENGTH);
667   string h= get_string (ARROW_HEIGHT);
668   line_arrows[0]= decode_arrow (env [ARROW_BEGIN], l, h);
669   line_arrows[1]= decode_arrow (env [ARROW_END], l, h);
670 }
671 
672 void
update()673 edit_env_rep::update () {
674   zoomf          = normal_zoom (get_double (ZOOM_FACTOR));
675   pixel          = (SI) tm_round ((std_shrinkf * PIXEL) / zoomf);
676   magn           = get_double (MAGNIFICATION);
677   index_level    = get_int (MATH_LEVEL);
678   display_style  = get_bool (MATH_DISPLAY);
679   math_condensed = get_bool (MATH_CONDENSED);
680   vert_pos       = get_int (MATH_VPOS);
681   preamble       = get_bool (PREAMBLE);
682 
683   update_mode ();
684   update_info_level ();
685   update_language ();
686   update_font ();
687 
688   update_geometry ();
689   update_frame ();
690   point_style= get_string (POINT_STYLE);
691   update_color ();
692   update_pattern_mode ();
693   update_dash_style ();
694   dash_style_unit= get_length (DASH_STYLE_UNIT);
695   update_line_arrows ();
696   text_at_halign= get_string (TEXT_AT_HALIGN);
697   text_at_valign= get_string (TEXT_AT_VALIGN);
698 
699   update_src_style ();
700   update_src_special ();
701   update_src_compact ();
702   update_src_close ();
703 }
704 
705 /******************************************************************************
706 * Update a particular changed variable
707 ******************************************************************************/
708 
709 void
update(string s)710 edit_env_rep::update (string s) {
711   switch (var_type[s]) {
712   case Env_User:
713     break;
714   case Env_Fixed:
715     break;
716   case Env_Zoom:
717     zoomf= normal_zoom (get_double (ZOOM_FACTOR));
718     pixel= (SI) tm_round ((std_shrinkf * PIXEL) / zoomf);
719     break;
720   case Env_Magnification:
721     magn= get_double (MAGNIFICATION);
722     update_font ();
723     update_color ();
724     break;
725   case Env_Magnify:
726     mgfy= get_double (MAGNIFY);
727     break;
728   case Env_Language:
729     update_language ();
730     break;
731   case Env_Mode:
732     update_mode ();
733     update_language ();
734     update_font ();
735     break;
736   case Env_Info_Level:
737     update_info_level ();
738     break;
739   case Env_Font:
740     update_font ();
741     break;
742   case Env_Font_Size:
743     update_font ();
744     break;
745   case Env_Index_Level:
746     index_level= get_int (MATH_LEVEL);
747     update_font ();
748     break;
749   case Env_Display_Style:
750     display_style= get_bool (MATH_DISPLAY);
751     break;
752   case Env_Math_Condensed:
753     math_condensed= get_bool (MATH_CONDENSED);
754     break;
755   case Env_Vertical_Pos:
756     vert_pos= get_int (MATH_VPOS);
757     break;
758   case Env_Color:
759     update_color ();
760     break;
761   case Env_Pattern_Mode:
762     update_pattern_mode ();
763     break;
764   case Env_Paragraph:
765     break;
766   case Env_Page:
767     break;
768   case Env_Page_Extents:
769     update_page_pars ();
770     break;
771   case Env_Preamble:
772     preamble= get_bool (PREAMBLE);
773     break;
774   case Env_Geometry:
775     update_geometry ();
776     break;
777   case Env_Frame:
778     update_frame ();
779     break;
780   case Env_Point_Style:
781     point_style= get_string (POINT_STYLE);
782     break;
783   case Env_Line_Width:
784     update_color ();
785     break;
786   case Env_Dash_Style:
787     update_dash_style();
788     break;
789   case Env_Dash_Style_Unit:
790     dash_style_unit= get_length (DASH_STYLE_UNIT);
791     break;
792   case Env_Fill_Color:
793     update_color ();
794     break;
795   case Env_Line_Arrows:
796     update_line_arrows();
797     break;
798   case Env_Text_At_Halign:
799     text_at_halign= get_string (TEXT_AT_HALIGN);
800     break;
801   case Env_Text_At_Valign:
802     text_at_valign= get_string (TEXT_AT_VALIGN);
803     break;
804   case Env_Src_Style:
805     update_src_style ();
806     break;
807   case Env_Src_Special:
808     update_src_special ();
809     break;
810   case Env_Src_Compact:
811     update_src_compact ();
812     break;
813   case Env_Src_Close:
814     update_src_close ();
815     break;
816   }
817 }
818