]> git.lyx.org Git - features.git/blob - src/mathed/math_defs.h
read ChangeLog, a lot of whitespace changes. experimental use of libtool
[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 <cstdio>
28 #include "LString.h"
29 #include "debug.h"
30
31 #include "array.h"
32
33 ///
34 enum math_align {
35         ///
36         MATH_ALIGN_LEFT = 1,
37         ///
38         MATH_ALIGN_RIGHT = 2,
39         ///
40         MATH_ALIGN_BOTTOM = 4,
41         ///
42         MATH_ALIGN_TOP = 8
43 };
44 ///
45 #define MATH_COLSEP 8
46 ///
47 #define MATH_ROWSEP 8
48
49
50 /// Standard Math Sizes (Math mode styles)
51 enum MathedStyles {
52         ///
53    LM_ST_DISPLAY = 0,
54    ///
55    LM_ST_TEXT,
56    ///
57    LM_ST_SCRIPT,
58    ///
59    LM_ST_SCRIPTSCRIPT
60 };
61
62
63 /// Standard LaTeX Math Environments
64 enum MathedEnvironment {
65         ///
66    LM_EN_INTEXT = 0,
67    ///
68    LM_EN_DISPLAY,
69    ///
70    LM_EN_EQUATION,
71    ///
72    LM_EN_EQNARRAYAST,
73    ///
74    LM_EN_EQNARRAY,
75    ///
76    LM_EN_ARRAY
77 };
78
79
80 /** The restrictions of a standard LaTeX math paragraph
81   allows to get a small number of text codes (<30) */
82 enum MathedTextCodes  {
83    /// This must be >= 0
84    LM_TC_MIN = 0,
85    /// Open and Close group
86    LM_TC_OPEN,
87    ///
88    LM_TC_CLOSE,
89    /// Tabulator
90    LM_TC_TAB,
91    /// New line
92    LM_TC_CR,
93    /// Math Inset
94    LM_TC_INSET,
95    /// Super and sub scripts
96    LM_TC_UP,
97    ///
98    LM_TC_DOWN,
99    /// Editable Math Inset
100    LM_TC_ACTIVE_INSET,
101    /// Editable Text Inset
102    LM_TC_TEXT_INSET,
103    ///
104    LM_FONT_BEGIN,
105    /// Internal code for constants
106    LM_TC_CONST,
107    /// Internal code for variables
108    LM_TC_VAR,
109    ///
110    LM_TC_RM,
111    ///
112    LM_TC_CAL,
113    ///
114    LM_TC_BF,
115    ///
116    LM_TC_SF,
117    ///
118    LM_TC_TT,
119    ///
120    LM_TC_IT,
121    ///
122    LM_TC_TEXTRM,
123    /// Math mode TeX characters ",;:{}"
124    LM_TC_TEX,
125    /// Special characters "{}&#_%"
126    LM_TC_SPECIAL,
127    /// Internal code for operators
128    LM_TC_BOP,
129    /// Internal code for symbols
130    LM_TC_SYMB,
131    ///
132    LM_TC_BOPS,
133    ///
134    LM_TC_BSYM,
135    ///
136    LM_FONT_END,
137    
138    /// This must be < 32 
139    LM_TC_MAX
140 };
141
142 ostream & operator<<(ostream &, MathedTextCodes mtc);
143
144 ///
145 #define LM_TC_NORMAL LM_TC_VAR
146  
147        
148 /// Types of lyx-math insets 
149 enum MathedInsetTypes  {
150    ///
151    LM_OT_MIN = 0,
152    /// A simple paragraph
153    LM_OT_PAR,
154    /// A simple numbered paragraph
155    LM_OT_PARN,
156    /// A multiline paragraph
157    LM_OT_MPAR,
158    /// A multiline numbered paragraph
159    LM_OT_MPARN,
160    /// An array
161    LM_OT_MATRIX,
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 MathedInset;
211 class MathParInset;
212
213
214 /** Abstract base class for all math objects.
215     A math insets is for use of the math editor only, it isn't a
216     general LyX inset. It's used to represent all the math objects.
217     The formulaInset (a LyX inset) encapsulates a math inset.
218  */
219 class MathedInset  {
220  public: 
221     /// A math inset has a name (usually its LaTeX name), type and font-size
222     MathedInset(char const * nm, short ot, short st);
223     ///
224     MathedInset(MathedInset *);
225     ///
226     virtual ~MathedInset() {}
227     
228     /// Draw the object 
229     virtual void Draw(int x, int baseline) = 0;
230     
231     /// Write LaTeX and Lyx code
232     virtual void Write(FILE * file) = 0;
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(FILE * file);
338     /// Write LaTeX code
339     virtual void Write(string & file);
340     ///
341     virtual void Metrics();
342     ///
343     virtual void UserSetSize(short);
344  
345     /// Data is stored in a LyXArray
346     virtual void SetData(LyxArrayBase *);
347     ///
348     virtual LyxArrayBase * GetData() { return array; }
349
350     /// Paragraph position
351     virtual void GetXY(int &, int &) const;
352     ///
353     virtual void setXY(int x, int y) { xo = x;  yo = y; }
354     ///
355     virtual void SetFocus(int, int) {}
356     ///
357     virtual bool Inside(int, int);   
358    
359     // Tab stuff used by Matrix.
360     ///
361     virtual void SetAlign(char, char const *) {}
362 //    ///
363 //    virtual int GetTabPos() { return 0; }
364 //    ///
365 //    virtual int GetTab(int) { return 0; }
366     ///
367     virtual int GetColumns() { return 1; }
368     ///
369     virtual int GetRows() { return 1; }
370     ///
371     virtual bool isMatrix() { return false; }
372 //    /// These functions should report an error
373 //    virtual char const* GetLabel() { return 0; }
374 //    virtual char const* GetLabel(int) { return 0; }
375
376     // Vertical switching
377     ///
378     virtual bool setArgumentIdx(int i) { return (i == 0); }
379     ///
380     virtual bool setNextArgIdx() { return false; }
381     ///
382     virtual int  getArgumentIdx() { return 0; }
383     ///
384     virtual int  getMaxArgumentIdx() { return 0; }
385 //    ///
386 //    virtual void SetLabel(char const *) {}
387     ///
388     virtual void SetStyle(short);
389         ///
390     virtual MathedRowSt * getRowSt() const { return 0; }
391         ///
392     virtual void setRowSt(MathedRowSt *) {}
393         ///
394     virtual bool Permit(short f) { return bool(f & flag); }
395     
396  protected:
397     /// Paragraph data is stored here
398     LyxArrayBase * array;
399     /// Cursor start position
400     int xo, yo;
401     /// 
402     short flag;
403
404  private:
405     ///
406     virtual void setFlag(MathedParFlag f) { flag |= f; }
407         ///
408     friend class InsetFormula;
409         ///
410     friend class MathedXIter;
411         ///
412     friend class MathedCursor;
413         ///
414     friend LyxArrayBase * mathed_parse(unsigned flags = 0,
415                                        LyxArrayBase * a = 0,
416                                        MathParInset ** p = 0);
417 };
418
419
420 /* The physical structure of a row and aditional information is stored here.
421     It allows to manage the extra info independently of the paragraph data.  
422     Only used for multiline paragraphs.
423  */
424 struct MathedRowSt {    
425     /// 
426     MathedRowSt(int n) {
427             w = new int[n + 1]; // this leaks
428         next = 0;
429         label = 0;
430         numbered = true;
431     }
432     ///
433     ~MathedRowSt() {
434         delete[] w;
435         if (label) delete[] label;
436     }
437     /// Should be const but...
438     MathedRowSt * getNext() const  { return next; }
439     /// ...we couldn't use this.
440     void setNext(MathedRowSt * n) { next = n; }
441     ///
442     char const * getLabel() const { return label; }
443     ///
444     bool isNumbered() const { return numbered; }
445     ///
446     int  getBaseline() const { return y; }    
447     ///
448     int  getTab(int i) { return w[i]; }
449     /// 
450     void setLabel(char * 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     char * label;
463     ///
464     bool numbered;
465     ///
466     MathedRowSt * next;
467         ///
468     friend class MathMatrixInset;
469         ///
470     friend class MathedXIter;
471 };
472
473
474 /** Multiline math paragraph base class.
475     This is the base to all multiline editable math objects
476     like array and eqnarray. 
477  */
478 class MathMatrixInset: public MathParInset {
479  public: 
480     ///
481     MathMatrixInset(int m = 1, int n = 1, short st = LM_ST_TEXT);
482     ///
483     MathMatrixInset(MathMatrixInset *);
484     ///
485     MathedInset * Clone();
486     ///
487     virtual ~MathMatrixInset();
488     ///
489     void Draw(int, int);
490     ///
491     void Write(FILE * file);
492     ///
493     void Write(string & file);
494     ///
495     void Metrics();
496     ///
497     void SetData(LyxArrayBase *);
498     ///
499     void SetAlign(char, char const *);
500     ///
501     char * GetAlign(char * vv) {
502         *vv = v_align;
503         return h_align;
504     }
505 //    ///
506 //    int GetTab(int);
507     ///
508     int GetColumns() { return nc; }
509     ///
510     int GetRows() { return nr; }
511     ///
512     virtual bool isMatrix() { return true; }
513
514     /// Use this to manage the extra information independently of paragraph
515     MathedRowSt * getRowSt() const { return row; }
516         ///
517     void setRowSt(MathedRowSt * r) { row = r; }
518     
519  protected:
520     ///  Number of columns & rows
521     int nc, nr;
522     /// tab sizes
523     int * ws;   
524     /// 
525     char v_align; // add approp. signedness
526     ///
527     char * h_align;
528     /// Vertical structure
529     MathedRowSt * row;
530
531 };
532
533
534
535 /*************************  Prototypes  **********************************/
536 /// 
537 LyxArrayBase * mathed_parse(unsigned flags, LyxArrayBase * data,
538                             MathParInset ** mt);
539 ///
540 void mathed_write(MathParInset *, FILE *, int *, char fragile,
541                   char const * label = 0);
542 ///
543 void mathed_write(MathParInset *, string &, int *, char fragile,
544                   char const * label = 0);
545 ///
546 void mathed_parser_file(FILE *, int);
547 ///
548 int mathed_parser_lineno();
549 ///
550 int MathedLookupBOP(short);
551
552 /************************ Inline functions ********************************/
553 ///
554 inline bool MathIsInset(short x)
555 {
556         return LM_TC_INSET <= x && x <= LM_TC_ACTIVE_INSET;
557 }
558
559 ///
560 inline bool MathIsFont(short x)
561 {
562         return LM_TC_CONST <= x && x <= LM_TC_BSYM;
563 }
564
565 ///
566 inline bool MathIsAlphaFont(short x)
567 {
568         return LM_TC_VAR <= x && x <= LM_TC_TEXTRM;
569 }
570
571 ///
572 inline bool MathIsActive(short x)
573 {
574         return LM_TC_INSET < x && x <= LM_TC_ACTIVE_INSET;
575 }
576
577 ///
578 inline bool MathIsUp(short x)
579 {
580         return x == LM_TC_UP;
581 }
582
583 ///
584 inline bool MathIsDown(short x)
585 {
586         return x == LM_TC_DOWN;
587 }
588
589 ///
590 inline bool MathIsScript(short x)
591 {
592         return x == LM_TC_DOWN || x == LM_TC_UP;
593 }
594
595 ///
596 inline bool MathIsBOPS(short x)
597 {
598         return MathedLookupBOP(x) > LMB_NONE;
599 }
600
601
602 ///
603 inline bool MathIsBinary(short x)
604 {
605     return x == LM_TC_BOP || x == LM_TC_BOPS;
606 }
607
608 ///
609 inline bool MathIsSymbol(short x) {
610     return LM_TC_SYMB <= x && x <= LM_TC_BSYM;
611 }
612      
613
614 inline 
615 MathedInset::MathedInset(char const * nm, short ot, short st):
616   name(nm), objtype(ot), size(st) 
617 {
618    width = ascent = descent = 0;
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 #endif