home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Linux / Divers / lyx-0.13.2.tar.gz / lyx-0.13.2.tar / lyx-0.13.2 / src / math_symbols.C < prev    next >
C/C++ Source or Header  |  1998-04-23  |  14KB  |  544 lines

  1. /*
  2.  *  File:        math_symbols.C
  3.  *  Purpose:     User interface to math symbols
  4.  *  Author:      Alejandro Aguilar Sierra <asierra@servidor.unam.mx>
  5.  *  Created:     November 1995
  6.  *  Version:     0.8 28/03/96
  7.  *  Description: Provides a GUI to introduce mathematical
  8.  *               symbols in lyx.
  9.  *
  10.  *  Dependencies: Xlib, XForms, Lyx
  11.  *
  12.  *  Copyright: (c) 1995, 1996, Alejandro Aguilar Sierra 
  13.  *
  14.  *   You are free to use and modify it under the terms of
  15.  *   the GNU General Public Licence version 2 or later.
  16.  */
  17.  
  18. #include <config.h>
  19. #include XPM_H_LOCATION
  20.  
  21. #ifdef __GNUG__
  22. #pragma implementation "math_panel.h"
  23. #endif
  24.  
  25. #include "lyx_main.h"
  26. #include "buffer.h"
  27. #include "BufferView.h"
  28. #include "minibuffer.h"
  29. #include "lyxrc.h"
  30. #include "lyxlib.h"
  31. #include "LyXView.h"
  32. #include "error.h"
  33.  
  34. #include "formula.h"
  35.  
  36. #include "math_panel.h"                 
  37. #include "math_parser.h"
  38.  
  39. //     $Id: math_symbols.C,v 1.1.1.1 1998/04/23 16:02:56 larsbj Exp $    
  40.  
  41. #if !defined(lint) && !defined(WITH_WARNINGS)
  42. static char vcid[] = "$Id: math_symbols.C,v 1.1.1.1 1998/04/23 16:02:56 larsbj Exp $";
  43. #endif /* lint */
  44.  
  45. extern void SmallUpdate(signed char);
  46. extern void BeforeChange();
  47. extern void Update(signed char);
  48. extern int UnlockInset(UpdatableInset*);
  49. extern short greek_kb_flag;
  50. extern MiniBuffer *minibuffer;
  51.  
  52. extern BufferView *current_view;
  53.  
  54. /* Bitmaps */
  55. #include "greek.xbm"
  56. #include "arrows.xbm"
  57. #include "brel.xbm"
  58. #include "bop.xbm"
  59. #include "misc.xbm"           
  60. #include "varsz.xbm"           
  61. #include "dots.xbm"
  62.  
  63. /* Latex code for those bitmaps */
  64. static char const *latex_greek[] =  {
  65.    "Gamma", "Delta", "Theta", "Lambda", "Xi", "Pi",
  66.    "Sigma", "Upsilon", "Phi", "Psi", "Omega",
  67.    "alpha", "beta", "gamma", "delta", "epsilon", "varepsilon", "zeta",
  68.    "eta", "theta", "vartheta", "iota", "kappa", "lambda", "mu",
  69.    "nu", "xi", "pi", "varpi", "rho", "sigma", "varsigma",
  70.    "tau", "upsilon", "phi", "varphi", "chi", "psi", "omega", ""
  71. };
  72.  
  73. static char const *latex_brel[] = {
  74.   "leq", "geq", "equiv", "models", 
  75.   "prec", "succ", "sim", "perp", 
  76.   "preceq", "succeq", "simeq", "mid", 
  77.   "ll", "gg", "asymp", "parallel", 
  78.   "subset", "supset", "approx", "smile", 
  79.   "subseteq", "supseteq", "cong", "frown", 
  80.   "sqsubseteq", "sqsupseteq", "doteq", "neq", 
  81.   "in", "ni", "propto", "notin", 
  82.   "vdash", "dashv", "bowtie", ""
  83. };
  84.  
  85. static char const* latex_arrow[] = {
  86.   "downarrow", "leftarrow", "Downarrow", "Leftarrow", 
  87.   "hookleftarrow", "rightarrow", "uparrow", "Rightarrow", "Uparrow",
  88.   "hookrightarrow","updownarrow", "Leftrightarrow", "leftharpoonup", 
  89.   "rightharpoonup", "rightleftharpoons", "leftrightarrow", "Updownarrow", 
  90.   "leftharpoondown", "rightharpoondown", "mapsto",
  91.   "Longleftarrow", "Longrightarrow", "Longleftrightarrow", 
  92.   "longleftrightarrow", "longleftarrow", "longrightarrow", "longmapsto",
  93.   "nwarrow", "nearrow", "swarrow", "searrow",  "",
  94. };
  95.  
  96. char const* latex_varsz[] = {
  97. "sum", "int", "oint", 
  98. "prod", "coprod", "bigsqcup", 
  99. "bigotimes", "bigodot", "bigoplus", 
  100. "bigcap", "bigcup", "biguplus", 
  101. "bigvee", "bigwedge", ""
  102. };
  103.  
  104. static char const* latex_bop[] = {   
  105.   "pm", "cap", "diamond", "oplus", 
  106.   "mp", "cup", "bigtriangleup", "ominus", 
  107.   "times", "uplus", "bigtriangledown", "otimes", 
  108.   "div", "sqcap", "triangleright", "oslash", 
  109.   "cdot", "sqcup", "triangleleft", "odot", 
  110.   "star", "vee", "amalg", "bigcirc", 
  111.   "setminus", "wedge", "dagger", "circ", 
  112.   "bullet", "wr", "ddagger", ""
  113. };
  114.  
  115. static char const* latex_misc[] = {
  116.   "nabla", "partial", "infty", "prime", "ell", 
  117.   "emptyset", "exists", "forall", "imath",  "jmath",
  118.   "Re", "Im", "aleph", "wp", "hbar", 
  119.   "angle", "top", "bot", "Vert", "neg", 
  120.   "flat", "natural", "sharp", "surd", "triangle", 
  121.   "diamondsuit", "heartsuit", "clubsuit", "spadesuit", "" 
  122. };
  123.  
  124. static char const* latex_dots[] = { 
  125.    "ldots", "cdots", "vdots", "ddots"
  126. };
  127.  
  128. static signed char latin2greek[] =  {
  129.   0, 1, 25, 3, 4, 23, 2, 7, 10, 24, 11, 12, 13, 14, -1, 16, 8, 18,
  130.   19, 21, 22, 17, 27, 15, 26, 6
  131. };
  132.  
  133. static signed char Latin2Greek[] =  {
  134.  -1, -1, -1, 1, -1, 8, 0, -1, -1, -1, -1, 3, -1, -1, -1,
  135.  5, 2, -1, 6, -1, 7, -1, 10, 4, 9, -1
  136. }; 
  137.  
  138. extern char** mathed_get_pixmap_from_icon(int d);
  139. static void math_cb(FL_OBJECT*, long);
  140. static char** pixmapFromBitmapData(char const *, int, int);
  141. void math_insert_symbol(char const* s);
  142. Bool math_insert_greek(char const c);
  143.  
  144. BitmapMenu *BitmapMenu::active = NULL;
  145.  
  146. BitmapMenu::BitmapMenu(int n,  FL_OBJECT* bt, BitmapMenu* prevx): nb(n)  {
  147.    w = h = 0;
  148.    form = 0;
  149.    i = 0;
  150.    ww = 2*FL_abs(FL_BOUND_WIDTH);
  151.    x = y = ww;
  152.    y += 8;
  153.    bitmap = new FL_OBJECTP[nb];
  154.    button = bt;
  155.    button->u_vdata = this;
  156.    prev = prevx;
  157.    next = NULL;
  158.    if (prev)
  159.      prev->next = this;
  160. }
  161.  
  162. BitmapMenu::~BitmapMenu() {
  163.  if (next) delete next;
  164.  fl_free_form(form);  
  165.  delete[] bitmap;
  166. }
  167.  
  168. void BitmapMenu::Hide()  {
  169.    fl_hide_form(form);
  170.    fl_set_button(button, 0);
  171.    active = NULL;
  172. }
  173.  
  174. void BitmapMenu::Show()  {
  175.    if (active)
  176.      active->Hide();
  177.    active = this;
  178.    int x = button->form->x + button->x, y = button->form->y + button->y;
  179.    fl_set_form_position(form, x, y + button->h);
  180.    fl_set_button(button, 1);
  181.    fl_show_form(form, FL_PLACE_POSITION, FL_NOBORDER, "");
  182. }
  183.  
  184. FL_OBJECT*
  185. BitmapMenu::AddBitmap(int id, int nx, int ny, int bw, int bh, unsigned char* data, Bool vert)
  186. {
  187.    if (i>=nb)
  188.      return NULL;
  189.    int wx=bw+ww/2, wy=bh+ww/2;
  190.    wx += (wx % nx);
  191.    wy += (wy % ny); 
  192.    FL_OBJECT *obj = fl_create_bmtable(1, x, y, wx, wy, "");   
  193.    fl_set_object_callback(obj, math_cb, id);
  194.    fl_set_object_lcol(obj, FL_BLUE);    
  195.    fl_set_object_boxtype(obj, FL_UP_BOX);   
  196.    fl_set_bmtable_data(obj, nx, ny, bw, bh, data);
  197.    if (vert) { 
  198.       y += wy + 8;
  199.       h = Maximum(y, h);
  200.       w = Maximum(x + wx + ww, w);
  201.    } else  {
  202.       x += wx + 8;
  203.       w = Maximum(x, w);
  204.       h = Maximum(y + wy + ww, h);
  205.    }
  206.    bitmap[i++] = obj;
  207.    return obj;
  208. }
  209.  
  210. void BitmapMenu::Create()
  211. {
  212.    if (i<nb)  {
  213.       fprintf(stderr, "Error: Bitmaps not created!");
  214.       return;
  215.    }
  216.    form = fl_bgn_form(FL_UP_BOX, w, h);   
  217.    for (i=0; i<nb; i++) {
  218.       fl_add_object(form, bitmap[i]);
  219.       bitmap[i]->u_vdata = this;
  220.    }
  221.    fl_end_form();
  222.    fl_register_raw_callback(form, KeyPressMask, peek_event);
  223. }
  224.  
  225. int BitmapMenu::GetIndex(FL_OBJECT* ob)
  226. {
  227.    if (active==this) {
  228.       int k = 0;
  229.       for (i=0; i<nb; i++) {
  230.      if (bitmap[i]==ob) 
  231.        return k+fl_get_bmtable(ob);
  232.      k += fl_get_bmtable_maxitems(bitmap[i]);
  233.       }
  234.    }
  235.    return -1;
  236. }
  237.  
  238. int peek_event(FL_FORM * /*form*/, void *xev)
  239. {
  240.    if (BitmapMenu::active==NULL)
  241.      return 0;
  242.   
  243.    if(((XEvent *)xev)->type == ButtonPress)
  244.    {
  245.      BitmapMenu::active->Hide();
  246.      return 1;
  247.    }
  248.    if(((XEvent *)xev)->type == KeyPress)
  249.    {
  250.       char c[5];
  251.       KeySym keysym;
  252.       XLookupString(&((XEvent *)xev)->xkey, &c[0], 5, &keysym, NULL);
  253.       if (keysym==XK_Left) 
  254.     BitmapMenu::active->Prev(); else
  255.       if (keysym==XK_Right) 
  256.     BitmapMenu::active->Next(); 
  257.       else 
  258.     BitmapMenu::active->Hide();
  259.       return 1;
  260.    }
  261.    return 0;  
  262. }
  263.  
  264. static void math_cb(FL_OBJECT* ob, long data)
  265. {
  266.    BitmapMenu* menu = (BitmapMenu*)ob->u_vdata;
  267.    int i = menu->GetIndex(ob);   
  268.    char const *s = 0;
  269.  
  270. //   fprintf(stderr, "data[%d]", data);     
  271.    if (i<0) return;
  272.    switch (data)  {
  273.     case MM_GREEK: 
  274.       s = latex_greek[i]; 
  275.       break;
  276.     case MM_ARROW: 
  277.       s = latex_arrow[i]; 
  278.       break;  
  279.     case MM_BRELATS: 
  280.       s = latex_brel[i]; 
  281.       break;  
  282.     case MM_BOP: 
  283.       s = latex_bop[i]; 
  284.       break;  
  285.     case MM_VARSIZE: 
  286.       s = latex_varsz[i];  
  287.       break;
  288.     case MM_MISC: 
  289.       s = latex_misc[i];  
  290.       break;
  291.     case MM_DOTS: 
  292. //      fprintf(stderr, "dots[%s %d]", latex_dots[i], i);
  293.       s = latex_dots[i-29];  
  294.       break;
  295.    }
  296.   
  297.    if (s)  {
  298.       if (current_view->available() && lyxrc->display_shortcuts) {
  299.       minibuffer->Set("Inserting symbol ", s);
  300.       }
  301.       current_view->getOwner()->getLyXFunc()->Dispatch(LFUN_INSERT_MATH, s);
  302.    }      
  303.    if (menu)  
  304.      menu->Hide(); 
  305. }
  306.  
  307. char** get_pixmap_from_symbol(char const *arg, int wx, int hx)
  308. {
  309.    char** data=NULL;               
  310.    latexkeys *l = in_word_set (arg, strlen(arg));
  311.    if (!l) 
  312.     return NULL;
  313.     
  314.    switch (l->token) {
  315.     case LM_TK_FRAC:
  316.       data = mathed_get_pixmap_from_icon(MM_FRAC);
  317.       break;
  318.     case LM_TK_SQRT: 
  319.       data = mathed_get_pixmap_from_icon(MM_SQRT);
  320.       break;
  321.     case LM_TK_BIGSYM:
  322.     case LM_TK_SYM:
  323.        // I have to use directly the bitmap data since the
  324.        // bitmap tables are not yet created when this
  325.        // function is called.
  326.        data = pixmapFromBitmapData(arg, wx, hx);
  327.        break;
  328.    }
  329.    
  330.    return data;
  331. }
  332.  
  333. Bool math_insert_greek(char const c)
  334. {
  335.    int i;
  336.    char const *s=NULL;
  337.    
  338.    if ('A'<=c && c<='Z') {
  339.       if ((i=Latin2Greek[c - 'A'])>=0)
  340.     s = latex_greek[i];
  341.    }   
  342.    if ('a'<=c && c<='z') {
  343.       if ((i=latin2greek[c - 'a'])>=0)
  344.     s = latex_greek[i+11];
  345.    }
  346.    if (s) {
  347.       math_insert_symbol(s);
  348.       if (greek_kb_flag<2) {
  349.      greek_kb_flag = 0;
  350.      UnlockInset(current_view->currentBuffer()->the_locking_inset);
  351.       }
  352.       return True;
  353.    } else
  354.      return False; 
  355. }
  356.  
  357. void math_insert_symbol(char const* s)
  358. {
  359.    if (current_view->available())   {
  360.       if (!current_view->currentBuffer()->the_locking_inset) {
  361.      InsetFormula* new_inset = new InsetFormula();
  362.      BeforeChange();
  363.      current_view->currentBuffer()->insertInset(new_inset);
  364. //     Update(1);//BUG
  365.      new_inset->Edit(0,0);
  366.      new_inset->InsertSymbol(s);
  367.       } else
  368.     if (current_view->currentBuffer()->the_locking_inset->LyxCode()==Inset::MATH_CODE)
  369.       ((InsetFormula*)current_view->currentBuffer()->the_locking_inset)->InsertSymbol(s);
  370.         else 
  371.       fprintf(stderr, "Math error: attempt to write on a wrong class of inset.\n");
  372.    }
  373. }
  374.  
  375. BitmapMenu* sym_menu=0;
  376.  
  377. void  create_symbol_menues(FD_panel *symb_form)
  378. {
  379.    FL_OBJECT* obj; 
  380.    BitmapMenu* menu;
  381.    
  382.    sym_menu = menu = new BitmapMenu(2, symb_form->greek);
  383.    obj = menu->AddBitmap(MM_GREEK, 6, 2, Greek_width, Greek_height, 
  384.                Greek_bits);         
  385.    fl_set_bmtable_maxitems(obj, 11);
  386.    obj = menu->AddBitmap(MM_GREEK, 7, 4, greek_width, greek_height,
  387.                greek_bits); 
  388.    menu->Create();
  389.    
  390.    menu = new BitmapMenu(1, symb_form->boperator, menu);
  391.    obj = menu->AddBitmap(MM_BOP, 4, 8, bop_width, bop_height,
  392.                          bop_bits);      
  393.    fl_set_bmtable_maxitems(obj, 31);
  394.    menu->Create();   
  395.       
  396.    menu = new BitmapMenu(1, symb_form->brelats, menu);
  397.    obj = menu->AddBitmap(MM_BRELATS, 4, 9, brel_width, brel_height, 
  398.              brel_bits);        
  399.    fl_set_bmtable_maxitems(obj, 35);       
  400.    menu->Create();
  401.    
  402.    menu = new BitmapMenu(3, symb_form->arrow, menu);
  403.    obj = menu->AddBitmap(MM_ARROW, 5, 4, arrow_width, arrow_height,
  404.              arrow_bits);
  405.    obj = menu->AddBitmap(MM_ARROW, 2, 4, larrow_width, larrow_height, 
  406.              larrow_bits, False);          
  407.    fl_set_bmtable_maxitems(obj, 7);
  408.    obj = menu->AddBitmap(MM_ARROW, 2, 2, darrow_width, darrow_height, 
  409.              darrow_bits);
  410.    menu->Create(); 
  411.      
  412.    menu = new BitmapMenu(1, symb_form->varsize, menu);
  413.     obj = menu->AddBitmap(MM_VARSIZE, 3, 5, varsz_width, varsz_height, 
  414.              varsz_bits);         
  415.    fl_set_bmtable_maxitems(obj, 14);
  416.    menu->Create();
  417.       
  418.    menu = new BitmapMenu(2, symb_form->misc, menu);
  419.      obj = menu->AddBitmap(MM_MISC, 5, 6, misc_width, misc_height,
  420.                misc_bits);         
  421.      fl_set_bmtable_maxitems(obj, 29);
  422.      obj = menu->AddBitmap(MM_DOTS, 4, 1, dots_width, dots_height, 
  423.                dots_bits);         
  424.    menu->Create();
  425. }
  426.  
  427. static
  428. char** pixmapFromBitmapData(char const *s, int wx, int hx)
  429. {
  430.     int i, id;
  431.     char** data=0;
  432.     
  433.     id=-1;
  434.     
  435.     for (i=0; i<6; i++) {
  436.     char const **latex_str = 0;
  437.     switch (i) {
  438.      case 0: latex_str = latex_greek; break;
  439.      case 1: latex_str = latex_bop; break;
  440.      case 2: latex_str = latex_brel; break;
  441.      case 3: latex_str = latex_arrow; break;
  442.      case 4: latex_str = latex_varsz; break;
  443.      case 5: latex_str = latex_misc; break;
  444.     }
  445.     
  446.     for (int k = 0; latex_str[k][0]>' '; k++) {
  447.         if (strcmp(latex_str[k], s)==0) {
  448.         id = k;
  449.         break;
  450.         }
  451.     }
  452.     if (id>=0) break;
  453.     }
  454.     if (i<6 && id>=0) {
  455.     unsigned char *bdata=0;
  456.     int w=0, h=0, dw=0, dh=0;
  457.  
  458.     lyxerr.debug(LString("Imando ") + int(i) + ", " + int(id), Error::MATHED);
  459.     switch (i) {
  460.      case 0: 
  461.         if (id<=10) {
  462.         w = Greek_width;
  463.         h = Greek_height;
  464.         bdata = Greek_bits;
  465.         dw = 6;  dh = 2;
  466.         } else {
  467.         w = greek_width;
  468.         h = greek_height;
  469.         bdata = greek_bits;
  470.         dw = 7;  dh = 4;
  471.         id -= 11;
  472.         }
  473.         break;
  474.      case 1:
  475.         w = bop_width;
  476.         h = bop_height;
  477.         bdata = bop_bits;
  478.         dw = 4;  dh = 8;
  479.         break;
  480.      case 2:
  481.         w = brel_width;
  482.         h = brel_height;
  483.         bdata = brel_bits;
  484.         dw = 4;  dh = 9;
  485.         break;
  486.      case 3:
  487.         if (id<20) {        
  488.         w = arrow_width;
  489.         h = arrow_height;
  490.         bdata = arrow_bits;
  491.         dw = 5;  dh = 4;
  492.         } else if (id>28) {        
  493.         w = darrow_width;
  494.         h = darrow_height;
  495.         bdata = darrow_bits;
  496.         dw = 2;  dh = 2;
  497.         id -= 29;
  498.         } else {        
  499.         w = larrow_width;
  500.         h = larrow_height;
  501.         bdata = larrow_bits;
  502.         dw = 2;  dh = 4;
  503.         id -= 20;
  504.         }
  505.         break;
  506.      case 4:
  507.         w = varsz_width;
  508.         h = varsz_height;
  509.         bdata = varsz_bits;
  510.         dw = 3;  dh = 5;
  511.         break;
  512.      case 5:
  513.         w = misc_width;
  514.         h = misc_height;
  515.         bdata = misc_bits;
  516.         dw = 5;  dh = 6;
  517.         break;
  518.     }
  519.     int ww = w/dw, hh = h/dh, x, y;
  520.    
  521.     XImage *xima = XCreateImage(fl_display, NULL, 1, XYBitmap, 0, 
  522.                     (char*)bdata, w, h, 8, 0);
  523.     xima->byte_order = LSBFirst;
  524.     xima->bitmap_bit_order = LSBFirst;
  525.     x = (id % dw)*ww;
  526.     y = (id/dw)*hh;
  527.     if (ww>wx) ww = wx;
  528.     if (hh>hx) hh = hx;
  529.     XImage *sbima = XSubImage(xima, x, y, ww, hh);
  530.     XpmCreateDataFromImage(fl_display, &data, sbima, sbima, 0);
  531.     
  532.     // Dirty hack to get blue symbols quickly
  533.     char *sx = strstr(data[2], "FFFFFFFF");
  534.     if (sx) {
  535.         for (int k=0; k<8; k++) sx[k] = '0';
  536.     }
  537.  
  538. //    XDestroyImage(xima);
  539.     }
  540.  
  541.     return data;
  542. }
  543.  
  544.