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"
29 MathedInset::MathedInset(MathedInset * inset)
32 name = inset->GetName();
33 objtype = inset->GetType();
34 size = inset->GetStyle();
35 width = inset->Width();
36 ascent = inset->Ascent();
37 descent = inset->Descent();
39 objtype = LM_OT_UNDEF;
41 width = ascent = descent = 0;
47 MathFuncInset::MathFuncInset(string const & nm, short ot, short st)
48 : MathedInset("", ot, st)
51 lims = (GetType() == LM_OT_FUNCLIM);
52 if (GetType() == LM_OT_UNDEF) {
62 MathedInset * MathFuncInset::Clone()
64 return new MathFuncInset(name, GetType(), GetStyle());
68 MathSpaceInset::MathSpaceInset(int sp, short ot, short st)
69 : MathedInset("", ot, st), space(sp)
73 MathedInset * MathSpaceInset::Clone()
75 return new MathSpaceInset(space, GetType(), GetStyle());
79 MathParInset::MathParInset(short st, string const & nm, short ot)
80 : MathedInset(nm, ot, st)
87 if (objtype == LM_OT_SCRIPT)
92 MathParInset::MathParInset(MathParInset * p)
97 MathedIter it(p->GetData());
102 MathParInset::~MathParInset()
105 MathedIter it(array);
112 MathedInset * MathParInset::Clone()
114 return new MathParInset(this);
118 void MathParInset::SetData(MathedArray * a)
122 // A standard paragraph shouldn't have any tabs nor CRs.
124 MathedIter it(array);
126 char c = it.GetChar();
127 if (c == LM_TC_TAB || c == LM_TC_CR)
136 MathSqrtInset::MathSqrtInset(short st)
137 : MathParInset(st, "sqrt", LM_OT_SQRT) {}
140 MathedInset * MathSqrtInset::Clone()
142 MathSqrtInset * p = new MathSqrtInset(GetStyle());
143 MathedIter it(array);
144 p->SetData(it.Copy());
149 bool MathSqrtInset::Inside(int x, int y)
151 return x >= xo - hmax
152 && x <= xo + width - hmax
158 MathDelimInset::MathDelimInset(int l, int r, short st)
159 : MathParInset(st, "", LM_OT_DELIM), left(l), right(r) {}
162 MathedInset * MathDelimInset::Clone()
164 MathDelimInset * p = new MathDelimInset(left, right, GetStyle());
165 MathedIter it(array);
166 p->SetData(it.Copy());
171 MathDecorationInset::MathDecorationInset(int d, short st)
172 : MathParInset(st, "", LM_OT_DECO), deco(d)
174 upper = (deco!= LM_underline && deco!= LM_underbrace);
178 MathedInset * MathDecorationInset::Clone()
180 MathDecorationInset * p = new MathDecorationInset(deco, GetStyle());
181 MathedIter it(array);
182 p->SetData(it.Copy());
187 MathFracInset::MathFracInset(short ot)
188 : MathParInset(LM_ST_TEXT, "frac", ot)
191 den = new MathParInset(LM_ST_TEXT); // this leaks
194 if (objtype == LM_OT_STACKREL) {
201 MathFracInset::~MathFracInset()
207 MathedInset * MathFracInset::Clone()
209 MathFracInset * p = new MathFracInset(GetType());
210 MathedIter itn(array);
211 MathedIter itd(den->GetData());
212 p->SetData(itn.Copy(), itd.Copy());
219 bool MathFracInset::setArgumentIdx(int i)
221 if (i == 0 || i == 1) {
229 void MathFracInset::SetStyle(short st)
231 MathParInset::SetStyle(st);
233 den->SetStyle((size == LM_ST_DISPLAY) ?
234 static_cast<short>(LM_ST_TEXT)
239 void MathFracInset::SetData(MathedArray * n, MathedArray * d)
242 MathParInset::SetData(n);
246 void MathFracInset::SetData(MathedArray * d)
249 MathParInset::SetData(d);
256 void MathFracInset::GetXY(int & x, int & y) const
259 MathParInset::GetXY(x, y);
265 MathedArray * MathFracInset::GetData()
270 return den->GetData();
274 bool MathFracInset::Inside(int x, int y)
276 int xx = xo - (width - w0) / 2;
278 return x >= xx && x <= xx + width && y <= yo + descent && y >= yo - ascent;
282 void MathFracInset::SetFocus(int /*x*/, int y)
284 // lyxerr << "y " << y << " " << yo << " " << den->yo << " ";
285 idx = (y > yo) ? 1: 0;
289 MathMatrixInset::MathMatrixInset(int m, int n, short st)
290 : MathParInset(st, "array", LM_OT_MATRIX), nc(m), nr(0), ws_(m),
291 v_align(0), h_align(nc, 'c')
296 row = new MathedRowSt(nc+1);
297 MathedXIter it(this);
298 for (int j = 1; j < n; ++j) it.addRow();
300 if (nr == 1 && nc > 1) {
301 for (int j = 0; j < nc - 1; ++j)
302 it.Insert('T', LM_TC_TAB);
305 row = new MathedRowSt(nc + 1);
311 MathMatrixInset::MathMatrixInset(MathMatrixInset * mt)
312 : MathParInset(mt->GetStyle(), mt->GetName(), mt->GetType()),
313 nc(mt->nc), nr(0), ws_(mt->nc), v_align(mt->v_align), h_align(mt->h_align)
316 it.SetData(mt->GetData());
319 MathedRowSt * r, * ro= 0, * mrow = mt->row;
320 //mrow = mt->row; // This must be redundant...
322 r = new MathedRowSt(nc + 1);
323 r->setNumbered(mrow->isNumbered());
325 r->setLabel(mrow->getLabel());
330 mrow = mrow->getNext();
340 MathMatrixInset::~MathMatrixInset()
342 MathedRowSt * r = row;
344 MathedRowSt * q = r->getNext();
351 MathedInset * MathMatrixInset::Clone()
353 return new MathMatrixInset(this);
357 void MathMatrixInset::SetAlign(char vv, string const & hh)
360 h_align = hh.substr(0, nc); // usr just h_align = hh; perhaps
364 // Check the number of tabs and crs
365 void MathMatrixInset::SetData(MathedArray * a)
371 // count tabs per row
384 it.Insert(' ', LM_TC_TAB);
394 // Automatically inserts tabs around bops
395 // DISABLED because it's very easy to insert tabs
400 void MathMatrixInset::draw(Painter & pain, int x, int baseline)
402 MathParInset::draw(pain, x, baseline);
406 void MathMatrixInset::Metrics()
409 MathedRowSt * cprow= 0;
412 // lyxerr << " MIDA ";
413 MathedXIter it(this);
414 row = it.adjustVerticalSt();
418 MathedRowSt * cxrow = row;
420 for (i = 0; i <= nc; ++i) cxrow->setTab(i, 0);
421 cxrow = cxrow->getNext();
425 MathParInset::Metrics();
427 if (nc <= 1 && !row->getNext()) {
429 row->descent(descent);
432 // Vertical positions of each row
435 for (i = 0; i < nc; ++i) {
436 if (cxrow == row || ws_[i] < cxrow->getTab(i))
437 ws_[i] = cxrow->getTab(i);
438 if (cxrow->getNext() == 0 && ws_[i] == 0) ws_[i] = df_width;
441 cxrow->setBaseline((cxrow == row) ?
443 cxrow->ascent() + cprow->descent()
444 + MATH_ROWSEP + cprow->getBaseline());
445 h += cxrow->ascent() + cxrow->descent() + MATH_ROWSEP;
447 cxrow = cxrow->getNext();
453 // Compute vertical align
455 case 't': ascent = row->getBaseline(); break;
456 case 'b': ascent = h - hl; break;
457 default: ascent = (row->getNext()) ? h / 2: h - hl; break;
459 descent = h - ascent + 2;
461 // Increase ws_[i] for 'R' columns (except the first one)
462 for (i = 1; i < nc; ++i)
463 if (h_align[i] == 'R')
464 ws_[i] += 10*df_width;
465 // Increase ws_[i] for 'C' column
466 if (h_align[0] == 'C')
467 if (ws_[0] < 7*workWidth/8)
468 ws_[0] = 7*workWidth/8;
474 int rg = MATH_COLSEP, ww, lf = 0; //, * w = cxrow->w;
475 for (i = 0; i < nc; ++i) {
477 if (cxrow->getTab(i) <= 0) {
478 cxrow->setTab(i, df_width);
481 switch (h_align[i]) {
486 lf = (ws_[i] - cxrow->getTab(i))/2;
490 lf = ws_[i] - cxrow->getTab(i);
495 else if (!cxrow->getNext())
496 lf = ws_[i] - cxrow->getTab(i);
498 lf = (ws_[i] - cxrow->getTab(i))/2;
501 ww = (isvoid) ? lf : lf + cxrow->getTab(i);
502 cxrow->setTab(i, lf + rg);
503 rg = ws_[i] - ww + MATH_COLSEP;
504 if (cxrow == row) width += ws_[i] + MATH_COLSEP;
506 cxrow->setBaseline(cxrow->getBaseline() - ascent);
507 cxrow = cxrow->getNext();
512 MathAccentInset::MathAccentInset(byte cx, MathedTextCodes f, int cd, short st)
513 : MathedInset("", LM_OT_ACCENT, st), c(cx), fn(f), code(cd)
519 MathAccentInset::MathAccentInset(MathedInset *ins, int cd, short st)
520 : MathedInset("", LM_OT_ACCENT, st),
521 c(0), fn(LM_TC_MIN), code(cd), inset(ins) {}
524 MathAccentInset::~MathAccentInset()
530 MathedInset * MathAccentInset::Clone()
535 p = new MathAccentInset(inset->Clone(), code, GetStyle());
537 p = new MathAccentInset(c, fn, code, GetStyle());
543 MathBigopInset::MathBigopInset(string const & nam, int id, short st)
544 : MathedInset(nam, LM_OT_BIGOP, st), sym(id)
550 MathedInset * MathBigopInset::Clone()
552 return new MathBigopInset(name, sym, GetStyle());
556 MathDotsInset::MathDotsInset(string const & nam, int id, short st)
557 : MathedInset(nam, LM_OT_DOTS, st), code(id) {}
560 MathedInset * MathDotsInset::Clone()
562 return new MathDotsInset(name, code, GetStyle());