]> git.lyx.org Git - lyx.git/blob - src/mathed/math_defs.h
plug a memleak in mathed + small cleanup
[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 /// 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 ///
146 std::ostream & operator<<(std::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(string const & nm, short ot, short st);
225     ///
226     explicit
227     MathedInset(MathedInset *);
228     ///
229     virtual ~MathedInset() {}
230
231     /// Draw the object
232     virtual void draw(Painter &, int x, int baseline) = 0;      
233
234     /// Write LaTeX and Lyx code
235     virtual void Write(std::ostream &, bool fragile) = 0;
236
237     /// Reproduces itself
238     virtual MathedInset * Clone() = 0;
239    
240     /// Compute the size of the object
241     virtual void Metrics() = 0; 
242     /// 
243     virtual int Ascent() const { return ascent; }
244     ///
245     virtual int Descent() const { return descent; }
246     ///
247     virtual int Width() const { return width; }
248     ///
249     virtual int Height() const { return ascent + descent; }
250     
251     ///
252     virtual bool GetLimits() const { return false; }
253     ///
254     virtual void SetLimits(bool) {}   
255    
256     ///
257     string const & GetName() const { return name; }
258     ///
259     short GetType() const { return objtype; }
260     ///
261     short GetStyle() const { return size; }
262           
263     //Man:  Avoid to use these functions if it's not strictly necessary 
264     ///
265     virtual void  SetType(short t) { objtype = t; }
266     ///
267     virtual void  SetStyle(short st) { size = st; } // Metrics();
268     ///
269     virtual void  SetName(string const & n) { name = n; }
270  protected:
271     ///
272     string name;
273     ///
274     short objtype;
275     ///
276     int width;
277     ///
278     int ascent;
279     ///
280     int descent;
281     ///
282     short size;
283     /// Default metrics
284     static int df_asc;
285     ///
286     static int df_des;
287     ///
288     static int df_width;
289     /// In a near future maybe we use a better fonts renderer than X
290     void drawStr(Painter &, short, int, int, int, byte const *, 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, string const & nm = string(),
323                  short ot = LM_OT_MIN);
324     ///
325     explicit
326     MathParInset(MathParInset *);
327     ///
328     virtual ~MathParInset();
329     ///
330     virtual MathedInset * Clone();
331
332     /// Draw the object on a drawable
333     virtual void draw(Painter &, int x, int baseline);
334
335     /// Write LaTeX code
336     virtual void Write(std::ostream &, bool fragile);
337
338     ///
339     virtual void Metrics();
340     ///
341     virtual void UserSetSize(short);
342  
343     /// Data is stored in a LyXArray
344     virtual void SetData(LyxArrayBase *);
345     ///
346     virtual LyxArrayBase * GetData() { return array; }
347
348     /// Paragraph position
349     virtual void GetXY(int &, int &) const;
350     ///
351     virtual void setXY(int x, int y) { xo = x;  yo = y; }
352     ///
353     virtual void SetFocus(int, int) {}
354     ///
355     virtual bool Inside(int, int);   
356    
357     // Tab stuff used by Matrix.
358     ///
359     virtual void SetAlign(char, string const &) {}
360     ///
361     virtual int GetColumns() const { return 1; }
362     ///
363     virtual int GetRows() const { return 1; }
364     ///
365     virtual bool isMatrix() const { return false; }
366     // Vertical switching
367     ///
368     virtual bool setArgumentIdx(int i) { return (i == 0); }
369     ///
370     virtual bool setNextArgIdx() { return false; }
371     ///
372     virtual int getArgumentIdx() const { return 0; }
373     ///
374     virtual int getMaxArgumentIdx() const { return 0; }
375     ///
376     virtual void SetStyle(short);
377     ///
378     virtual MathedRowSt * getRowSt() const { return 0; }
379     ///
380     virtual void setRowSt(MathedRowSt *) {}
381     ///
382     virtual bool Permit(short f) { return bool(f & flag); }
383     
384  protected:
385     /// Paragraph data is stored here
386     LyxArrayBase * array;
387     /// Cursor start position
388     int xo;
389     ///
390     int yo;
391     /// 
392     short flag;
393
394  private:
395     ///
396     virtual void setFlag(MathedParFlag f) { flag |= f; }
397     ///
398     friend class InsetFormula;
399     ///
400     friend class MathedXIter;
401     ///
402     friend class MathedCursor;
403     ///
404     friend LyxArrayBase * mathed_parse(unsigned flags = 0,
405                                        LyxArrayBase * a = 0,
406                                        MathParInset ** p = 0);
407 };
408
409
410 /** The physical structure of a row and aditional information is stored here.
411     It allows to manage the extra info independently of the paragraph data.  
412     Only used for multiline paragraphs.
413  */
414 struct MathedRowSt {    
415     ///
416     explicit
417     MathedRowSt(int n) {
418             w = new int[n + 1]; // this leaks
419             asc = desc = y = 0;
420             for (int i = 0 ; i < n + 1 ; ++i)
421               w[i] = 0;
422             next = 0;
423             numbered = true;
424     }
425     ///
426     ~MathedRowSt() {
427             delete[] w;
428     }
429     /// Should be const but...
430     MathedRowSt * getNext() const  { return next; }
431     /// ...we couldn't use this.
432     void setNext(MathedRowSt * n) { next = n; }
433     ///
434     string const & getLabel() const { return label; }
435     ///
436     bool isNumbered() const { return numbered; }
437     ///
438     int  getBaseline() const { return y; }
439     ///
440     void setBaseline(int b) { y = b; }
441     ///
442     int ascent() const { return asc; }
443     ///
444     int descent() const { return desc; }
445     ///
446     void ascent(int a) { asc = a; }
447     ///
448     void descent(int d) { desc = d; }
449     ///
450     int  getTab(int i) const { return w[i]; }
451     /// 
452     void setLabel(string const & 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     string label;
465     ///
466     bool numbered;
467     ///
468     MathedRowSt * next;
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, string const &);
498     ///
499     int GetColumns() const { return nc; }
500     ///
501     int GetRows() const { return nr; }
502     ///
503     virtual bool isMatrix() const { return true; }
504
505     /// Use this to manage the extra information independently of paragraph
506     MathedRowSt * getRowSt() const { return row; }
507     ///
508     void setRowSt(MathedRowSt * r) { row = r; }
509     
510  protected:
511     ///  Number of columns & rows
512     int nc;
513     ///
514     int nr;
515     /// tab sizes
516     int * ws;   
517     /// 
518     char v_align; // add approp. type
519     ///
520     string h_align; // a vector would perhaps be more correct
521     /// Vertical structure
522     MathedRowSt * row;
523
524 };
525
526
527
528 /*************************  Prototypes  **********************************/
529 /// 
530 LyxArrayBase * mathed_parse(unsigned flags, LyxArrayBase * data,
531                             MathParInset ** mt);
532 ///
533 void mathed_write(MathParInset *, std::ostream &, int *, bool fragile,
534                   string const & label = string());
535
536 ///
537 void mathed_parser_file(std::istream &, int);
538 ///
539 int mathed_parser_lineno();
540 ///
541 int MathedLookupBOP(short);
542
543 /************************ Inline functions ********************************/
544
545 ///
546 inline
547 bool MathIsInset(short x)
548 {
549         return LM_TC_INSET <= x && x <= LM_TC_ACTIVE_INSET;
550 }
551
552 ///
553 inline
554 bool MathIsFont(short x)
555 {
556         return LM_TC_CONST <= x && x <= LM_TC_BSYM;
557 }
558
559 ///
560 inline
561 bool MathIsAlphaFont(short x)
562 {
563         return LM_TC_VAR <= x && x <= LM_TC_TEXTRM;
564 }
565
566 ///
567 inline
568 bool MathIsActive(short x)
569 {
570         return LM_TC_INSET < x && x <= LM_TC_ACTIVE_INSET;
571 }
572
573 ///
574 inline
575 bool MathIsUp(short x)
576 {
577         return x == LM_TC_UP;
578 }
579
580 ///
581 inline
582 bool MathIsDown(short x)
583 {
584         return x == LM_TC_DOWN;
585 }
586
587 ///
588 inline
589 bool MathIsScript(short x)
590 {
591         return x == LM_TC_DOWN || x == LM_TC_UP;
592 }
593
594 ///
595 inline
596 bool MathIsBOPS(short x)
597 {
598         return MathedLookupBOP(x) > LMB_NONE;
599 }
600
601 ///
602 inline
603 bool MathIsBinary(short x)
604 {
605     return x == LM_TC_BOP || x == LM_TC_BOPS;
606 }
607
608 ///
609 inline
610 bool MathIsSymbol(short x) {
611     return LM_TC_SYMB <= x && x <= LM_TC_BSYM;
612 }
613      
614
615 inline
616 MathedInset::MathedInset(string const & nm, short ot, short st):
617   name(nm), objtype(ot), size(st) 
618 {
619    width = ascent = descent = 0;
620 }
621
622
623 inline
624 bool MathParInset::Inside(int x, int y) 
625 {
626   return (x >= xo && x <= xo + width && y <= yo + descent && y >= yo - ascent);
627 }
628
629
630 inline
631 void MathParInset::GetXY(int & x, int & y) const
632 {
633    x = xo; y = yo;
634 }
635
636
637 inline
638 void MathParInset::UserSetSize(short sz)
639 {
640    if (sz >= 0) {
641        size = sz;      
642        flag = flag & ~LMPF_FIXED_SIZE;
643    }
644 }
645
646
647 inline
648 void MathParInset::SetStyle(short sz) 
649 {
650     if (Permit(LMPF_FIXED_SIZE)) {
651         if (Permit(LMPF_SCRIPT)) 
652           sz = (sz < LM_ST_SCRIPT) ? LM_ST_SCRIPT: LM_ST_SCRIPTSCRIPT;
653         if (Permit(LMPF_SMALLER) && sz < LM_ST_SCRIPTSCRIPT) {
654             ++sz;
655         } 
656         MathedInset::SetStyle(sz);
657     }
658 }
659
660 #endif