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