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