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_draw.C < prev    next >
C/C++ Source or Header  |  1998-04-23  |  9KB  |  367 lines

  1. /*
  2.  *  File:        math_draw.C
  3.  *  Purpose:     Interaction and drawing for mathed
  4.  *  Author:      Alejandro Aguilar Sierra <asierra@servidor.unam.mx> 
  5.  *  Created:     January 1996
  6.  *  Description: Math drawing and interaction for a WYSIWYG math editor.
  7.  *
  8.  *  Dependencies: Xlib, XForms
  9.  *
  10.  *  Copyright: (c) 1996, Alejandro Aguilar Sierra
  11.  *
  12.  *   Version: 0.8beta, Mathed & Lyx project.
  13.  *
  14.  *   You are free to use and modify this code under the terms of
  15.  *   the GNU General Public Licence version 2 or later.
  16.  */
  17.  
  18. #include <config.h>
  19. #include FORMS_H_LOCATION
  20. #include "math_cursor.h"
  21. #include "math_parser.h"
  22.  
  23. extern void mathed_set_font(short type, int style);
  24. extern int mathed_char_width(short type, int style, byte c);
  25. extern int mathed_string_width(short type, int style, byte const* s, int ls);
  26. extern int mathed_string_height(short, int, byte const*, int, int&, int&);
  27. extern int mathed_char_height(short, int, byte, int&, int&);
  28.    
  29. GC canvasGC=0, mathGC=0, mathLineGC=0, latexGC=0, cursorGC=0, mathFrameGC=0;
  30.  
  31.  
  32. long unsigned int MathedInset::pm;
  33.  
  34. void
  35. MathSpaceInset::Draw(int x, int y)
  36.  
  37. // XPoint p[4] = {{++x, y-3}, {x, y}, {x+width-2, y}, {x+width-2, y-3}};
  38.  
  39. // Sadly, HP-UX CC can't handle that kind of initialization.
  40.  
  41.    XPoint p[4];
  42.    p[0].x = ++x;    p[0].y = y-3;
  43.    p[1].x = x;        p[1].y = y;
  44.    p[2].x = x+width-2;    p[2].y = y;
  45.    p[3].x = x+width-2;    p[3].y = y-3;
  46.  
  47.    XDrawLines(fl_display,pm,(space) ? latexGC: mathGC,p,4,CoordModeOrigin);
  48.    XFlush(fl_display);
  49. }
  50.  
  51. void 
  52. MathParInset::Draw(int x, int y)
  53. {
  54.    byte cx, cxp=0;
  55.    int xp=0, ls;
  56.    int asc=df_asc, des=0;
  57.    bool limits = false;
  58.     
  59.    xo = x;  yo = y; 
  60.    if (!array || array->Empty()) {
  61.       mathed_set_font(LM_TC_VAR, 1);
  62.        if (array) {
  63.        MathedXIter data(this);
  64.        data.GetPos(x, y);
  65.        }
  66.       XDrawRectangle(fl_display,pm,mathLineGC,x,y-df_asc, df_width, df_asc);
  67.       XFlush(fl_display);
  68.       return;
  69.    }  
  70.    MathedXIter data(this);
  71.    data.GoBegin();
  72.    while (data.OK()) {
  73.       data.GetPos(x, y);
  74.       cx = data.GetChar();
  75.       if (cx >= ' ') {
  76.      byte *s = data.GetString(ls);
  77.       drawStr(data.FCode(), size, x, y, s, ls);
  78.       mathed_char_height(data.FCode(), size, s[ls-1], asc, des);
  79.       limits = false;
  80.       } else {
  81.       if (cx==0) break;
  82.      if (MathIsInset(cx)) {
  83.         int yy = y;
  84.         MathedInset *p = data.GetInset();
  85.         if (cx==LM_TC_UP) {
  86.            if (limits) {
  87.           x -= (xp>p->Width()) ? p->Width()+(xp-p->Width())/2: xp;  
  88.           yy -= (asc + p->Descent()+4);
  89.            } else
  90.           yy -= (p->Descent()>asc) ? p->Descent()+4: asc;
  91.         } else
  92.         if (cx==LM_TC_DOWN) {
  93.            if (limits) {
  94.           x -= (xp>p->Width()) ? p->Width()+(xp-p->Width())/2: xp;
  95.           yy += des + p->Ascent() + 2;
  96.            } else
  97.          yy += des + p->Ascent()/2;
  98.         } else {
  99.            asc = p->Ascent();
  100.            des = p->Descent();
  101.         }
  102.         p->Draw(x, yy);
  103.         if (cx!=LM_TC_UP && cx!=LM_TC_DOWN) {
  104.            limits = p->GetLimits();
  105.            if (limits) xp = p->Width();
  106.         }
  107.         data.Next();
  108.      } else 
  109.        if (cx==LM_TC_TAB) {
  110.            if ((cxp==cx || cxp==LM_TC_CR || data.IsFirst())) { // && objtype==L
  111.            XDrawRectangle(fl_display,pm,mathLineGC,
  112.                   x,y-df_asc, df_width, df_asc);
  113.            }
  114.        
  115.           XFlush(fl_display);
  116.           data.Next();
  117.           limits = false;
  118.        } else
  119.         if (cx==LM_TC_CR) {
  120.         if (cxp==LM_TC_TAB || cxp==LM_TC_CR || data.IsFirst()) { //  && objtype==LM_OT_MATRIX) {
  121.           XDrawRectangle(fl_display,pm,mathLineGC,x,y-df_asc, df_width, df_asc);
  122.         }
  123.         data.Next();
  124.         limits = false;
  125.         }
  126.      else {     
  127.         fprintf(stderr, "GMathed Error: Unrecognized code[%d]\n", cx);
  128.         break;
  129.      }
  130.       }
  131.       cxp = cx;
  132.    }
  133.    if (cxp==LM_TC_TAB || cxp==LM_TC_CR) { // && objtype==LM_OT_MATRIX) {
  134.       data.GetPos(x, y);
  135.       XDrawRectangle(fl_display,pm,mathLineGC,x,y-df_asc, df_width, df_asc);
  136.       XFlush(fl_display);
  137.    }
  138. }
  139.  
  140.  
  141. void 
  142. MathParInset::Metrics()
  143. {
  144.     byte cx, cxp=0, *s;
  145.     int ls;
  146.     int asc=df_asc, des=0;
  147.     int tb = 0, tab=0;
  148.  
  149.     bool limits = false;
  150.     
  151.     ascent = df_asc;//mathed_char_height(LM_TC_VAR, size, 'I', asc, des); 
  152.     width = df_width;
  153.     descent = 0;
  154.     if (!array) return;
  155.     if (array->Empty()) return;
  156.     
  157.     ascent = 0;
  158.     MathedXIter data(this);
  159.     data.GoBegin();
  160.     while (data.OK()) {
  161.     cx = data.GetChar();      
  162.     if (cx >= ' ') {
  163.         s = data.GetString(ls);
  164.         mathed_string_height(data.FCode(), size, s, ls, asc, des);
  165.         if (asc > ascent) ascent = asc;
  166.         if (des > descent) descent = des;
  167.         limits = false;
  168.     } else
  169.       if (MathIsInset(cx)) {
  170.           MathedInset *p = data.GetInset();
  171.           p->SetStyle(size);   
  172.           p->Metrics();
  173.           if (cx==LM_TC_UP) {
  174.           asc += (limits) ? p->Height()+4: p->Ascent() + 
  175.             ((p->Descent()>asc) ? p->Descent()-asc+4: 0);
  176.           } else
  177.         if (cx==LM_TC_DOWN) {
  178.             des += ((limits) ? p->Height()+4: p->Height()-p->Ascent()/2);
  179.         } else {
  180.             asc = p->Ascent();
  181.             des = p->Descent();
  182.         }
  183.           if (asc > ascent) ascent = asc;
  184.           if (des > descent) descent = des;
  185.           if (cx!=LM_TC_UP && cx!=LM_TC_DOWN)
  186.         limits = p->GetLimits();
  187.           data.Next();
  188.       } else 
  189.       if (cx==LM_TC_TAB) {
  190.           int x, y;
  191.           data.GetIncPos(x, y);
  192.           if (data.IsFirst() || cxp==LM_TC_TAB || cxp==LM_TC_CR) {
  193.           if (ascent<df_asc) ascent = df_asc;
  194.           tb = x;
  195.           }
  196.           data.setTab(x-tb, tab);
  197.           tb = x;
  198.           tab++;
  199.           limits = false;                   
  200.           data.Next();
  201.       } else
  202.       if (cx==LM_TC_CR) {
  203.           if (tb>0) {
  204.           int x, y;
  205.           data.GetIncPos(x, y);
  206.           if (data.IsFirst() || cxp==LM_TC_TAB || cxp==LM_TC_CR) {
  207.               if (ascent<df_asc) ascent = df_asc;
  208.               tb = x;
  209.           } 
  210.           data.setTab(x-tb, tab);
  211.           } else //if (GetColumns()==1) 
  212.             {
  213.           int x, y;
  214.           data.GetIncPos(x, y);
  215.           data.setTab(x, tab);
  216.           if (ascent<df_asc) ascent = df_asc;
  217.           } 
  218.           tb=tab=0;
  219.           data.subMetrics(ascent, descent);
  220.           ascent = df_asc;   
  221.           descent = 0;
  222.           data.Next();
  223.       }      
  224.     else {
  225.         fprintf(stderr, "Mathed Error: Unrecognized code[%d]\n", cx);
  226.         break;
  227.     }       
  228.     cxp = cx;
  229.     }
  230.     data.GetIncPos(width, ls);
  231.     
  232.     // No matter how simple is a matrix, it is NOT a subparagraph
  233.     if (isMatrix()) {
  234.     if (cxp==LM_TC_TAB) {
  235.         if (ascent<df_asc) ascent = df_asc;
  236.         data.setTab(0, tab);
  237.     } else {
  238.       data.setTab(width-tb, tab);
  239.     }
  240.     }
  241.           
  242.     data.subMetrics(ascent, descent);
  243. }
  244.  
  245.  
  246. void
  247. MathSqrtInset::Draw(int x, int y)
  248.    MathParInset::Draw(x+hmax+2, y); 
  249.    int h=ascent, d=descent, h2=Height()/2, w2 = (Height()>4*hmax)?hmax:hmax/2; 
  250.    XPoint p[4];
  251.    p[0].x = x+width-1, p[0].y = y-h;
  252.    p[1].x = x+hmax,    p[1].y = y-h;
  253.    p[2].x = x+w2,      p[2].y = y+d;
  254.    p[3].x = x,         p[3].y = y+d-h2;
  255.    XDrawLines(fl_display, pm, mathLineGC,p, 4, CoordModeOrigin);
  256.    XFlush(fl_display);
  257. }
  258.  
  259. void
  260. MathSqrtInset::Metrics()
  261. {
  262.    MathParInset::Metrics();
  263.    ascent += 4;
  264.    descent += 2;
  265.    int a, b;
  266.    hmax = mathed_char_height(LM_TC_VAR, size, 'I',a, b);
  267.    if (hmax<10) hmax = 10;
  268.    width += hmax + 4;
  269. }
  270.  
  271. void
  272. MathFracInset::Draw(int x, int y)
  273.     short idxp = idx;
  274.     short sizex = size;
  275.     
  276.     idx = 0;
  277.     if (size==LM_ST_DISPLAY) size++;
  278.     MathParInset::Draw(x+(width-w0)/2, y - des0);
  279.     den->Draw(x+(width-w1)/2, y + den->Ascent() + 2 - dh);
  280.     size = sizex;
  281.     if (objtype==LM_OT_FRAC)
  282.       XDrawLine(fl_display, pm, mathLineGC, x+2, y-dh, x+width-4, y - dh);
  283.     XFlush(fl_display);
  284.     idx = idxp;
  285. }
  286.  
  287. void
  288. MathFracInset::Metrics()
  289. {
  290.     if (!dh) {
  291.     int a, b;
  292.     dh = mathed_char_height(LM_TC_CONST, size, 'I', a, b)/2;
  293.     }
  294.     short idxp = idx;
  295.     short sizex = size; 
  296.     idx = 0;
  297.     if (size==LM_ST_DISPLAY) size++; 
  298.     MathParInset::Metrics();
  299.     size = sizex;
  300.     w0 = width;
  301.     int as = Height() + 2 + dh;
  302.     des0 = Descent() + 2 + dh;
  303.     den->Metrics();  
  304.     w1 = den->Width();   
  305.     width = ((w0 > w1) ? w0: w1) + 12;
  306.     ascent = as; 
  307.     descent = den->Height()+ 2 - dh;
  308.     idx = idxp;
  309. }
  310.  
  311.  
  312. void
  313. MathBigopInset::Draw(int x, int y)
  314. {
  315.    int ls;
  316.    char c;
  317.    char const *s;
  318.    short t;
  319.    
  320.    if (sym<256 || sym==LM_oint) {
  321.       ls = 1;
  322.       c = (sym==LM_oint) ? LM_int: sym;
  323.       s = &c;
  324.       t = LM_TC_BSYM;
  325.    } else {
  326.       s = name;
  327.       ls = strlen(name);
  328.       t = LM_TC_TEXTRM;
  329.    }
  330.    mathed_set_font(t, size);
  331.    if (sym==LM_oint) {
  332.       XDrawArc(fl_display, pm, mathLineGC, x,y-5*width/4,width,width,0,23040);
  333.       XFlush(fl_display);
  334.       x++;
  335.    }
  336.    XDrawString(fl_display, pm, mathGC, x, y, s, ls);
  337.    XFlush(fl_display);
  338. }
  339.  
  340. void
  341. MathBigopInset::Metrics()
  342. {   
  343.    int ls;
  344.    char c;
  345.    char const *s;
  346.    short t;
  347.  
  348.    if (sym<256 || sym==LM_oint) {
  349.       ls = 1;
  350.       c = (sym==LM_oint) ? LM_int: sym;
  351.       s = &c;
  352.       t = LM_TC_BSYM;
  353.    } else {
  354.       s = name;
  355.       ls = strlen(name);
  356.       t = LM_TC_TEXTRM;
  357.    }
  358.    mathed_set_font(t, size);
  359.    mathed_string_height(t, size, (unsigned char const *)s, ls, ascent, descent);
  360.    width = mathed_string_width(t, size, (unsigned char const *)s, ls);
  361.    if (sym==LM_oint) width += 2;
  362. }
  363.  
  364.