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