lyx_mirror/src/frontends/xforms/MathsSymbols.C

472 lines
9.7 KiB
C++
Raw Normal View History

/**
* \file MathsSymbols.C
* Copyright 2001 the LyX Team
* Read the file COPYING
*
* \author Alejandro Aguilar Sierra
* \author John Levon
*/
#include <config.h>
#include <algorithm>
#include XPM_H_LOCATION
#ifdef __GNUG__
#pragma implementation
#endif
#include "support/lstrings.h"
#include "support/LAssert.h"
#include "debug.h"
#include "MathsSymbols.h"
#include "FormMaths.h"
using std::max;
using std::endl;
using std::ostream;
/* Latex code for those bitmaps */
static
char const * latex_greek[] = {
"Gamma", "Delta", "Theta", "Lambda", "Xi", "Pi",
"Sigma", "Upsilon", "Phi", "Psi", "Omega",
"alpha", "beta", "gamma", "delta", "epsilon", "varepsilon", "zeta",
"eta", "theta", "vartheta", "iota", "kappa", "lambda", "mu",
"nu", "xi", "pi", "varpi", "rho", "sigma", "varsigma",
"tau", "upsilon", "phi", "varphi", "chi", "psi", "omega", ""
};
static
char const * latex_brel[] = {
"leq", "geq", "equiv", "models",
"prec", "succ", "sim", "perp",
"preceq", "succeq", "simeq", "mid",
"ll", "gg", "asymp", "parallel",
"subset", "supset", "approx", "smile",
"subseteq", "supseteq", "cong", "frown",
"sqsubseteq", "sqsupseteq", "doteq", "neq",
"in", "ni", "propto", "notin",
"vdash", "dashv", "bowtie", ""
};
static
char const * latex_arrow[] = {
"downarrow", "leftarrow", "Downarrow", "Leftarrow",
"hookleftarrow", "rightarrow", "uparrow", "Rightarrow", "Uparrow",
"hookrightarrow", "updownarrow", "Leftrightarrow", "leftharpoonup",
"rightharpoonup", "rightleftharpoons", "leftrightarrow", "Updownarrow",
"leftharpoondown", "rightharpoondown", "mapsto",
"Longleftarrow", "Longrightarrow", "Longleftrightarrow",
"longleftrightarrow", "longleftarrow", "longrightarrow", "longmapsto",
"nwarrow", "nearrow", "swarrow", "searrow", "",
};
char const * latex_varsz[] = {
"sum", "int", "oint",
"prod", "coprod", "bigsqcup",
"bigotimes", "bigodot", "bigoplus",
"bigcap", "bigcup", "biguplus",
"bigvee", "bigwedge", ""
};
static
char const * latex_bop[] = {
"pm", "cap", "diamond", "oplus",
"mp", "cup", "bigtriangleup", "ominus",
"times", "uplus", "bigtriangledown", "otimes",
"div", "sqcap", "triangleright", "oslash",
"cdot", "sqcup", "triangleleft", "odot",
"star", "vee", "amalg", "bigcirc",
"setminus", "wedge", "dagger", "circ",
"bullet", "wr", "ddagger", ""
};
static
char const * latex_misc[] = {
"nabla", "partial", "infty", "prime", "ell",
"emptyset", "exists", "forall", "imath", "jmath",
"Re", "Im", "aleph", "wp", "hbar",
"angle", "top", "bot", "Vert", "neg",
"flat", "natural", "sharp", "surd", "triangle",
"diamondsuit", "heartsuit", "clubsuit", "spadesuit", ""
};
static
char const * latex_dots[] = {
"ldots", "cdots", "vdots", "ddots"
};
BitmapMenu * BitmapMenu::active = 0;
extern "C" void C_MathsSymbolsBitmapCB(FL_OBJECT * ob, long data)
{
BitmapMenu * menu = static_cast<BitmapMenu*>(ob->u_vdata);
int const i = menu->GetIndex(ob);
string str;
lyxerr[Debug::GUI] << "Bitmap callback value " << data << endl;
if (i < 0)
return;
switch (data) {
case MM_GREEK:
str = latex_greek[i];
break;
case MM_ARROW:
str = latex_arrow[i];
break;
case MM_BRELATS:
str = latex_brel[i];
break;
case MM_BOP:
str = latex_bop[i];
break;
case MM_VARSIZE:
str = latex_varsz[i];
break;
case MM_MISC:
str = latex_misc[i];
break;
case MM_DOTS:
/* ewww */
str = latex_dots[i - 29];
break;
default:
Assert(false);
break;
}
menu->form_->insertSymbol(str);
menu->hide();
}
extern "C" int C_MathsSymbolsPeekCB(FL_FORM *, void * xev)
{
if (!BitmapMenu::active)
return 0;
if (static_cast<XEvent *>(xev)->type == ButtonPress) {
BitmapMenu::active->hide();
return 1;
}
if (static_cast<XEvent *>(xev)->type != KeyPress)
return 0;
/* yuck */
char c[5];
KeySym keysym;
XLookupString(&static_cast<XEvent *>(xev)->xkey, &c[0], 5, &keysym, 0);
if (keysym == XK_Left)
BitmapMenu::active->prev();
else if (keysym == XK_Right)
BitmapMenu::active->next();
else
BitmapMenu::active->hide();
return 1;
}
BitmapMenu::BitmapMenu(FormMaths * f, int n, FL_OBJECT * bt, BitmapMenu * prevx)
: current_(0), bitmaps_(n), form_(f)
{
w = h = 0;
form = 0;
ww = 2 * FL_abs(FL_BOUND_WIDTH);
x = y = ww;
y += 8;
button = bt;
button->u_vdata = this;
prev_ = prevx;
next_ = 0;
if (prev_)
prev_->next_ = this;
}
BitmapMenu::~BitmapMenu()
{
delete next_;
if (form->visible)
hide();
fl_free_form(form);
}
void BitmapMenu::hide()
{
fl_hide_form(form);
fl_set_button(button, 0);
active = 0;
}
void BitmapMenu::show()
{
if (active)
active->hide();
active = this;
fl_set_button(button, 1);
fl_show_form(form, FL_PLACE_MOUSE, FL_NOBORDER, "");
}
FL_OBJECT *
BitmapMenu::AddBitmap(int id, int nx, int ny, int bw, int bh,
unsigned char const * data, bool vert)
{
if (current_ >= bitmaps_.size())
return 0;
int wx = bw + ww / 2;
int wy = bh + ww / 2;
wx += (wx % nx);
wy += (wy % ny);
FL_OBJECT * obj = fl_create_bmtable(1, x, y, wx, wy, "");
fl_set_object_callback(obj, C_MathsSymbolsBitmapCB, id);
fl_set_object_lcol(obj, FL_BLUE);
fl_set_object_boxtype(obj, FL_UP_BOX);
fl_set_bmtable_data(obj, nx, ny, bw, bh, data);
if (vert) {
y += wy + 8;
h = max(y, h);
w = max(x + wx + ww, w);
} else {
x += wx + 8;
w = max(x, w);
h = max(y + wy + ww, h);
}
bitmaps_[current_++] = obj;
return obj;
}
void BitmapMenu::create()
{
Assert(current_ >= bitmaps_.size());
form = fl_bgn_form(FL_UP_BOX, w, h);
for (current_ = 0; current_ < bitmaps_.size(); ++current_) {
fl_add_object(form, bitmaps_[current_]);
bitmaps_[current_]->u_vdata = this;
}
fl_end_form();
fl_register_raw_callback(form, KeyPressMask, C_MathsSymbolsPeekCB);
}
int BitmapMenu::GetIndex(FL_OBJECT * ob)
{
if (active == this) {
int k = 0;
for (current_ = 0; current_ < bitmaps_.size(); ++current_) {
if (bitmaps_[current_] == ob)
return k + fl_get_bmtable(ob);
k += fl_get_bmtable_maxitems(bitmaps_[current_]);
}
}
return -1;
}
/* the below is stuff used by Toolbar to make icons. It should be elsewhere
* but depends on the name arrays above ...
*/
#include "greek.xbm"
#include "arrows.xbm"
#include "brel.xbm"
#include "bop.xbm"
#include "misc.xbm"
#include "varsz.xbm"
#include "dots.xbm"
#include "mathed/math_parser.h"
#include "frac.xpm"
#include "sqrt.xpm"
#include "delim.xbm"
#include "delim.xpm"
#include "deco.xbm"
#include "deco.xpm"
#include "space.xpm"
#include "matrix.xpm"
#include "equation.xpm"
static char const ** mathed_get_pixmap_from_icon(int d)
{
switch (d) {
case MM_FRAC: return frac;
case MM_SQRT: return sqrt_xpm;
case MM_DELIM: return delim;
case MM_MATRIX: return matrix;
case MM_EQU: return equation;
case MM_DECO: return deco;
case MM_SPACE: return space_xpm;
default: return 0;
}
}
static char const ** pixmapFromBitmapData(char const * s, int wx, int hx)
{
char const ** data = 0;
int id = -1;
int i = 0;
for (; i < 6; ++i) {
char const ** latex_str = 0;
switch (i) {
case 0: latex_str = latex_greek; break;
case 1: latex_str = latex_bop; break;
case 2: latex_str = latex_brel; break;
case 3: latex_str = latex_arrow; break;
case 4: latex_str = latex_varsz; break;
case 5: latex_str = latex_misc; break;
}
for (int k = 0; latex_str[k][0] > ' '; ++k) {
if (compare(latex_str[k], s) == 0) {
id = k;
break;
}
}
if (id >= 0) break;
}
if (i < 6 && id >= 0) {
unsigned char const * bdata = 0;
int w = 0;
int h = 0;
int dw = 0;
int dh = 0;
lyxerr[Debug::MATHED] << "Imando " << i << ", " << id << endl;
switch (i) {
case 0:
if (id <= 10) {
w = Greek_width;
h = Greek_height;
bdata = Greek_bits;
dw = 6;
dh = 2;
} else {
w = greek_width;
h = greek_height;
bdata = greek_bits;
dw = 7;
dh = 4;
id -= 11;
}
break;
case 1:
w = bop_width;
h = bop_height;
bdata = bop_bits;
dw = 4;
dh = 8;
break;
case 2:
w = brel_width;
h = brel_height;
bdata = brel_bits;
dw = 4;
dh = 9;
break;
case 3:
if (id < 20) {
w = arrow_width;
h = arrow_height;
bdata = arrow_bits;
dw = 5;
dh = 4;
} else if (id > 28) {
w = darrow_width;
h = darrow_height;
bdata = darrow_bits;
dw = 2;
dh = 2;
id -= 29;
} else {
w = larrow_width;
h = larrow_height;
bdata = larrow_bits;
dw = 2;
dh = 4;
id -= 20;
}
break;
case 4:
w = varsz_width;
h = varsz_height;
bdata = varsz_bits;
dw = 3;
dh = 5;
break;
case 5:
w = misc_width;
h = misc_height;
bdata = misc_bits;
dw = 5;
dh = 6;
break;
}
int ww = w / dw;
int hh = h / dh;
XImage * xima = XCreateImage(fl_get_display(), 0, 1, XYBitmap, 0,
const_cast<char*>(reinterpret_cast<char const *>(bdata)), w, h, 8, 0);
xima->byte_order = LSBFirst;
xima->bitmap_bit_order = LSBFirst;
int x = (id % dw) * ww;
int y = (id/dw) * hh;
if (ww > wx) ww = wx;
if (hh > hx) hh = hx;
XImage * sbima = XSubImage(xima, x, y, ww, hh);
XpmCreateDataFromImage(fl_get_display(), const_cast<char***>(&data), sbima, sbima, 0);
// Dirty hack to get blue symbols quickly
char * sx = const_cast<char*>(strstr(data[2], "FFFFFFFF"));
if (sx) {
for (int k = 0; k < 8; ++k) sx[k] = '0';
}
// XDestroyImage(xima);
}
return data;
}
char const ** get_pixmap_from_symbol(char const * arg, int wx, int hx)
{
char const ** data = 0;
latexkeys const * l = in_word_set (arg, strlen(arg));
if (!l)
return 0;
switch (l->token) {
case LM_TK_FRAC:
data = mathed_get_pixmap_from_icon(MM_FRAC);
break;
case LM_TK_SQRT:
data = mathed_get_pixmap_from_icon(MM_SQRT);
break;
case LM_TK_BIGSYM:
case LM_TK_SYM:
// I have to use directly the bitmap data since the
// bitmap tables are not yet created when this
// function is called.
data = pixmapFromBitmapData(arg, wx, hx);
break;
}
return data;
}