diff --git a/src/mathed/Makefile.am b/src/mathed/Makefile.am index fc8b159985..43067976fe 100644 --- a/src/mathed/Makefile.am +++ b/src/mathed/Makefile.am @@ -5,8 +5,6 @@ noinst_LTLIBRARIES = libmathed.la INCLUDES = -I$(srcdir)/../ $(SIGC_CFLAGS) $(BOOST_INCLUDES) libmathed_la_SOURCES = \ - preview.h \ - preview.C \ textpainter.C \ textpainter.h \ formulabase.C \ diff --git a/src/mathed/formula.C b/src/mathed/formula.C index 794706c144..f936639491 100644 --- a/src/mathed/formula.C +++ b/src/mathed/formula.C @@ -30,12 +30,15 @@ #include "BufferView.h" #include "gettext.h" #include "debug.h" -#include "frontends/Alert.h" #include "support/LOstream.h" #include "support/LAssert.h" -#include "support/filetools.h" // LibFileSearch +#include "support/lyxlib.h" +#include "support/systemcall.h" +#include "support/filetools.h" +#include "frontends/Alert.h" #include "frontends/LyXView.h" #include "frontends/Painter.h" +#include "graphics/GraphicsImage.h" #include "lyxrc.h" #include "math_hullinset.h" #include "math_support.h" @@ -43,7 +46,9 @@ #include "textpainter.h" #include "preview.h" -#include "graphics/GraphicsCacheItem.h" +#include +#include +#include using std::ostream; using std::ifstream; @@ -57,12 +62,23 @@ using std::getline; InsetFormula::InsetFormula() : par_(MathAtom(new MathHullInset)) -{} +{ + init(); +} + + +InsetFormula::InsetFormula(InsetFormula const & f) + : InsetFormulaBase(f), par_(f.par_), loader_(f.loader_.filename()) +{ + init(); +} InsetFormula::InsetFormula(MathInsetTypes t) : par_(MathAtom(new MathHullInset(t))) -{} +{ + init(); +} InsetFormula::InsetFormula(string const & s) @@ -78,6 +94,7 @@ InsetFormula::InsetFormula(string const & s) par_ = MathAtom(new MathHullInset(LM_OT_SIMPLE)); } } + init(); metrics(); } @@ -163,43 +180,32 @@ void InsetFormula::read(Buffer const *, LyXLex & lex) void InsetFormula::draw(BufferView * bv, LyXFont const & font, int y, float & xx, bool) const { - metrics(bv, font); - int const x = int(xx); - int const w = par_->width(); - int const h = par_->height(); - int const a = par_->ascent(); + int const w = width(bv, font); + int const d = descent(bv, font); + int const a = ascent(bv, font); + int const h = a + d; MathPainterInfo pi(bv->painter()); - pi.base.style = display() ? LM_ST_DISPLAY : LM_ST_TEXT; - pi.base.font = font; - pi.base.font.setColor(LColor::math); - if (lcolor.getX11Name(LColor::mathbg)!=lcolor.getX11Name(LColor::background)) - pi.pain.fillRectangle(x, y - a, w, h, LColor::mathbg); + if (canPreview()) { + pi.pain.image(x + 1, y - a + 1, w - 2, h - 2, *(loader_.image())); + } else { + pi.base.style = display() ? LM_ST_DISPLAY : LM_ST_TEXT; + pi.base.font = font; + pi.base.font.setColor(LColor::math); + if (lcolor.getX11Name(LColor::mathbg) + != lcolor.getX11Name(LColor::background)) + pi.pain.fillRectangle(x, y - a, w, h, LColor::mathbg); - if (mathcursor && - const_cast(mathcursor->formula()) == this) - { - mathcursor->drawSelection(pi); - pi.pain.rectangle(x, y - a, w, h, LColor::mathframe); - } - - par_->draw(pi, x, y); - - // preview stuff - if (lyxrc.preview) { - ostringstream os; - WriteStream wi(os, false, false); - par_->write(wi); - if (preview(os.str(), preview_)) { - lyxerr << "image could be drawn\n"; - pi.pain.image(x + w + 2, y - a + 1, w - 2, h - 2, *(preview_->image())); - } else { - pi.pain.fillRectangle(x + w, y - a, w, h, LColor::white); + if (mathcursor && + const_cast(mathcursor->formula()) == this) + { + mathcursor->drawSelection(pi); + pi.pain.rectangle(x, y - a, w, h, LColor::mathframe); } - pi.pain.rectangle(x + w, y - a, w, h, LColor::mathframe); - xx += w; + + par_->draw(pi, x, y); } xx += w; @@ -395,22 +401,26 @@ bool InsetFormula::insetAllowed(Inset::Code code) const int InsetFormula::ascent(BufferView *, LyXFont const &) const { - return par_->ascent() + 1; + const int a = par_->ascent(); + if (!canPreview()) + return a + 1; + return a + 1 - (par_->height() - loader_.image()->getHeight()) / 2; } int InsetFormula::descent(BufferView *, LyXFont const &) const { - return par_->descent() + 1; + const int d = par_->descent(); + if (!canPreview()) + return d + 1; + return d + 1 - (par_->height() - loader_.image()->getHeight()) / 2; } int InsetFormula::width(BufferView * bv, LyXFont const & font) const { metrics(bv, font); - int const w = par_->width(); - // double the space for the preview if needed - return lyxrc.preview ? 2 * w : w; + return canPreview() ? loader_.image()->getWidth() : par_->width(); } @@ -418,3 +428,94 @@ MathInsetTypes InsetFormula::getType() const { return hull()->getType(); } + + +// +// preview stuff +// + +bool InsetFormula::canPreview() const +{ + return lyxrc.preview && !par_->asNestInset()->editing() + && loader_.status() == grfx::Ready; +} + + +void InsetFormula::statusChanged() +{ + //lyxerr << "### InsetFormula::statusChanged called!, status: " + // << loader_.status() << "\n"; + if (loader_.status() == grfx::Ready) + view()->updateInset(this, false); + else if (loader_.status() == grfx::WaitingToLoad) + loader_.startLoading(); +} + + +void InsetFormula::init() +{ + if (lyxrc.preview) + loader_.statusChanged.connect + (boost::bind(&InsetFormula::statusChanged, this)); +} + + +void InsetFormula::updatePreview() const +{ + // nothing to be done if no preview requested + if (!lyxrc.preview) + return; + //lyxerr << "### updatePreview() called\n"; + + // get LaTeX + ostringstream ls; + WriteStream wi(ls, false, false); + par_->write(wi); + string const data = ls.str(); + + // built some unique filename + ostringstream os; + os << "preview_"; + for (string::const_iterator it = data.begin(); it != data.end(); ++it) + os << char('A' + (*it & 15)) << char('a' + (*it >> 4)); + string base = os.str(); + string dir = OnlyPath(lyx::tempName()); + string file = dir + base + ".eps"; + + // everything is fine already + if (loader_.filename() == file) + return; + + // The real work starts. + string const texfile = dir + base + ".tex"; + std::ofstream of(texfile.c_str()); + of << "\\batchmode" + << "\\documentclass{article}" + << "\\usepackage{amssymb}" + << "\\thispagestyle{empty}" + << "\\pdfoutput=0" + << "\\begin{document}" + << data + << "\\end{document}\n"; + of.close(); + + string const cmd = +// "latex " + base + ".tex ; " + " +// "dvips -x 2500 -R -E -o " + base + ".eps " + base + ".dvi "; + // Herbert says this is faster + "pdflatex --interaction batchmode " + base + "; " + + "dvips -x 2000 -R -E -o " + base + ".eps " + base + ".dvi "; + //lyxerr << "calling: '" << "(cd " + dir + "; " + cmd + ")\n"; + Systemcall sc; + sc.startscript(Systemcall::Wait, "(cd " + dir + "; " + cmd + ")"); + + // now we are done, start actual loading + loader_.reset(file); + //lyxerr << "file '" << file << "' registered for preview\n"; + + // clean up a bit + lyx::unlink(dir + base + ".tex"); + lyx::unlink(dir + base + ".aux"); + lyx::unlink(dir + base + ".dvi"); + lyx::unlink(dir + base + ".log"); +} diff --git a/src/mathed/formula.h b/src/mathed/formula.h index 48916ff90b..12e94a5203 100644 --- a/src/mathed/formula.h +++ b/src/mathed/formula.h @@ -25,6 +25,7 @@ #include "math_defs.h" #include "math_atom.h" #include "graphics/GraphicsTypes.h" +#include "graphics/GraphicsLoader.h" class MathHullInset; @@ -38,6 +39,8 @@ public: /// explicit InsetFormula(string const &); /// + InsetFormula(InsetFormula const &); + /// int ascent(BufferView *, LyXFont const &) const; /// int descent(BufferView *, LyXFont const &) const; @@ -89,10 +92,18 @@ private: MathHullInset const * hull() const; /// void handleExtern(string const & arg); + /// + void statusChanged(); + /// + void init(); + /// + void updatePreview() const; + /// + bool canPreview() const; /// contents MathAtom par_; /// LaTeX preview - mutable grfx::GraphicPtr preview_; + mutable grfx::Loader loader_; }; #endif diff --git a/src/mathed/formulabase.C b/src/mathed/formulabase.C index dd2e3ddc3e..c8e5f0f608 100644 --- a/src/mathed/formulabase.C +++ b/src/mathed/formulabase.C @@ -24,6 +24,7 @@ #include "formula.h" #include "formulamacro.h" +#include "lyxrc.h" #include "commandtags.h" #include "BufferView.h" #include "lyxtext.h" @@ -157,6 +158,8 @@ void InsetFormulaBase::metrics(BufferView * bv) const mi.base.font = font_; mi.base.font.setColor(LColor::math); par()->metrics(mi); + if (lyxrc.preview) + updatePreview(); } @@ -519,7 +522,7 @@ InsetFormulaBase::localDispatch(BufferView * bv, kb_action action, case LFUN_BACKSPACE: bv->lockedInsetStoreUndo(Undo::DELETE); mathcursor->backspace(); - bv->updateInset(this, true); + updateLocal(bv, true); break; case LFUN_DELETE_WORD_FORWARD: diff --git a/src/mathed/formulabase.h b/src/mathed/formulabase.h index 0f7be78eaf..d72e3fdb79 100644 --- a/src/mathed/formulabase.h +++ b/src/mathed/formulabase.h @@ -138,6 +138,8 @@ protected: void metrics(BufferView * bv = 0) const; /// void handleFont(BufferView * bv, string const & arg, string const & font); + /// + virtual void updatePreview() const {} /// mutable int xo_; diff --git a/src/mathed/preview.C b/src/mathed/preview.C index 7c53763307..3448fce4df 100644 --- a/src/mathed/preview.C +++ b/src/mathed/preview.C @@ -1,91 +1 @@ -#include - -#include "debug.h" -#include "support/systemcall.h" -#include "graphics/GraphicsTypes.h" -#include "graphics/GraphicsImage.h" -#include "graphics/GraphicsCache.h" -#include "graphics/GraphicsImage.h" -#include "graphics/GraphicsParams.h" -#include "graphics/GraphicsCacheItem.h" -#include "Lsstream.h" - -#include - -#include -#include - -using namespace std; - - -// built some unique filename -string canonical_name(string const & str) -{ - ostringstream os; - for (string::const_iterator it = str.begin(); it != str.end(); ++it) - os << char('A' + (*it & 15)) << char('a' + (*it >> 4)); - return os.str(); -} - - -bool preview(string const & str, grfx::GraphicPtr & graphic) -{ - string base = canonical_name(str); - string dir = "/tmp/lyx/"; - string file = dir + base + ".eps"; - cerr << "writing '" << str << "' to '" << file << "'\n"; - - // get the cache - grfx::GCache & gc = grfx::GCache::get(); - - // look up the file - if (gc.inCache(file)) { - - // it's already in there. Get hold of it. - grfx::GraphicPtr gr = grfx::GraphicPtr(gc.graphic(file)); - - // is it already loaded? - if (gr->status() == grfx::Loaded) { - cerr << "file '" << file << "' ready for display\n"; - graphic = gr; - grfx::GParams pars; - bool const res = graphic->image()->setPixmap(pars); - return res; - } - - // otherwise we have to wait again - cerr << "file '" << file << "' not finished loading\n"; - return false; - } - - // The real work starts. - string const texfile = dir + base + ".tex"; - std::ofstream of(texfile.c_str()); - of << "\\batchmode" - << "\\documentclass{article}" - << "\\usepackage{amssymb}" - << "\\thispagestyle{empty}" - << "\\pdfoutput=0" - << "\\begin{document}" - << str - << "\\end{document}\n"; - of.close(); - - string const cmd = -// "latex " + base + ".tex ; " + " -// "dvips -x 2500 -R -E -o " + base + ".eps " + base + ".dvi "; - // Herbert says this is faster - "pdflatex --interaction batchmode " + base + "; " + - "dvips -x 2000 -R -E -o " + base + ".eps " + base + ".dvi "; - //cerr << "calling: '" << "(cd " + dir + "; " + cmd + ")\n"; - Systemcall sc; - sc.startscript(Systemcall::Wait, "(cd " + dir + "; " + cmd + ")"); - - // now we are done, add the file to the cache - gc.add(file); - gc.graphic(file)->startLoading(); - - // This might take a while. Wait for the next round. - cerr << "file '" << file << "' registered\n"; - return false; -} +// code is currently directly inseide InsetFormula