#include "mathed/InsetMathUnknown.h"
-#include "support/debug.h"
-#include "support/docstream.h"
-
#include "frontends/FontMetrics.h"
-#include "frontends/Painter.h"
+#include "support/debug.h"
+#include "support/docstream.h"
#include "support/gettext.h"
#include "support/lassert.h"
#include "support/lyxalgo.h"
}
+bool MathData::addToMathRow(MathRow & mrow, MetricsInfo & mi) const
+{
+ bool has_contents = false;
+ BufferView * bv = mi.base.bv;
+ MathData * ar = const_cast<MathData*>(this);
+ ar->updateMacros(&bv->cursor(), mi.macrocontext,
+ InternalUpdate);
+
+ // FIXME: for completion, try to insert the relevant data in the
+ // mathrow (like is done for text rows). We could add a pair of
+ // InsetMathColor inset, but these come with extra spacing of
+ // their own.
+ DocIterator const & inlineCompletionPos = bv->inlineCompletionPos();
+ bool const has_completion = inlineCompletionPos.inMathed()
+ && &inlineCompletionPos.cell() == this;
+ size_t const compl_pos = has_completion ? inlineCompletionPos.pos() : 0;
+
+ for (size_t i = 0 ; i < size() ; ++i) {
+ has_contents |= (*this)[i]->addToMathRow(mrow, mi);
+ if (i + 1 == compl_pos) {
+ mrow.back().compl_text = bv->inlineCompletion();
+ mrow.back().compl_unique_to = bv->inlineCompletionUniqueChars();
+ }
+ }
+ return has_contents;
+}
+
+
#if 0
namespace {
mindes_ = (3 * xascent) / 4;
slevel_ = (4 * xascent) / 5;
sshift_ = xascent / 4;
- kerning_ = 0;
-
- if (empty()) {
- // Cache the dimension.
- mi.base.bv->coordCache().arrays().add(this, dim);
- return;
- }
-
- Cursor & cur = mi.base.bv->cursor();
- const_cast<MathData*>(this)->updateMacros(&cur, mi.macrocontext, InternalUpdate);
-
- DocIterator const & inlineCompletionPos = mi.base.bv->inlineCompletionPos();
- MathData const * inlineCompletionData = 0;
- if (inlineCompletionPos.inMathed())
- inlineCompletionData = &inlineCompletionPos.cell();
-
- dim.asc = 0;
- dim.wid = 0;
- Dimension d;
- CoordCache::Insets & coords = mi.base.bv->coordCache().insets();
- for (pos_type i = 0, n = size(); i != n; ++i) {
- MathAtom const & at = operator[](i);
- at->metrics(mi, d);
- coords.add(at.nucleus(), d);
- dim += d;
- if (i == n - 1)
- kerning_ = at->kerning(mi.base.bv);
-
- // HACK to draw completion suggestion inline
- if (inlineCompletionData != this
- || size_t(inlineCompletionPos.pos()) != i + 1)
- continue;
- docstring const & completion = mi.base.bv->inlineCompletion();
- if (completion.length() == 0)
- continue;
+ MathRow mrow(mi, this);
+ mrow_cache_[mi.base.bv] = mrow;
+ mrow.metrics(mi, dim);
+ kerning_ = mrow.kerning(mi.base.bv);
- FontInfo font = mi.base.font;
- augmentFont(font, from_ascii("mathnormal"));
- dim.wid += mathed_string_width(font, completion);
- }
// Cache the dimension.
mi.base.bv->coordCache().arrays().add(this, dim);
}
-void MathData::draw(PainterInfo & pi, int x, int y) const
+void MathData::draw(PainterInfo & pi, int const x, int const y) const
{
//lyxerr << "MathData::draw: x: " << x << " y: " << y << endl;
BufferView & bv = *pi.base.bv;
Dimension const & dim = bv.coordCache().getArrays().dim(this);
- if (empty()) {
- pi.pain.rectangle(x, y - dim.ascent(), dim.width(), dim.height(), Color_mathline);
- return;
- }
-
// don't draw outside the workarea
if (y + dim.descent() <= 0
|| y - dim.ascent() >= bv.workHeight()
|| x >= bv. workWidth())
return;
- DocIterator const & inlineCompletionPos = bv.inlineCompletionPos();
- MathData const * inlineCompletionData = 0;
- if (inlineCompletionPos.inMathed())
- inlineCompletionData = &inlineCompletionPos.cell();
-
- CoordCache::Insets & coords = pi.base.bv->coordCache().insets();
- for (size_t i = 0, n = size(); i != n; ++i) {
- MathAtom const & at = operator[](i);
- coords.add(at.nucleus(), x, y);
- at->drawSelection(pi, x, y);
- at->draw(pi, x, y);
- x += coords.dim(at.nucleus()).wid;
-
- // Is the inline completion here?
- if (inlineCompletionData != this
- || size_t(inlineCompletionPos.pos()) != i + 1)
- continue;
- docstring const & completion = bv.inlineCompletion();
- if (completion.length() == 0)
- continue;
- FontInfo f = pi.base.font;
- augmentFont(f, from_ascii("mathnormal"));
-
- // draw the unique and the non-unique completion part
- // Note: this is not time-critical as it is
- // only done once per screen.
- size_t uniqueTo = bv.inlineCompletionUniqueChars();
- docstring s1 = completion.substr(0, uniqueTo);
- docstring s2 = completion.substr(uniqueTo);
-
- if (!s1.empty()) {
- f.setColor(Color_inlinecompletion);
- pi.pain.text(x, y, s1, f);
- x += mathed_string_width(f, s1);
- }
-
- if (!s2.empty()) {
- f.setColor(Color_nonunique_inlinecompletion);
- pi.pain.text(x, y, s2, f);
- x += mathed_string_width(f, s2);
- }
- }
+ MathRow const & mrow = mrow_cache_[pi.base.bv];
+ mrow.draw(pi, x, y);
}
void MathData::detachMacroParameters(DocIterator * cur, const size_type macroPos)
{
MathMacro * macroInset = operator[](macroPos).nucleus()->asMacro();
+ // We store this now, because the inset pointer will be invalidated in the scond loop below
+ size_t const optionals = macroInset->optionals();
// detach all arguments
vector<MathData> detachedArgs;
// only [] after the last non-empty argument can be dropped later
size_t lastNonEmptyOptional = 0;
- for (size_t l = 0; l < detachedArgs.size() && l < macroInset->optionals(); ++l) {
+ for (size_t l = 0; l < detachedArgs.size() && l < optionals; ++l) {
if (!detachedArgs[l].empty())
lastNonEmptyOptional = l;
}
// optional arguments to be put back?
pos_type p = macroPos + 1;
size_t j = 0;
- for (; j < detachedArgs.size() && j < macroInset->optionals(); ++j) {
+ // We do not want to use macroInset below, the insert() call in
+ // the loop will invalidate it.
+ macroInset = 0;
+ for (; j < detachedArgs.size() && j < optionals; ++j) {
// another non-empty parameter follows?
bool canDropEmptyOptional = j >= lastNonEmptyOptional;
int MathData::pos2x(BufferView const * bv, size_type pos) const
-{
- return pos2x(bv, pos, 0);
-}
-
-
-int MathData::pos2x(BufferView const * bv, size_type pos, int glue) const
{
int x = 0;
size_type target = min(pos, size());
CoordCache::Insets const & coords = bv->coordCache().getInsets();
for (size_type i = 0; i < target; ++i) {
const_iterator it = begin() + i;
- if ((*it)->getChar() == ' ')
- x += glue;
//lyxerr << "char: " << (*it)->getChar()
// << "width: " << (*it)->width() << endl;
x += coords.dim((*it).nucleus()).wid;
MathData::size_type MathData::x2pos(BufferView const * bv, int targetx) const
-{
- return x2pos(bv, targetx, 0);
-}
-
-
-MathData::size_type MathData::x2pos(BufferView const * bv, int targetx, int glue) const
{
const_iterator it = begin();
int lastx = 0;
// find first position after targetx
for (; currx < targetx && it != end(); ++it) {
lastx = currx;
- if ((*it)->getChar() == ' ')
- currx += glue;
currx += coords.dim((*it).nucleus()).wid;
}