X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fmathed%2Fformula.C;h=a6c0b602018d1942208792fcdc2a17c6e4868572;hb=46880e2b9b49632c56bab2377ce9a3c826cf8d1d;hp=f84f38c25965fc8c0a50330d8dead9934e99a01b;hpb=65d4b136161a96d10cec620985a159cf8953303c;p=lyx.git diff --git a/src/mathed/formula.C b/src/mathed/formula.C index f84f38c259..a6c0b60201 100644 --- a/src/mathed/formula.C +++ b/src/mathed/formula.C @@ -30,18 +30,24 @@ #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" #include "math_mathmlstream.h" #include "textpainter.h" -#include "preview.h" + +#include +#include +#include using std::ostream; using std::ifstream; @@ -54,32 +60,28 @@ using std::getline; InsetFormula::InsetFormula() - : par_(MathAtom(new MathHullInset)) -{} - - -InsetFormula::InsetFormula(MathInsetTypes t) - : par_(MathAtom(new MathHullInset(t))) + : par_(MathAtom(new MathHullInset)), loader_(0) {} -InsetFormula::InsetFormula(string const & s) +InsetFormula::InsetFormula(BufferView * bv) + : par_(MathAtom(new MathHullInset)), loader_(0) { - if (s.size()) { - bool res = mathed_parse_normal(par_, s); + view_ = bv; +} - if (!res) - res = mathed_parse_normal(par_, "$" + s + "$"); - if (!res) { - lyxerr << "cannot interpret '" << s << "' as math\n"; - par_ = MathAtom(new MathHullInset(LM_OT_SIMPLE)); - } - } - metrics(); +InsetFormula::InsetFormula(string const & data) + : par_(MathAtom(new MathHullInset)), loader_(0) +{ + if (!data.size()) + return; + if (!mathed_parse_normal(par_, data)) + lyxerr << "cannot interpret '" << data << "' as math\n"; } + Inset * InsetFormula::clone(Buffer const &, bool) const { return new InsetFormula(*this); @@ -102,6 +104,7 @@ int InsetFormula::latex(Buffer const *, ostream & os, bool fragile, bool) const } + int InsetFormula::ascii(Buffer const *, ostream & os, int) const { #if 0 @@ -148,6 +151,7 @@ void InsetFormula::read(Buffer const *, LyXLex & lex) { mathed_parse_normal(par_, lex); metrics(); + updatePreview(); } @@ -161,40 +165,36 @@ 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 x = int(xx); - int w = par_->width(); - int h = par_->height(); - int a = par_->ascent(); + int const x = int(xx); + 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.font = font; - pi.base.font.setColor(LColor::math); - pi.base.style = display() ? LM_ST_DISPLAY : LM_ST_TEXT; - - 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); + 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.style = 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); + } - // preview stuff -#if 0 - ostringstream os; - WriteStream wi(os, false, false); - par_->write(wi); - if (grfx::ImagePtr image = preview(os.str())) - pain.image(x, y, w, h, *image); -#endif + par_->draw(pi, x, y); + } - xx += par_->width(); + xx += w; xo_ = x; yo_ = y; @@ -295,7 +295,7 @@ InsetFormula::localDispatch(BufferView * bv, kb_action action, int x; int y; mathcursor->getPos(x, y); - hull()->mutate(arg); + mutate(arg); mathcursor->setPos(x, y); mathcursor->normalize(); updateLocal(bv, true); @@ -318,10 +318,10 @@ InsetFormula::localDispatch(BufferView * bv, kb_action action, int x = 0; int y = 0; mathcursor->getPos(x, y); - if (getType() == LM_OT_SIMPLE) - hull()->mutate(LM_OT_EQUATION); + if (hullType() == "simple") + mutate("equation"); else - hull()->mutate(LM_OT_SIMPLE); + mutate("simple"); mathcursor->setPos(x, y); mathcursor->normalize(); updateLocal(bv, true); @@ -340,13 +340,15 @@ InsetFormula::localDispatch(BufferView * bv, kb_action action, result = InsetFormulaBase::localDispatch(bv, action, arg); } + //updatePreview(); + return result; } bool InsetFormula::display() const { - return getType() != LM_OT_SIMPLE; + return hullType() != "simple" && hullType() != "none"; } @@ -387,24 +389,120 @@ 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); - return par_->width(); + return canPreview() ? loader_->image()->getWidth() : par_->width(); +} + + +string InsetFormula::hullType() const +{ + return hull() ? hull()->getType() : "none"; +} + + +void InsetFormula::mutate(string const & type ) +{ + if (hull()) + hull()->mutate(type); } -MathInsetTypes InsetFormula::getType() const +// +// preview stuff +// + +bool InsetFormula::canPreview() const { - return hull()->getType(); + return lyxrc.preview && loader_ && !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::updatePreview() +{ + // nothing to be done if no preview requested + lyxerr << "### updatePreview() called\n"; + if (!lyxrc.preview) + return; + + // get LaTeX + ostringstream ls; + WriteStream wi(ls, false, false); + par_->write(wi); + string const data = ls.str(); + + // the preview cache, maps contents to image loaders + typedef std::map > cache_type; + static cache_type theCache; + static int theCounter = 0; + + // set our loader corresponding to our current data + cache_type::const_iterator it = theCache.find(data); + + // is this old data? + if (it != theCache.end()) { + // we have already a loader, connect to it anyway + //lyxerr << "### updatePreview(), old loader: " << loader_ << "\n"; + loader_ = it->second.get(); + loader_->statusChanged.connect + (boost::bind(&InsetFormula::statusChanged, this)); + return; + } + + // construct new file name + static string const dir = OnlyPath(lyx::tempName()); + ostringstream os; + os << dir << theCounter++ << ".lyxpreview"; + string file = os.str(); + + // the real work starts + //lyxerr << "### updatePreview(), new file " << file << "\n"; + std::ofstream of(file.c_str()); + of << "\\batchmode" + << "\\documentclass{article}" + << "\\usepackage{amssymb}" + << "\\thispagestyle{empty}" + << "\\pdfoutput=0" + << "\\begin{document}" + << data + << "\\end{document}\n"; + of.close(); + + // now we are done, start actual loading we will get called back via + // InsetFormula::statusChanged() if this is finished + theCache[data].reset(new grfx::Loader(file)); + //lyxerr << "### updatePreview(), new loader: " << loader_ << "\n"; + loader_ = theCache.find(data)->second.get(); + loader_->startLoading(); + loader_->statusChanged.connect(boost::bind(&InsetFormula::statusChanged, this)); +} +