]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/MathsSymbols.C
Bugfixes: checkboxes to radiobuttons (from J�rgen S) and remove a little
[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/LAssert.h" 
20 #include "support/lstrings.h"
21 #include "debug.h"
22 #include "MathsSymbols.h"
23 #include "FormMathsPanel.h"
24  
25 using std::max;
26 using std::endl;
27 using std::ostream;
28
29 #ifndef CXX_GLOBAL_CSTD
30 using std::strstr;
31 #endif
32
33
34 /* Latex code for those bitmaps */
35
36 #include "greek.xbm"
37 #include "arrows.xbm"
38 #include "brel.xbm"
39 #include "bop.xbm"
40 #include "misc.xbm"
41 #include "varsz.xbm"
42 #include "dots.xbm"
43
44 #include "ams_misc.xbm"
45 #include "ams_arrows.xbm"
46 #include "ams_rel.xbm"
47 #include "ams_nrel.xbm"
48 #include "ams_ops.xbm"
49
50 #include "mathed/math_parser.h"
51 #include "frac.xpm"
52 #include "sub.xpm"
53 #include "super.xpm"
54 #include "style.xpm"
55 #include "sqrt.xpm"
56 #include "delim.xbm"
57 #include "delim.xpm"
58 #include "deco.xbm"
59 #include "deco.xpm"
60 #include "space.xpm"
61 #include "matrix.xpm"
62 #include "equation.xpm"
63
64 char const * function_names[] = {
65         "arccos", "arcsin", "arctan", "arg", "bmod",
66         "cos", "cosh", "cot", "coth", "csc", "deg",
67         "det", "dim", "exp", "gcd", "hom", "inf", "ker",
68         "lg", "lim", "liminf", "limsup", "ln", "log",
69         "max", "min", "sec", "sin", "sinh", "sup",
70         "tan", "tanh"
71 };
72
73 int const nr_function_names = sizeof(function_names) /
74                                      sizeof(char const *);
75
76 char const * latex_arrow[] = {
77         "downarrow", "leftarrow", "Downarrow", "Leftarrow",
78         "hookleftarrow", "rightarrow", "uparrow", "Rightarrow", "Uparrow",
79         "hookrightarrow", "updownarrow", "Leftrightarrow", "leftharpoonup",
80         "rightharpoonup", "rightleftharpoons", "leftrightarrow", "Updownarrow",
81         "leftharpoondown", "rightharpoondown", "mapsto",
82         "Longleftarrow", "Longrightarrow", "Longleftrightarrow",
83         "longleftrightarrow", "longleftarrow", "longrightarrow", "longmapsto",
84         "nwarrow", "nearrow", "swarrow", "searrow",  "",
85 };
86
87 int const nr_latex_arrow = sizeof(latex_arrow) / sizeof(char const *);
88
89 char const * latex_bop[] = {
90         "pm", "cap", "diamond", "oplus",
91         "mp", "cup", "bigtriangleup", "ominus",
92         "times", "uplus", "bigtriangledown", "otimes",
93         "div", "sqcap", "triangleright", "oslash",
94         "cdot", "sqcup", "triangleleft", "odot",
95         "star", "vee", "amalg", "bigcirc",
96         "setminus", "wedge", "dagger", "circ",
97         "bullet", "wr", "ddagger", ""
98 };
99
100 int const nr_latex_bop = sizeof(latex_bop) / sizeof(char const *);
101
102 char const * latex_brel[] = {
103         "leq", "geq", "equiv", "models",
104         "prec", "succ", "sim", "perp",
105         "preceq", "succeq", "simeq", "mid",
106         "ll", "gg", "asymp", "parallel",
107         "subset", "supset", "approx", "smile",
108         "subseteq", "supseteq", "cong", "frown",
109         "sqsubseteq", "sqsupseteq", "doteq", "neq",
110         "in", "ni", "propto", "notin",
111         "vdash", "dashv", "bowtie", ""
112 };
113
114 int const nr_latex_brel = sizeof(latex_brel) / sizeof(char const *);
115
116 char const * latex_dots[] = {
117         "ldots", "cdots", "vdots", "ddots"
118 };
119
120 int const nr_latex_dots = sizeof(latex_dots) / sizeof(char const *);
121
122 char const * latex_greek[] = {
123         "Gamma", "Delta", "Theta", "Lambda", "Xi", "Pi",
124         "Sigma", "Upsilon", "Phi", "Psi", "Omega",
125         "alpha", "beta", "gamma", "delta", "epsilon", "varepsilon", "zeta",
126         "eta", "theta", "vartheta", "iota", "kappa", "lambda", "mu",
127         "nu", "xi", "pi", "varpi", "rho", "sigma", "varsigma",
128         "tau", "upsilon", "phi", "varphi", "chi", "psi", "omega", ""
129 };
130
131 int const nr_latex_greek = sizeof(latex_greek) / sizeof(char const *);
132
133 char const * latex_misc[] = {
134         "nabla", "partial", "infty", "prime", "ell",
135         "emptyset", "exists", "forall", "imath",  "jmath",
136         "Re", "Im", "aleph", "wp", "hbar",
137         "angle", "top", "bot", "Vert", "neg",
138         "flat", "natural", "sharp", "surd", "triangle",
139         "diamondsuit", "heartsuit", "clubsuit", "spadesuit", 
140         "mathbb N", "mathbb Z", "mathbb Q", 
141         "mathbb R", "mathbb C", "mathbb H",
142         "mathcal F", "mathcal L", 
143         "mathcal H", "mathcal O",""
144 };
145
146 int const nr_latex_misc = sizeof(latex_misc) / sizeof(char const *);
147
148 char const * latex_varsz[] = {
149         "sum", "int", "oint",
150         "prod", "coprod", "bigsqcup",
151         "bigotimes", "bigodot", "bigoplus",
152         "bigcap", "bigcup", "biguplus",
153         "bigvee", "bigwedge", ""
154 };
155
156 int const nr_latex_varsz = sizeof(latex_varsz) / sizeof(char const *);
157
158 char const * latex_ams_misc[] = {
159         "digamma", "varkappa", "beth", "daleth", "gimel",
160         "ulcorner", "urcorner", "llcorner", "lrcorner",
161         "hbar", "hslash", "vartriangle",
162         "triangledown", "square", "lozenge",
163         "circledS", "angle", "measuredangle",
164         "nexists", "mho", "Finv",
165         "Game", "Bbbk", "backprime",
166         "varnothing", "blacktriangle", "blacktriangledown",
167         "blacksquare", "blacklozenge", "bigstar",
168         "sphericalangle", "complement", "eth",
169         "diagup", "diagdown", ""
170 };
171
172 int const nr_latex_ams_misc = sizeof(latex_ams_misc) / sizeof(char const *);
173
174 char const * latex_ams_arrows[] = {
175         "dashrightarrow", "dashleftarrow", "leftleftarrows",
176         "leftrightarrows", "Lleftarrow", "twoheadleftarrow",
177         "leftarrowtail", "looparrowleft", "leftrightharpoons",
178         "curvearrowleft", "circlearrowleft", "Lsh",
179         "upuparrows", "upharpoonleft", "downharpoonleft",
180         "multimap", "leftrightsquigarrow", "rightrightarrows",
181         "rightleftarrows", "rightrightarrows", "rightleftarrows",
182         "twoheadrightarrow", "rightarrowtail", "looparrowright",
183         "rightleftharpoons", "curvearrowright", "circlearrowright",
184         "Rsh", "downdownarrows", "upharpoonright", 
185         "downharpoonright", "rightsquigarrow",
186         "nleftarrow", "nrightarrow", "nLeftarrow",
187         "nRightarrow", "nleftrightarrow", "nLeftrightarrow"
188 };
189
190 int const nr_latex_ams_arrows = sizeof(latex_ams_arrows) / sizeof(char const *);
191
192 char const * latex_ams_rel[] = {
193         "leqq", "leqslant", "eqslantless",
194         "lesssim", "lessapprox", "approxeq",
195         "lessdot", "lll", "lessgtr",
196         "lesseqgtr", "lesseqqgtr", "doteqdot",
197         "risingdotseq", "fallingdotseq", "backsim",
198         "backsimeq", "subseteqq", "Subset",
199         "sqsubset", "preccurlyeq", "curlyeqprec",
200         "precsim", "precapprox", "vartriangleleft",
201         "trianglelefteq", "vDash", "Vvdash",
202         "smallsmile", "smallfrown", "bumpeq",
203         "Bumpeq", "geqq", "geqslant",
204         "eqslantgtr", "gtrsim", "gtrapprox",
205         "gtrdot", "ggg", "gtrless", 
206         "gtreqless", "gtreqqless", "eqcirc",
207         "circeq", "triangleq", "thicksim",
208         "thickapprox", "supseteqq", "Supset",
209         "sqsupset", "succcurlyeq", "curlyeqsucc",
210         "succsim", "succapprox", "vartriangleright",
211         "trianglerighteq", "Vdash", "shortmid",
212         "shortparallel", "between", "pitchfork", 
213         "varpropto", "blacktriangleleft", "therefore",
214         "backepsilon", "blacktriangleright", "because"
215 };
216
217 int const nr_latex_ams_rel = sizeof(latex_ams_rel) / sizeof(char const *);
218
219 char const * latex_ams_nrel[] = {
220         "nless", "nleq", "nleqslant",
221         "nleqq", "lneq", "lneqq",
222         "lvertneqq", "lnsim", "lnapprox", 
223         "nprec", "npreceq", "precnsim",
224         "precnapprox", "nsim", "nshortmid",
225         "nmid", "nvdash", "nvDash",
226         "ntriangleleft", "ntrianglelefteq", "nsubseteq",
227         "subsetneq", "varsubsetneq", "subsetneqq",
228         "varsubsetneqq", "ngtr", "ngeq",
229         "ngeqslant", "ngeqq", "gneq",
230         "gneqq", "gverteqq", "gnsim",
231         "gnapprox", "nsucc", "nsucceq",
232         "succnsim", "succnapprox", "ncong",
233         "nshortparallel", "nparallel", "nvDash",
234         "nVDash", "ntriangleright", "ntrianglerighteq",
235         "nsupseteq", "nsupseteqq", "supsetneq",
236         "varsupsetneq", "supsetneqq", "varsupsetneqq"
237 };
238
239 int const nr_latex_ams_nrel = sizeof(latex_ams_nrel) / sizeof(char const *);
240
241
242 char const * latex_ams_ops[] = {
243         "dotplus", "smallsetminus", "Cap",
244         "Cup", "barwedge", "veebar",
245         "doublebarwedge", "boxminus", "boxtimes",
246         "boxdot", "boxplus", "divideontimes",
247         "ltimes", "rtimes", "leftthreetimes",
248         "rightthreetimes", "curlywedge", "curlyvee",
249         "circleddash", "circledast", "circledcirc",
250         "centerdot", "intercal", ""
251 };
252
253 int const nr_latex_ams_ops = sizeof(latex_ams_ops) / sizeof(char const *);
254
255 static char const ** mathed_get_pixmap_from_icon(int d)
256 {
257         switch (d) {
258                 case MM_FRAC: return frac;
259                 case MM_SQRT: return sqrt_xpm;
260                 case MM_SUPER: return super_xpm;
261                 case MM_SUB: return sub_xpm;
262                 case MM_STYLE: return style_xpm;
263                 case MM_DELIM: return delim;
264                 case MM_MATRIX: return matrix;
265                 case MM_EQU: return equation;
266                 case MM_DECO: return deco;
267                 case MM_SPACE: return space_xpm;
268                 default: return 0;
269         }
270 }
271  
272 static char const ** pixmapFromBitmapData(char const * s, int wx, int hx)
273 {
274         char const ** data = 0;
275
276         int id = -1;
277
278         int i = 0;
279         for (; i < 11; ++i) {
280                 char const ** latex_str = 0;
281                 switch (i) {
282                 case 0: latex_str = latex_greek; break;
283                 case 1: latex_str = latex_bop; break;
284                 case 2: latex_str = latex_brel; break;
285                 case 3: latex_str = latex_arrow; break;
286                 case 4: latex_str = latex_varsz; break;
287                 case 5: latex_str = latex_misc; break;
288                 case 6: latex_str = latex_ams_misc; break;
289                 case 7: latex_str = latex_ams_arrows; break;
290                 case 8: latex_str = latex_ams_rel; break;
291                 case 9: latex_str = latex_ams_nrel; break;
292                 case 10: latex_str = latex_ams_ops; break;
293                 // Add AMS stuff here -- MV
294                 }
295
296                 for (int k = 0; latex_str[k][0] > ' '; ++k) {
297                         if (compare(latex_str[k], s) == 0) {
298                                 id = k;
299                                 break;
300                         }
301                 }
302                 if (id >= 0) break;
303         }
304         if (i < 11 && id >= 0) {
305                 unsigned char const * bdata = 0;
306                 int w = 0;
307                 int h = 0;
308                 int dw = 0;
309                 int dh = 0;
310
311                 lyxerr [Debug::MATHED] << "Imando " << i << ", " << id << endl;
312                 switch (i) {
313                 case 0:
314                         if (id <= 10) {
315                                 w = Greek_width;
316                                 h = Greek_height;
317                                 bdata = Greek_bits;
318                                 dw = 6;
319                                 dh = 2;
320                         } else {
321                                 w = greek_width;
322                                 h = greek_height;
323                                 bdata = greek_bits;
324                                 dw = 7;
325                                 dh = 4;
326                                 id -= 11;
327                         }
328                         break;
329                 case 1:
330                         w = bop_width;
331                         h = bop_height;
332                         bdata = bop_bits;
333                         dw = 4;
334                         dh = 8;
335                         break;
336                 case 2:
337                         w = brel_width;
338                         h = brel_height;
339                         bdata = brel_bits;
340                         dw = 4;
341                         dh = 9;
342                         break;
343                 case 3:
344                         if (id < 20) {
345                                 w = arrow_width;
346                                 h = arrow_height;
347                                 bdata = arrow_bits;
348                                 dw = 5;
349                                 dh = 4;
350                         } else if (id > 28) {
351                                 w = darrow_width;
352                                 h = darrow_height;
353                                 bdata = darrow_bits;
354                                 dw = 2;
355                                 dh = 2;
356                                 id -= 29;
357                         } else {
358                                 w = larrow_width;
359                                 h = larrow_height;
360                                 bdata = larrow_bits;
361                                 dw = 2;
362                                 dh = 4;
363                                 id -= 20;
364                         }
365                         break;
366                 case 4:
367                         w = varsz_width;
368                         h = varsz_height;
369                         bdata = varsz_bits;
370                         dw = 3;
371                         dh = 5;
372                         break;
373                 case 5:
374                         if (id < 29) {
375                                 w = misc_width;
376                                 h = misc_height;
377                                 bdata = misc_bits;
378                                 dw = 5;
379                                 dh = 6;
380                         } else if (id > 36) {
381                                 w = misc3_width;
382                                 h = misc3_height;
383                                 bdata = misc3_bits;
384                                 dw = 3;
385                                 dh = 2;
386                                 id -= 37;
387                         } else {
388                                 w = misc2_width;
389                                 h = misc2_height;
390                                 bdata = misc2_bits;
391                                 dw = 2;
392                                 dh = 2;
393                                 id -= 29;
394                         }
395                         break;
396                 case 7:
397                 case 8:
398                 case 9:
399                 case 10:
400                         // to be added -- MV
401                         break;
402                 }
403                 int ww = w / dw;
404                 int hh = h / dh;
405                 XImage * xima = XCreateImage(fl_get_display(), 0, 1, XYBitmap, 0,
406                                              const_cast<char*>(reinterpret_cast<char const *>(bdata)), w, h, 8, 0);
407                 xima->byte_order = LSBFirst;
408                 xima->bitmap_bit_order = LSBFirst;
409                 int x = (id % dw) * ww;
410                 int y = (id/dw) * hh;
411                 if (ww > wx) ww = wx;
412                 if (hh > hx) hh = hx;
413                 XImage * sbima = XSubImage(xima, x, y, ww, hh);
414                 XpmCreateDataFromImage(fl_get_display(), const_cast<char***>(&data), sbima, sbima, 0);
415
416                 // Dirty hack to get blue symbols quickly
417                 char * sx = const_cast<char*>(strstr(data[2], "FFFFFFFF"));
418                 if (sx) {
419                         for (int k = 0; k < 8; ++k) sx[k] = '0';
420                 }
421
422 //      XDestroyImage(xima);
423         }
424
425         return data;
426 }
427
428  
429 char const ** get_pixmap_from_symbol(char const * arg, int wx, int hx)
430 {
431         lyx::Assert(arg);
432         
433         char const ** data = 0;
434         latexkeys const * l = in_word_set(arg);
435         if (!l)
436                 return 0;
437
438         switch (l->token) {
439         case LM_TK_FRAC:
440                 data = mathed_get_pixmap_from_icon(MM_FRAC);
441                 break;
442         case LM_TK_SQRT:
443                 data = mathed_get_pixmap_from_icon(MM_SQRT);
444                 break;
445         case LM_TK_SYM:
446         case LM_TK_CMR:
447         case LM_TK_CMSY:
448         case LM_TK_CMEX:
449         case LM_TK_CMM:
450         case LM_TK_MSA:
451         case LM_TK_MSB:
452                 // I have to use directly the bitmap data since the
453                 // bitmap tables are not yet created when this
454                 // function is called.
455                 data = pixmapFromBitmapData(arg, wx, hx);
456                 break;
457         default:
458                 break;
459         }
460
461         return data;
462 }