/** * \file MathsSymbols.C * Copyright 2001 the LyX Team * Read the file COPYING * * \author Alejandro Aguilar Sierra * \author John Levon */ #include #include #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(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(xev)->type == ButtonPress) { BitmapMenu::active->hide(); return 1; } if (static_cast(xev)->type != KeyPress) return 0; /* yuck */ char c[5]; KeySym keysym; XLookupString(&static_cast(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(reinterpret_cast(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(&data), sbima, sbima, 0); // Dirty hack to get blue symbols quickly char * sx = const_cast(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; }