2001-02-13 13:28:32 +00:00
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#include "math_matrixinset.h"
|
|
|
|
#include "math_rowst.h"
|
|
|
|
#include "math_xiter.h"
|
2001-02-14 15:00:50 +00:00
|
|
|
#include "support/LOstream.h"
|
|
|
|
|
|
|
|
using std::ostream;
|
2001-02-13 13:28:32 +00:00
|
|
|
|
|
|
|
extern int number_of_newlines;
|
|
|
|
|
|
|
|
MathMatrixInset::MathMatrixInset(int m, int n, short st)
|
2001-02-16 09:25:43 +00:00
|
|
|
: MathParInset(st, "array", LM_OT_MATRIX), nc_(m), nr_(0), ws_(m),
|
|
|
|
v_align_(0), h_align_(nc_, 'c'), row_(0)
|
2001-02-13 13:28:32 +00:00
|
|
|
{
|
2001-02-16 09:25:43 +00:00
|
|
|
flag = 15;
|
|
|
|
if (n > 0) {
|
|
|
|
row_ = new MathedRowSt(nc_ + 1);
|
|
|
|
MathedXIter it(this);
|
|
|
|
for (int j = 1; j < n; ++j) it.addRow();
|
|
|
|
nr_ = n;
|
|
|
|
if (nr_ == 1 && nc_ > 1) {
|
|
|
|
for (int j = 0; j < nc_ - 1; ++j)
|
2001-02-17 18:52:53 +00:00
|
|
|
it.insert('T', LM_TC_TAB);
|
2001-02-16 09:25:43 +00:00
|
|
|
}
|
|
|
|
} else if (n < 0) {
|
|
|
|
row_ = new MathedRowSt(nc_ + 1);
|
|
|
|
nr_ = 1;
|
2001-02-13 13:28:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MathMatrixInset::MathMatrixInset(MathMatrixInset * mt)
|
|
|
|
: MathParInset(mt->GetStyle(), mt->GetName(), mt->GetType()),
|
2001-02-16 09:25:43 +00:00
|
|
|
nc_(mt->nc_), nr_(0), ws_(mt->nc_),
|
|
|
|
v_align_(mt->v_align_), h_align_(mt->h_align_)
|
2001-02-13 13:28:32 +00:00
|
|
|
{
|
2001-02-19 18:29:10 +00:00
|
|
|
MathedIter it(mt->GetData());
|
2001-02-16 09:25:43 +00:00
|
|
|
array = it.Copy();
|
|
|
|
if (mt->row_ != 0) {
|
|
|
|
MathedRowSt * ro = 0;
|
|
|
|
MathedRowSt * mrow = mt->row_;
|
|
|
|
|
|
|
|
while (mrow) {
|
|
|
|
MathedRowSt * r = new MathedRowSt(nc_ + 1);
|
|
|
|
r->setNumbered(mrow->isNumbered());
|
|
|
|
//if (mrow->label)
|
|
|
|
r->setLabel(mrow->getLabel());
|
|
|
|
if (!ro)
|
|
|
|
row_ = r;
|
|
|
|
else
|
|
|
|
ro->setNext(r);
|
|
|
|
mrow = mrow->getNext();
|
|
|
|
ro = r;
|
|
|
|
++nr_;
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
row_ = 0;
|
|
|
|
flag = mt->flag;
|
2001-02-13 13:28:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MathMatrixInset::~MathMatrixInset()
|
|
|
|
{
|
2001-02-16 09:25:43 +00:00
|
|
|
MathedRowSt * r = row_;
|
|
|
|
while (r) {
|
|
|
|
MathedRowSt * q = r->getNext();
|
|
|
|
delete r;
|
|
|
|
r = q;
|
|
|
|
}
|
2001-02-13 13:28:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MathedInset * MathMatrixInset::Clone()
|
|
|
|
{
|
2001-02-16 09:25:43 +00:00
|
|
|
return new MathMatrixInset(this);
|
2001-02-13 13:28:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void MathMatrixInset::SetAlign(char vv, string const & hh)
|
|
|
|
{
|
2001-02-16 09:25:43 +00:00
|
|
|
v_align_ = vv;
|
|
|
|
h_align_ = hh.substr(0, nc_); // usr just h_align = hh; perhaps
|
2001-02-13 13:28:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Check the number of tabs and crs
|
2001-02-16 09:25:43 +00:00
|
|
|
void MathMatrixInset::setData(MathedArray * a)
|
2001-02-13 13:28:32 +00:00
|
|
|
{
|
2001-02-16 09:25:43 +00:00
|
|
|
if (!a) return;
|
|
|
|
MathedIter it(a);
|
|
|
|
int nn = nc_ - 1;
|
|
|
|
nr_ = 1;
|
|
|
|
// count tabs per row
|
|
|
|
while (it.OK()) {
|
|
|
|
if (it.IsTab()) {
|
|
|
|
if (nn < 0) {
|
|
|
|
it.Delete();
|
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
// it.Next();
|
|
|
|
--nn;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (it.IsCR()) {
|
|
|
|
while (nn > 0) {
|
2001-02-17 18:52:53 +00:00
|
|
|
it.insert(' ', LM_TC_TAB);
|
2001-02-16 09:25:43 +00:00
|
|
|
--nn;
|
|
|
|
}
|
|
|
|
nn = nc_ - 1;
|
|
|
|
++nr_;
|
|
|
|
}
|
|
|
|
it.Next();
|
2001-02-13 13:28:32 +00:00
|
|
|
}
|
2001-02-16 09:25:43 +00:00
|
|
|
it.Reset();
|
|
|
|
|
|
|
|
// Automatically inserts tabs around bops
|
|
|
|
// DISABLED because it's very easy to insert tabs
|
|
|
|
array = a;
|
2001-02-13 13:28:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void MathMatrixInset::draw(Painter & pain, int x, int baseline)
|
|
|
|
{
|
2001-02-16 09:25:43 +00:00
|
|
|
MathParInset::draw(pain, x, baseline);
|
2001-02-13 13:28:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void MathMatrixInset::Metrics()
|
|
|
|
{
|
2001-02-16 09:25:43 +00:00
|
|
|
if (!row_) {
|
|
|
|
// lyxerr << " MIDA ";
|
|
|
|
MathedXIter it(this);
|
|
|
|
row_ = it.adjustVerticalSt();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Clean the arrays
|
|
|
|
MathedRowSt * cxrow = row_;
|
|
|
|
while (cxrow) {
|
|
|
|
for (int i = 0; i <= nc_; ++i)
|
|
|
|
cxrow->setTab(i, 0);
|
|
|
|
cxrow = cxrow->getNext();
|
2001-02-13 13:28:32 +00:00
|
|
|
}
|
|
|
|
|
2001-02-16 09:25:43 +00:00
|
|
|
// Basic metrics
|
|
|
|
MathParInset::Metrics();
|
|
|
|
|
|
|
|
if (nc_ <= 1 && !row_->getNext()) {
|
|
|
|
row_->ascent(ascent);
|
|
|
|
row_->descent(descent);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Vertical positions of each row
|
|
|
|
cxrow = row_;
|
|
|
|
MathedRowSt * cprow = 0;
|
|
|
|
int h = 0;
|
|
|
|
while (cxrow) {
|
|
|
|
for (int i = 0; i < nc_; ++i) {
|
|
|
|
if (cxrow == row_ || ws_[i] < cxrow->getTab(i))
|
|
|
|
ws_[i] = cxrow->getTab(i);
|
|
|
|
if (cxrow->getNext() == 0 && ws_[i] == 0)
|
|
|
|
ws_[i] = df_width;
|
|
|
|
}
|
|
|
|
|
|
|
|
cxrow->setBaseline((cxrow == row_) ?
|
|
|
|
cxrow->ascent() :
|
|
|
|
cxrow->ascent() + cprow->descent()
|
|
|
|
+ MATH_ROWSEP + cprow->getBaseline());
|
|
|
|
h += cxrow->ascent() + cxrow->descent() + MATH_ROWSEP;
|
|
|
|
cprow = cxrow;
|
|
|
|
cxrow = cxrow->getNext();
|
|
|
|
}
|
|
|
|
|
|
|
|
int hl = Descent();
|
|
|
|
h -= MATH_ROWSEP;
|
|
|
|
|
|
|
|
// Compute vertical align
|
|
|
|
switch (v_align_) {
|
|
|
|
case 't':
|
|
|
|
ascent = row_->getBaseline();
|
2001-02-13 13:28:32 +00:00
|
|
|
break;
|
2001-02-16 09:25:43 +00:00
|
|
|
case 'b':
|
|
|
|
ascent = h - hl;
|
2001-02-13 13:28:32 +00:00
|
|
|
break;
|
2001-02-16 09:25:43 +00:00
|
|
|
default:
|
|
|
|
ascent = (row_->getNext()) ? h / 2 : h - hl;
|
2001-02-13 13:28:32 +00:00
|
|
|
break;
|
|
|
|
}
|
2001-02-16 09:25:43 +00:00
|
|
|
descent = h - ascent + 2;
|
|
|
|
|
|
|
|
// Increase ws_[i] for 'R' columns (except the first one)
|
|
|
|
for (int i = 1; i < nc_; ++i)
|
|
|
|
if (h_align_[i] == 'R')
|
|
|
|
ws_[i] += 10 * df_width;
|
|
|
|
// Increase ws_[i] for 'C' column
|
|
|
|
if (h_align_[0] == 'C')
|
|
|
|
if (ws_[0] < 7 * workWidth / 8)
|
|
|
|
ws_[0] = 7 * workWidth / 8;
|
|
|
|
|
|
|
|
// Adjust local tabs
|
|
|
|
cxrow = row_;
|
|
|
|
width = MATH_COLSEP;
|
|
|
|
while (cxrow) {
|
|
|
|
int rg = MATH_COLSEP;
|
|
|
|
int lf = 0;
|
|
|
|
for (int i = 0; i < nc_; ++i) {
|
|
|
|
bool isvoid = false;
|
|
|
|
if (cxrow->getTab(i) <= 0) {
|
|
|
|
cxrow->setTab(i, df_width);
|
|
|
|
isvoid = true;
|
|
|
|
}
|
|
|
|
switch (h_align_[i]) {
|
|
|
|
case 'l':
|
|
|
|
lf = 0;
|
|
|
|
break;
|
|
|
|
case 'c':
|
|
|
|
lf = (ws_[i] - cxrow->getTab(i))/2;
|
|
|
|
break;
|
|
|
|
case 'r':
|
|
|
|
case 'R':
|
|
|
|
lf = ws_[i] - cxrow->getTab(i);
|
|
|
|
break;
|
|
|
|
case 'C':
|
|
|
|
if (cxrow == row_)
|
|
|
|
lf = 0;
|
|
|
|
else if (!cxrow->getNext())
|
|
|
|
lf = ws_[i] - cxrow->getTab(i);
|
|
|
|
else
|
|
|
|
lf = (ws_[i] - cxrow->getTab(i))/2;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
int ww = (isvoid) ? lf : lf + cxrow->getTab(i);
|
|
|
|
cxrow->setTab(i, lf + rg);
|
|
|
|
rg = ws_[i] - ww + MATH_COLSEP;
|
|
|
|
if (cxrow == row_)
|
|
|
|
width += ws_[i] + MATH_COLSEP;
|
|
|
|
}
|
|
|
|
cxrow->setBaseline(cxrow->getBaseline() - ascent);
|
|
|
|
cxrow = cxrow->getNext();
|
|
|
|
}
|
2001-02-13 13:28:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void MathMatrixInset::Write(ostream & os, bool fragile)
|
|
|
|
{
|
2001-02-16 09:25:43 +00:00
|
|
|
if (GetType() == LM_OT_MATRIX) {
|
2001-02-13 13:28:32 +00:00
|
|
|
if (fragile)
|
|
|
|
os << "\\protect";
|
|
|
|
os << "\\begin{"
|
|
|
|
<< name
|
|
|
|
<< '}';
|
2001-02-16 09:25:43 +00:00
|
|
|
if (v_align_ == 't' || v_align_ == 'b') {
|
2001-02-13 13:28:32 +00:00
|
|
|
os << '['
|
2001-02-16 09:25:43 +00:00
|
|
|
<< char(v_align_)
|
2001-02-13 13:28:32 +00:00
|
|
|
<< ']';
|
|
|
|
}
|
|
|
|
os << '{'
|
2001-02-16 09:25:43 +00:00
|
|
|
<< h_align_
|
2001-02-13 13:28:32 +00:00
|
|
|
<< "}\n";
|
|
|
|
++number_of_newlines;
|
|
|
|
}
|
|
|
|
MathParInset::Write(os, fragile);
|
|
|
|
if (GetType() == LM_OT_MATRIX){
|
|
|
|
os << "\n";
|
|
|
|
if (fragile)
|
|
|
|
os << "\\protect";
|
|
|
|
os << "\\end{"
|
|
|
|
<< name
|
|
|
|
<< '}';
|
|
|
|
++number_of_newlines;
|
|
|
|
}
|
|
|
|
}
|