fix for the first item on Martin's list

some infrastructure for drawing as ascii art


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@3761 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
André Pönitz 2002-03-18 11:45:53 +00:00
parent 6c80f6633d
commit 99cb25781a
16 changed files with 256 additions and 21 deletions

View File

@ -5,6 +5,8 @@ noinst_LTLIBRARIES = libmathed.la
INCLUDES = -I${srcdir}/../ $(SIGC_CFLAGS) $(BOOST_INCLUDES)
libmathed_la_SOURCES = \
textpainter.C \
textpainter.h \
formulabase.C \
formulabase.h \
formula.C \

View File

@ -47,6 +47,7 @@
#include "math_pos.h"
#include "math_spaceinset.h"
#include "undo_funcs.h"
#include "textpainter.h"
#include "frontends/Dialogs.h"
#include "intl.h"
@ -460,6 +461,12 @@ InsetFormulaBase::localDispatch(BufferView * bv, kb_action action,
break;
case LFUN_TAB:
if (0) {
TextMetricsInfo mi;
par()->metrics(mi);
TextPainter tpain(par()->width(), par()->height());
par()->draw(tpain, 0, par()->ascent());
}
mathcursor->idxNext();
updateLocal(bv, false);
break;

View File

@ -203,14 +203,9 @@ void MathCursor::pushRight(MathAtom & t)
bool MathCursor::popLeft()
{
//cerr << "Leaving atom "; par()->write(cerr, false); cerr << " left\n";
//cerr << "Leaving atom to the left\n";
if (Cursor_.size() <= 1)
return false;
if (par()->asScriptInset()) {
par()->asScriptInset()->removeEmptyScripts();
if (par()->asScriptInset()->empty())
plainErase();
}
Cursor_.pop_back();
return true;
}
@ -221,11 +216,6 @@ bool MathCursor::popRight()
//cerr << "Leaving atom "; par()->write(cerr, false); cerr << " right\n";
if (Cursor_.size() <= 1)
return false;
if (par()->asScriptInset()) {
par()->asScriptInset()->removeEmptyScripts();
if (par()->asScriptInset()->empty())
plainErase();
}
Cursor_.pop_back();
posRight();
return true;
@ -974,6 +964,19 @@ void MathCursor::normalize()
dump("error 4");
}
pos() = min(pos(), size());
// remove empty scripts if possible
for (pos_type i = 0; i < size(); ++i) {
MathScriptInset * p = array().at(i)->asScriptInset();
if (p) {
p->removeEmptyScripts();
if (p->empty())
array().erase(i);
}
}
// fix again position
pos() = min(pos(), size());
}

View File

