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