]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/MathsSymbols.C
Compile fixes for DEC cxx, John's maths and keymap patches.
[lyx.git] / src / frontends / xforms / MathsSymbols.C
1 /**
2  * \file MathsSymbols.C
3  * Copyright 2001 the LyX Team
4  * Read the file COPYING
5  *
6  * \author Alejandro Aguilar Sierra
7  * \author John Levon
8  */
9
10 #include <config.h>
11 #include <algorithm>
12  
13 #include XPM_H_LOCATION
14
15 #ifdef __GNUG__
16 #pragma implementation
17 #endif
18
19 #include "support/lstrings.h"
20 #include "support/LAssert.h" 
21 #include "debug.h"
22
23 #include "MathsSymbols.h"
24 #include "FormMaths.h"
25  
26 using std::max;
27 using std::endl;
28 using std::ostream;
29
30 /* Latex code for those bitmaps */
31 static
32 char const * latex_greek[] = {
33         "Gamma", "Delta", "Theta", "Lambda", "Xi", "Pi",
34         "Sigma", "Upsilon", "Phi", "Psi", "Omega",
35         "alpha", "beta", "gamma", "delta", "epsilon", "varepsilon", "zeta",
36         "eta", "theta", "vartheta", "iota", "kappa", "lambda", "mu",
37         "nu", "xi", "pi", "varpi", "rho", "sigma", "varsigma",
38         "tau", "upsilon", "phi", "varphi", "chi", "psi", "omega", ""
39 };
40
41 static
42 char const * latex_brel[] = {
43         "leq", "geq", "equiv", "models",
44         "prec", "succ", "sim", "perp",
45         "preceq", "succeq", "simeq", "mid",
46         "ll", "gg", "asymp", "parallel",
47         "subset", "supset", "approx", "smile",
48         "subseteq", "supseteq", "cong", "frown",
49         "sqsubseteq", "sqsupseteq", "doteq", "neq",
50         "in", "ni", "propto", "notin",
51         "vdash", "dashv", "bowtie", ""
52 };
53
54 static
55 char const * latex_arrow[] = {
56         "downarrow", "leftarrow", "Downarrow", "Leftarrow",
57         "hookleftarrow", "rightarrow", "uparrow", "Rightarrow", "Uparrow",
58         "hookrightarrow", "updownarrow", "Leftrightarrow", "leftharpoonup",
59         "rightharpoonup", "rightleftharpoons", "leftrightarrow", "Updownarrow",
60         "leftharpoondown", "rightharpoondown", "mapsto",
61         "Longleftarrow", "Longrightarrow", "Longleftrightarrow",
62         "longleftrightarrow", "longleftarrow", "longrightarrow", "longmapsto",
63         "nwarrow", "nearrow", "swarrow", "searrow",  "",
64 };
65
66 char const * latex_varsz[] = {
67         "sum", "int", "oint",
68         "prod", "coprod", "bigsqcup",
69         "bigotimes", "bigodot", "bigoplus",
70         "bigcap", "bigcup", "biguplus",
71         "bigvee", "bigwedge", ""
72 };
73
74 static
75 char const * latex_bop[] = {
76         "pm", "cap", "diamond", "oplus",
77         "mp", "cup", "bigtriangleup", "ominus",
78         "times", "uplus", "bigtriangledown", "otimes",
79         "div", "sqcap", "triangleright", "oslash",
80         "cdot", "sqcup", "triangleleft", "odot",
81         "star", "vee", "amalg", "bigcirc",
82         "setminus", "wedge", "dagger", "circ",
83         "bullet", "wr", "ddagger", ""
84 };
85
86 static
87 char const * latex_misc[] = {
88         "nabla", "partial", "infty", "prime", "ell",
89         "emptyset", "exists", "forall", "imath",  "jmath",
90         "Re", "Im", "aleph", "wp", "hbar",
91         "angle", "top", "bot", "Vert", "neg",
92         "flat", "natural", "sharp", "surd", "triangle",
93         "diamondsuit", "heartsuit", "clubsuit", "spadesuit", ""
94 };
95
96 static
97 char const * latex_dots[] = {
98         "ldots", "cdots", "vdots", "ddots"
99 };
100
101 BitmapMenu * BitmapMenu::active = 0;
102
103 extern "C" void C_MathsSymbolsBitmapCB(FL_OBJECT * ob, long data)
104 {
105         BitmapMenu * menu = static_cast<BitmapMenu*>(ob->u_vdata);
106         int const i = menu->GetIndex(ob);
107         string str;
108
109         lyxerr[Debug::GUI] << "Bitmap callback value " << data << endl;
110  
111         if (i < 0) 
112                 return;
113  
114         switch (data) {
115                 case MM_GREEK:
116                         str = latex_greek[i];
117                         break;
118                 case MM_ARROW:
119                         str = latex_arrow[i];
120                         break;
121                 case MM_BRELATS:
122                         str = latex_brel[i];
123                         break;
124                 case MM_BOP:
125                         str = latex_bop[i];
126                         break;
127                 case MM_VARSIZE:
128                         str = latex_varsz[i];
129                         break;
130                 case MM_MISC:
131                         str = latex_misc[i];
132                         break;
133                 case MM_DOTS:
134                         /* ewww */
135                         str = latex_dots[i - 29];
136                         break;
137                 default:
138                         Assert(false);
139                         break;
140         }
141
142         menu->form_->insertSymbol(str);
143         menu->hide();
144 }
145
146  
147 extern "C" int C_MathsSymbolsPeekCB(FL_FORM *, void * xev)
148 {
149         if (!BitmapMenu::active)
150                 return 0;
151
152         if (static_cast<XEvent *>(xev)->type == ButtonPress) {
153                 BitmapMenu::active->hide();
154                 return 1;
155         }
156  
157         if (static_cast<XEvent *>(xev)->type != KeyPress)
158                 return 0;
159
160         /* yuck */
161  
162         char c[5];
163         KeySym keysym;
164         XLookupString(&static_cast<XEvent *>(xev)->xkey, &c[0], 5, &keysym, 0);
165         if (keysym == XK_Left)
166                 BitmapMenu::active->prev(); 
167         else if (keysym == XK_Right)
168                 BitmapMenu::active->next();
169         else
170                 BitmapMenu::active->hide();
171  
172         return 1;
173 }
174
175
176 BitmapMenu::BitmapMenu(FormMaths * f, int n,  FL_OBJECT * bt, BitmapMenu * prevx)
177         : current_(0), bitmaps_(n), form_(f)
178 {
179         w = h = 0;
180         form = 0;
181         ww = 2 * FL_abs(FL_BOUND_WIDTH);
182         x = y = ww;
183         y += 8;
184         button = bt;
185         button->u_vdata = this;
186         prev_ = prevx;
187         next_ = 0;
188         if (prev_)
189                 prev_->next_ = this;
190 }
191
192
193 BitmapMenu::~BitmapMenu()
194 {
195         delete next_;
196         if (form->visible) 
197                 hide();
198         fl_free_form(form);
199 }
200
201
202 void BitmapMenu::hide()
203 {
204         fl_hide_form(form);
205         fl_set_button(button, 0);
206         active = 0;
207 }
208
209
210 void BitmapMenu::show()
211 {
212         if (active)
213                 active->hide();
214         active = this;
215  
216         fl_set_button(button, 1);
217         fl_show_form(form, FL_PLACE_MOUSE, FL_NOBORDER, "");
218 }
219
220
221 FL_OBJECT *
222 BitmapMenu::AddBitmap(int id, int nx, int ny, int bw, int bh,
223                       unsigned char const * data, bool vert)
224 {
225         if (current_ >= bitmaps_.size())
226                 return 0;
227  
228         int wx = bw + ww / 2;
229         int wy = bh + ww / 2;
230         wx += (wx % nx);
231         wy += (wy % ny);
232         FL_OBJECT * obj = fl_create_bmtable(1, x, y, wx, wy, "");
233         fl_set_object_callback(obj, C_MathsSymbolsBitmapCB, id);
234         fl_set_object_lcol(obj, FL_BLUE);
235         fl_set_object_boxtype(obj, FL_UP_BOX);
236         fl_set_bmtable_data(obj, nx, ny, bw, bh, data);
237         if (vert) {
238                 y += wy + 8;
239                 h = max(y, h);
240                 w = max(x + wx + ww, w);
241         } else  {
242                 x += wx + 8;
243                 w = max(x, w);
244                 h = max(y + wy + ww, h);
245         }
246         bitmaps_[current_++] = obj;
247         return obj;
248 }
249
250
251 void BitmapMenu::create()
252 {
253         Assert(current_ >= bitmaps_.size());
254  
255         form = fl_bgn_form(FL_UP_BOX, w, h);
256  
257         for (current_ = 0; current_ < bitmaps_.size(); ++current_) {
258                 fl_add_object(form, bitmaps_[current_]);
259                 bitmaps_[current_]->u_vdata = this;
260         }
261  
262         fl_end_form();
263  
264         fl_register_raw_callback(form, KeyPressMask, C_MathsSymbolsPeekCB);
265 }
266
267
268 int BitmapMenu::GetIndex(FL_OBJECT * ob)
269 {
270         if (active == this) {
271                 int k = 0;
272                 for (current_ = 0; current_ < bitmaps_.size(); ++current_) {
273                         if (bitmaps_[current_] == ob)
274                                 return k + fl_get_bmtable(ob);
275                         k += fl_get_bmtable_maxitems(bitmaps_[current_]);
276                 }
277         }
278         return -1;
279 }
280
281 /* the below is stuff used by Toolbar to make icons. It should be elsewhere
282  * but depends on the name arrays above ...
283  */
284
285 #include "greek.xbm"
286 #include "arrows.xbm"
287 #include "brel.xbm"
288 #include "bop.xbm"
289 #include "misc.xbm"
290 #include "varsz.xbm"
291 #include "dots.xbm"
292 #include "mathed/math_parser.h"
293 #include "frac.xpm"
294 #include "sqrt.xpm"
295 #include "delim.xbm"
296 #include "delim.xpm"
297 #include "deco.xbm"
298 #include "deco.xpm"
299 #include "space.xpm"
300 #include "matrix.xpm"
301 #include "equation.xpm"
302
303 static char const ** mathed_get_pixmap_from_icon(int d)
304 {
305         switch (d) {
306                 case MM_FRAC: return frac;
307                 case MM_SQRT: return sqrt_xpm;
308                 case MM_DELIM: return delim;
309                 case MM_MATRIX: return matrix;
310                 case MM_EQU: return equation;
311                 case MM_DECO: return deco;
312                 case MM_SPACE: return space_xpm;
313                 default: return 0;
314         }
315 }
316  
317 static char const ** pixmapFromBitmapData(char const * s, int wx, int hx)
318 {
319         char const ** data = 0;
320
321         int id = -1;
322
323         int i = 0;
324         for (; i < 6; ++i) {
325                 char const ** latex_str = 0;
326                 switch (i) {
327                 case 0: latex_str = latex_greek; break;
328                 case 1: latex_str = latex_bop; break;
329                 case 2: latex_str = latex_brel; break;
330                 case 3: latex_str = latex_arrow; break;
331                 case 4: latex_str = latex_varsz; break;
332                 case 5: latex_str = latex_misc; break;
333                 }
334
335                 for (int k = 0; latex_str[k][0] > ' '; ++k) {
336                         if (compare(latex_str[k], s) == 0) {
337                                 id = k;
338                                 break;
339                         }
340                 }
341                 if (id >= 0) break;
342         }
343         if (i < 6 && id >= 0) {
344                 unsigned char const * bdata = 0;
345                 int w = 0;
346                 int h = 0;
347                 int dw = 0;
348                 int dh = 0;
349
350                 lyxerr[Debug::MATHED] << "Imando " << i << ", " << id << endl;
351                 switch (i) {
352                 case 0:
353                         if (id <= 10) {
354                                 w = Greek_width;
355                                 h = Greek_height;
356                                 bdata = Greek_bits;
357                                 dw = 6;
358                                 dh = 2;
359                         } else {
360                                 w = greek_width;
361                                 h = greek_height;
362                                 bdata = greek_bits;
363                                 dw = 7;
364                                 dh = 4;
365                                 id -= 11;
366                         }
367                         break;
368                 case 1:
369                         w = bop_width;
370                         h = bop_height;
371                         bdata = bop_bits;
372                         dw = 4;
373                         dh = 8;
374                         break;
375                 case 2:
376                         w = brel_width;
377                         h = brel_height;
378                         bdata = brel_bits;
379                         dw = 4;
380                         dh = 9;
381                         break;
382                 case 3:
383                         if (id < 20) {
384                                 w = arrow_width;
385                                 h = arrow_height;
386                                 bdata = arrow_bits;
387                                 dw = 5;
388                                 dh = 4;
389                         } else if (id > 28) {
390                                 w = darrow_width;
391                                 h = darrow_height;
392                                 bdata = darrow_bits;
393                                 dw = 2;
394                                 dh = 2;
395                                 id -= 29;
396                         } else {
397                                 w = larrow_width;
398                                 h = larrow_height;
399                                 bdata = larrow_bits;
400                                 dw = 2;
401                                 dh = 4;
402                                 id -= 20;
403                         }
404                         break;
405                 case 4:
406                         w = varsz_width;
407                         h = varsz_height;
408                         bdata = varsz_bits;
409                         dw = 3;
410                         dh = 5;
411                         break;
412                 case 5:
413                         w = misc_width;
414                         h = misc_height;
415                         bdata = misc_bits;
416                         dw = 5;
417                         dh = 6;
418                         break;
419                 }
420                 int ww = w / dw;
421                 int hh = h / dh;
422
423                 XImage * xima = XCreateImage(fl_get_display(), 0, 1, XYBitmap, 0,
424                                              const_cast<char*>(reinterpret_cast<char const *>(bdata)), w, h, 8, 0);
425                 xima->byte_order = LSBFirst;
426                 xima->bitmap_bit_order = LSBFirst;
427                 int x = (id % dw) * ww;
428                 int y = (id/dw) * hh;
429                 if (ww > wx) ww = wx;
430                 if (hh > hx) hh = hx;
431                 XImage * sbima = XSubImage(xima, x, y, ww, hh);
432                 XpmCreateDataFromImage(fl_get_display(), const_cast<char***>(&data), sbima, sbima, 0);
433
434                 // Dirty hack to get blue symbols quickly
435                 char * sx = const_cast<char*>(strstr(data[2], "FFFFFFFF"));
436                 if (sx) {
437                         for (int k = 0; k < 8; ++k) sx[k] = '0';
438                 }
439
440 //      XDestroyImage(xima);
441         }
442
443         return data;
444 }
445
446  
447 char const ** get_pixmap_from_symbol(char const * arg, int wx, int hx)
448 {
449         char const ** data = 0;
450         latexkeys const * l = in_word_set (arg, strlen(arg));
451         if (!l)
452                 return 0;
453
454         switch (l->token) {
455         case LM_TK_FRAC:
456                 data = mathed_get_pixmap_from_icon(MM_FRAC);
457                 break;
458         case LM_TK_SQRT:
459                 data = mathed_get_pixmap_from_icon(MM_SQRT);
460                 break;
461         case LM_TK_BIGSYM:
462         case LM_TK_SYM:
463                 // I have to use directly the bitmap data since the
464                 // bitmap tables are not yet created when this
465                 // function is called.
466                 data = pixmapFromBitmapData(arg, wx, hx);
467                 break;
468         }
469
470         return data;
471 }