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