mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-26 19:25:39 +00:00
Improve handling of top and bottom margin
The 20px space on top and bottom of document have traditionally been obtained by adding the to the ascent/descent of the first/last row. This reads to annoyances like selections that are drawn in these margins and issues with the nesting marker. The change is to add the values to a separate member of the Row object, and to add new Row::total(Ascent|Descent) methods that add the effect of this padding. Moreover, some methods are added to TextMetrics to simplify the BufferView code. Fixes bug #9545.
This commit is contained in:
parent
90dccf89e3
commit
ff7cdf1b74
@ -360,6 +360,20 @@ int BufferView::leftMargin() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int BufferView::topMargin() const
|
||||||
|
{
|
||||||
|
// original value was 20px, which is 0.2in at 100dpi
|
||||||
|
return zoomedPixels(20);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int BufferView::bottomMargin() const
|
||||||
|
{
|
||||||
|
// original value was 20px, which is 0.2in at 100dpi
|
||||||
|
return zoomedPixels(20);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int BufferView::inPixels(Length const & len) const
|
int BufferView::inPixels(Length const & len) const
|
||||||
{
|
{
|
||||||
Font const font = buffer().params().getFont();
|
Font const font = buffer().params().getFont();
|
||||||
@ -582,29 +596,25 @@ void BufferView::updateScrollbar()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Look at paragraph heights on-screen
|
// Look at paragraph heights on-screen
|
||||||
pair<pit_type, ParagraphMetrics const *> first = tm.first();
|
for (pit_type pit = tm.firstPit(); pit <= tm.lastPit(); ++pit) {
|
||||||
pair<pit_type, ParagraphMetrics const *> last = tm.last();
|
|
||||||
for (pit_type pit = first.first; pit <= last.first; ++pit) {
|
|
||||||
d->par_height_[pit] = tm.parMetrics(pit).height();
|
d->par_height_[pit] = tm.parMetrics(pit).height();
|
||||||
LYXERR(Debug::SCROLLING, "storing height for pit " << pit << " : "
|
LYXERR(Debug::SCROLLING, "storing height for pit " << pit << " : "
|
||||||
<< d->par_height_[pit]);
|
<< d->par_height_[pit]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int top_pos = first.second->position() - first.second->ascent();
|
bool first_visible = tm.firstPit() == 0 && tm.topPosition() >= 0;
|
||||||
int bottom_pos = last.second->position() + last.second->descent();
|
bool last_visible = tm.lastPit() + 1 == int(parsize) && tm.bottomPosition() <= height_;
|
||||||
bool first_visible = first.first == 0 && top_pos >= 0;
|
|
||||||
bool last_visible = last.first + 1 == int(parsize) && bottom_pos <= height_;
|
|
||||||
if (first_visible && last_visible) {
|
if (first_visible && last_visible) {
|
||||||
d->scrollbarParameters_.min = 0;
|
d->scrollbarParameters_.min = 0;
|
||||||
d->scrollbarParameters_.max = 0;
|
d->scrollbarParameters_.max = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
d->scrollbarParameters_.min = top_pos;
|
d->scrollbarParameters_.min = tm.topPosition();
|
||||||
for (size_t i = 0; i != size_t(first.first); ++i)
|
for (size_t i = 0; i != size_t(tm.firstPit()); ++i)
|
||||||
d->scrollbarParameters_.min -= d->par_height_[i];
|
d->scrollbarParameters_.min -= d->par_height_[i];
|
||||||
d->scrollbarParameters_.max = bottom_pos;
|
d->scrollbarParameters_.max = tm.bottomPosition();
|
||||||
for (size_t i = last.first + 1; i != parsize; ++i)
|
for (size_t i = tm.lastPit() + 1; i != parsize; ++i)
|
||||||
d->scrollbarParameters_.max += d->par_height_[i];
|
d->scrollbarParameters_.max += d->par_height_[i];
|
||||||
|
|
||||||
// The reference is the top position so we remove one page.
|
// The reference is the top position so we remove one page.
|
||||||
@ -941,9 +951,9 @@ bool BufferView::scrollToCursor(DocIterator const & dit, bool const recenter)
|
|||||||
bot_pit = max_pit;
|
bot_pit = max_pit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bot_pit == tm.first().first - 1)
|
if (bot_pit == tm.firstPit() - 1)
|
||||||
tm.newParMetricsUp();
|
tm.newParMetricsUp();
|
||||||
else if (bot_pit == tm.last().first + 1)
|
else if (bot_pit == tm.lastPit() + 1)
|
||||||
tm.newParMetricsDown();
|
tm.newParMetricsDown();
|
||||||
|
|
||||||
if (tm.contains(bot_pit)) {
|
if (tm.contains(bot_pit)) {
|
||||||
@ -953,8 +963,7 @@ bool BufferView::scrollToCursor(DocIterator const & dit, bool const recenter)
|
|||||||
CursorSlice const & cs = dit.innerTextSlice();
|
CursorSlice const & cs = dit.innerTextSlice();
|
||||||
int offset = coordOffset(dit).y_;
|
int offset = coordOffset(dit).y_;
|
||||||
int ypos = pm.position() + offset;
|
int ypos = pm.position() + offset;
|
||||||
Dimension const & row_dim =
|
Row const & row = pm.getRow(cs.pos(), dit.boundary());
|
||||||
pm.getRow(cs.pos(), dit.boundary()).dim();
|
|
||||||
int scrolled = 0;
|
int scrolled = 0;
|
||||||
if (recenter)
|
if (recenter)
|
||||||
scrolled = scroll(ypos - height_/2);
|
scrolled = scroll(ypos - height_/2);
|
||||||
@ -963,7 +972,7 @@ bool BufferView::scrollToCursor(DocIterator const & dit, bool const recenter)
|
|||||||
// the screen height, we scroll to a heuristic value of height_ / 4.
|
// the screen height, we scroll to a heuristic value of height_ / 4.
|
||||||
// FIXME: This heuristic value should be replaced by a recursive search
|
// FIXME: This heuristic value should be replaced by a recursive search
|
||||||
// for a row in the inset that can be visualized completely.
|
// for a row in the inset that can be visualized completely.
|
||||||
else if (row_dim.height() > height_) {
|
else if (row.height() > height_) {
|
||||||
if (ypos < defaultRowHeight())
|
if (ypos < defaultRowHeight())
|
||||||
scrolled = scroll(ypos - height_ / 4);
|
scrolled = scroll(ypos - height_ / 4);
|
||||||
else if (ypos > height_ - defaultRowHeight())
|
else if (ypos > height_ - defaultRowHeight())
|
||||||
@ -972,14 +981,14 @@ bool BufferView::scrollToCursor(DocIterator const & dit, bool const recenter)
|
|||||||
|
|
||||||
// If the top part of the row falls of the screen, we scroll
|
// If the top part of the row falls of the screen, we scroll
|
||||||
// up to align the top of the row with the top of the screen.
|
// up to align the top of the row with the top of the screen.
|
||||||
else if (ypos - row_dim.ascent() < 0 && ypos < height_) {
|
else if (ypos - row.totalAscent() < 0 && ypos < height_) {
|
||||||
int ynew = row_dim.ascent();
|
int ynew = row.totalAscent();
|
||||||
scrolled = scrollUp(ynew - ypos);
|
scrolled = scrollUp(ynew - ypos);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the bottom of the row falls of the screen, we scroll down.
|
// If the bottom of the row falls of the screen, we scroll down.
|
||||||
else if (ypos + row_dim.descent() > height_ && ypos > 0) {
|
else if (ypos + row.totalDescent() > height_ && ypos > 0) {
|
||||||
int ynew = height_ - row_dim.descent();
|
int ynew = height_ - row.totalDescent();
|
||||||
scrolled = scrollDown(ypos - ynew);
|
scrolled = scrollDown(ypos - ynew);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -997,15 +1006,14 @@ bool BufferView::scrollToCursor(DocIterator const & dit, bool const recenter)
|
|||||||
|
|
||||||
d->anchor_pit_ = bot_pit;
|
d->anchor_pit_ = bot_pit;
|
||||||
CursorSlice const & cs = dit.innerTextSlice();
|
CursorSlice const & cs = dit.innerTextSlice();
|
||||||
Dimension const & row_dim =
|
Row const & row = pm.getRow(cs.pos(), dit.boundary());
|
||||||
pm.getRow(cs.pos(), dit.boundary()).dim();
|
|
||||||
|
|
||||||
if (recenter)
|
if (recenter)
|
||||||
d->anchor_ypos_ = height_/2;
|
d->anchor_ypos_ = height_/2;
|
||||||
else if (d->anchor_pit_ == 0)
|
else if (d->anchor_pit_ == 0)
|
||||||
d->anchor_ypos_ = offset + pm.ascent();
|
d->anchor_ypos_ = offset + pm.ascent();
|
||||||
else if (d->anchor_pit_ == max_pit)
|
else if (d->anchor_pit_ == max_pit)
|
||||||
d->anchor_ypos_ = height_ - offset - row_dim.descent();
|
d->anchor_ypos_ = height_ - offset - row.totalDescent();
|
||||||
else if (offset > height_)
|
else if (offset > height_)
|
||||||
d->anchor_ypos_ = height_ - offset - defaultRowHeight();
|
d->anchor_ypos_ = height_ - offset - defaultRowHeight();
|
||||||
else
|
else
|
||||||
@ -2441,11 +2449,10 @@ int BufferView::scrollDown(int offset)
|
|||||||
TextMetrics & tm = d->text_metrics_[text];
|
TextMetrics & tm = d->text_metrics_[text];
|
||||||
int const ymax = height_ + offset;
|
int const ymax = height_ + offset;
|
||||||
while (true) {
|
while (true) {
|
||||||
pair<pit_type, ParagraphMetrics const *> last = tm.last();
|
int bottom_pos = tm.bottomPosition();
|
||||||
int bottom_pos = last.second->position() + last.second->descent();
|
|
||||||
if (lyxrc.scroll_below_document)
|
if (lyxrc.scroll_below_document)
|
||||||
bottom_pos += height_ - minVisiblePart();
|
bottom_pos += height_ - minVisiblePart();
|
||||||
if (last.first + 1 == int(text->paragraphs().size())) {
|
if (tm.lastPit() + 1 == int(text->paragraphs().size())) {
|
||||||
if (bottom_pos <= height_)
|
if (bottom_pos <= height_)
|
||||||
return 0;
|
return 0;
|
||||||
offset = min(offset, bottom_pos - height_);
|
offset = min(offset, bottom_pos - height_);
|
||||||
@ -2466,9 +2473,8 @@ int BufferView::scrollUp(int offset)
|
|||||||
TextMetrics & tm = d->text_metrics_[text];
|
TextMetrics & tm = d->text_metrics_[text];
|
||||||
int ymin = - offset;
|
int ymin = - offset;
|
||||||
while (true) {
|
while (true) {
|
||||||
pair<pit_type, ParagraphMetrics const *> first = tm.first();
|
int const top_pos = tm.topPosition();
|
||||||
int top_pos = first.second->position() - first.second->ascent();
|
if (tm.firstPit() == 0) {
|
||||||
if (first.first == 0) {
|
|
||||||
if (top_pos >= 0)
|
if (top_pos >= 0)
|
||||||
return 0;
|
return 0;
|
||||||
offset = min(offset, - top_pos);
|
offset = min(offset, - top_pos);
|
||||||
@ -2983,7 +2989,7 @@ Point BufferView::coordOffset(DocIterator const & dit) const
|
|||||||
ParagraphMetrics const & pm = tm.parMetrics(sl.pit());
|
ParagraphMetrics const & pm = tm.parMetrics(sl.pit());
|
||||||
|
|
||||||
LBUFERR(!pm.rows().empty());
|
LBUFERR(!pm.rows().empty());
|
||||||
y -= pm.rows()[0].ascent();
|
y -= pm.rows()[0].totalAscent();
|
||||||
#if 1
|
#if 1
|
||||||
// FIXME: document this mess
|
// FIXME: document this mess
|
||||||
size_t rend;
|
size_t rend;
|
||||||
@ -3000,7 +3006,7 @@ Point BufferView::coordOffset(DocIterator const & dit) const
|
|||||||
#endif
|
#endif
|
||||||
for (size_t rit = 0; rit != rend; ++rit)
|
for (size_t rit = 0; rit != rend; ++rit)
|
||||||
y += pm.rows()[rit].height();
|
y += pm.rows()[rit].height();
|
||||||
y += pm.rows()[rend].ascent();
|
y += pm.rows()[rend].totalAscent();
|
||||||
|
|
||||||
TextMetrics const & bottom_tm = textMetrics(dit.bottom().text());
|
TextMetrics const & bottom_tm = textMetrics(dit.bottom().text());
|
||||||
|
|
||||||
@ -3189,7 +3195,7 @@ void BufferView::draw(frontend::Painter & pain, bool paint_caret)
|
|||||||
: "\t\t*** START DRAWING ***"));
|
: "\t\t*** START DRAWING ***"));
|
||||||
Text & text = buffer_.text();
|
Text & text = buffer_.text();
|
||||||
TextMetrics const & tm = d->text_metrics_[&text];
|
TextMetrics const & tm = d->text_metrics_[&text];
|
||||||
int const y = tm.first().second->position();
|
int const y = tm.parMetrics(tm.firstPit()).position();
|
||||||
PainterInfo pi(this, pain);
|
PainterInfo pi(this, pain);
|
||||||
|
|
||||||
// Check whether the row where the cursor lives needs to be scrolled.
|
// Check whether the row where the cursor lives needs to be scrolled.
|
||||||
@ -3244,8 +3250,7 @@ void BufferView::draw(frontend::Painter & pain, bool paint_caret)
|
|||||||
tm.draw(pi, 0, y);
|
tm.draw(pi, 0, y);
|
||||||
|
|
||||||
// and possibly grey out below
|
// and possibly grey out below
|
||||||
pair<pit_type, ParagraphMetrics const *> lastpm = tm.last();
|
int const y2 = tm.bottomPosition();
|
||||||
int const y2 = lastpm.second->position() + lastpm.second->descent();
|
|
||||||
|
|
||||||
if (y2 < height_) {
|
if (y2 < height_) {
|
||||||
Color color = buffer().isInternal()
|
Color color = buffer().isInternal()
|
||||||
@ -3261,9 +3266,7 @@ void BufferView::draw(frontend::Painter & pain, bool paint_caret)
|
|||||||
updateScrollbar();
|
updateScrollbar();
|
||||||
|
|
||||||
// Normalize anchor for next time
|
// Normalize anchor for next time
|
||||||
pair<pit_type, ParagraphMetrics const *> firstpm = tm.first();
|
for (pit_type pit = tm.firstPit(); pit <= tm.lastPit(); ++pit) {
|
||||||
pair<pit_type, ParagraphMetrics const *> lastpm = tm.last();
|
|
||||||
for (pit_type pit = firstpm.first; pit <= lastpm.first; ++pit) {
|
|
||||||
ParagraphMetrics const & pm = tm.parMetrics(pit);
|
ParagraphMetrics const & pm = tm.parMetrics(pit);
|
||||||
if (pm.position() + pm.descent() > 0) {
|
if (pm.position() + pm.descent() > 0) {
|
||||||
if (d->anchor_pit_ != pit
|
if (d->anchor_pit_ != pit
|
||||||
|
@ -104,9 +104,12 @@ public:
|
|||||||
|
|
||||||
/// right margin
|
/// right margin
|
||||||
int rightMargin() const;
|
int rightMargin() const;
|
||||||
|
|
||||||
/// left margin
|
/// left margin
|
||||||
int leftMargin() const;
|
int leftMargin() const;
|
||||||
|
/// top margin
|
||||||
|
int topMargin() const;
|
||||||
|
/// bottom margin
|
||||||
|
int bottomMargin() const;
|
||||||
|
|
||||||
/// return the on-screen size of this length
|
/// return the on-screen size of this length
|
||||||
/*
|
/*
|
||||||
|
@ -161,6 +161,7 @@ pos_type Row::Element::right_pos() const
|
|||||||
|
|
||||||
Row::Row()
|
Row::Row()
|
||||||
: separator(0), label_hfill(0), left_margin(0), right_margin(0),
|
: separator(0), label_hfill(0), left_margin(0), right_margin(0),
|
||||||
|
top_padding(0), bottom_padding(0),
|
||||||
sel_beg(-1), sel_end(-1),
|
sel_beg(-1), sel_end(-1),
|
||||||
begin_margin_sel(false), end_margin_sel(false),
|
begin_margin_sel(false), end_margin_sel(false),
|
||||||
changed_(true),
|
changed_(true),
|
||||||
|
@ -209,6 +209,10 @@ public:
|
|||||||
int ascent() const { return dim_.asc; }
|
int ascent() const { return dim_.asc; }
|
||||||
///
|
///
|
||||||
int descent() const { return dim_.des; }
|
int descent() const { return dim_.des; }
|
||||||
|
///
|
||||||
|
int totalAscent() const { return ascent() + top_padding; }
|
||||||
|
///
|
||||||
|
int totalDescent() const { return dim_.des + bottom_padding; }
|
||||||
|
|
||||||
/// The offset of the left-most cursor position on the row
|
/// The offset of the left-most cursor position on the row
|
||||||
int left_x() const;
|
int left_x() const;
|
||||||
@ -303,6 +307,10 @@ public:
|
|||||||
int left_margin;
|
int left_margin;
|
||||||
/// the right margin of the row
|
/// the right margin of the row
|
||||||
int right_margin;
|
int right_margin;
|
||||||
|
/// possible padding above the row
|
||||||
|
int top_padding;
|
||||||
|
/// possible padding below the row
|
||||||
|
int bottom_padding;
|
||||||
///
|
///
|
||||||
mutable pos_type sel_beg;
|
mutable pos_type sel_beg;
|
||||||
///
|
///
|
||||||
|
@ -127,18 +127,15 @@ bool TextMetrics::contains(pit_type pit) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pair<pit_type, ParagraphMetrics const *> TextMetrics::first() const
|
pit_type TextMetrics::firstPit() const
|
||||||
{
|
{
|
||||||
ParMetricsCache::const_iterator it = par_metrics_.begin();
|
return par_metrics_.begin()->first;
|
||||||
return make_pair(it->first, &it->second);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pair<pit_type, ParagraphMetrics const *> TextMetrics::last() const
|
pit_type TextMetrics::lastPit() const
|
||||||
{
|
{
|
||||||
LBUFERR(!par_metrics_.empty());
|
return par_metrics_.rbegin()->first;
|
||||||
ParMetricsCache::const_reverse_iterator it = par_metrics_.rbegin();
|
|
||||||
return make_pair(it->first, &it->second);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -284,6 +281,20 @@ int TextMetrics::rightMargin(pit_type const pit) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int TextMetrics::topPosition() const
|
||||||
|
{
|
||||||
|
ParagraphMetrics const & firstpm = par_metrics_.begin()->second;
|
||||||
|
return firstpm.position() - firstpm.ascent();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int TextMetrics::bottomPosition() const
|
||||||
|
{
|
||||||
|
ParagraphMetrics const & lastpm = par_metrics_.rbegin()->second;
|
||||||
|
return lastpm.position() + lastpm.descent();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void TextMetrics::applyOuterFont(Font & font) const
|
void TextMetrics::applyOuterFont(Font & font) const
|
||||||
{
|
{
|
||||||
FontInfo lf(font_.fontInfo());
|
FontInfo lf(font_.fontInfo());
|
||||||
@ -561,21 +572,14 @@ bool TextMetrics::redoParagraph(pit_type const pit, bool const align_rows)
|
|||||||
// specially tailored for the main text.
|
// specially tailored for the main text.
|
||||||
// Top and bottom margin of the document (only at top-level)
|
// Top and bottom margin of the document (only at top-level)
|
||||||
if (text_->isMainText()) {
|
if (text_->isMainText()) {
|
||||||
// original value was 20px, which is 0.2in at 100dpi
|
|
||||||
int const margin = bv_->zoomedPixels(20);
|
|
||||||
if (pit == 0) {
|
if (pit == 0) {
|
||||||
pm.rows().front().dim().asc += margin;
|
pm.rows().front().top_padding += bv_->topMargin();
|
||||||
/* coverity thinks that we should update pm.dim().asc
|
pm.dim().asc += bv_->topMargin();
|
||||||
* below, but all the rows heights are actually counted as
|
|
||||||
* part of the paragraph metric descent see loop above).
|
|
||||||
*/
|
|
||||||
// coverity[copy_paste_error]
|
|
||||||
pm.dim().des += margin;
|
|
||||||
}
|
}
|
||||||
ParagraphList const & pars = text_->paragraphs();
|
ParagraphList const & pars = text_->paragraphs();
|
||||||
if (pit + 1 == pit_type(pars.size())) {
|
if (pit + 1 == pit_type(pars.size())) {
|
||||||
pm.rows().back().dim().des += margin;
|
pm.rows().back().bottom_padding += bv_->bottomMargin();
|
||||||
pm.dim().des += margin;
|
pm.dim().des += bv_->bottomMargin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,9 +45,10 @@ public:
|
|||||||
///
|
///
|
||||||
bool contains(pit_type pit) const;
|
bool contains(pit_type pit) const;
|
||||||
///
|
///
|
||||||
std::pair<pit_type, ParagraphMetrics const *> first() const;
|
pit_type firstPit() const;
|
||||||
///
|
///
|
||||||
std::pair<pit_type, ParagraphMetrics const *> last() const;
|
pit_type lastPit() const;
|
||||||
|
|
||||||
/// is this row the last in the text?
|
/// is this row the last in the text?
|
||||||
bool isLastRow(Row const & row) const;
|
bool isLastRow(Row const & row) const;
|
||||||
/// is this row the first in the text?
|
/// is this row the first in the text?
|
||||||
@ -123,8 +124,14 @@ public:
|
|||||||
|
|
||||||
///
|
///
|
||||||
int rightMargin(ParagraphMetrics const & pm) const;
|
int rightMargin(ParagraphMetrics const & pm) const;
|
||||||
|
///
|
||||||
int rightMargin(pit_type const pit) const;
|
int rightMargin(pit_type const pit) const;
|
||||||
|
|
||||||
|
/// position of the top of the first paragraph.
|
||||||
|
int topPosition() const;
|
||||||
|
/// position of the bottom of the last paragraph.
|
||||||
|
int bottomPosition() const;
|
||||||
|
|
||||||
///
|
///
|
||||||
void draw(PainterInfo & pi, int x, int y) const;
|
void draw(PainterInfo & pi, int x, int y) const;
|
||||||
|
|
||||||
|
@ -1046,9 +1046,8 @@ void GuiWorkArea::generateSyntheticMouseEvent()
|
|||||||
if (tm.empty())
|
if (tm.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pair<pit_type, const ParagraphMetrics *> pp = up ? tm.first() : tm.last();
|
pit_type const pit = up ? tm.firstPit() : tm.lastPit();
|
||||||
ParagraphMetrics const & pm = *pp.second;
|
ParagraphMetrics const & pm = tm.parMetrics(pit);
|
||||||
pit_type const pit = pp.first;
|
|
||||||
|
|
||||||
if (pm.rows().empty())
|
if (pm.rows().empty())
|
||||||
return;
|
return;
|
||||||
|
@ -4384,7 +4384,7 @@ void InsetTabular::metrics(MetricsInfo & mi, Dimension & dim) const
|
|||||||
|
|
||||||
// with LYX_VALIGN_BOTTOM the descent is relative to the last par
|
// with LYX_VALIGN_BOTTOM the descent is relative to the last par
|
||||||
// = descent of text in last par + bottomOffset:
|
// = descent of text in last par + bottomOffset:
|
||||||
int const lastpardes = tm.last().second->descent()
|
int const lastpardes = tm.parMetrics(tm.lastPit()).descent()
|
||||||
+ bottomOffset(mi.base.bv);
|
+ bottomOffset(mi.base.bv);
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
switch (tabular.getVAlignment(cell)) {
|
switch (tabular.getVAlignment(cell)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user