Adapt caret height to context in mathed.

Compute a height from current font and current cell vertical
dimensions in MathData::metrics(), because this is where current font
is known.

Introduce BufferView::setCaretAscentDescent to remember this value.

This mechanism is not used for text because Cursor::current_font is
restored by undo, and the caret height would not be changed then. But
in principle it is doable.
This commit is contained in:
Jean-Marc Lasgouttes 2018-04-27 00:03:48 +02:00
parent 2f1eb35b86
commit 90cfe4ec3b
3 changed files with 40 additions and 9 deletions

View File

@ -230,7 +230,8 @@ enum ScreenUpdateStrategy {
struct BufferView::Private
{
Private(BufferView & bv) : update_strategy_(FullScreenUpdate),
Private(BufferView & bv) :
update_strategy_(FullScreenUpdate),
update_flags_(Update::Force),
wh_(0), cursor_(bv),
anchor_pit_(0), anchor_ypos_(0),
@ -238,7 +239,8 @@ struct BufferView::Private
last_inset_(0), clickable_inset_(false),
mouse_position_cache_(),
bookmark_edit_position_(-1), gui_(0),
horiz_scroll_offset_(0)
horiz_scroll_offset_(0),
caret_ascent_(0), caret_descent_(0)
{
xsel_cache_.set = false;
}
@ -317,6 +319,12 @@ struct BufferView::Private
/// a slice pointing to the start of the row where cursor was
/// at previous draw event
CursorSlice last_row_slice_;
// The vertical size of the blinking caret. Only used for math
// Using it for text could be bad when undo restores the cursor
// current font, since the caret size could become wrong.
int caret_ascent_;
int caret_descent_;
};
@ -2982,13 +2990,26 @@ bool BufferView::paragraphVisible(DocIterator const & dit) const
}
void BufferView::setCaretAscentDescent(int asc, int des)
{
d->caret_ascent_ = asc;
d->caret_descent_ = des;
}
void BufferView::caretPosAndHeight(Point & p, int & h) const
{
int asc, des;
Cursor const & cur = cursor();
if (cur.inMathed()) {
asc = d->caret_ascent_;
des = d->caret_descent_;
} else {
Font const font = cur.real_current_font;
frontend::FontMetrics const & fm = theFontMetrics(font);
int const asc = fm.maxAscent();
int const des = fm.maxDescent();
asc = fm.maxAscent();
des = fm.maxDescent();
}
h = asc + des;
p = getPos(cur);
p.y_ -= asc;

View File

@ -307,6 +307,8 @@ public:
bool paragraphVisible(DocIterator const & dit) const;
/// is the cursor currently visible in the view
bool cursorInView(Point const & p, int h) const;
/// set the ascent and descent of the caret
void setCaretAscentDescent(int asc, int des);
/// get the position and height of the caret
void caretPosAndHeight(Point & p, int & h) const;

View File

@ -262,6 +262,7 @@ bool isInside(DocIterator const & it, MathData const & ar,
void MathData::metrics(MetricsInfo & mi, Dimension & dim, bool tight) const
{
frontend::FontMetrics const & fm = theFontMetrics(mi.base.font);
BufferView * bv = mi.base.bv;
int const Iascent = fm.dimension('I').ascent();
int xascent = fm.dimension('x').ascent();
if (xascent >= Iascent)
@ -273,8 +274,8 @@ void MathData::metrics(MetricsInfo & mi, Dimension & dim, bool tight) const
MathRow mrow(mi, this);
mrow.metrics(mi, dim);
mrow_cache_[mi.base.bv] = mrow;
kerning_ = mrow.kerning(mi.base.bv);
mrow_cache_[bv] = mrow;
kerning_ = mrow.kerning(bv);
// Set a minimal ascent/descent for the cell
if (tight)
@ -286,8 +287,15 @@ void MathData::metrics(MetricsInfo & mi, Dimension & dim, bool tight) const
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.
Cursor & cur = bv->cursor();
if (cur.inMathed() && &cur.cell() == this)
bv->setCaretAscentDescent(min(dim.asc, fm.maxAscent()),
min(dim.des, fm.maxDescent()));
// Cache the dimension.
mi.base.bv->coordCache().arrays().add(this, dim);
bv->coordCache().arrays().add(this, dim);
}