From 99cb25781ac599f3aeefb5b391b95ed26b74405f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Andr=C3=A9=20P=C3=B6nitz?= Date: Mon, 18 Mar 2002 11:45:53 +0000 Subject: [PATCH] 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 --- src/mathed/Makefile.am | 2 ++ src/mathed/formulabase.C | 7 +++++ src/mathed/math_cursor.C | 25 ++++++++------- src/mathed/math_hullinset.C | 14 +++++++++ src/mathed/math_hullinset.h | 4 +++ src/mathed/math_inset.C | 13 ++++++++ src/mathed/math_inset.h | 11 +++++-- src/mathed/math_iterator.C | 10 +++--- src/mathed/math_metricsinfo.h | 16 ++++++++-- src/mathed/math_scriptinset.C | 43 ++++++++++++++++++++++++-- src/mathed/math_scriptinset.h | 10 ++++++ src/mathed/math_support.h | 6 ++++ src/mathed/math_xdata.C | 57 +++++++++++++++++++++++++++++++++++ src/mathed/math_xdata.h | 5 +++ src/mathed/textpainter.C | 25 +++++++++++++++ src/mathed/textpainter.h | 29 ++++++++++++++++++ 16 files changed, 256 insertions(+), 21 deletions(-) create mode 100644 src/mathed/textpainter.C create mode 100644 src/mathed/textpainter.h diff --git a/src/mathed/Makefile.am b/src/mathed/Makefile.am index bb91e4f0fe..d5c8aa8df5 100644 --- a/src/mathed/Makefile.am +++ b/src/mathed/Makefile.am @@ -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 \ diff --git a/src/mathed/formulabase.C b/src/mathed/formulabase.C index d7298a06b2..2fc70e88a8 100644 --- a/src/mathed/formulabase.C +++ b/src/mathed/formulabase.C @@ -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; diff --git a/src/mathed/math_cursor.C b/src/mathed/math_cursor.C index 98e772ccb4..e62ac1920d 100644 --- a/src/mathed/math_cursor.C +++ b/src/mathed/math_cursor.C @@ -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()); } diff --git a/src/mathed/math_hullinset.C b/src/mathed/math_hullinset.C index 4d34cb134f..b1d31998dd 100644 --- a/src/mathed/math_hullinset.C +++ b/src/mathed/math_hullinset.C @@ -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(); diff --git a/src/mathed/math_hullinset.h b/src/mathed/math_hullinset.h index 35c63f12a2..98b16a5f21 100644 --- a/src/mathed/math_hullinset.h +++ b/src/mathed/math_hullinset.h @@ -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); diff --git a/src/mathed/math_inset.C b/src/mathed/math_inset.C index 57605c13be..313c23f1b8 100644 --- a/src/mathed/math_inset.C +++ b/src/mathed/math_inset.C @@ -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"; diff --git a/src/mathed/math_inset.h b/src/mathed/math_inset.h index 509eaee2ce..6783d5714c 100644 --- a/src/mathed/math_inset.h +++ b/src/mathed/math_inset.h @@ -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; } diff --git a/src/mathed/math_iterator.C b/src/mathed/math_iterator.C index 91e022bae4..9d4e9c11ba 100644 --- a/src/mathed/math_iterator.C +++ b/src/mathed/math_iterator.C @@ -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 diff --git a/src/mathed/math_metricsinfo.h b/src/mathed/math_metricsinfo.h index 9c2e720547..3046587bef 100644 --- a/src/mathed/math_metricsinfo.h +++ b/src/mathed/math_metricsinfo.h @@ -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 diff --git a/src/mathed/math_scriptinset.C b/src/mathed/math_scriptinset.C index 2576987dea..65091ea1c5 100644 --- a/src/mathed/math_scriptinset.C +++ b/src/mathed/math_scriptinset.C @@ -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; + } } diff --git a/src/mathed/math_scriptinset.h b/src/mathed/math_scriptinset.h index f09f7154a8..042d45872c 100644 --- a/src/mathed/math_scriptinset.h +++ b/src/mathed/math_scriptinset.h @@ -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; diff --git a/src/mathed/math_support.h b/src/mathed/math_support.h index ba2d711c80..9b46410b7c 100644 --- a/src/mathed/math_support.h +++ b/src/mathed/math_support.h @@ -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); diff --git a/src/mathed/math_xdata.C b/src/mathed/math_xdata.C index 2fcdbfeff3..e15e052b09 100644 --- a/src/mathed/math_xdata.C +++ b/src/mathed/math_xdata.C @@ -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; diff --git a/src/mathed/math_xdata.h b/src/mathed/math_xdata.h index 3a6739591b..082711b823 100644 --- a/src/mathed/math_xdata.h +++ b/src/mathed/math_xdata.h @@ -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; diff --git a/src/mathed/textpainter.C b/src/mathed/textpainter.C new file mode 100644 index 0000000000..b1ecc52cab --- /dev/null +++ b/src/mathed/textpainter.C @@ -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; +} diff --git a/src/mathed/textpainter.h b/src/mathed/textpainter.h new file mode 100644 index 0000000000..d5e86fbf8d --- /dev/null +++ b/src/mathed/textpainter.h @@ -0,0 +1,29 @@ +#ifndef TEXTPAINTER_H +#define TEXTPAINTER_H + +#include + +class TextPainter { + public: + /// + TextPainter(int xmax, int ymax); + /// + void draw(int x, int y, char const * str); + + private: + /// + typedef std::vector data_type; + /// + char at(int x, int y) const; + /// + char & at(int x, int y); + + /// + data_type data_; + /// + int xmax_; + /// + int ymax_; +}; + +#endif -- 2.39.5