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