1 
2 /******************************************************************************
3 * MODULE     : tm_button.cpp
4 * DESCRIPTION: Text widgets for output only
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 "boxes.hpp"
13 #include "Boxes/construct.hpp"
14 #include "font.hpp"
15 #include "tm_frame.hpp"
16 #include "message.hpp"
17 #ifdef AQUATEXMACS
18 #include "Cocoa/aqua_simple_widget.h"
19 #else
20 #ifdef QTTEXMACS
21 #include "Qt/qt_simple_widget.hpp"
22 #else
23 #include "Widkit/simple_wk_widget.hpp"
24 #endif
25 #endif
26 
27 /******************************************************************************
28 * Getting extents of a typesetted tree
29 * Application: get window size for widget tree
30 ******************************************************************************/
31 
32 #include "gui.hpp"
33 #include "drd_std.hpp"
34 #include "drd_info.hpp"
35 #include "convert.hpp"
36 #include "formatter.hpp"
37 #include "Format/format.hpp"
38 #include "new_style.hpp"
39 
40 void use_modules (tree t);
41 
42 void
initialize_environment(edit_env & env,tree doc,drd_info & drd)43 initialize_environment (edit_env& env, tree doc, drd_info& drd) {
44   env->write_default_env ();
45   bool ok;
46   tree t, style= extract (doc, "style");
47   hashmap<string,tree> H;
48   style_get_cache (style, H, t, ok);
49   if (ok) {
50     env->patch_env (H);
51     ok= drd->set_locals (t);
52     drd->set_environment (H);
53   }
54   if (!ok) {
55     if (!is_tuple (style)) FAILED ("tuple expected as style");
56     H= get_style_env (style);
57     drd= get_style_drd (style);
58     style_set_cache (style, H, drd->get_locals ());
59     env->patch_env (H);
60     drd->set_environment (H);
61   }
62   use_modules (env->read (THE_MODULES));
63   tree init= extract (doc, "initial");
64   for (int i=0; i<N(init); i++)
65     if (is_func (init[i], ASSOCIATE, 2) && is_atomic (init[i][0]))
66       env->write (init[i][0]->label, init[i][1]);
67   // env->write (PAGE_TYPE, "a5");
68   env->update ();
69 }
70 
71 tree
tree_extents(tree doc)72 tree_extents (tree doc) {
73   drd_info drd ("none", std_drd);
74   hashmap<string,tree> h1 (UNINIT), h2 (UNINIT);
75   hashmap<string,tree> h3 (UNINIT), h4 (UNINIT);
76   hashmap<string,tree> h5 (UNINIT), h6 (UNINIT);
77   edit_env env (drd, "none", h1, h2, h3, h4, h5, h6);
78   initialize_environment (env, doc, drd);
79   tree t= extract (doc, "body");
80   lazy lz= make_lazy (env, t, path ());
81   format vf= make_query_vstream_width (array<line_item>(), array<line_item>());
82   format rf= lz->query (LAZY_BOX, vf);
83   SI w= ((format_vstream) rf)->width;
84   box b= (box) lz->produce (LAZY_BOX, make_format_width (w));
85   SI h= b->h ();
86   w += env->get_length (PAGE_SCREEN_LEFT);
87   w += env->get_length (PAGE_SCREEN_RIGHT);
88   h += env->get_length (PAGE_SCREEN_TOP);
89   h += env->get_length (PAGE_SCREEN_BOT);
90   return tuple (as_tree ((w / (5*PIXEL)) + 1), as_tree ((h / (5*PIXEL)) + 1));
91 }
92 
93 /******************************************************************************
94 * Typesetted boxes as widgets
95 ******************************************************************************/
96 
97 class box_widget_rep: public simple_widget_rep {
98   box    b;
99   color  bg;
100   bool   transparent;
101   double zoomf;
102   double magf;
103   int    dw, dh;
104 
105 public:
106   box_widget_rep (box b, color bg, bool trans, double zoom, int dw, int dh);
107   operator tree ();
108 
109   void handle_get_size_hint (SI& w, SI& h);
110   void handle_repaint (renderer ren, SI x1, SI y1, SI x2, SI y2);
111 };
112 
box_widget_rep(box b2,color bg2,bool trans2,double zoom,int dw2,int dh2)113 box_widget_rep::box_widget_rep
114   (box b2, color bg2, bool trans2, double zoom, int dw2, int dh2):
115     simple_widget_rep (), b (b2),
116     bg (bg2), transparent (trans2),
117     zoomf (zoom), magf (zoom / std_shrinkf),
118     dw (dw2+2*PIXEL), dh (dh2+2*PIXEL) {}
119 
operator tree()120 box_widget_rep::operator tree () {
121   return tree (TUPLE, "box", (tree) b);
122 }
123 
124 void
handle_get_size_hint(SI & w,SI & h)125 box_widget_rep::handle_get_size_hint (SI& w, SI& h) {
126   SI X1= b->x1, Y1= b->y1;
127   SI X2= b->x2, Y2= b->y2;
128   w = ((SI) ceil ((X2- X1) * magf)) + 2*dw;
129   h = ((SI) ceil ((Y2- Y1) * magf)) + 2*dh;
130   abs_round (w, h);
131 }
132 
133 void
handle_repaint(renderer ren,SI x1,SI y1,SI x2,SI y2)134 box_widget_rep::handle_repaint (renderer ren, SI x1, SI y1, SI x2, SI y2) {
135   SI w, h;
136   handle_get_size_hint (w, h);
137   if (!transparent) {
138     ren->set_background (bg);
139     ren->set_pencil (bg);
140     ren->fill (x1, y1, x2, y2);
141   }
142   ren->set_zoom_factor (zoomf);
143   rectangles l (rectangle (0, 0, w, h));
144   SI x= ((((SI) (w / magf)) - b->w()) >> 1) - b->x1;
145   SI y= ((((SI) (h / magf)) - b->h()) >> 1) - b->y1 - ((SI) (h / magf));
146   b->redraw (ren, path(), l, x, y);
147   ren->reset_zoom_factor ();
148 }
149 
150 /******************************************************************************
151 * Interface
152 ******************************************************************************/
153 
154 widget
box_widget(box b,bool tr)155 box_widget (box b, bool tr) {
156   color col= light_grey;
157   return widget (tm_new<box_widget_rep> (b, col, tr, 5/6.0, 3*PIXEL, 3*PIXEL));
158 }
159 
160 widget
box_widget(scheme_tree p,string s,color col,bool trans,bool ink)161 box_widget (scheme_tree p, string s, color col, bool trans, bool ink) {
162   string family  = "roman";
163   string fn_class= "mr";
164   string series  = "medium";
165   string shape   = "normal";
166   int    sz      = 10;
167   int    dpi     = 600;
168   int    n       = arity (p);
169   if ((n >= 1) && is_atomic (p[0])) family  = as_string (p[0]);
170   if ((n >= 2) && is_atomic (p[1])) fn_class= as_string (p[1]);
171   if ((n >= 3) && is_atomic (p[2])) series  = as_string (p[2]);
172   if ((n >= 4) && is_atomic (p[3])) shape   = as_string (p[3]);
173   if ((n >= 5) && is_atomic (p[4])) sz      = as_int (p[4]);
174   if ((n >= 6) && is_atomic (p[5])) dpi     = as_int (p[5]);
175   font fn= find_font (family, fn_class, series, shape, sz, dpi);
176   box  b = text_box (decorate (), 0, s, fn, col);
177   if (ink) b= resize_box (decorate (), b, b->x3, b->y3, b->x4, b->y4, true);
178   return box_widget (b, trans);
179 }
180 
181 tree enrich_embedded_document (tree body, tree style);
182 
183 static bool
is_transparent(tree init)184 is_transparent (tree init) {
185   for (int i=0; i<N(init); i++)
186     if (is_func (init[i], ASSOCIATE, 2) && init[i][0] == BG_COLOR)
187       return false;
188   return true;
189 }
190 
191 widget
texmacs_output_widget(tree doc,tree style)192 texmacs_output_widget (tree doc, tree style) {
193   doc= enrich_embedded_document (doc, style);
194   drd_info drd ("none", std_drd);
195   hashmap<string,tree> h1 (UNINIT), h2 (UNINIT);
196   hashmap<string,tree> h3 (UNINIT), h4 (UNINIT);
197   hashmap<string,tree> h5 (UNINIT), h6 (UNINIT);
198   edit_env env (drd, "none", h1, h2, h3, h4, h5, h6);
199   initialize_environment (env, doc, drd);
200   tree t= extract (doc, "body");
201   lazy lz= make_lazy (env, t, path ());
202   format vf= make_query_vstream_width (array<line_item>(), array<line_item>());
203   format rf= lz->query (LAZY_BOX, vf);
204   SI w= ((format_vstream) rf)->width;
205   box b= (box) lz->produce (LAZY_BOX, make_format_width (w));
206   //cout << (b->w()>>8) << ", " << (b->h()>>8) << "\n";
207   //SI dw1= env->get_length (PAGE_SCREEN_LEFT);
208   //SI dw2= env->get_length (PAGE_SCREEN_RIGHT);
209   //SI dh1= env->get_length (PAGE_SCREEN_BOT);
210   //SI dh2= env->get_length (PAGE_SCREEN_TOP);
211   color col= env->get_color (BG_COLOR);
212   if (env->get_string (BG_COLOR) == "white" &&
213       is_transparent (extract (doc, "body")))
214 #ifdef QTTEXMACS
215     col= rgb_color (236, 236, 236);
216 #else
217     col= light_grey;
218 #endif
219   return widget (tm_new<box_widget_rep> (b, col, false, 1.0, 0, 0));
220 }
221