]> git.lyx.org Git - features.git/blob - src/frontends/xforms/MathsSymbols.C
Martin's Angstrom patch.
[features.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         "textrm Å", "textrm Ø", "mathcircumflex", "_", 
141         "mathrm T",
142         "mathbb N", "mathbb Z", "mathbb Q", 
143         "mathbb R", "mathbb C", "mathbb H",
144         "mathcal F", "mathcal L", 
145         "mathcal H", "mathcal O", ""
146 };
147
148 int const nr_latex_misc = sizeof(latex_misc) / sizeof(char const *);
149
150 char const * latex_varsz[] = {
151         "sum", "int", "oint",
152         "prod", "coprod", "bigsqcup",
153         "bigotimes", "bigodot", "bigoplus",
154         "bigcap", "bigcup", "biguplus",
155         "bigvee", "bigwedge", ""
156 };
157
158 int const nr_latex_varsz = sizeof(latex_varsz) / sizeof(char const *);
159
160 char const * latex_ams_misc[] = {
161         "digamma", "varkappa", "beth", "daleth", "gimel",
162         "ulcorner", "urcorner", "llcorner", "lrcorner",
163         "hbar", "hslash", "vartriangle",
164         "triangledown", "square", "lozenge",
165         "circledS", "angle", "measuredangle",
166         "nexists", "mho", "Finv",
167         "Game", "Bbbk", "backprime",
168         "varnothing", "blacktriangle", "blacktriangledown",
169         "blacksquare", "blacklozenge", "bigstar",
170         "sphericalangle", "complement", "eth",
171         "diagup", "diagdown", ""
172 };
173
174 int const nr_latex_ams_misc = sizeof(latex_ams_misc) / sizeof(char const *);
175
176 char const * latex_ams_arrows[] = {
177         "dashrightarrow", "dashleftarrow", "leftleftarrows",
178         "leftrightarrows", "Lleftarrow", "twoheadleftarrow",
179         "leftarrowtail", "looparrowleft", "leftrightharpoons",
180         "curvearrowleft", "circlearrowleft", "Lsh",
181         "upuparrows", "upharpoonleft", "downharpoonleft",
182         "multimap", "leftrightsquigarrow", "rightrightarrows",
183         "rightleftarrows", "rightrightarrows", "rightleftarrows",
184         "twoheadrightarrow", "rightarrowtail", "looparrowright",
185         "rightleftharpoons", "curvearrowright", "circlearrowright",
186         "Rsh", "downdownarrows", "upharpoonright", 
187         "downharpoonright", "rightsquigarrow",
188         "nleftarrow", "nrightarrow", "nLeftarrow",
189         "nRightarrow", "nleftrightarrow", "nLeftrightarrow"
190 };
191
192 int const nr_latex_ams_arrows = sizeof(latex_ams_arrows) / sizeof(char const *);
193
194 char const * latex_ams_rel[] = {
195         "leqq", "leqslant", "eqslantless", "eqslantgtr", "gtrsim", "gtrapprox",
196         "lesssim", "lessapprox", "approxeq", "gtrdot", "ggg", "gtrless",
197         "lessdot", "lll", "lessgtr", "gtreqless", "gtreqqless", "eqcirc",
198         "lesseqgtr", "lesseqqgtr", "doteqdot", "circeq", "triangleq", "thicksim",
199         "risingdotseq", "fallingdotseq", "backsim", "thickapprox", "supseteqq", "Supset",
200         "backsimeq", "subseteqq", "Subset","sqsupset", "succcurlyeq", "curlyeqsucc",
201         "sqsubset", "preccurlyeq", "curlyeqprec", "succsim", "succapprox", "vartriangleright",
202         "precsim", "precapprox", "vartriangleleft", "trianglerighteq", "Vdash", "shortmid",
203         "trianglelefteq", "vDash", "Vvdash", "shortparallel", "between", "pitchfork",
204         "smallsmile", "smallfrown", "bumpeq", "varpropto", "blacktriangleleft", "therefore",
205         "Bumpeq", "geqq", "geqslant", "backepsilon", "blacktriangleright", "because"
206 };
207
208 int const nr_latex_ams_rel = sizeof(latex_ams_rel) / sizeof(char const *);
209
210 char const * latex_ams_nrel[] = {
211         "nless", "nleq", "nleqslant", "ngeqslant", "ngeqq", "gneq",
212         "nleqq", "lneq", "lneqq","gneqq", "gverteqq", "gnsim",
213         "lvertneqq", "lnsim", "lnapprox", "gnapprox", "nsucc", "nsucceq",
214         "nprec", "npreceq", "precnsim","succnsim", "succnapprox", "ncong",
215         "precnapprox", "nsim", "nshortmid", "nshortparallel", "nparallel", "nvDash",
216         
217         "nmid", "nvdash", "nvDash","nVDash", "ntriangleright", "ntrianglerighteq",
218         "ntriangleleft", "ntrianglelefteq", "nsubseteq", "nsupseteq", "nsupseteqq", "supsetneq",
219         "subsetneq", "varsubsetneq", "subsetneqq", "varsupsetneq", "supsetneqq", "varsupsetneqq",
220         "varsubsetneqq", "ngtr", "ngeq","", "", ""
221 };
222
223 int const nr_latex_ams_nrel = sizeof(latex_ams_nrel) / sizeof(char const *);
224
225
226 char const * latex_ams_ops[] = {
227         "dotplus", "smallsetminus", "Cap",
228         "Cup", "barwedge", "veebar",
229         "doublebarwedge", "boxminus", "boxtimes",
230         "boxdot", "boxplus", "divideontimes",
231         "ltimes", "rtimes", "leftthreetimes",
232         "rightthreetimes", "curlywedge", "curlyvee",
233         "circleddash", "circledast", "circledcirc",
234         "centerdot", "intercal", ""
235 };
236
237 int const nr_latex_ams_ops = sizeof(latex_ams_ops) / sizeof(char const *);
238
239 static char const ** mathed_get_pixmap_from_icon(int d)
240 {
241         switch (d) {
242                 case MM_FRAC: return frac;
243                 case MM_SQRT: return sqrt_xpm;
244                 case MM_SUPER: return super_xpm;
245                 case MM_SUB: return sub_xpm;
246                 case MM_STYLE: return style_xpm;
247                 case MM_DELIM: return delim;
248                 case MM_MATRIX: return matrix;
249                 case MM_EQU: return equation;
250                 case MM_DECO: return deco;
251                 case MM_SPACE: return space_xpm;
252                 default: return 0;
253         }
254 }
255  
256 static char const ** pixmapFromBitmapData(char const * s, int wx, int hx)
257 {
258         char const ** data = 0;
259
260         int id = -1;
261
262         int i = 0;
263         for (; i < 11; ++i) {
264                 char const ** latex_str = 0;
265                 switch (i) {
266                 case 0: latex_str = latex_greek; break;
267                 case 1: latex_str = latex_bop; break;
268                 case 2: latex_str = latex_brel; break;
269                 case 3: latex_str = latex_arrow; break;
270                 case 4: latex_str = latex_varsz; break;
271                 case 5: latex_str = latex_misc; break;
272                 case 6: latex_str = latex_ams_misc; break;
273                 case 7: latex_str = latex_ams_arrows; break;
274                 case 8: latex_str = latex_ams_rel; break;
275                 case 9: latex_str = latex_ams_nrel; break;
276                 case 10: latex_str = latex_ams_ops; break;
277                 // Add AMS stuff here -- MV
278                 }
279
280                 for (int k = 0; latex_str[k][0] > ' '; ++k) {
281                         if (compare(latex_str[k], s) == 0) {
282                                 id = k;
283                                 break;
284                         }
285                 }
286                 if (id >= 0) break;
287         }
288         if (i < 11 && id >= 0) {
289                 unsigned char const * bdata = 0;
290                 int w = 0;
291                 int h = 0;
292                 int dw = 0;
293                 int dh = 0;
294
295                 lyxerr [Debug::MATHED] << "Imando " << i << ", " << id << endl;
296                 switch (i) {
297                 case 0:
298                         if (id <= 10) {
299                                 w = Greek_width;
300                                 h = Greek_height;
301                                 bdata = Greek_bits;
302                                 dw = 6;
303                                 dh = 2;
304                         } else {
305                                 w = greek_width;
306                                 h = greek_height;
307                                 bdata = greek_bits;
308                                 dw = 7;
309                                 dh = 4;
310                                 id -= 11;
311                         }
312                         break;
313                 case 1:
314                         w = bop_width;
315                         h = bop_height;
316                         bdata = bop_bits;
317                         dw = 4;
318                         dh = 8;
319                         break;
320                 case 2:
321                         w = brel_width;
322                         h = brel_height;
323                         bdata = brel_bits;
324                         dw = 4;
325                         dh = 9;
326                         break;
327                 case 3:
328                         if (id < 20) {
329                                 w = arrow_width;
330                                 h = arrow_height;
331                                 bdata = arrow_bits;
332                                 dw = 5;
333                                 dh = 4;
334                         } else if (id > 28) {
335                                 w = darrow_width;
336                                 h = darrow_height;
337                                 bdata = darrow_bits;
338                                 dw = 2;
339                                 dh = 2;
340                                 id -= 29;
341                         } else {
342                                 w = larrow_width;
343                                 h = larrow_height;
344                                 bdata = larrow_bits;
345                                 dw = 2;
346                                 dh = 4;
347                                 id -= 20;
348                         }
349                         break;
350                 case 4:
351                         w = varsz_width;
352                         h = varsz_height;
353                         bdata = varsz_bits;
354                         dw = 3;
355                         dh = 5;
356                         break;
357                 case 5:
358                         if (id < 29) {
359                                 w = misc_width;
360                                 h = misc_height;
361                                 bdata = misc_bits;
362                                 dw = 5;
363                                 dh = 6;
364                         } else if (id > 36) {
365                                 w = misc3_width;
366                                 h = misc3_height;
367                                 bdata = misc3_bits;
368                                 dw = 3;
369                                 dh = 2;
370                                 id -= 37;
371                         } else {
372                                 w = misc2_width;
373                                 h = misc2_height;
374                                 bdata = misc2_bits;
375                                 dw = 2;
376                                 dh = 2;
377                                 id -= 29;
378                         }
379                         break;
380                 case 7:
381                 case 8:
382                 case 9:
383                 case 10:
384                         // to be added -- MV
385                         break;
386                 }
387                 int ww = w / dw;
388                 int hh = h / dh;
389                 XImage * xima = XCreateImage(fl_get_display(), 0, 1, XYBitmap, 0,
390                                              const_cast<char*>(reinterpret_cast<char const *>(bdata)), w, h, 8, 0);
391                 xima->byte_order = LSBFirst;
392                 xima->bitmap_bit_order = LSBFirst;
393                 int x = (id % dw) * ww;
394                 int y = (id/dw) * hh;
395                 if (ww > wx) ww = wx;
396                 if (hh > hx) hh = hx;
397                 XImage * sbima = XSubImage(xima, x, y, ww, hh);
398                 XpmCreateDataFromImage(fl_get_display(), const_cast<char***>(&data), sbima, sbima, 0);
399
400                 // Dirty hack to get blue symbols quickly
401                 char * sx = const_cast<char*>(strstr(data[2], "FFFFFFFF"));
402                 if (sx) {
403                         for (int k = 0; k < 8; ++k) sx[k] = '0';
404                 }
405
406 //      XDestroyImage(xima);
407         }
408
409         return data;
410 }
411
412  
413 char const ** get_pixmap_from_symbol(char const * arg, int wx, int hx)
414 {
415         lyx::Assert(arg);
416         
417         char const ** data = 0;
418         latexkeys const * l = in_word_set(arg);
419         if (!l)
420                 return 0;
421
422         switch (l->token) {
423         case LM_TK_FRAC:
424                 data = mathed_get_pixmap_from_icon(MM_FRAC);
425                 break;
426         case LM_TK_SQRT:
427                 data = mathed_get_pixmap_from_icon(MM_SQRT);
428                 break;
429         case LM_TK_SYM:
430         case LM_TK_CMR:
431         case LM_TK_CMSY:
432         case LM_TK_CMEX:
433         case LM_TK_CMM:
434         case LM_TK_MSA:
435         case LM_TK_MSB:
436                 // I have to use directly the bitmap data since the
437                 // bitmap tables are not yet created when this
438                 // function is called.
439                 data = pixmapFromBitmapData(arg, wx, hx);
440                 break;
441         default:
442                 break;
443         }
444
445         return data;
446 }