3 * Purpose: Implementation of insets for mathed
4 * Author: Alejandro Aguilar Sierra <asierra@servidor.unam.mx>
5 * Created: January 1996
8 * Dependencies: Xlib, XForms
10 * Copyright: (c) 1996, 1997 Alejandro Aguilar Sierra
14 * You are free to use and modify this code under the terms of
15 * the GNU General Public Licence version 2 or later.
21 #pragma implementation "math_inset.h"
24 #include "math_iter.h"
25 #include "math_inset.h"
26 #include "symbol_def.h"
30 char * strnew(char const * s)
32 char * s1 = new char[strlen(s)+1];
37 MathedInset::MathedInset(MathedInset * inset)
40 name = inset->GetName();
41 objtype = inset->GetType();
42 size = inset->GetStyle();
43 width = inset->Width();
44 ascent = inset->Ascent();
45 descent = inset->Descent();
47 objtype = LM_OT_UNDEF;
49 width = ascent = descent = 0;
55 MathFuncInset::MathFuncInset(char const * nm, short ot, short st):
56 MathedInset("", ot, st)
59 lims = (GetType() == LM_OT_FUNCLIM);
60 if (GetType() == LM_OT_UNDEF) {
69 MathFuncInset * MathFuncInset::Clone()
72 MathedInset *l = new MathFuncInset(name, GetType(), GetStyle());
75 return new MathFuncInset(name, GetType(), GetStyle());
78 MathSpaceInset::MathSpaceInset(int sp, short ot, short st):
79 MathedInset("", ot, st), space(sp)
83 MathSpaceInset * MathSpaceInset::Clone()
86 MathedInset *l = new MathSpaceInset(space, GetType(), GetStyle());
89 return new MathSpaceInset(space, GetType(), GetStyle());
92 MathParInset::MathParInset(short st, char const * nm, short ot):
93 MathedInset(nm, ot, st)
100 if (objtype == LM_OT_SCRIPT)
104 MathParInset::MathParInset(MathParInset * p): MathedInset(p)
107 p->setArgumentIdx(0);
108 MathedIter it(p->GetData());
113 MathParInset::~MathParInset()
116 MathedIter it(array);
123 MathParInset * MathParInset::Clone()
126 MathParInset * p = new MathParInset(this);
129 return new MathParInset(this);
133 void MathParInset::SetData(LyxArrayBase * a)
137 // A standard paragraph shouldn't have any tabs nor CRs.
139 MathedIter it(array);
141 char c = it.GetChar();
142 if (c == LM_TC_TAB || c == LM_TC_CR)
151 MathSqrtInset::MathSqrtInset(short st): MathParInset(st, "sqrt", LM_OT_SQRT)
156 MathSqrtInset * MathSqrtInset::Clone()
158 MathSqrtInset * p = new MathSqrtInset(GetStyle());
159 MathedIter it(array);
160 p->SetData(it.Copy());
165 bool MathSqrtInset::Inside(int x, int y)
167 return (x>= xo-hmax && x<= xo+width-hmax && y<= yo+descent && y>= yo-ascent);
171 MathDelimInset::MathDelimInset(int l, int r, short st):
172 MathParInset(st, "", LM_OT_DELIM), left(l), right(r)
176 MathDelimInset * MathDelimInset::Clone()
178 MathDelimInset * p = new MathDelimInset(left, right, GetStyle());
179 MathedIter it(array);
180 p->SetData(it.Copy());
185 MathDecorationInset::MathDecorationInset(int d, short st):
186 MathParInset(st, "", LM_OT_DECO), deco(d)
188 upper = (deco!= LM_underline && deco!= LM_underbrace);
191 MathDecorationInset * MathDecorationInset::Clone()
193 MathDecorationInset * p = new MathDecorationInset(deco, GetStyle());
194 MathedIter it(array);
195 p->SetData(it.Copy());
199 MathFracInset::MathFracInset(short ot): MathParInset(LM_ST_TEXT, "frac", ot)
202 den = new MathParInset(LM_ST_TEXT); // this leaks
205 if (objtype == LM_OT_STACKREL) {
211 MathFracInset::~MathFracInset()
216 MathFracInset * MathFracInset::Clone()
218 MathFracInset * p = new MathFracInset(GetType());
219 MathedIter itn(array);
220 MathedIter itd(den->GetData());
221 p->SetData(itn.Copy(), itd.Copy());
227 bool MathFracInset::setArgumentIdx(int i)
229 if (i == 0 || i == 1) {
237 void MathFracInset::SetStyle(short st)
239 MathParInset::SetStyle(st);
241 den->SetStyle((size == LM_ST_DISPLAY) ? (short)LM_ST_TEXT: size);
244 void MathFracInset::SetData(LyxArrayBase * n, LyxArrayBase * d)
247 MathParInset::SetData(n);
250 void MathFracInset::SetData(LyxArrayBase * d)
253 MathParInset::SetData(d);
259 void MathFracInset::GetXY(int & x, int & y) const
262 MathParInset::GetXY(x, y);
267 LyxArrayBase * MathFracInset::GetData()
272 return den->GetData();
276 bool MathFracInset::Inside(int x, int y)
278 int xx = xo - (width-w0)/2;
280 return (x>= xx && x<= xx+width && y<= yo+descent && y>= yo-ascent);
283 void MathFracInset::SetFocus(int /*x*/, int y)
285 // lyxerr << "y " << y << " " << yo << " " << den->yo << " ";
286 idx = (y > yo) ? 1: 0;
290 MathMatrixInset::MathMatrixInset(int m, int n, short st):
291 MathParInset(st, "array", LM_OT_MATRIX), nc(m)
295 h_align = new char[nc+1];
296 for (int i = 0; i < nc; i++) h_align[i] = 'c';
302 row = new MathedRowSt(nc+1);
303 MathedXIter it(this);
304 for (int j = 1; j < n; j++) it.addRow();
306 if (nr == 1 && nc>1) {
307 for (int j = 0; j < nc - 1; j++)
308 it.Insert('T', LM_TC_TAB);
311 row = new MathedRowSt(nc+1);
317 MathMatrixInset::MathMatrixInset(MathMatrixInset * mt):
318 MathParInset(mt->GetStyle(), mt->GetName(), mt->GetType())
323 h_align = new char[nc+1];
324 strcpy(h_align, mt->GetAlign(&v_align));
326 it.SetData(mt->GetData());
329 MathedRowSt *r, *ro= 0, *mrow = mt->row;
332 r = new MathedRowSt(nc+1);
333 r->numbered = mrow->numbered;
335 r->label = strnew(mrow->label);
350 MathMatrixInset::~MathMatrixInset()
354 MathedRowSt * r = row;
356 MathedRowSt * q = r->next;
362 MathMatrixInset * MathMatrixInset::Clone()
364 MathMatrixInset * mt = new MathMatrixInset(this);
368 void MathMatrixInset::SetAlign(char vv, char const* hh)
371 strncpy(h_align, hh, nc);
375 // Check the number of tabs and crs
376 void MathMatrixInset::SetData(LyxArrayBase * a)
382 // count tabs per row
395 it.Insert(' ', LM_TC_TAB);
405 // Automatically inserts tabs around bops
406 // DISABLED because it's very easy to insert tabs
411 void MathMatrixInset::Draw(int x, int baseline)
413 MathParInset::Draw(x, baseline);
416 void MathMatrixInset::Metrics()
418 int i, /*cy,*/ hl, h= 0;
419 MathedRowSt *cprow= 0, *cxrow;
422 // lyxerr << " MIDA ";
423 MathedXIter it(this);
424 row = it.adjustVerticalSt();
430 for (i= 0; i<= nc; i++) cxrow->w[i] = 0;
435 MathParInset::Metrics();
437 if (nc<= 1 && !row->next) {
442 // Vertical positions of each row
445 for (i= 0; i<nc; i++) {
446 if (cxrow == row || ws[i]<cxrow->w[i]) ws[i]= cxrow->w[i];
447 if (cxrow->next == 0 && ws[i] == 0) ws[i] = df_width;
450 cxrow->y = (cxrow == row) ? cxrow->asc:
451 cxrow->asc + cprow->desc + MATH_ROWSEP + cprow->y;
452 h += cxrow->asc + cxrow->desc + MATH_ROWSEP;
460 // Compute vertical align
462 case 't': ascent = row->y; break;
463 case 'b': ascent = h - hl; break;
464 default: ascent = (row->next) ? h/2: h - hl; break;
466 descent = h - ascent + 2;
473 int rg= MATH_COLSEP, ww, lf= 0, *w = cxrow->w;
474 for (i= 0; i<nc; i++) {
480 switch (h_align[i]) {
481 case 'l': lf = 0; break;
482 case 'c': lf = (ws[i] - w[i])/2;
484 case 'r': lf = ws[i] - w[i]; break;
486 ww = (isvoid) ? lf: lf + w[i];
488 rg = ws[i] - ww + MATH_COLSEP;
489 if (cxrow == row) width += ws[i] + MATH_COLSEP;
496 MathAccentInset::MathAccentInset(byte cx, MathedTextCodes f, int cd, short st):
497 MathedInset("", LM_OT_ACCENT, st), c(cx), fn(f), code(cd)
502 MathAccentInset::MathAccentInset(MathedInset *ins, int cd, short st):
503 MathedInset("", LM_OT_ACCENT, st), c(0), fn(LM_TC_MIN), code(cd), inset(ins)
508 MathAccentInset::~MathAccentInset()
514 MathAccentInset * MathAccentInset::Clone()
519 p = new MathAccentInset(inset->Clone(), code, GetStyle());
521 p = new MathAccentInset(c, fn, code, GetStyle());
527 MathBigopInset::MathBigopInset(char const* nam, int id, short st):
528 MathedInset(nam, LM_OT_BIGOP, st), sym(id)
533 MathBigopInset * MathBigopInset::Clone()
536 MathBigopInset* p = new MathBigopInset(name, sym, GetStyle());
539 return new MathBigopInset(name, sym, GetStyle());
542 MathDotsInset::MathDotsInset(char const * nam, int id, short st):
543 MathedInset(nam, LM_OT_DOTS, st), code(id)
547 MathDotsInset * MathDotsInset::Clone()
550 MathDotsInset* p = new MathDotsInset(name, code, GetStyle());
553 return new MathDotsInset(name, code, GetStyle());