]> git.lyx.org Git - lyx.git/blobdiff - src/mathed/MathData.cpp
Fix a crash with uninitialized buffer member of MathData
[lyx.git] / src / mathed / MathData.cpp
index beb1299b9afa565a3f63a1cb9f3d00683fd87218..9bfd558fe2856d8e1475648b8c9b1963255cf25a 100644 (file)
@@ -48,10 +48,18 @@ namespace lyx {
 
 MathData::MathData(Buffer * buf, const_iterator from, const_iterator to)
        : base_type(from, to), minasc_(0), mindes_(0), slevel_(0),
-         sshift_(0), kerning_(0), buffer_(buf)
+         sshift_(0), buffer_(buf)
 {}
 
 
+void MathData::setBuffer(Buffer & b)
+{
+       buffer_ = &b;
+       for (MathAtom & at : *this)
+               at.nucleus()->setBuffer(b);
+}
+
+
 MathAtom & MathData::operator[](pos_type pos)
 {
        LBUFERR(pos < size());
@@ -212,11 +220,6 @@ bool MathData::contains(MathData const & ar) const
 }
 
 
-void MathData::touch() const
-{
-}
-
-
 bool MathData::addToMathRow(MathRow & mrow, MetricsInfo & mi) const
 {
        bool has_contents = false;
@@ -264,13 +267,14 @@ bool isInside(DocIterator const & it, MathData const & ar,
 #endif
 
 
-void MathData::metrics(MetricsInfo & mi, Dimension & dim) const
+void MathData::metrics(MetricsInfo & mi, Dimension & dim, bool tight) const
 {
        frontend::FontMetrics const & fm = theFontMetrics(mi.base.font);
-       dim = fm.dimension('I');
-       int xascent = fm.dimension('x').ascent();
-       if (xascent >= dim.asc)
-               xascent = (2 * dim.asc) / 3;
+       BufferView * bv = mi.base.bv;
+       int const Iascent = fm.dimension('I').ascent();
+       int xascent = fm.xHeight();
+       if (xascent >= Iascent)
+               xascent = (2 * Iascent) / 3;
        minasc_ = xascent;
        mindes_ = (3 * xascent) / 4;
        slevel_ = (4 * xascent) / 5;
@@ -278,11 +282,30 @@ void MathData::metrics(MetricsInfo & mi, Dimension & dim) const
 
        MathRow mrow(mi, this);
        mrow.metrics(mi, dim);
-       mrow_cache_[mi.base.bv] = mrow;
-       kerning_ = mrow.kerning(mi.base.bv);
 
-       // Cache the dimension.
-       mi.base.bv->coordCache().arrays().add(this, dim);
+       // Set a minimal ascent/descent for the cell
+       if (tight)
+               // FIXME: this is the minimal ascent seen empirically, check
+               // what the TeXbook says.
+               dim.asc = max(dim.asc, fm.xHeight());
+       else {
+               dim.asc = max(dim.asc, fm.maxAscent());
+               dim.des = max(dim.des, fm.maxDescent());
+       }
+
+       // This is one of the the few points where the drawing font is known,
+       // so that we can set the caret vertical dimensions.
+       mrow.caret_ascent = min(dim.asc, fm.maxAscent());
+       mrow.caret_descent = min(dim.des, fm.maxDescent());
+       /// do the same for math cells linearized in the row
+       MathRow caret_row = MathRow(mrow.caret_ascent, mrow.caret_descent);
+       for (auto const & e : mrow)
+               if (e.type == MathRow::BEGIN && e.ar)
+                       bv->setMathRow(e.ar, caret_row);
+
+       // Cache row and dimension.
+       bv->setMathRow(this, mrow);
+       bv->coordCache().arrays().add(this, dim);
 }
 
 
@@ -326,7 +349,7 @@ void MathData::draw(PainterInfo & pi, int const x, int const y) const
        setXY(*pi.base.bv, x, y);
 
        drawSelection(pi, x, y);
-       MathRow const & mrow = mrow_cache_[pi.base.bv];
+       MathRow const & mrow = pi.base.bv->mathRow(this);
        mrow.draw(pi, x, y);
 }
 
@@ -357,6 +380,12 @@ void MathData::drawT(TextPainter & pain, int x, int y) const
 }
 
 
+int MathData::kerning(BufferView const * bv) const
+{
+       return  bv->mathRow(this).kerning(bv);
+}
+
+
 void MathData::updateBuffer(ParIterator const & it, UpdateType utype)
 {
        // pass down