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: 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(string const & nm, short ot, short st)
56 : MathedInset("", ot, st)
59 lims = (GetType() == LM_OT_FUNCLIM);
60 if (GetType() == LM_OT_UNDEF) {
70 MathedInset * MathFuncInset::Clone()
72 return new MathFuncInset(name, GetType(), GetStyle());
76 MathSpaceInset::MathSpaceInset(int sp, short ot, short st)
77 : MathedInset("", ot, st), space(sp)
81 MathedInset * MathSpaceInset::Clone()
83 return new MathSpaceInset(space, GetType(), GetStyle());
87 MathParInset::MathParInset(short st, string const & nm, short ot)
88 : MathedInset(nm, ot, st)
95 if (objtype == LM_OT_SCRIPT)
100 MathParInset::MathParInset(MathParInset * p)
104 p->setArgumentIdx(0);
105 MathedIter it(p->GetData());
110 MathParInset::~MathParInset()
113 MathedIter it(array);
120 MathedInset * MathParInset::Clone()
122 return new MathParInset(this);
126 void MathParInset::SetData(LyxArrayBase * a)
130 // A standard paragraph shouldn't have any tabs nor CRs.
132 MathedIter it(array);
134 char c = it.GetChar();
135 if (c == LM_TC_TAB || c == LM_TC_CR)
144 MathSqrtInset::MathSqrtInset(short st)
145 : MathParInset(st, "sqrt", LM_OT_SQRT) {}
148 MathedInset * MathSqrtInset::Clone()
150 MathSqrtInset * p = new MathSqrtInset(GetStyle());
151 MathedIter it(array);
152 p->SetData(it.Copy());
157 bool MathSqrtInset::Inside(int x, int y)
159 return x >= xo - hmax
160 && x <= xo + width - hmax
166 MathDelimInset::MathDelimInset(int l, int r, short st)
167 : MathParInset(st, "", LM_OT_DELIM), left(l), right(r) {}
170 MathedInset * MathDelimInset::Clone()
172 MathDelimInset * p = new MathDelimInset(left, right, GetStyle());
173 MathedIter it(array);
174 p->SetData(it.Copy());
179 MathDecorationInset::MathDecorationInset(int d, short st)
180 : MathParInset(st, "", LM_OT_DECO), deco(d)
182 upper = (deco!= LM_underline && deco!= LM_underbrace);
186 MathedInset * MathDecorationInset::Clone()
188 MathDecorationInset * p = new MathDecorationInset(deco, GetStyle());
189 MathedIter it(array);
190 p->SetData(it.Copy());
195 MathFracInset::MathFracInset(short ot)
196 : MathParInset(LM_ST_TEXT, "frac", ot)
199 den = new MathParInset(LM_ST_TEXT); // this leaks
202 if (objtype == LM_OT_STACKREL) {
209 MathFracInset::~MathFracInset()
215 MathedInset * MathFracInset::Clone()
217 MathFracInset * p = new MathFracInset(GetType());
218 MathedIter itn(array);
219 MathedIter itd(den->GetData());
220 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) ?
242 static_cast<short>(LM_ST_TEXT)
247 void MathFracInset::SetData(LyxArrayBase * n, LyxArrayBase * d)
250 MathParInset::SetData(n);
254 void MathFracInset::SetData(LyxArrayBase * d)
257 MathParInset::SetData(d);
264 void MathFracInset::GetXY(int & x, int & y) const
267 MathParInset::GetXY(x, y);
273 LyxArrayBase * MathFracInset::GetData()
278 return den->GetData();
282 bool MathFracInset::Inside(int x, int y)
284 int xx = xo - (width - w0) / 2;
286 return x >= xx && x <= xx + width && y <= yo + descent && y >= yo - ascent;
290 void MathFracInset::SetFocus(int /*x*/, int y)
292 // lyxerr << "y " << y << " " << yo << " " << den->yo << " ";
293 idx = (y > yo) ? 1: 0;
297 MathMatrixInset::MathMatrixInset(int m, int n, short st)
298 : MathParInset(st, "array", LM_OT_MATRIX), nc(m)
302 h_align = new char[nc + 1];
303 for (int i = 0; i < nc; ++i) h_align[i] = 'c';
309 row = new MathedRowSt(nc+1);
310 MathedXIter it(this);
311 for (int j = 1; j < n; ++j) it.addRow();
313 if (nr == 1 && nc > 1) {
314 for (int j = 0; j < nc - 1; ++j)
315 it.Insert('T', LM_TC_TAB);
318 row = new MathedRowSt(nc + 1);
324 MathMatrixInset::MathMatrixInset(MathMatrixInset * mt)
325 : MathParInset(mt->GetStyle(), mt->GetName(), mt->GetType())
330 h_align = new char[nc + 1];
331 strcpy(h_align, mt->GetAlign(&v_align));
333 it.SetData(mt->GetData());
336 MathedRowSt * r, * ro= 0, * mrow = mt->row;
337 //mrow = mt->row; // This must be redundant...
339 r = new MathedRowSt(nc + 1);
340 r->numbered = mrow->numbered;
342 r->label = mrow->label;
357 MathMatrixInset::~MathMatrixInset()
361 MathedRowSt * r = row;
363 MathedRowSt * q = r->next;
370 MathedInset * MathMatrixInset::Clone()
372 return new MathMatrixInset(this);
376 void MathMatrixInset::SetAlign(char vv, string const & hh)
379 ::strncpy(h_align, hh.c_str(), nc);
383 // Check the number of tabs and crs
384 void MathMatrixInset::SetData(LyxArrayBase * a)
390 // count tabs per row
403 it.Insert(' ', LM_TC_TAB);
413 // Automatically inserts tabs around bops
414 // DISABLED because it's very easy to insert tabs
419 void MathMatrixInset::draw(Painter & pain, int x, int baseline)
421 MathParInset::draw(pain, x, baseline);
425 void MathMatrixInset::Metrics()
428 MathedRowSt * cprow= 0;
431 // lyxerr << " MIDA ";
432 MathedXIter it(this);
433 row = it.adjustVerticalSt();
437 MathedRowSt * cxrow = row;
439 for (i = 0; i <= nc; ++i) cxrow->w[i] = 0;
444 MathParInset::Metrics();
446 if (nc <= 1 && !row->next) {
451 // Vertical positions of each row
454 for (i = 0; i < nc; ++i) {
455 if (cxrow == row || ws[i]<cxrow->w[i]) ws[i]= cxrow->w[i];
456 if (cxrow->next == 0 && ws[i] == 0) ws[i] = df_width;
459 cxrow->y = (cxrow == row) ? cxrow->asc:
460 cxrow->asc + cprow->desc + MATH_ROWSEP + cprow->y;
461 h += cxrow->asc + cxrow->desc + MATH_ROWSEP;
469 // Compute vertical align
471 case 't': ascent = row->y; break;
472 case 'b': ascent = h - hl; break;
473 default: ascent = (row->next) ? h / 2: h - hl; break;
475 descent = h - ascent + 2;
482 int rg = MATH_COLSEP, ww, lf = 0, * w = cxrow->w;
483 for (i = 0; i < nc; ++i) {
489 switch (h_align[i]) {
490 case 'l': lf = 0; break;
491 case 'c': lf = (ws[i] - w[i])/2;
493 case 'r': lf = ws[i] - w[i]; break;
495 ww = (isvoid) ? lf: lf + w[i];
497 rg = ws[i] - ww + MATH_COLSEP;
498 if (cxrow == row) width += ws[i] + MATH_COLSEP;
506 MathAccentInset::MathAccentInset(byte cx, MathedTextCodes f, int cd, short st)
507 : MathedInset("", LM_OT_ACCENT, st), c(cx), fn(f), code(cd)
513 MathAccentInset::MathAccentInset(MathedInset *ins, int cd, short st)
514 : MathedInset("", LM_OT_ACCENT, st),
515 c(0), fn(LM_TC_MIN), code(cd), inset(ins) {}
518 MathAccentInset::~MathAccentInset()
524 MathedInset * MathAccentInset::Clone()
529 p = new MathAccentInset(inset->Clone(), code, GetStyle());
531 p = new MathAccentInset(c, fn, code, GetStyle());
537 MathBigopInset::MathBigopInset(string const & nam, int id, short st)
538 : MathedInset(nam, LM_OT_BIGOP, st), sym(id)
544 MathedInset * MathBigopInset::Clone()
546 return new MathBigopInset(name, sym, GetStyle());
550 MathDotsInset::MathDotsInset(string const & nam, int id, short st)
551 : MathedInset(nam, LM_OT_DOTS, st), code(id) {}
554 MathedInset * MathDotsInset::Clone()
556 return new MathDotsInset(name, code, GetStyle());