@ -199,6 +199,20 @@ void MathHullInset::draw(Painter & pain, int x, int y) const
}
void MathHullInset::metrics(TextMetricsInfo const & mi) const
{
ascent_ = 1;
descent_ = 0;
width_ = normalName(objtype_).size();
}
void MathHullInset::draw(TextPainter & pain, int x, int y) const
{
pain.draw(x, y, normalName(objtype_).c_str());
}
string MathHullInset::label(row_type row) const
{
row_type n = nrows();

View File

@ -31,6 +31,10 @@ public:
///
void draw(Painter &, int x, int y) const;
///
void metrics(TextMetricsInfo const & st) const;
///
void draw(TextPainter &, int x, int y) const;
///
string label(row_type row) const;
///
void label(row_type row, string const & label);

View File

@ -206,6 +206,19 @@ void MathInset::draw(Painter &, int, int) const
}
void MathInset::metrics(TextMetricsInfo const & mi) const
{
lyxerr << "MathInset::metrics(Text) called directly!\n";
}
void MathInset::draw(TextPainter &, int, int) const
{
lyxerr << "MathInset::draw(Text) called directly!\n";
}
void MathInset::write(WriteStream &) const
{
lyxerr << "MathInset::write() called directly!\n";

View File

@ -99,8 +99,6 @@ public:
/// the virtual base destructor
virtual ~MathInset() {}
/// draw the object
virtual void draw(Painter &, int x, int y) const;
/// reproduce itself
virtual MathInset * clone() const = 0;
/// substitutes macro arguments if necessary
@ -108,6 +106,13 @@ public:
/// compute the size of the object, sets ascend_, descend_ and width_
// updates the (xo,yo)-caches of all contained cells
virtual void metrics(MathMetricsInfo const & st) const;
/// draw the object
virtual void draw(Painter &, int x, int y) const;
/// the ascent of the inset above the baseline
/// compute the size of the object for text based drawing
virtual void metrics(TextMetricsInfo const & st) const;
/// draw the object as text
virtual void draw(TextPainter &, int x, int y) const;
/// the ascent of the inset above the baseline
virtual int ascent() const { return 1; }
/// the descent of the inset below the baseline
@ -175,6 +180,8 @@ public:
virtual int cellXOffset(idx_type) const { return 0; }
/// any additional y-offset when drawing a cell?
virtual int cellYOffset(idx_type) const { return 0; }
/// can we enter this cell?
virtual bool validCell(idx_type) const { return true; }
/// identifies certain types of insets
virtual MathArrayInset * asArrayInset() { return 0; }

View File

@ -104,12 +104,14 @@ void MathIterator::operator++()
return;
}
// otherwise move on one cell if possible
if (top.idx_ + 1 < top.par_->nargs()) {
// otherwise try to move on one cell if possible
while (top.idx_ + 1 < top.par_->nargs()) {
// idx() == nargs() is _not_ valid!
++top.idx_;
top.pos_ = 0;
return;
if (top.par_->validCell(top.idx_)) {
top.pos_ = 0;
return;
}
}
// otherwise leave array, move on one position

View File

@ -1,7 +1,8 @@
#ifndef MATH_METRICSINFO
#define MATH_METRICSINFO
#ifndef MATH_METRICSINFO_H
#define MATH_METRICSINFO_H
#include "lyxfont.h"
#include "textpainter.h"
class BufferView;
class MathNestInset;
@ -42,4 +43,15 @@ struct MathMetricsInfo {
int idx;
};
struct TextMetricsInfo {
///
TextMetricsInfo()
{}
/// used to pass some info down
MathNestInset const * inset;
///
int idx;
};
#endif

View File

@ -201,6 +201,24 @@ void MathScriptInset::metrics(MathInset const * nuc,
}
void MathScriptInset::metrics(TextMetricsInfo const & mi) const
{
metrics(0, mi);
}
void MathScriptInset::metrics(MathInset const * nuc,
TextMetricsInfo const & mi) const
{
MathNestInset::metrics(mi_);
if (nuc)
nuc->metrics(mi);
//ascent_ = ascent2(nuc);
//descent_ = descent2(nuc);
//width_ = width2(nuc);
}
void MathScriptInset::draw(Painter & pain, int x, int y) const
{
//lyxerr << "unexpected call to MathScriptInset::draw()\n";
@ -213,7 +231,7 @@ void MathScriptInset::draw(MathInset const * nuc, Painter & pain,
{
if (nuc)
nuc->draw(pain, x + dxx(nuc), y);
else if (editing())
else // if (editing())
drawStr(pain, LM_TC_TEX, mi_, x + dxx(nuc), y, ".");
if (hasUp())
@ -223,6 +241,25 @@ void MathScriptInset::draw(MathInset const * nuc, Painter & pain,
down().draw(pain, x + dx0(nuc), y + dy0(nuc));
}
void MathScriptInset::draw(TextPainter & pain, int x, int y) const
{
//lyxerr << "unexpected call to MathScriptInset::draw()\n";
draw(0, pain, x, y);
}
void MathScriptInset::draw(MathInset const * nuc, TextPainter & pain,
int x, int y) const
{
if (nuc)
nuc->draw(pain, x + dxx(nuc), y);
if (hasUp())
up().draw(pain, x + dx1(nuc), y - dy1(nuc));
if (hasDown())
down().draw(pain, x + dx0(nuc), y + dy0(nuc));
}
bool MathScriptInset::hasLimits(MathInset const * nuc) const
{
@ -251,8 +288,10 @@ bool MathScriptInset::hasLimits(MathInset const * nuc) const
void MathScriptInset::removeEmptyScripts()
{
for (int i = 0; i <= 1; ++i)
if (script_[i] && !cell(i).size())
if (script_[i] && cell(i).size() == 0) {
cell(i).clear();
script_[i] = false;
}
}

View File

@ -28,12 +28,20 @@ public:
void metrics(MathMetricsInfo const & st) const;
///
void draw(Painter &, int x, int y) const;
///
void metrics(TextMetricsInfo const & st) const;
///
void draw(TextPainter &, int x, int y) const;
///
void metrics(MathInset const * nuc, MathMetricsInfo const & st) const;
///
void draw(MathInset const * nuc, Painter &, int x, int y) const;
///
void metrics(MathInset const * nuc, TextMetricsInfo const & st) const;
///
void draw(MathInset const * nuc, TextPainter &, int x, int y) const;
///
int ascent2(MathInset const * nuc) const;
///
int descent2(MathInset const * nuc) const;
@ -44,6 +52,8 @@ public:
bool idxLeft(idx_type &, pos_type &) const;
///
bool idxRight(idx_type &, pos_type &) const;
/// can we enter this cell?
bool validCell(idx_type i) const { return script_[i]; }
/// identifies scriptinsets
MathScriptInset const * asScriptInset() const;

View File

@ -7,6 +7,7 @@
#include "LString.h"
class Painter;
class TextPainter;
class latexkeys;
class MathMetricsInfo;
class MathInset;
@ -46,6 +47,11 @@ void drawStr(Painter & pain, MathTextCodes type, MathMetricsInfo const & siz,
void drawChar(Painter & pain, MathTextCodes type, MathMetricsInfo const & siz,
int x, int y, char c);
void drawStr(TextPainter & p, MathTextCodes type, MathMetricsInfo const & siz,
int x, int y, string const & s);
void drawChar(TextPainter & p, MathTextCodes type, MathMetricsInfo const & siz,
int x, int y, char c);
void math_font_max_dim(MathTextCodes code, MathMetricsInfo const & siz,
int & asc, int & desc);

View File

@ -7,6 +7,7 @@
#include "math_scriptinset.h"
#include "math_support.h"
#include "Painter.h"
#include "textpainter.h"
#include "debug.h"
@ -111,6 +112,62 @@ void MathXArray::draw(Painter & pain, int x, int y) const
}
void MathXArray::metrics(TextMetricsInfo const & mi) const
{
//if (clean_)
// return;
ascent_ = 0;
descent_ = 0;
width_ = 0;
for (const_iterator it = begin(); it != end(); ++it) {
MathInset const * p = it->nucleus();
MathScriptInset const * q = (it + 1 == end()) ? 0 : asScript(it);
if (q) {
q->metrics(p, mi);
ascent_ = max(ascent_, q->ascent2(p));
descent_ = max(descent_, q->descent2(p));
width_ += q->width2(p);
++it;
} else {
p->metrics(mi);
ascent_ = max(ascent_, p->ascent());
descent_ = max(descent_, p->descent());
width_ += p->width();
}
}
}
void MathXArray::draw(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();
MathScriptInset const * q = (it + 1 == et) ? 0 : asScript(it);
if (q) {
q->draw(p, pain, x, y);
x += q->width2(p);
++it;
} else {
p->draw(pain, x, y);
x += p->width();
}
}
}
int MathXArray::pos2x(size_type targetpos) const
{
int x = 0;

View File

@ -13,6 +13,7 @@
#endif
class Painter;
class TextPainter;
/** This class extends a MathArray by drawing routines and caches for
@ -32,6 +33,10 @@ public:
void metrics(MathMetricsInfo const & st) const;
/// redraw cell using cache metrics information
void draw(Painter & pain, int x, int y) const;
/// rebuild cached metrics information
void metrics(TextMetricsInfo const & st) const;
/// redraw cell using cache metrics information
void draw(TextPainter & pain, int x, int y) const;
/// mark cell for re-drawing
void touch() const;

25
src/mathed/textpainter.C Normal file
View File

@ -0,0 +1,25 @@
#include "textpainter.h"
TextPainter::TextPainter(int xmax, int ymax)
: xmax_(xmax), ymax_(ymax), data_((xmax_ + 1) * (ymax_ + 1))
{}
char & TextPainter::at(int x, int y)
{
return data_[y * xmax_ + x];
}
char TextPainter::at(int x, int y) const
{
return data_[y * xmax_ + x];
}
void TextPainter::draw(int x, int y, char const * str)
{
for (int i = 0; *str; ++i, ++str)
at(x + i, y) = *str;
}

29
src/mathed/textpainter.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef TEXTPAINTER_H
#define TEXTPAINTER_H
#include <vector>
class TextPainter {
public:
///
TextPainter(int xmax, int ymax);
///
void draw(int x, int y, char const * str);
private:
///
typedef std::vector<char> data_type;
///
char at(int x, int y) const;
///
char & at(int x, int y);
///
data_type data_;
///
int xmax_;
///
int ymax_;
};
#endif