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