mirror of
https://git.lyx.org/repos/lyx.git
synced 2025-01-11 11:08:41 +00:00
a step towards world domination^H^H^H
aehm... move things from the parbox inset to an abstract base class 'MathTextInset' and have a shot on implementing an ERT inset on top of that. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@4819 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
cdbe361370
commit
990069f546
@ -51,6 +51,8 @@ libmathed_la_SOURCES = \
|
||||
math_dotsinset.h \
|
||||
math_envinset.C \
|
||||
math_envinset.h \
|
||||
math_ertinset.C \
|
||||
math_ertinset.h \
|
||||
math_extern.C \
|
||||
math_extern.h \
|
||||
math_exfuncinset.C \
|
||||
@ -134,6 +136,8 @@ libmathed_la_SOURCES = \
|
||||
math_support.h \
|
||||
math_symbolinset.C \
|
||||
math_symbolinset.h \
|
||||
math_textinset.C \
|
||||
math_textinset.h \
|
||||
math_unknowninset.C \
|
||||
math_unknowninset.h \
|
||||
math_undersetinset.C \
|
||||
|
@ -208,9 +208,11 @@ void InsetFormulaBase::insetUnlock(BufferView * bv)
|
||||
}
|
||||
|
||||
|
||||
void InsetFormulaBase::getCursorPos(BufferView * bv, int & x, int & y) const
|
||||
void InsetFormulaBase::getCursorPos(BufferView *, int & x, int & y) const
|
||||
{
|
||||
metrics(bv);
|
||||
// calling metrics here destroys the cached xo,yo positions e.g. in
|
||||
// MathParboxinset. And it would be too expensive anyway...
|
||||
//metrics(bv);
|
||||
mathcursor->getPos(x, y);
|
||||
//x -= xo_;
|
||||
y -= yo_;
|
||||
@ -403,6 +405,7 @@ InsetFormulaBase::localDispatch(BufferView * bv, kb_action action,
|
||||
|
||||
if (!mathcursor)
|
||||
return UNDISPATCHED;
|
||||
string argument = arg;
|
||||
|
||||
RESULT result = DISPATCHED;
|
||||
bool sel = false;
|
||||
@ -696,11 +699,6 @@ InsetFormulaBase::localDispatch(BufferView * bv, kb_action action,
|
||||
result = UNDISPATCHED;
|
||||
break;
|
||||
|
||||
case LFUN_BREAKPARAGRAPH:
|
||||
case LFUN_BREAKPARAGRAPHKEEPLAYOUT:
|
||||
//lyxerr << "LFUN ignored\n";
|
||||
break;
|
||||
|
||||
case LFUN_INSET_ERT:
|
||||
// interpret this as if a backslash was typed
|
||||
bv->lockedInsetStoreUndo(Undo::EDIT);
|
||||
@ -708,15 +706,21 @@ InsetFormulaBase::localDispatch(BufferView * bv, kb_action action,
|
||||
updateLocal(bv, true);
|
||||
break;
|
||||
|
||||
case LFUN_BREAKPARAGRAPH:
|
||||
case LFUN_BREAKPARAGRAPHKEEPLAYOUT:
|
||||
case LFUN_BREAKPARAGRAPH_SKIP:
|
||||
argument = "\n";
|
||||
// fall through
|
||||
|
||||
case -1:
|
||||
case LFUN_INSERT_MATH:
|
||||
case LFUN_SELFINSERT:
|
||||
if (!arg.empty()) {
|
||||
if (!argument.empty()) {
|
||||
bv->lockedInsetStoreUndo(Undo::EDIT);
|
||||
if (arg.size() == 1)
|
||||
result = mathcursor->interpret(arg[0]) ? DISPATCHED : FINISHED_RIGHT;
|
||||
if (argument.size() == 1)
|
||||
result = mathcursor->interpret(argument[0]) ? DISPATCHED : FINISHED_RIGHT;
|
||||
else
|
||||
result = mathcursor->interpret(arg) ? DISPATCHED : FINISHED_RIGHT;
|
||||
result = mathcursor->interpret(argument) ? DISPATCHED : FINISHED_RIGHT;
|
||||
updateLocal(bv, true);
|
||||
}
|
||||
break;
|
||||
|
@ -1399,6 +1399,12 @@ bool MathCursor::interpret(char c)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (c == '\n') {
|
||||
if (currentMode() == MathInset::TEXT_MODE)
|
||||
insert(c);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (c == ' ') {
|
||||
if (currentMode() == MathInset::TEXT_MODE) {
|
||||
// insert spaces in text mode,
|
||||
|
42
src/mathed/math_ertinset.C
Normal file
42
src/mathed/math_ertinset.C
Normal file
@ -0,0 +1,42 @@
|
||||
|
||||
#include "math_ertinset.h"
|
||||
#include "math_mathmlstream.h"
|
||||
|
||||
|
||||
MathInset * MathErtInset::clone() const
|
||||
{
|
||||
return new MathErtInset(*this);
|
||||
}
|
||||
|
||||
|
||||
void MathErtInset::metrics(MathMetricsInfo & mi) const
|
||||
{
|
||||
MathFontSetChanger dummy(mi.base, "lyxert");
|
||||
MathTextInset::metrics(mi);
|
||||
cache_.colinfo_[0].align_ = 'l';
|
||||
metricsMarkers2();
|
||||
}
|
||||
|
||||
|
||||
void MathErtInset::draw(MathPainterInfo & pi, int x, int y) const
|
||||
{
|
||||
MathFontSetChanger dummy(pi.base, "lyxert");
|
||||
MathTextInset::draw(pi, x + 1, y);
|
||||
drawMarkers2(pi, x, y);
|
||||
}
|
||||
|
||||
|
||||
void MathErtInset::write(WriteStream & os) const
|
||||
{
|
||||
if (os.latex())
|
||||
os << cell(0);
|
||||
else
|
||||
os << "\\lyxert{" << cell(0) << '}';
|
||||
}
|
||||
|
||||
|
||||
void MathErtInset::infoize(std::ostream & os) const
|
||||
{
|
||||
os << "Box: Ert";
|
||||
}
|
||||
|
26
src/mathed/math_ertinset.h
Normal file
26
src/mathed/math_ertinset.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef MATH_ERTINSET_H
|
||||
#define MATH_ERTINSET_H
|
||||
|
||||
#include "math_textinset.h"
|
||||
|
||||
// implements support for \parbox
|
||||
|
||||
class MathErtInset : public MathTextInset {
|
||||
public:
|
||||
///
|
||||
MathErtInset() {}
|
||||
///
|
||||
MathInset * clone() const;
|
||||
///
|
||||
mode_type currentMode() const { return TEXT_MODE; }
|
||||
///
|
||||
void metrics(MathMetricsInfo & mi) const;
|
||||
///
|
||||
void draw(MathPainterInfo & pi, int x, int y) const;
|
||||
///
|
||||
void infoize(std::ostream & os) const;
|
||||
///
|
||||
void write(WriteStream & os) const;
|
||||
};
|
||||
|
||||
#endif
|
@ -8,6 +8,7 @@
|
||||
#include "math_casesinset.h"
|
||||
#include "math_decorationinset.h"
|
||||
#include "math_dotsinset.h"
|
||||
#include "math_ertinset.h"
|
||||
#include "math_fboxinset.h"
|
||||
#include "math_fontinset.h"
|
||||
#include "math_fontoldinset.h"
|
||||
@ -180,41 +181,6 @@ latexkeys const * in_word_set(string const & str)
|
||||
MathAtom createMathInset(string const & s)
|
||||
{
|
||||
lyxerr[Debug::MATHED] << "creating inset with name: '" << s << "'\n";
|
||||
if (s.size() == 2 && s[0] == '#' && s[1] >= '1' && s[1] <= '9')
|
||||
return MathAtom(new MathMacroArgument(s[1] - '0'));
|
||||
|
||||
if (s.size() == 3 && s[0] == '\\' && s[1] == '#'
|
||||
&& s[2] >= '1' && s[2] <= '9')
|
||||
return MathAtom(new MathMacroArgument(s[2] - '0'));
|
||||
if (s == "kern")
|
||||
return MathAtom(new MathKernInset);
|
||||
if (s == "xymatrix")
|
||||
return MathAtom(new MathXYMatrixInset);
|
||||
if (s == "xrightarrow" || s == "xleftarrow")
|
||||
return MathAtom(new MathXArrowInset(s));
|
||||
if (s == "split" || s == "gathered" || s == "aligned")
|
||||
return MathAtom(new MathSplitInset(s));
|
||||
if (s == "cases")
|
||||
return MathAtom(new MathCasesInset);
|
||||
if (s == "substack")
|
||||
return MathAtom(new MathSubstackInset);
|
||||
if (s == "subarray" || s == "array")
|
||||
return MathAtom(new MathArrayInset(s, 1, 1));
|
||||
if (s == "sqrt")
|
||||
return MathAtom(new MathSqrtInset);
|
||||
if (s == "root")
|
||||
return MathAtom(new MathRootInset);
|
||||
if (s == "stackrel")
|
||||
return MathAtom(new MathStackrelInset);
|
||||
if (s == "binom" || s == "choose")
|
||||
return MathAtom(new MathBinomInset(s == "choose"));
|
||||
if (s == "over" || s == "frac")
|
||||
return MathAtom(new MathFracInset);
|
||||
if (s == "atop")
|
||||
return MathAtom(new MathFracInset(true));
|
||||
if (s == "lefteqn")
|
||||
return MathAtom(new MathLefteqnInset);
|
||||
|
||||
latexkeys const * l = in_word_set(s);
|
||||
if (l) {
|
||||
string const & inset = l->inset;
|
||||
@ -246,6 +212,42 @@ MathAtom createMathInset(string const & s)
|
||||
return MathAtom(new MathSymbolInset(l));
|
||||
}
|
||||
|
||||
if (s.size() == 2 && s[0] == '#' && s[1] >= '1' && s[1] <= '9')
|
||||
return MathAtom(new MathMacroArgument(s[1] - '0'));
|
||||
if (s.size() == 3 && s[0] == '\\' && s[1] == '#'
|
||||
&& s[2] >= '1' && s[2] <= '9')
|
||||
return MathAtom(new MathMacroArgument(s[2] - '0'));
|
||||
if (s == "kern")
|
||||
return MathAtom(new MathKernInset);
|
||||
if (s == "xymatrix")
|
||||
return MathAtom(new MathXYMatrixInset);
|
||||
if (s == "xrightarrow" || s == "xleftarrow")
|
||||
return MathAtom(new MathXArrowInset(s));
|
||||
if (s == "split" || s == "gathered" || s == "aligned")
|
||||
return MathAtom(new MathSplitInset(s));
|
||||
if (s == "cases")
|
||||
return MathAtom(new MathCasesInset);
|
||||
if (s == "substack")
|
||||
return MathAtom(new MathSubstackInset);
|
||||
if (s == "subarray" || s == "array")
|
||||
return MathAtom(new MathArrayInset(s, 1, 1));
|
||||
if (s == "sqrt")
|
||||
return MathAtom(new MathSqrtInset);
|
||||
if (s == "root")
|
||||
return MathAtom(new MathRootInset);
|
||||
if (s == "stackrel")
|
||||
return MathAtom(new MathStackrelInset);
|
||||
if (s == "binom" || s == "choose")
|
||||
return MathAtom(new MathBinomInset(s == "choose"));
|
||||
if (s == "over" || s == "frac")
|
||||
return MathAtom(new MathFracInset);
|
||||
if (s == "atop")
|
||||
return MathAtom(new MathFracInset(true));
|
||||
if (s == "lefteqn")
|
||||
return MathAtom(new MathLefteqnInset);
|
||||
if (s == "lyxert")
|
||||
return MathAtom(new MathErtInset);
|
||||
|
||||
if (MathMacroTable::has(s))
|
||||
return MathAtom(new MathMacro(s));
|
||||
|
||||
|
@ -128,8 +128,8 @@ void MathGridInset::setDefaults()
|
||||
{
|
||||
if (ncols() <= 0)
|
||||
lyxerr << "positive number of columns expected\n";
|
||||
if (nrows() <= 0)
|
||||
lyxerr << "positive number of rows expected\n";
|
||||
//if (nrows() <= 0)
|
||||
// lyxerr << "positive number of rows expected\n";
|
||||
for (col_type col = 0; col < ncols(); ++col) {
|
||||
colinfo_[col].align_ = defaultColAlign(col);
|
||||
colinfo_[col].skip_ = defaultColSpace(col);
|
||||
|
@ -26,6 +26,13 @@ class MathGridInset : public MathNestInset {
|
||||
int dummy_;
|
||||
/// special multi colums alignment
|
||||
string align_;
|
||||
/// these should be a per-cell property, but ok to have it here
|
||||
/// for single-column grids like paragraphs
|
||||
mutable int glue_;
|
||||
///
|
||||
mutable pos_type begin_;
|
||||
///
|
||||
mutable pos_type end_;
|
||||
};
|
||||
|
||||
/// additional per-row information
|
||||
@ -198,9 +205,9 @@ public:
|
||||
//void octavize(OctaveStream &) const;
|
||||
|
||||
protected:
|
||||
/// returns x offset of cell comapared to inset
|
||||
/// returns x offset of cell compared to inset
|
||||
int cellXOffset(idx_type idx) const;
|
||||
/// returns y offset of cell comapared to inset
|
||||
/// returns y offset of cell compared to inset
|
||||
int cellYOffset(idx_type idx) const;
|
||||
/// returns proper 'end of line' code for LaTeX
|
||||
string eolString(row_type row, bool fragile = false) const;
|
||||
@ -209,6 +216,7 @@ protected:
|
||||
/// extract number of columns from alignment string
|
||||
col_type guessColumns(string const & halign) const;
|
||||
|
||||
public:
|
||||
/// row info
|
||||
std::vector<RowInfo> rowinfo_;
|
||||
/// column info
|
||||
|
@ -280,7 +280,7 @@ WriteStream & operator<<(WriteStream & ws, MathArray const & ar)
|
||||
WriteStream & operator<<(WriteStream & ws, char const * s)
|
||||
{
|
||||
ws.os() << s;
|
||||
ws.addlines(int(lyx::count(s, s+strlen(s), '\n')));
|
||||
ws.addlines(int(lyx::count(s, s + strlen(s), '\n')));
|
||||
return ws;
|
||||
}
|
||||
|
||||
@ -288,8 +288,10 @@ WriteStream & operator<<(WriteStream & ws, char const * s)
|
||||
WriteStream & operator<<(WriteStream & ws, char c)
|
||||
{
|
||||
ws.os() << c;
|
||||
if (c == '\n')
|
||||
if (c == '\n') {
|
||||
lyxerr << "writing a newline\n";
|
||||
ws.addlines(1);
|
||||
}
|
||||
return ws;
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
#include "math_metricsinfo.h"
|
||||
#include "math_support.h"
|
||||
#include "debug.h"
|
||||
#include "frontends/Painter.h"
|
||||
|
||||
|
||||
|
@ -7,9 +7,9 @@
|
||||
|
||||
using std::vector;
|
||||
|
||||
|
||||
MathParboxInset::MathParboxInset()
|
||||
: MathNestInset(1), lyx_width_(0), tex_width_("0mm"),
|
||||
position_('c')
|
||||
: lyx_width_(0), tex_width_("0mm"), position_('c')
|
||||
{
|
||||
lyxerr << "constructing MathParboxInset\n";
|
||||
}
|
||||
@ -35,207 +35,23 @@ void MathParboxInset::setWidth(string const & w)
|
||||
}
|
||||
|
||||
|
||||
int MathParboxInset::screenrows() const
|
||||
{
|
||||
return rows_.size();
|
||||
}
|
||||
|
||||
|
||||
int MathParboxInset::pos2row(pos_type pos) const
|
||||
{
|
||||
for (int r = 0, n = rows_.size(); r < n; ++r)
|
||||
if (pos >= rows_[r].begin && pos <= rows_[r].end)
|
||||
return r;
|
||||
lyxerr << "illegal row for pos " << pos << "\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void MathParboxInset::getPos(idx_type idx, pos_type pos, int & x, int & y) const
|
||||
{
|
||||
int const r = pos2row(pos);
|
||||
MathXArray const & ar = cells_[idx];
|
||||
x = ar.xo() + ar.pos2x(rows_[r].begin, pos, rows_[r].glue);
|
||||
y = ar.yo() + rows_[r].yo;
|
||||
// move cursor visually into empty cells ("blue rectangles");
|
||||
if (cell(0).empty())
|
||||
x += 2;
|
||||
//lyxerr << "getPos cursor at pos " << pos << " in row " << r
|
||||
// << " x: " << x << " y: " << y << "\n";
|
||||
}
|
||||
|
||||
|
||||
bool MathParboxInset::idxUpDown(idx_type & idx, pos_type & pos, bool up,
|
||||
int targetx) const
|
||||
{
|
||||
// try to move only one screen row up or down if possible
|
||||
int row = pos2row(pos);
|
||||
int const x = cells_[idx].pos2x(rows_[row].begin, pos, rows_[row].glue);
|
||||
if (up) {
|
||||
if (row == 0)
|
||||
return false;
|
||||
--row;
|
||||
} else {
|
||||
++row;
|
||||
if (row == screenrows())
|
||||
return false;
|
||||
}
|
||||
pos = xcell(0).x2pos(rows_[row].begin, x, rows_[row].glue);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void MathParboxInset::metrics(MathMetricsInfo & mi) const
|
||||
{
|
||||
MathFontSetChanger dummy(mi.base, "textnormal");
|
||||
|
||||
// we do our own metrics fiddling
|
||||
// delete old cache
|
||||
rows_.clear();
|
||||
|
||||
#if 0
|
||||
|
||||
dim_ = xcell(0).metrics(mi);
|
||||
|
||||
#else
|
||||
|
||||
vector<Dimension> dims;
|
||||
xcell(0).metricsExternal(mi, dims);
|
||||
|
||||
int spaces = 0;
|
||||
Dimension safe;
|
||||
Dimension curr;
|
||||
safe.clear(mi.base.font);
|
||||
curr.clear(mi.base.font);
|
||||
int begin = 0;
|
||||
int safepos = 0;
|
||||
int yo = 0;
|
||||
for (size_type i = 0, n = cell(0).size(); i < n; ++i) {
|
||||
//lyxerr << "at pos: " << i << " of " << n << " safepos: " << safepos
|
||||
// << " curr: " << curr << " safe: " << safe
|
||||
// << " spaces: " << spaces << endl;
|
||||
|
||||
|
||||
// 0 1 2 3 4 5 6
|
||||
// <char> <char> <char> <space> <char> <char> <char>
|
||||
// ................... <safe>
|
||||
// ..........................<curr>
|
||||
// ....................<safepos>
|
||||
|
||||
// Special handling of spaces. We reached a safe position for breaking.
|
||||
if (cell(0)[i]->getChar() == ' ') {
|
||||
//lyxerr << "reached safe pos\n";
|
||||
// we don't count the space into the safe pos
|
||||
safe += curr;
|
||||
// we reset to this safepos if the next chunk does not fit
|
||||
safepos = i;
|
||||
++spaces;
|
||||
// restart chunk with size of the space
|
||||
curr.clear(mi.base.font);
|
||||
curr += dims[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
// This is a regular char. Go on if we either don't care for
|
||||
// the width limit or have not reached that limit.
|
||||
curr += dims[i];
|
||||
if (curr.w + safe.w <= lyx_width_)
|
||||
continue;
|
||||
|
||||
// We passed the limit. Create a row entry.
|
||||
//lyxerr << "passed limit\n";
|
||||
MathXArray::Row row;
|
||||
if (spaces) {
|
||||
// but we had a space break before this position.
|
||||
// so retreat to this position
|
||||
int glue = lyx_width_ - safe.w + dims[safepos].w;
|
||||
row.dim = safe;
|
||||
row.glue = glue / spaces;
|
||||
row.begin = begin;
|
||||
row.end = safepos; // this is position of the safe space
|
||||
i = safepos; // i gets incremented at end of loop
|
||||
begin = i + 1; // next chunk starts after the space
|
||||
//lyxerr << "... but had safe pos. glue: " << row.glue << "\n";
|
||||
//lyxerr << " safe.w: " << safe.w
|
||||
// << " dim.w: " << dims[safepos].w << " spaces: " << spaces << "\n";
|
||||
spaces = 0;
|
||||
} else {
|
||||
lyxerr << "... without safe pos\n";
|
||||
// This item is too large and it is the only one.
|
||||
// We have no choice but to produce an overfull box.
|
||||
row.dim = curr; // safe should be 0.
|
||||
row.glue = 0; // does not matter
|
||||
row.begin = begin;
|
||||
row.end = i + 1;
|
||||
begin = i + 1;
|
||||
}
|
||||
row.yo = yo;
|
||||
yo += row.dim.height();
|
||||
rows_.push_back(row);
|
||||
// in any case, start the new row with empty boxes
|
||||
curr.clear(mi.base.font);
|
||||
safe.clear(mi.base.font);
|
||||
}
|
||||
// last row: put in everything else
|
||||
MathXArray::Row row;
|
||||
row.dim = safe;
|
||||
row.dim += curr;
|
||||
row.begin = begin;
|
||||
row.end = cell(0).size();
|
||||
row.glue = 0; // last line is left aligned
|
||||
row.yo = yo;
|
||||
rows_.push_back(row);
|
||||
|
||||
// what to report?
|
||||
dim_.w = lyx_width_;
|
||||
dim_.a = rows_.front().dim.a;
|
||||
dim_.d = rows_.back().dim.d + yo;
|
||||
MathFontSetChanger dummy1(mi.base, "textnormal");
|
||||
MathWidthChanger dummy2(mi.base, lyx_width_);
|
||||
MathTextInset::metrics(mi);
|
||||
metricsMarkers2();
|
||||
xcell(0).setDim(dim_);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void MathParboxInset::draw(MathPainterInfo & pi, int x, int y) const
|
||||
{
|
||||
MathFontSetChanger dummy(pi.base, "textnormal");
|
||||
#if 0
|
||||
xcell(0).draw(pi, x + 1, y);
|
||||
#else
|
||||
xcell(0).drawExternal(pi, x + 1, y, rows_);
|
||||
#endif
|
||||
MathTextInset::draw(pi, x + 1, y);
|
||||
drawMarkers2(pi, x, y);
|
||||
}
|
||||
|
||||
|
||||
void MathParboxInset::drawSelection(MathPainterInfo & pi,
|
||||
idx_type, pos_type pos1, idx_type, pos_type pos2) const
|
||||
{
|
||||
int row1 = pos2row(pos1);
|
||||
int row2 = pos2row(pos2);
|
||||
if (row1 == row2) {
|
||||
/*
|
||||
MathXArray & c = xcell(0);
|
||||
int x1 = c.xo() + c.pos2x(i1.pos_);
|
||||
int y1 = c.yo() - c.ascent();
|
||||
int x2 = c.xo() + c.pos2x(i2.pos_);
|
||||
int y2 = c.yo() + c.descent();
|
||||
pi.pain.fillRectangle(x1, y1, x2 - x1, y2 - y1, LColor::selection);
|
||||
} else {
|
||||
vector<MathInset::idx_type> indices = idxBetween(idx1, idx2);
|
||||
for (unsigned i = 0; i < indices.size(); ++i) {
|
||||
MathXArray & c = i1.xcell(indices[i]);
|
||||
int x1 = c.xo();
|
||||
int y1 = c.yo() - c.ascent();
|
||||
int x2 = c.xo() + c.width();
|
||||
int y2 = c.yo() + c.descent();
|
||||
pi.pain.fillRectangle(x1, y1, x2 - x1, y2 - y1, LColor::selection);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MathParboxInset::write(WriteStream & os) const
|
||||
{
|
||||
os << "\\parbox";
|
||||
|
@ -1,9 +1,11 @@
|
||||
#ifndef MATH_PARBOXINSET_H
|
||||
#define MATH_PARBOXINSET_H
|
||||
|
||||
#include "math_nestinset.h"
|
||||
#include "math_textinset.h"
|
||||
|
||||
class MathParboxInset : public MathNestInset {
|
||||
// implements support for \parbox
|
||||
|
||||
class MathParboxInset : public MathTextInset {
|
||||
public:
|
||||
///
|
||||
MathParboxInset();
|
||||
@ -13,15 +15,10 @@ public:
|
||||
MathInset * clone() const;
|
||||
///
|
||||
mode_type currentMode() const { return TEXT_MODE; }
|
||||
/// get cursor position
|
||||
void getPos(idx_type idx, pos_type pos, int & x, int & y) const;
|
||||
///
|
||||
void metrics(MathMetricsInfo & mi) const;
|
||||
///
|
||||
void draw(MathPainterInfo &, int x, int y) const;
|
||||
/// draw selection background
|
||||
void drawSelection(MathPainterInfo & pi,
|
||||
idx_type idx1, pos_type pos1, idx_type idx2, pos_type pos2) const;
|
||||
///
|
||||
void infoize(std::ostream & os) const;
|
||||
///
|
||||
@ -30,21 +27,13 @@ public:
|
||||
void setWidth(string const & width);
|
||||
///
|
||||
void setPosition(string const & pos);
|
||||
/// moves cursor up or down
|
||||
bool idxUpDown(idx_type &, pos_type & pos, bool up, int targetx) const;
|
||||
private:
|
||||
/// number of rows on screen
|
||||
int screenrows() const;
|
||||
/// row corresponding to given position
|
||||
int pos2row(pos_type pos) const;
|
||||
/// width on screen
|
||||
int lyx_width_;
|
||||
/// width for TeX
|
||||
string tex_width_;
|
||||
/// htb
|
||||
/// one of htb
|
||||
char position_;
|
||||
/// cached metrics
|
||||
mutable std::vector<MathXArray::Row> rows_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -4,12 +4,6 @@
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
MathParInset::MathParInset()
|
||||
{
|
||||
lyxerr << "constructing MathParInset\n";
|
||||
}
|
||||
|
||||
|
||||
void MathParInset::metrics(MathMetricsInfo & mi) const
|
||||
{
|
||||
MathFontSetChanger dummy1(mi.base, "textnormal");
|
||||
|
@ -6,7 +6,7 @@
|
||||
class MathParInset : public MathHullInset {
|
||||
public:
|
||||
///
|
||||
MathParInset();
|
||||
MathParInset() {}
|
||||
///
|
||||
mode_type currentMode() const { return TEXT_MODE; }
|
||||
///
|
||||
|
@ -69,14 +69,12 @@ following hack as starting point to write some macros:
|
||||
#include "support/lstrings.h"
|
||||
|
||||
#include <cctype>
|
||||
#include <stack>
|
||||
#include <algorithm>
|
||||
|
||||
using std::istream;
|
||||
using std::ostream;
|
||||
using std::ios;
|
||||
using std::endl;
|
||||
using std::stack;
|
||||
using std::fill;
|
||||
using std::vector;
|
||||
using std::atoi;
|
||||
@ -156,7 +154,7 @@ void catInit()
|
||||
theCatcode[''] = catIgnore;
|
||||
theCatcode[' '] = catSpace;
|
||||
theCatcode['\t'] = catSpace;
|
||||
theCatcode['\r'] = catSpace;
|
||||
theCatcode['\r'] = catNewline;
|
||||
theCatcode['~'] = catActive;
|
||||
theCatcode['%'] = catComment;
|
||||
}
|
||||
@ -184,8 +182,6 @@ public:
|
||||
char character() const { return char_; }
|
||||
///
|
||||
string asString() const;
|
||||
///
|
||||
bool isCR() const;
|
||||
|
||||
private:
|
||||
///
|
||||
@ -196,11 +192,6 @@ private:
|
||||
CatCode cat_;
|
||||
};
|
||||
|
||||
bool Token::isCR() const
|
||||
{
|
||||
return cs_ == "\\" || cs_ == "cr" || cs_ == "crcr";
|
||||
}
|
||||
|
||||
string Token::asString() const
|
||||
{
|
||||
return cs_.size() ? cs_ : string(1, char_);
|
||||
@ -371,6 +362,17 @@ string Parser::getArg(char left, char right)
|
||||
}
|
||||
|
||||
|
||||
void Parser::skipSpaceTokens(istream & is, char c)
|
||||
{
|
||||
// skip trailing spaces
|
||||
while (catcode(c) == catSpace || catcode(c) == catNewline)
|
||||
if (!is.get(c))
|
||||
break;
|
||||
//lyxerr << "putting back: " << c << "\n";
|
||||
is.putback(c);
|
||||
}
|
||||
|
||||
|
||||
void Parser::tokenize(istream & is)
|
||||
{
|
||||
// eat everything up to the next \end_inset or end of stream
|
||||
@ -390,17 +392,6 @@ void Parser::tokenize(istream & is)
|
||||
}
|
||||
|
||||
|
||||
void Parser::skipSpaceTokens(istream & is, char c)
|
||||
{
|
||||
// skip trailing spaces
|
||||
while (catcode(c) == catSpace || catcode(c) == catNewline)
|
||||
if (!is.get(c))
|
||||
break;
|
||||
//lyxerr << "putting back: " << c << "\n";
|
||||
is.putback(c);
|
||||
}
|
||||
|
||||
|
||||
void Parser::tokenize(string const & buffer)
|
||||
{
|
||||
static bool init_done = false;
|
||||
@ -423,7 +414,7 @@ void Parser::tokenize(string const & buffer)
|
||||
if (catcode(c) == catNewline)
|
||||
; //push_back(Token("par"));
|
||||
else {
|
||||
push_back(Token(' ', catSpace));
|
||||
push_back(Token('\n', catNewline));
|
||||
is.putback(c);
|
||||
}
|
||||
break;
|
||||
@ -620,6 +611,9 @@ void Parser::parse1(MathGridInset & grid, unsigned flags,
|
||||
else if (t.cat() == catSpace && !mathmode)
|
||||
cell->push_back(MathAtom(new MathCharInset(t.character())));
|
||||
|
||||
else if (t.cat() == catNewline && !mathmode)
|
||||
cell->push_back(MathAtom(new MathCharInset(t.character())));
|
||||
|
||||
else if (t.cat() == catParameter) {
|
||||
Token const & n = getToken();
|
||||
cell->push_back(MathAtom(new MathMacroArgument(n.character()-'0')));
|
||||
@ -1065,8 +1059,13 @@ void Parser::parse1(MathGridInset & grid, unsigned flags,
|
||||
|
||||
else {
|
||||
MathAtom p = createMathInset(t.cs());
|
||||
bool mode = mathmode;
|
||||
if (mathmode && p->currentMode() == MathInset::TEXT_MODE)
|
||||
mode = false;
|
||||
if (!mathmode && p->currentMode() == MathInset::MATH_MODE)
|
||||
mode = true;
|
||||
for (MathInset::idx_type i = 0; i < p->nargs(); ++i)
|
||||
parse(p->cell(i), FLAG_ITEM, mathmode);
|
||||
parse(p->cell(i), FLAG_ITEM, mode);
|
||||
cell->push_back(p);
|
||||
}
|
||||
}
|
||||
|
@ -355,10 +355,10 @@ void MathScriptInset::write(WriteStream & os) const
|
||||
os << "{}";
|
||||
}
|
||||
|
||||
if (hasDown() && down().data().size())
|
||||
if (hasDown() && down().size())
|
||||
os << "_{" << down().data() << '}';
|
||||
|
||||
if (hasUp() && up().data().size())
|
||||
if (hasUp() && up().size())
|
||||
os << "^{" << up().data() << '}';
|
||||
}
|
||||
|
||||
@ -423,8 +423,8 @@ void MathScriptInset::mathematicize(MathematicaStream & os) const
|
||||
|
||||
void MathScriptInset::mathmlize( MathMLStream & os) const
|
||||
{
|
||||
bool d = hasDown() && down().data().size();
|
||||
bool u = hasUp() && up().data().size();
|
||||
bool d = hasDown() && down().size();
|
||||
bool u = hasUp() && up().size();
|
||||
|
||||
if (u && d)
|
||||
os << MTag("msubsup");
|
||||
|
@ -557,6 +557,7 @@ fontinfo fontinfos[] = {
|
||||
{"textipa", inh_family, inh_series, inh_shape, LColor::black},
|
||||
|
||||
{"lyxtex", inh_family, inh_series, inh_shape, LColor::latex},
|
||||
{"lyxert", LyXFont::TYPEWRITER_FAMILY, inh_series, inh_shape, LColor::latex},
|
||||
{"lyxsymbol", LyXFont::SYMBOL_FAMILY, inh_series, inh_shape, LColor::math},
|
||||
{"lyxboldsymbol",
|
||||
LyXFont::SYMBOL_FAMILY, LyXFont::BOLD_SERIES, inh_shape, LColor::math},
|
||||
|
165
src/mathed/math_textinset.C
Normal file
165
src/mathed/math_textinset.C
Normal file
@ -0,0 +1,165 @@
|
||||
|
||||
#include "math_textinset.h"
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
MathTextInset::MathTextInset()
|
||||
: MathNestInset(1)
|
||||
{}
|
||||
|
||||
|
||||
MathInset * MathTextInset::clone() const
|
||||
{
|
||||
return new MathTextInset(*this);
|
||||
}
|
||||
|
||||
|
||||
MathInset::idx_type MathTextInset::pos2row(pos_type pos) const
|
||||
{
|
||||
for (pos_type r = 0, n = cache_.nargs(); r < n; ++r)
|
||||
if (pos >= cache_.cellinfo_[r].begin_ && pos <= cache_.cellinfo_[r].end_)
|
||||
return r;
|
||||
lyxerr << "illegal row for pos " << pos << "\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void MathTextInset::getPos(idx_type, pos_type pos, int & x, int & y) const
|
||||
{
|
||||
idx_type const i = pos2row(pos);
|
||||
pos_type const p = pos - cache_.cellinfo_[i].begin_;
|
||||
cache_.getPos(i, p, x, y);
|
||||
}
|
||||
|
||||
|
||||
bool MathTextInset::idxUpDown(idx_type &, pos_type & pos, bool up,
|
||||
int targetx) const
|
||||
{
|
||||
// try to move only one screen row up or down if possible
|
||||
idx_type i = pos2row(pos);
|
||||
MathGridInset::CellInfo const & cell1 = cache_.cellinfo_[i];
|
||||
int const x = cells_[0].pos2x(cell1.begin_, pos, cell1.glue_);
|
||||
if (up) {
|
||||
if (i == 0)
|
||||
return false;
|
||||
--i;
|
||||
} else {
|
||||
++i;
|
||||
if (i == cache_.nargs())
|
||||
return false;
|
||||
}
|
||||
MathGridInset::CellInfo const & cell2 = cache_.cellinfo_[i];
|
||||
pos = xcell(0).x2pos(cell2.begin_, x, cell2.glue_);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void MathTextInset::metrics(MathMetricsInfo & mi) const
|
||||
{
|
||||
xcell(0).metrics(mi);
|
||||
|
||||
// we do our own metrics fiddling
|
||||
// delete old cache
|
||||
cache_ = MathGridInset(1, 0);
|
||||
|
||||
int spaces = 0;
|
||||
int safe = 0;
|
||||
int curr = 0;
|
||||
int begin = 0;
|
||||
int safepos = 0;
|
||||
for (size_type i = 0, n = cell(0).size(); i < n; ++i) {
|
||||
//lyxerr << "at pos: " << i << " of " << n << " safepos: " << safepos
|
||||
// << " curr: " << curr << " safe: " << safe
|
||||
// << " spaces: " << spaces << endl;
|
||||
|
||||
// 0 1 2 3 4 5 6
|
||||
// <char> <char> <char> <space> <char> <char> <char>
|
||||
// ................... <safe>
|
||||
// ..........................<curr>
|
||||
// ....................<safepos>
|
||||
|
||||
// Special handling of spaces. We reached a safe position for breaking.
|
||||
char const c = cell(0)[i]->getChar();
|
||||
if (c == ' ') {
|
||||
//lyxerr << "reached safe pos\n";
|
||||
// we don't count the space into the safe pos
|
||||
safe += curr;
|
||||
// we reset to this safepos if the next chunk does not fit
|
||||
safepos = i;
|
||||
++spaces;
|
||||
// restart chunk with size of the space
|
||||
curr = cell(0)[i]->width();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c != '\n') {
|
||||
// This is a regular char. Go on if we either don't care for
|
||||
// the width limit or have not reached that limit.
|
||||
curr += cell(0)[i]->width();
|
||||
if (!mi.base.restrictwidth || curr + safe <= mi.base.textwidth)
|
||||
continue;
|
||||
}
|
||||
|
||||
// We passed the limit. Create a row entry.
|
||||
//lyxerr << "passed limit\n";
|
||||
cache_.appendRow();
|
||||
MathXArray & ar = cache_.xcell(cache_.nargs() - 1);
|
||||
MathGridInset::CellInfo & row = cache_.cellinfo_.back();
|
||||
if (c == '\n') {
|
||||
// we are here because we hit a hard newline
|
||||
row.begin_ = begin;
|
||||
row.end_ = i + 1;
|
||||
begin = i + 1; // next chunk starts after the newline
|
||||
spaces = 0;
|
||||
} else if (spaces) {
|
||||
// but we had a space break before this position.
|
||||
// so retreat to this position
|
||||
//lyxerr << "... but had safe pos.\n";
|
||||
row.begin_ = begin;
|
||||
row.end_ = safepos; // this is position of the safe space
|
||||
i = safepos; // i gets incremented at end of loop
|
||||
begin = i + 1; // next chunk starts after the space
|
||||
spaces = 0;
|
||||
} else {
|
||||
// This item is too large and it is the only one.
|
||||
// We have no choice but to produce an overfull box.
|
||||
lyxerr << "... without safe pos\n";
|
||||
row.begin_ = begin;
|
||||
row.end_ = i + 1;
|
||||
begin = i + 1;
|
||||
}
|
||||
ar.data() =
|
||||
MathArray(cell(0).begin() + row.begin_, cell(0).begin() + row.end_);
|
||||
//lyxerr << "line: " << ar << "\n";
|
||||
// in any case, start the new row with empty boxes
|
||||
curr = 0;
|
||||
safe = 0;
|
||||
}
|
||||
// last row: put in everything else
|
||||
cache_.appendRow();
|
||||
MathXArray & ar = cache_.xcell(cache_.nargs() - 1);
|
||||
MathGridInset::CellInfo & row = cache_.cellinfo_.back();
|
||||
row.begin_ = begin;
|
||||
row.end_ = cell(0).size();
|
||||
ar.data() =
|
||||
MathArray(cell(0).begin() + row.begin_, cell(0).begin() + row.end_);
|
||||
//lyxerr << "last line: " << ar.data() << "\n";
|
||||
|
||||
// what to report?
|
||||
cache_.metrics(mi);
|
||||
dim_ = cache_.dimensions();
|
||||
//lyxerr << "outer dim: " << dim_ << endl;
|
||||
}
|
||||
|
||||
|
||||
void MathTextInset::draw(MathPainterInfo & pi, int x, int y) const
|
||||
{
|
||||
cache_.draw(pi, x + 1, y);
|
||||
}
|
||||
|
||||
|
||||
void MathTextInset::drawSelection(MathPainterInfo & pi,
|
||||
idx_type idx1, pos_type pos1, idx_type idx2, pos_type pos2) const
|
||||
{
|
||||
cache_.drawSelection(pi, idx1, pos1, idx2, pos2);
|
||||
}
|
32
src/mathed/math_textinset.h
Normal file
32
src/mathed/math_textinset.h
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef MATH_TEXTINSET_H
|
||||
#define MATH_TEXTINSET_H
|
||||
|
||||
#include "math_gridinset.h"
|
||||
|
||||
// not yet a substitute for the real text inset...
|
||||
|
||||
class MathTextInset : public MathNestInset {
|
||||
public:
|
||||
///
|
||||
MathTextInset();
|
||||
///
|
||||
MathInset * clone() const;
|
||||
/// get cursor position
|
||||
void getPos(idx_type idx, pos_type pos, int & x, int & y) const;
|
||||
/// this stores metrics information in cache_
|
||||
void metrics(MathMetricsInfo & mi) const;
|
||||
/// draw according to cached metrics
|
||||
void draw(MathPainterInfo &, int x, int y) const;
|
||||
/// draw selection background
|
||||
void drawSelection(MathPainterInfo & pi,
|
||||
idx_type idx1, pos_type pos1, idx_type idx2, pos_type pos2) const;
|
||||
/// moves cursor up or down
|
||||
bool idxUpDown(idx_type &, pos_type & pos, bool up, int targetx) const;
|
||||
protected:
|
||||
/// row corresponding to given position
|
||||
idx_type pos2row(pos_type pos) const;
|
||||
/// cached metrics
|
||||
mutable MathGridInset cache_;
|
||||
};
|
||||
|
||||
#endif
|
@ -50,38 +50,11 @@ Dimension const & MathXArray::metrics(MathMetricsInfo & mi) const
|
||||
}
|
||||
|
||||
|
||||
void MathXArray::metricsExternal(MathMetricsInfo & mi,
|
||||
std::vector<Dimension> & v) const
|
||||
{
|
||||
//if (clean_)
|
||||
// return;
|
||||
|
||||
clean_ = true;
|
||||
drawn_ = false;
|
||||
|
||||
if (empty()) {
|
||||
mathed_char_dim(mi.base.font, 'I', dim_);
|
||||
return;
|
||||
}
|
||||
|
||||
dim_.clear();
|
||||
for (const_iterator it = begin(), et = end(); it != et; ++it) {
|
||||
MathInset const * p = it->nucleus();
|
||||
p->metrics(mi);
|
||||
v.push_back(p->dimensions());
|
||||
}
|
||||
//for (int i = 0; i < size(); ++i)
|
||||
// lyxerr << "i: " << i << " dim: " << v[i] << endl;
|
||||
//lyxerr << "MathXArray::metrics(): '" << dim_ << "\n";
|
||||
}
|
||||
|
||||
|
||||
void MathXArray::draw(MathPainterInfo & pi, int x, int y) const
|
||||
{
|
||||
//if (drawn_ && x == xo_ && y == yo_)
|
||||
// return;
|
||||
|
||||
//lyxerr << "x: " << x << " y: " << y << " " << pain.workAreaHeight() << endl;
|
||||
//lyxerr << "MathXArray::draw: x: " << x << " y: " << y << endl;
|
||||
|
||||
xo_ = x;
|
||||
yo_ = y;
|
||||
@ -96,48 +69,18 @@ void MathXArray::draw(MathPainterInfo & pi, int x, int y) const
|
||||
if (x >= pi.pain.paperWidth()) // don't draw right of workarea
|
||||
return;
|
||||
|
||||
const_iterator it = begin(), et = end();
|
||||
|
||||
if (it == et) {
|
||||
if (empty()) {
|
||||
pi.pain.rectangle(x, y - ascent(), width(), height(), LColor::mathline);
|
||||
return;
|
||||
}
|
||||
|
||||
for (; it != et; ++it) {
|
||||
for (const_iterator it = begin(), et = end(); it != et; ++it) {
|
||||
(*it)->draw(pi, x, y);
|
||||
x += (*it)->width();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MathXArray::drawExternal(MathPainterInfo & pi, int x, int y,
|
||||
std::vector<Row> const & v) const
|
||||
{
|
||||
//for (size_type r = 0; r < v.size(); ++r)
|
||||
// lyxerr << "row " << r << " to: " << v[r].end << endl;
|
||||
//lyxerr << " data: " << *this << endl;
|
||||
|
||||
xo_ = x;
|
||||
yo_ = y;
|
||||
|
||||
for (size_type r = 0; r < v.size(); ++r) {
|
||||
int xx = x;
|
||||
int yy = y + v[r].yo;
|
||||
for (size_type pos = v[r].begin; pos < v[r].end && pos < size(); ++pos) {
|
||||
//lyxerr << "drawing pos " << pos << " of " << size()
|
||||
// << " " << int(operator[](pos)->getChar()) << endl;
|
||||
MathInset const * p = operator[](pos).nucleus();
|
||||
// insert extra glue if necessary
|
||||
if (p->getChar() == ' ')
|
||||
xx += v[r].glue;
|
||||
// ordinary case
|
||||
p->draw(pi, xx, yy);
|
||||
xx += p->width();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Dimension const & MathXArray::metricsT(TextMetricsInfo const & mi) const
|
||||
{
|
||||
//if (clean_)
|
||||
@ -155,19 +98,14 @@ void MathXArray::drawT(TextPainter & pain, int x, int y) const
|
||||
{
|
||||
//if (drawn_ && x == xo_ && y == yo_)
|
||||
// return;
|
||||
|
||||
//lyxerr << "x: " << x << " y: " << y << " " << pain.workAreaHeight() << endl;
|
||||
|
||||
xo_ = x;
|
||||
yo_ = y;
|
||||
drawn_ = true;
|
||||
|
||||
const_iterator it = begin(), et = end();
|
||||
|
||||
for (; it != et; ++it) {
|
||||
MathInset const * p = it->nucleus();
|
||||
p->drawT(pain, x, y);
|
||||
x += p->width();
|
||||
for (const_iterator it = begin(), et = end(); it != et; ++it) {
|
||||
(*it)->drawT(pain, x, y);
|
||||
x += (*it)->width();
|
||||
}
|
||||
}
|
||||
|
||||
@ -282,3 +220,10 @@ void MathXArray::towards(int & x, int & y) const
|
||||
x = cx + int(r * (x - cx));
|
||||
y = cy + int(r * (y - cy));
|
||||
}
|
||||
|
||||
|
||||
std::ostream & operator<<(std::ostream & os, MathXArray const & ar)
|
||||
{
|
||||
os << ar.data();
|
||||
}
|
||||
|
||||
|
@ -36,34 +36,12 @@ public:
|
||||
MathArray & data() { return *this; }
|
||||
MathArray const & data() const { return *this; }
|
||||
|
||||
// helper structure for external metrics computations as done
|
||||
// in parboxes
|
||||
struct Row {
|
||||
/// constructor
|
||||
Row() {}
|
||||
/// first position of this row
|
||||
size_type begin;
|
||||
/// last position of this row plus one
|
||||
size_type end;
|
||||
/// y offset relative to yo
|
||||
int yo;
|
||||
/// dimensions of this row
|
||||
Dimension dim;
|
||||
/// glue between words
|
||||
int glue;
|
||||
};
|
||||
|
||||
/// constructor
|
||||
MathXArray();
|
||||
/// rebuild cached metrics information
|
||||
Dimension const & metrics(MathMetricsInfo & mi) const;
|
||||
/// rebuild cached metrics information
|
||||
void metricsExternal(MathMetricsInfo & mi, std::vector<Dimension> &) const;
|
||||
/// redraw cell using cache metrics information
|
||||
void draw(MathPainterInfo & pi, int x, int y) const;
|
||||
/// redraw cell using external metrics information
|
||||
void drawExternal(MathPainterInfo & pi, int x, int y,
|
||||
std::vector<MathXArray::Row> const &) const;
|
||||
/// rebuild cached metrics information
|
||||
Dimension const & metricsT(TextMetricsInfo const & mi) const;
|
||||
/// redraw cell using cache metrics information
|
||||
|
Loading…
Reference in New Issue
Block a user