]> git.lyx.org Git - features.git/blob - src/mathed/math_defs.h
my changes during the holidyas...i expect some compilers to have some problems, but...
[features.git] / src / mathed / math_defs.h
1 // -*- C++ -*-
2 /*
3  *  File:        math_defs.h
4  *  Purpose:     Math editor definitions 
5  *  Author:      Alejandro Aguilar Sierra <asierra@servidor.unam.mx> 
6  *  Created:     January 1996
7  *  Description: Math paragraph and objects for a WYSIWYG math editor.
8  *
9  *  Dependencies: Xlib
10  *
11  *  Copyright: (c) 1996, 1997 Alejandro Aguilar Sierra
12  *
13  *   Version: 0.8beta, Mathed & Lyx project.
14  *
15  *   You are free to use and modify this code under the terms of
16  *   the GNU General Public Licence version 2 or later.
17  * 
18  */
19
20 #ifndef MATH_DEFS
21 #define MATH_DEFS
22
23 #ifdef __GNUG__
24 #pragma interface
25 #endif
26
27 #include "LString.h"
28 #include "debug.h"
29
30 #include "array.h"
31
32 ///
33 enum math_align {
34         ///
35         MATH_ALIGN_LEFT = 1,
36         ///
37         MATH_ALIGN_RIGHT = 2,
38         ///
39         MATH_ALIGN_BOTTOM = 4,
40         ///
41         MATH_ALIGN_TOP = 8
42 };
43 ///
44 #define MATH_COLSEP 8
45 ///
46 #define MATH_ROWSEP 8
47
48
49 /// Standard Math Sizes (Math mode styles)
50 enum MathedStyles {
51         ///
52         LM_ST_DISPLAY = 0,
53         ///
54         LM_ST_TEXT,
55         ///
56         LM_ST_SCRIPT,
57         ///
58         LM_ST_SCRIPTSCRIPT
59 };
60
61
62 /// Standard LaTeX Math Environments
63 enum MathedEnvironment {
64         ///
65         LM_EN_INTEXT = 0,
66         ///
67         LM_EN_DISPLAY,
68         ///
69         LM_EN_EQUATION,
70         ///
71         LM_EN_EQNARRAYAST,
72         ///
73         LM_EN_EQNARRAY,
74         ///
75         LM_EN_ARRAY
76 };
77
78
79 /** The restrictions of a standard LaTeX math paragraph
80   allows to get a small number of text codes (<30) */
81 enum MathedTextCodes  {
82         /// This must be >= 0
83         LM_TC_MIN = 0,
84         /// Open and Close group
85         LM_TC_OPEN,
86         ///
87         LM_TC_CLOSE,
88         /// Tabulator
89         LM_TC_TAB,
90         /// New line
91         LM_TC_CR,
92         /// Math Inset
93         LM_TC_INSET,
94         /// Super and sub scripts
95         LM_TC_UP,
96         ///
97         LM_TC_DOWN,
98         /// Editable Math Inset
99         LM_TC_ACTIVE_INSET,
100         /// Editable Text Inset
101         LM_TC_TEXT_INSET,
102         ///
103         LM_FONT_BEGIN,
104         /// Internal code for constants
105         LM_TC_CONST,
106         /// Internal code for variables
107         LM_TC_VAR,
108         ///
109         LM_TC_RM,
110         ///
111         LM_TC_CAL,
112         ///
113         LM_TC_BF,
114         ///
115         LM_TC_SF,
116         ///
117         LM_TC_TT,
118         ///
119         LM_TC_IT,
120         ///
121         LM_TC_TEXTRM,
122         /// Math mode TeX characters ",;:{}"
123         LM_TC_TEX,
124         /// Special characters "{}&#_%"
125         LM_TC_SPECIAL,
126         /// Internal code for operators
127         LM_TC_BOP,
128         /// Internal code for symbols
129         LM_TC_SYMB,
130         ///
131         LM_TC_BOPS,
132         ///
133         LM_TC_BSYM,
134         ///
135         LM_FONT_END,
136         
137         /// This must be < 32 
138         LM_TC_MAX
139 };
140
141 ostream & operator<<(ostream &, MathedTextCodes mtc);
142
143 ///
144 #define LM_TC_NORMAL LM_TC_VAR
145  
146        
147 /// Types of lyx-math insets 
148 enum MathedInsetTypes  {
149         ///
150         LM_OT_MIN = 0,
151         /// A simple paragraph
152         LM_OT_PAR,
153         /// A simple numbered paragraph
154         LM_OT_PARN,
155         /// A multiline paragraph
156         LM_OT_MPAR,
157         /// A multiline numbered paragraph
158         LM_OT_MPARN,
159         /// An array
160         LM_OT_MATRIX,
161         /// A big operator
162         LM_OT_BIGOP,
163         /// A LaTeX macro
164         LM_OT_UNDEF,
165         ///
166         LM_OT_FUNC,
167         ///
168         LM_OT_FUNCLIM,
169         ///
170         LM_OT_SCRIPT,
171         ///
172         LM_OT_SPACE,
173         ///
174         LM_OT_DOTS,
175         /// A fraction
176         LM_OT_FRAC,
177         ///
178         LM_OT_ATOP,
179         ///
180         LM_OT_STACKREL,
181         /// A radical
182         LM_OT_SQRT,
183         /// A delimiter
184         LM_OT_DELIM,
185         /// A decoration
186         LM_OT_DECO,
187         /// An accent
188         LM_OT_ACCENT,
189         ///
190         LM_OT_MACRO,
191         ///
192         LM_OT_MACRO_ARG,
193         ///
194         LM_OT_MAX
195 };
196
197 ///
198 enum MathedBinaryTypes {
199         ///
200         LMB_NONE = 0,
201         ///
202         LMB_RELATION,
203         ///
204         LMB_OPERATOR,
205         ///
206         LMB_BOP = (LMB_RELATION | LMB_OPERATOR)
207 };
208
209 class MathParInset;
210
211 /** Abstract base class for all math objects.
212     A math insets is for use of the math editor only, it isn't a
213     general LyX inset. It's used to represent all the math objects.
214     The formulaInset (a LyX inset) encapsulates a math inset.
215  */
216 class MathedInset  {
217  public: 
218     /// A math inset has a name (usually its LaTeX name), type and font-size
219     MathedInset(char const * nm, short ot, short st);
220     ///
221     MathedInset(MathedInset *);
222     ///
223     virtual ~MathedInset() {}
224     
225     /// Draw the object 
226     virtual void Draw(int x, int baseline) = 0;
227
228     /// Write LaTeX and Lyx code
229     virtual void Write(ostream &) = 0;
230
231     /// Write LaTeX and Lyx code
232     virtual void Write(string & file) = 0;
233    
234     /// Reproduces itself
235     virtual MathedInset * Clone() = 0;
236    
237     /// Compute the size of the object
238     virtual void Metrics() = 0; 
239     /// 
240     virtual int Ascent() const { return ascent; }
241     ///
242     virtual int Descent() const { return descent; }
243     ///
244     virtual int Width() const { return width; }
245     ///
246     virtual int Height() const { return ascent + descent; }
247     
248     ///
249     virtual bool GetLimits() const { return false; }
250     ///
251     virtual void SetLimits(bool) {}   
252    
253     ///
254     char const * GetName() const { return name; }
255     ///
256     short GetType() const { return objtype; }
257     ///
258     short GetStyle() const { return size; }
259           
260     //Man:  Avoid to use these functions if it's not strictly necessary 
261     ///
262     virtual void  SetType(short t) { objtype = t; }
263     ///
264     virtual void  SetStyle(short st) { size = st; } // Metrics();
265     ///
266     virtual void  SetName(char const * n) { name = n; }
267     /// 
268     void setDrawable(long unsigned int d) { pm = d; }
269  
270  protected:
271     ///
272     char const * name;
273     ///
274     short objtype;
275     ///
276     int width;
277     ///
278     int ascent;
279     ///
280     int descent;
281     ///
282     short size;
283     /// This works while only one process can draw unless
284     /// the process have their own data
285     static long unsigned int pm;
286     /// Default metrics
287     static int df_asc, df_des, df_width;
288
289     /// In a near future maybe we use a better fonts renderer than X
290     void drawStr(short, int, int, int, byte *, int);
291         ///
292     friend class MathedCursor;
293         ///
294     friend void mathed_init_fonts();
295 };
296
297 struct MathedRowSt;
298
299
300 /// Paragraph permissions
301 enum MathedParFlag {
302         LMPF_BASIC = 0,
303         /// If false can use a non-standard size
304         LMPF_FIXED_SIZE = 1,
305         /// If true can insert newlines 
306         LMPF_ALLOW_CR  = 2,
307         /// If true can use tabs
308         LMPF_ALLOW_TAB = 4,
309         /// If true can insert new columns
310         LMPF_ALLOW_NEW_COL = 8,
311         /// Smaller than current size (frac)
312         LMPF_SMALLER = 16,
313         /// Script size (subscript, stackrel)
314         LMPF_SCRIPT = 32
315 };
316
317
318 /** The math paragraph base class, base to all editable math objects */
319 class MathParInset: public MathedInset  {
320  public: 
321     ///
322     MathParInset(short st = LM_ST_TEXT, char const * nm = 0,
323                  short ot = LM_OT_MIN);
324     ///
325     MathParInset(MathParInset *);
326     ///
327     virtual ~MathParInset();
328     ///
329     virtual MathedInset * Clone();
330
331     /// Draw the object on a drawable
332     virtual void Draw(int x, int baseline);
333
334     /// Write LaTeX code
335     virtual void Write(ostream &);
336
337     /// Write LaTeX code
338     virtual void Write(string & file);
339     ///
340     virtual void Metrics();
341     ///
342     virtual void UserSetSize(short);
343  
344     /// Data is stored in a LyXArray
345     virtual void SetData(LyxArrayBase *);
346     ///
347     virtual LyxArrayBase * GetData() { return array; }
348
349     /// Paragraph position
350     virtual void GetXY(int &, int &) const;
351     ///
352     virtual void setXY(int x, int y) { xo = x;  yo = y; }
353     ///
354     virtual void SetFocus(int, int) {}
355     ///
356     virtual bool Inside(int, int);   
357    
358     // Tab stuff used by Matrix.
359     ///
360     virtual void SetAlign(char, char const *) {}
361 //    ///
362 //    virtual int GetTabPos() { return 0; }
363 //    ///
364 //    virtual int GetTab(int) { return 0; }
365     ///
366     virtual int GetColumns() { return 1; }
367     ///
368     virtual int GetRows() { return 1; }
369     ///
370     virtual bool isMatrix() { return false; }
371 //    /// These functions should report an error
372 //    virtual char const* GetLabel() { return 0; }
373 //    virtual char const* GetLabel(int) { return 0; }
374
375     // Vertical switching
376     ///
377     virtual bool setArgumentIdx(int i) { return (i == 0); }
378     ///
379     virtual bool setNextArgIdx() { return false; }
380     ///
381     virtual int  getArgumentIdx() { return 0; }
382     ///
383     virtual int  getMaxArgumentIdx() { return 0; }
384 //    ///
385 //    virtual void SetLabel(char const *) {}
386     ///
387     virtual void SetStyle(short);
388         ///
389     virtual MathedRowSt * getRowSt() const { return 0; }
390         ///
391     virtual void setRowSt(MathedRowSt *) {}
392         ///
393     virtual bool Permit(short f) { return bool(f & flag); }
394     
395  protected:
396     /// Paragraph data is stored here
397     LyxArrayBase * array;
398     /// Cursor start position
399     int xo, yo;
400     /// 
401     short flag;
402
403  private:
404     ///
405     virtual void setFlag(MathedParFlag f) { flag |= f; }
406         ///
407     friend class InsetFormula;
408         ///
409     friend class MathedXIter;
410         ///
411     friend class MathedCursor;
412         ///
413     friend LyxArrayBase * mathed_parse(unsigned flags = 0,
414                                        LyxArrayBase * a = 0,
415                                        MathParInset ** p = 0);
416 };
417
418
419 /* The physical structure of a row and aditional information is stored here.
420     It allows to manage the extra info independently of the paragraph data.  
421     Only used for multiline paragraphs.
422  */
423 struct MathedRowSt {    
424     /// 
425     MathedRowSt(int n) {
426             w = new int[n + 1]; // this leaks
427             asc = desc = y = 0;
428             for (int i = 0 ; i < n + 1 ; ++i)
429               w[i] = 0;
430             next = 0;
431             label = 0;
432             numbered = true;
433     }
434     ///
435     ~MathedRowSt() {
436         delete[] w;
437         if (label) delete[] label;
438     }
439     /// Should be const but...
440     MathedRowSt * getNext() const  { return next; }
441     /// ...we couldn't use this.
442     void setNext(MathedRowSt * n) { next = n; }
443     ///
444     char const * getLabel() const { return label; }
445     ///
446     bool isNumbered() const { return numbered; }
447     ///
448     int  getBaseline() const { return y; }    
449     ///
450     int  getTab(int i) { return w[i]; }
451     /// 
452     void setLabel(char * l) { label = l; }
453     ///
454     void setNumbered(bool nf) { numbered = nf; }
455     ///
456     void setTab(int i, int t) { w[i] = t; }
457     
458  private:
459     /// Vericals 
460     int asc, desc, y;
461     /// widths 
462     int * w;
463     /// 
464     char * label;
465     ///
466     bool numbered;
467     ///
468     MathedRowSt * next;
469         ///
470     friend class MathMatrixInset;
471         ///
472     friend class MathedXIter;
473 };
474
475
476 /** Multiline math paragraph base class.
477     This is the base to all multiline editable math objects
478     like array and eqnarray. 
479  */
480 class MathMatrixInset: public MathParInset {
481  public: 
482     ///
483     MathMatrixInset(int m = 1, int n = 1, short st = LM_ST_TEXT);
484     ///
485     MathMatrixInset(MathMatrixInset *);
486     ///
487     MathedInset * Clone();
488     ///
489     virtual ~MathMatrixInset();
490     ///
491     void Draw(int, int);
492     ///
493     void Write(ostream &);
494     ///
495     void Write(string & file);
496     ///
497     void Metrics();
498     ///
499     void SetData(LyxArrayBase *);
500     ///
501     void SetAlign(char, char const *);
502     ///
503     char * GetAlign(char * vv) {
504         *vv = v_align;
505         return h_align;
506     }
507 //    ///
508 //    int GetTab(int);
509     ///
510     int GetColumns() { return nc; }
511     ///
512     int GetRows() { return nr; }
513     ///
514     virtual bool isMatrix() { return true; }
515
516     /// Use this to manage the extra information independently of paragraph
517     MathedRowSt * getRowSt() const { return row; }
518         ///
519     void setRowSt(MathedRowSt * r) { row = r; }
520     
521  protected:
522     ///  Number of columns & rows
523     int nc, nr;
524     /// tab sizes
525     int * ws;   
526     /// 
527     char v_align; // add approp. signedness
528     ///
529     char * h_align;
530     /// Vertical structure
531     MathedRowSt * row;
532
533 };
534
535
536
537 /*************************  Prototypes  **********************************/
538 /// 
539 LyxArrayBase * mathed_parse(unsigned flags, LyxArrayBase * data,
540                             MathParInset ** mt);
541 ///
542 void mathed_write(MathParInset *, ostream &, int *, char fragile,
543                   char const * label = 0);
544
545 ///
546 void mathed_write(MathParInset *, string &, int *, char fragile,
547                   char const * label = 0);
548 ///
549 void mathed_parser_file(istream &, int);
550 ///
551 int mathed_parser_lineno();
552 ///
553 int MathedLookupBOP(short);
554
555 /************************ Inline functions ********************************/
556 ///
557 inline bool MathIsInset(short x)
558 {
559         return LM_TC_INSET <= x && x <= LM_TC_ACTIVE_INSET;
560 }
561
562 ///
563 inline bool MathIsFont(short x)
564 {
565         return LM_TC_CONST <= x && x <= LM_TC_BSYM;
566 }
567
568 ///
569 inline bool MathIsAlphaFont(short x)
570 {
571         return LM_TC_VAR <= x && x <= LM_TC_TEXTRM;
572 }
573
574 ///
575 inline bool MathIsActive(short x)
576 {
577         return LM_TC_INSET < x && x <= LM_TC_ACTIVE_INSET;
578 }
579
580 ///
581 inline bool MathIsUp(short x)
582 {
583         return x == LM_TC_UP;
584 }
585
586 ///
587 inline bool MathIsDown(short x)
588 {
589         return x == LM_TC_DOWN;
590 }
591
592 ///
593 inline bool MathIsScript(short x)
594 {
595         return x == LM_TC_DOWN || x == LM_TC_UP;
596 }
597
598 ///
599 inline bool MathIsBOPS(short x)
600 {
601         return MathedLookupBOP(x) > LMB_NONE;
602 }
603
604
605 ///
606 inline bool MathIsBinary(short x)
607 {
608     return x == LM_TC_BOP || x == LM_TC_BOPS;
609 }
610
611 ///
612 inline bool MathIsSymbol(short x) {
613     return LM_TC_SYMB <= x && x <= LM_TC_BSYM;
614 }
615      
616
617 inline 
618 MathedInset::MathedInset(char const * nm, short ot, short st):
619   name(nm), objtype(ot), size(st) 
620 {
621    width = ascent = descent = 0;
622 }
623
624 inline
625 bool MathParInset::Inside(int x, int y) 
626 {
627   return (x >= xo && x <= xo + width && y <= yo + descent && y >= yo - ascent);
628 }
629
630
631 inline
632 void MathParInset::GetXY(int & x, int & y) const
633 {
634    x = xo; y = yo;
635 }
636
637
638 inline
639 void MathParInset::UserSetSize(short sz)
640 {
641    if (sz >= 0) {
642        size = sz;      
643        flag = flag & ~LMPF_FIXED_SIZE;
644    }
645 }
646
647
648 inline
649 void MathParInset::SetStyle(short sz) 
650 {
651     if (Permit(LMPF_FIXED_SIZE)) {
652         if (Permit(LMPF_SCRIPT)) 
653           sz = (sz < LM_ST_SCRIPT) ? LM_ST_SCRIPT: LM_ST_SCRIPTSCRIPT;
654         if (Permit(LMPF_SMALLER) && sz < LM_ST_SCRIPTSCRIPT) {
655             ++sz;
656         } 
657         MathedInset::SetStyle(sz);
658     }
659 }
660
661 #endif