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