* Text: Move some more stuff from Text to TextMetrics:

- getFont() becomes TextMetrics::getDisplayFont()
- setCharFont() now needs a display font.
- setInsetFont() and setFont() now needs a BufferView, will be transferred to TextMetrics too.
- isRTL(): moved to TextMetrics
- isRTLBoundary(): ditto
- font_: ditto

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@20014 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Abdelrazak Younes 2007-09-02 21:48:49 +00:00
parent 80a05b1eb5
commit d35d25460b
13 changed files with 238 additions and 222 deletions

View File

@ -1459,9 +1459,10 @@ Font Cursor::getFont() const
// on space? Take the font before (only for RTL boundary stay)
if (pos > 0) {
TextMetrics const & tm = bv().textMetrics(&text);
if (pos == sl.lastpos()
|| (par.isSeparator(pos) &&
!text.isRTLBoundary(buffer(), par, pos)))
!tm.isRTLBoundary(par, pos)))
--pos;
}
@ -1509,6 +1510,7 @@ void Cursor::setCurrentFont()
pos_type cpos = pos();
Paragraph & par = paragraph();
Text const & ctext = *text();
TextMetrics const & tm = bv().textMetrics(&ctext);
// are we behind previous char in fact? -> go to that char
if (cpos > 0 && boundary())
@ -1524,7 +1526,7 @@ void Cursor::setCurrentFont()
// abc| def -> font of c
// abc |[WERBEH], i.e. boundary==true -> font of c
// abc [WERBEH]| def, font of the space
if (!ctext.isRTLBoundary(buffer(), par, cpos))
if (!tm.isRTLBoundary(par, cpos))
--cpos;
}
}
@ -1532,11 +1534,11 @@ void Cursor::setCurrentFont()
// get font
BufferParams const & bufparams = buffer().params();
current_font = par.getFontSettings(bufparams, cpos);
real_current_font = ctext.getFont(buffer(), par, cpos);
real_current_font = tm.getDisplayFont(par, cpos);
// special case for paragraph end
if (pos() == lastpos()
&& ctext.isRTLBoundary(buffer(), par, pos())
&& tm.isRTLBoundary(par, pos())
&& !boundary()) {
Language const * lang = par.getParLanguage(bufparams);
current_font.setLanguage(lang);

View File

@ -14,18 +14,17 @@
#include "FontIterator.h"
#include "Buffer.h"
#include "Text.h"
#include "TextMetrics.h"
#include "Paragraph.h"
namespace lyx {
FontIterator::FontIterator(Buffer const & buffer, Text const & text,
FontIterator::FontIterator(TextMetrics const & tm,
Paragraph const & par, pos_type pos)
: buffer_(buffer), text_(text), par_(par), pos_(pos),
font_(text.getFont(buffer, par, pos)),
: tm_(tm), par_(par), pos_(pos),
font_(tm.getDisplayFont(par, pos)),
endspan_(par.fontSpan(pos).last),
bodypos_(par.beginOfBody())
{}
@ -47,7 +46,7 @@ FontIterator & FontIterator::operator++()
{
++pos_;
if (pos_ > endspan_ || pos_ == bodypos_) {
font_ = text_.getFont(buffer_, par_, pos_);
font_ = tm_.getDisplayFont(par_, pos_);
endspan_ = par_.fontSpan(pos_).last;
}
return *this;

View File

@ -27,16 +27,15 @@
namespace lyx {
class Buffer;
class Text;
class Paragraph;
class TextMetrics;
class FontIterator : std::iterator<std::forward_iterator_tag, Font>
{
public:
///
FontIterator(Buffer const & buffer, Text const & text,
FontIterator(TextMetrics const & tm,
Paragraph const & par, pos_type pos);
///
Font const & operator*() const;
@ -47,9 +46,7 @@ public:
private:
///
Buffer const & buffer_;
///
Text const & text_;
TextMetrics const & tm_;
///
Paragraph const & par_;
///

View File

@ -440,6 +440,7 @@ void Text::insertChar(Cursor & cur, char_type c)
recordUndo(cur, Undo::INSERT);
TextMetrics const & tm = cur.bv().textMetrics(this);
Buffer const & buffer = cur.buffer();
Paragraph & par = cur.paragraph();
// try to remove this
@ -458,8 +459,8 @@ void Text::insertChar(Cursor & cur, char_type c)
!(contains(number_seperators, c) &&
cur.pos() != 0 &&
cur.pos() != cur.lastpos() &&
getFont(buffer, par, cur.pos()).number() == Font::ON &&
getFont(buffer, par, cur.pos() - 1).number() == Font::ON)
tm.getDisplayFont(par, cur.pos()).number() == Font::ON &&
tm.getDisplayFont(par, cur.pos() - 1).number() == Font::ON)
)
number(cur); // Set current_font.number to OFF
} else if (isDigit(c) &&
@ -473,11 +474,13 @@ void Text::insertChar(Cursor & cur, char_type c)
|| par.isSeparator(cur.pos() - 2)
|| par.isNewline(cur.pos() - 2))
) {
setCharFont(buffer, pit, cur.pos() - 1, cur.current_font);
setCharFont(buffer, pit, cur.pos() - 1, cur.current_font,
tm.font_);
} else if (contains(number_seperators, c)
&& cur.pos() >= 2
&& getFont(buffer, par, cur.pos() - 2).number() == Font::ON) {
setCharFont(buffer, pit, cur.pos() - 1, cur.current_font);
&& tm.getDisplayFont(par, cur.pos() - 2).number() == Font::ON) {
setCharFont(buffer, pit, cur.pos() - 1, cur.current_font,
tm.font_);
}
}
}
@ -508,7 +511,7 @@ void Text::insertChar(Cursor & cur, char_type c)
if ((cur.pos() >= 2) && (par.isLineSeparator(cur.pos() - 1))) {
// get font in front and behind the space in question. But do NOT
// use getFont(cur.pos()) because the character c is not inserted yet
Font const & pre_space_font = getFont(buffer, par, cur.pos() - 2);
Font const & pre_space_font = tm.getDisplayFont(par, cur.pos() - 2);
Font const & post_space_font = cur.real_current_font;
bool pre_space_rtl = pre_space_font.isVisibleRightToLeft();
bool post_space_rtl = post_space_font.isVisibleRightToLeft();
@ -521,7 +524,7 @@ void Text::insertChar(Cursor & cur, char_type c)
(pre_space_rtl == par.isRightToLeftPar(buffer.params())) ?
pre_space_font.language() : post_space_font.language();
Font space_font = getFont(buffer, par, cur.pos() - 1);
Font space_font = tm.getDisplayFont(par, cur.pos() - 1);
space_font.setLanguage(lang);
par.setFont(cur.pos() - 1, space_font);
}

View File

@ -52,11 +52,6 @@ public:
// count as empty.
bool empty() const;
///
Font getFont(Buffer const & buffer, Paragraph const & par,
pos_type pos) const;
///
void applyOuterFont(Buffer const & buffer, Font &) const;
///
Font getLayoutFont(Buffer const & buffer, pit_type pit) const;
///
@ -67,7 +62,7 @@ public:
* and the inset is not allowed inside a font change (see below).
*/
void setCharFont(Buffer const & buffer, pit_type pit, pos_type pos,
Font const & font);
Font const & font, Font const & display_font);
/** Needed to propagate font changes to all text cells of insets
* that are not allowed inside a font change (bug 1973).
@ -76,7 +71,7 @@ public:
* FIXME: This should be removed, see documentation of noFontChange
* in insetbase.h
*/
void setInsetFont(Buffer const & buffer, pit_type pit, pos_type pos,
void setInsetFont(BufferView const & bv, pit_type pit, pos_type pos,
Font const & font, bool toggleall = false);
/// what you expect when pressing \<enter\> at cursor position
@ -106,7 +101,7 @@ public:
/// FIXME: replace Cursor with DocIterator.
void setFont(Cursor & cur, Font const &, bool toggleall = false);
/// Set font from \p begin to \p end and rebreak.
void setFont(Buffer const & buffer, CursorSlice const & begin,
void setFont(BufferView const & bv, CursorSlice const & begin,
CursorSlice const & end, Font const &,
bool toggleall = false);
@ -257,14 +252,6 @@ public:
docstring getPossibleLabel(Cursor & cur) const;
/// is this paragraph right-to-left?
bool isRTL(Buffer const &, Paragraph const & par) const;
/// is this position in the paragraph right-to-left?
bool isRTL(Buffer const & buffer, CursorSlice const & sl, bool boundary) const;
/// is between pos-1 and pos an RTL<->LTR boundary?
bool isRTLBoundary(Buffer const & buffer, Paragraph const & par,
pos_type pos) const;
/// would be a RTL<->LTR boundary between pos and the given font?
bool isRTLBoundary(Buffer const & buffer, Paragraph const & par,
pos_type pos, Font const & font) const;
///
bool checkAndActivateInset(Cursor & cur, bool front);
@ -289,14 +276,6 @@ public:
///
ParagraphList pars_;
/// FIXME: this font_ member has nothing to do here!
/// It is used in applyOuterFont() and setCharFont() for reasons
/// that are not clear... to hand hand the outermost language and
/// also for char style apparently.
/// our 'outermost' font. This is handed down from the surrounding
/// inset through the pi/mi parameter (pi.base.font)
Font font_;
///
bool autoBreakRows_;
private:

View File

@ -81,92 +81,6 @@ bool Text::isMainText(Buffer const & buffer) const
}
// Gets the fully instantiated font at a given position in a paragraph
// Basically the same routine as Paragraph::getFont() in Paragraph.cpp.
// The difference is that this one is used for displaying, and thus we
// are allowed to make cosmetic improvements. For instance make footnotes
// smaller. (Asger)
Font Text::getFont(Buffer const & buffer, Paragraph const & par,
pos_type const pos) const
{
BOOST_ASSERT(pos >= 0);
LayoutPtr const & layout = par.layout();
// FIXME: broken?
BufferParams const & params = buffer.params();
pos_type const body_pos = par.beginOfBody();
// We specialize the 95% common case:
if (!par.getDepth()) {
Font f = par.getFontSettings(params, pos);
if (!isMainText(buffer))
applyOuterFont(buffer, f);
Font lf;
Font rlf;
if (layout->labeltype == LABEL_MANUAL && pos < body_pos) {
lf = layout->labelfont;
rlf = layout->reslabelfont;
} else {
lf = layout->font;
rlf = layout->resfont;
}
// In case the default family has been customized
if (lf.family() == Font::INHERIT_FAMILY)
rlf.setFamily(params.getFont().family());
return f.realize(rlf);
}
// The uncommon case need not be optimized as much
Font layoutfont;
if (pos < body_pos)
layoutfont = layout->labelfont;
else
layoutfont = layout->font;
Font font = par.getFontSettings(params, pos);
font.realize(layoutfont);
if (!isMainText(buffer))
applyOuterFont(buffer, font);
// Find the pit value belonging to paragraph. This will not break
// even if pars_ would not be a vector anymore.
// Performance appears acceptable.
pit_type pit = pars_.size();
for (pit_type it = 0; it < pit; ++it)
if (&pars_[it] == &par) {
pit = it;
break;
}
// Realize against environment font information
// NOTE: the cast to pit_type should be removed when pit_type
// changes to a unsigned integer.
if (pit < pit_type(pars_.size()))
font.realize(outerFont(pit, pars_));
// Realize with the fonts of lesser depth.
font.realize(params.getFont());
return font;
}
// There are currently two font mechanisms in LyX:
// 1. The font attributes in a lyxtext, and
// 2. The inset-specific font properties, defined in an inset's
// metrics() and draw() methods and handed down the inset chain through
// the pi/mi parameters, and stored locally in a lyxtext in font_.
// This is where the two are integrated in the final fully realized
// font.
void Text::applyOuterFont(Buffer const & buffer, Font & font) const {
Font lf(font_);
lf.reduce(buffer.params().getFont());
lf.realize(font);
lf.setLanguage(font.language());
font = lf;
}
Font Text::getLayoutFont(Buffer const & buffer, pit_type const pit) const
{
LayoutPtr const & layout = pars_[pit].layout();
@ -209,7 +123,7 @@ Font Text::getLabelFont(Buffer const & buffer, Paragraph const & par) const
void Text::setCharFont(Buffer const & buffer, pit_type pit,
pos_type pos, Font const & fnt)
pos_type pos, Font const & fnt, Font const & display_font)
{
Font font = fnt;
LayoutPtr const & layout = pars_[pit].layout();
@ -237,7 +151,7 @@ void Text::setCharFont(Buffer const & buffer, pit_type pit,
// Inside inset, apply the inset's font attributes if any
// (charstyle!)
if (!isMainText(buffer))
layoutfont.realize(font_);
layoutfont.realize(display_font);
layoutfont.realize(buffer.params().getFont());
@ -248,7 +162,7 @@ void Text::setCharFont(Buffer const & buffer, pit_type pit,
}
void Text::setInsetFont(Buffer const & buffer, pit_type pit,
void Text::setInsetFont(BufferView const & bv, pit_type pit,
pos_type pos, Font const & font, bool toggleall)
{
BOOST_ASSERT(pars_[pit].isInset(pos) &&
@ -263,7 +177,7 @@ void Text::setInsetFont(Buffer const & buffer, pit_type pit,
CursorSlice cellend = cs;
cellend.pit() = cellend.lastpit();
cellend.pos() = cellend.lastpos();
text->setFont(buffer, cs, cellend, font, toggleall);
text->setFont(bv, cs, cellend, font, toggleall);
}
}
}
@ -425,15 +339,17 @@ void Text::setFont(Cursor & cur, Font const & font, bool toggleall)
// Ok, we have a selection.
recordUndoSelection(cur);
setFont(cur.buffer(), cur.selectionBegin().top(),
setFont(cur.bv(), cur.selectionBegin().top(),
cur.selectionEnd().top(), font, toggleall);
}
void Text::setFont(Buffer const & buffer, CursorSlice const & begin,
void Text::setFont(BufferView const & bv, CursorSlice const & begin,
CursorSlice const & end, Font const & font,
bool toggleall)
{
Buffer const & buffer = bv.buffer();
// Don't use forwardChar here as ditend might have
// pos() == lastpos() and forwardChar would miss it.
// Can't use forwardPos either as this descends into
@ -449,10 +365,11 @@ void Text::setFont(Buffer const & buffer, CursorSlice const & begin,
// text cells of the inset (bug 1973).
// FIXME: This should change, see documentation
// of noFontChange in Inset.h
setInsetFont(buffer, pit, pos, font, toggleall);
Font f = getFont(buffer, dit.paragraph(), pos);
setInsetFont(bv, pit, pos, font, toggleall);
TextMetrics const & tm = bv.textMetrics(this);
Font f = tm.getDisplayFont(dit.paragraph(), pos);
f.update(font, language, toggleall);
setCharFont(buffer, pit, pos, f);
setCharFont(buffer, pit, pos, f, tm.font_);
}
}
}
@ -735,10 +652,10 @@ bool Text::cursorRight(Cursor & cur)
if (checkAndActivateInset(cur, true))
return false;
TextMetrics const & tm = cur.bv().textMetrics(this);
// if left of boundary -> just jump to right side
// but for RTL boundaries don't, because: abc|DDEEFFghi -> abcDDEEF|Fghi
if (cur.boundary() &&
!isRTLBoundary(cur.buffer(), cur.paragraph(), cur.pos()))
// but for RTL boundaries don't, because: abc|DDEEFFghi -> abcDDEEF|Fghi
if (cur.boundary() && !tm.isRTLBoundary(cur.paragraph(), cur.pos()))
return setCursor(cur, cur.pit(), cur.pos(), true, false);
// next position is left of boundary,
@ -767,7 +684,7 @@ bool Text::cursorRight(Cursor & cur)
// in front of RTL boundary? Stay on this side of the boundary because:
// ab|cDDEEFFghi -> abc|DDEEFFghi
if (isRTLBoundary(cur.buffer(), cur.paragraph(), cur.pos() + 1))
if (tm.isRTLBoundary(cur.paragraph(), cur.pos() + 1))
return setCursor(cur, cur.pit(), cur.pos() + 1, true, true);
// move right

View File

@ -103,7 +103,8 @@ namespace {
if (font.language() != ignore_language ||
font.number() != Font::IGNORE) {
Paragraph & par = cur.paragraph();
if (cur.boundary() != text->isRTLBoundary(cur.buffer(), par,
TextMetrics const & tm = cur.bv().textMetrics(text);
if (cur.boundary() != tm.isRTLBoundary(par,
cur.pos(), cur.real_current_font))
text->setCursor(cur, cur.pit(), cur.pos(),
false, !cur.boundary());
@ -251,56 +252,6 @@ bool Text::isRTL(Buffer const & buffer, Paragraph const & par) const
}
bool Text::isRTL(Buffer const & buffer, CursorSlice const & sl, bool boundary) const
{
if (!lyxrc.rtl_support && !sl.text())
return false;
int correction = 0;
if (boundary && sl.pos() > 0)
correction = -1;
Paragraph const & par = getPar(sl.pit());
return getFont(buffer, par, sl.pos() + correction).isVisibleRightToLeft();
}
bool Text::isRTLBoundary(Buffer const & buffer, Paragraph const & par,
pos_type pos) const
{
if (!lyxrc.rtl_support)
return false;
// no RTL boundary at line start
if (pos == 0)
return false;
bool left = getFont(buffer, par, pos - 1).isVisibleRightToLeft();
bool right;
if (pos == par.size())
right = par.isRightToLeftPar(buffer.params());
else
right = getFont(buffer, par, pos).isVisibleRightToLeft();
return left != right;
}
bool Text::isRTLBoundary(Buffer const & buffer, Paragraph const & par,
pos_type pos, Font const & font) const
{
if (!lyxrc.rtl_support)
return false;
bool left = font.isVisibleRightToLeft();
bool right;
if (pos == par.size())
right = par.isRightToLeftPar(buffer.params());
else
right = getFont(buffer, par, pos).isVisibleRightToLeft();
return left != right;
}
void Text::dispatch(Cursor & cur, FuncRequest & cmd)
{
LYXERR(Debug::ACTION) << "Text::dispatch: cmd: " << cmd << endl;

View File

@ -198,6 +198,135 @@ int TextMetrics::rightMargin(pit_type const pit) const
}
void TextMetrics::applyOuterFont(Font & font) const
{
Font lf(font_);
lf.reduce(bv_->buffer().params().getFont());
lf.realize(font);
lf.setLanguage(font.language());
font = lf;
}
Font TextMetrics::getDisplayFont(Paragraph const & par,
pos_type const pos) const
{
BOOST_ASSERT(pos >= 0);
LayoutPtr const & layout = par.layout();
Buffer const & buffer = bv_->buffer();
// FIXME: broken?
BufferParams const & params = buffer.params();
pos_type const body_pos = par.beginOfBody();
// We specialize the 95% common case:
if (!par.getDepth()) {
Font f = par.getFontSettings(params, pos);
if (!text_->isMainText(buffer))
applyOuterFont(f);
Font lf;
Font rlf;
if (layout->labeltype == LABEL_MANUAL && pos < body_pos) {
lf = layout->labelfont;
rlf = layout->reslabelfont;
} else {
lf = layout->font;
rlf = layout->resfont;
}
// In case the default family has been customized
if (lf.family() == Font::INHERIT_FAMILY)
rlf.setFamily(params.getFont().family());
return f.realize(rlf);
}
// The uncommon case need not be optimized as much
Font layoutfont;
if (pos < body_pos)
layoutfont = layout->labelfont;
else
layoutfont = layout->font;
Font font = par.getFontSettings(params, pos);
font.realize(layoutfont);
if (!text_->isMainText(buffer))
applyOuterFont(font);
// Find the pit value belonging to paragraph. This will not break
// even if pars_ would not be a vector anymore.
// Performance appears acceptable.
ParagraphList const & pars = text_->paragraphs();
pit_type pit = pars.size();
for (pit_type it = 0; it < pit; ++it)
if (&pars[it] == &par) {
pit = it;
break;
}
// Realize against environment font information
// NOTE: the cast to pit_type should be removed when pit_type
// changes to a unsigned integer.
if (pit < pit_type(pars.size()))
font.realize(outerFont(pit, pars));
// Realize with the fonts of lesser depth.
font.realize(params.getFont());
return font;
}
bool TextMetrics::isRTL(CursorSlice const & sl, bool boundary) const
{
if (!lyxrc.rtl_support && !sl.text())
return false;
int correction = 0;
if (boundary && sl.pos() > 0)
correction = -1;
Paragraph const & par = text_->getPar(sl.pit());
return getDisplayFont(par, sl.pos() + correction).isVisibleRightToLeft();
}
bool TextMetrics::isRTLBoundary(Paragraph const & par,
pos_type pos) const
{
if (!lyxrc.rtl_support)
return false;
// no RTL boundary at line start
if (pos == 0)
return false;
bool left = getDisplayFont(par, pos - 1).isVisibleRightToLeft();
bool right;
if (pos == par.size())
right = par.isRightToLeftPar(bv_->buffer().params());
else
right = getDisplayFont(par, pos).isVisibleRightToLeft();
return left != right;
}
bool TextMetrics::isRTLBoundary(Paragraph const & par,
pos_type pos, Font const & font) const
{
if (!lyxrc.rtl_support)
return false;
bool left = font.isVisibleRightToLeft();
bool right;
if (pos == par.size())
right = par.isRightToLeftPar(bv_->buffer().params());
else
right = getDisplayFont(par, pos).isVisibleRightToLeft();
return left != right;
}
bool TextMetrics::redoParagraph(pit_type const pit)
{
Paragraph & par = text_->getPar(pit);
@ -243,7 +372,7 @@ bool TextMetrics::redoParagraph(pit_type const pit)
int const w = max_width_ - leftMargin(max_width_, pit, ii->pos)
- right_margin;
Font const & font = ii->inset->noFontChange() ?
bufferfont : text_->getFont(buffer, par, ii->pos);
bufferfont : getDisplayFont(par, ii->pos);
MetricsInfo mi(bv_, font, w);
changed |= ii->inset->metrics(mi, dim);
changed |= (old_dim != dim);
@ -531,7 +660,7 @@ pit_type TextMetrics::rowBreakPoint(int width, pit_type const pit,
// pixel width since last breakpoint
int chunkwidth = 0;
FontIterator fi = FontIterator(buffer, *text_, par, pos);
FontIterator fi = FontIterator(*this, par, pos);
pos_type point = end;
pos_type i = pos;
for ( ; i < end; ++i, ++fi) {
@ -622,7 +751,7 @@ int TextMetrics::rowWidth(int right_margin, pit_type const pit,
pos_type i = first;
if (i < end) {
FontIterator fi = FontIterator(buffer, *text_, par, i);
FontIterator fi = FontIterator(*this, par, i);
for ( ; i < end; ++i, ++fi) {
if (body_pos > 0 && i == body_pos) {
FontMetrics const & fm = theFontMetrics(
@ -668,7 +797,7 @@ boost::tuple<int, int> TextMetrics::rowHeight(pit_type const pit, pos_type const
// start with so we don't have to do the assignment below too
// often.
Buffer const & buffer = bv_->buffer();
Font font = text_->getFont(buffer, par, first);
Font font = getDisplayFont(par, first);
Font::FONT_SIZE const tmpsize = font.size();
font = text_->getLayoutFont(buffer, pit);
Font::FONT_SIZE const size = font.size();
@ -933,7 +1062,7 @@ pos_type TextMetrics::getColumnNearX(pit_type const pit,
bool const rtl = (bidi.level(c) % 2 == 1);
if (left_side == rtl) {
++c;
boundary = text_->isRTLBoundary(buffer, par, c);
boundary = isRTLBoundary(par, c);
}
}
@ -1319,7 +1448,7 @@ int TextMetrics::cursorX(CursorSlice const & sl,
// Use font span to speed things up, see above
if (pos < font_span.first || pos > font_span.last) {
font_span = par.fontSpan(pos);
font = text_->getFont(buffer, par, pos);
font = getDisplayFont(par, pos);
}
x += pm.singleWidth(pos, font);
@ -1332,7 +1461,7 @@ int TextMetrics::cursorX(CursorSlice const & sl,
// see correction above
if (boundary_correction) {
if (text_->isRTL(buffer, sl, boundary))
if (isRTL(sl, boundary))
x -= singleWidth(pit, ppos);
else
x += singleWidth(pit, ppos);
@ -1648,10 +1777,9 @@ int TextMetrics::leftMargin(int max_width,
int TextMetrics::singleWidth(pit_type pit, pos_type pos) const
{
Buffer const & buffer = bv_->buffer();
ParagraphMetrics const & pm = par_metrics_[pit];
return pm.singleWidth(pos, text_->getFont(buffer, text_->getPar(pit), pos));
return pm.singleWidth(pos, getDisplayFont(text_->getPar(pit), pos));
}
@ -1886,7 +2014,7 @@ void TextMetrics::drawRowSelection(PainterInfo & pi, int x, Row const & row,
// but for RTL boundaries don't, because: abc|DDEEFFghi -> abcDDEEF|Fghi
if (cur.boundary()) {
cur.boundary(false);
} else if (text_->isRTLBoundary(buffer, cur.paragraph(), cur.pos() + 1)) {
} else if (isRTLBoundary(cur.paragraph(), cur.pos() + 1)) {
// in front of RTL boundary -> Stay on this side of the boundary because:
// ab|cDDEEFFghi -> abc|DDEEFFghi
++cur.pos();

View File

@ -14,6 +14,7 @@
#ifndef TEXT_METRICS_H
#define TEXT_METRICS_H
#include "Font.h"
#include "ParagraphMetrics.h"
#include "support/types.h"
@ -48,6 +49,33 @@ public:
/// compute text metrics.
bool metrics(MetricsInfo & mi, Dimension & dim);
/// Gets the fully instantiated font at a given position in a paragraph
/// Basically the same routine as Paragraph::getFont() in Paragraph.cpp.
/// The difference is that this one is used for displaying, and thus we
/// are allowed to make cosmetic improvements. For instance make footnotes
/// smaller. (Asger)
Font getDisplayFont(Paragraph const & par,
pos_type pos) const;
/// There are currently two font mechanisms in LyX:
/// 1. The font attributes in a lyxtext, and
/// 2. The inset-specific font properties, defined in an inset's
/// metrics() and draw() methods and handed down the inset chain through
/// the pi/mi parameters, and stored locally in a lyxtext in font_.
/// This is where the two are integrated in the final fully realized
/// font.
void applyOuterFont(Font &) const;
/// is this position in the paragraph right-to-left?
bool isRTL(CursorSlice const & sl, bool boundary) const;
/// is between pos-1 and pos an RTL<->LTR boundary?
bool isRTLBoundary(Paragraph const & par,
pos_type pos) const;
/// would be a RTL<->LTR boundary between pos and the given font?
bool isRTLBoundary(Paragraph const & par,
pos_type pos, Font const & font) const;
/// Rebreaks the given paragraph.
/// \retval true if a full screen redraw is needed.
/// \retval false if a single paragraph redraw is enough.
@ -227,6 +255,16 @@ private:
/// Paragraph grouped by owning text
ParPosCache pars_;
*/
// temporary public:
public:
/// our 'outermost' font.
/// This is handed down from the surrounding
/// inset through the pi/mi parameter (pi.base.font)
/// It is used in applyOuterFont() and setCharFont() for reasons
/// that are not clear... to hand hand the outermost language and
/// also for char style apparently.
Font font_;
};
/// return the default height of a row in pixels, considering font zoom

View File

@ -175,7 +175,7 @@ Point coordOffset(BufferView const & bv, DocIterator const & dit,
// of xx:yy
if (sl.text()) {
bool boundary_i = boundary && i + 1 == dit.depth();
bool rtl = sl.text()->isRTL(bv.buffer(), sl, boundary_i);
bool rtl = bv.textMetrics(sl.text()).isRTL(sl, boundary_i);
if (rtl)
x -= lastw;
}
@ -211,15 +211,16 @@ Point coordOffset(BufferView const & bv, DocIterator const & dit,
y += pm.rows()[rit].height();
y += pm.rows()[rend].ascent();
TextMetrics const & bottom_tm = bv.textMetrics(dit.bottom().text());
// Make relative position from the nested inset now bufferview absolute.
int xx = bv.textMetrics(dit.bottom().text()).cursorX(
dit.bottom(), boundary && dit.depth() == 1);
int xx = bottom_tm.cursorX(dit.bottom(), boundary && dit.depth() == 1);
x += xx;
// In the RTL case place the nested inset at the left of the cursor in
// the outer paragraph
bool boundary_1 = boundary && 1 == dit.depth();
bool rtl = dit.bottom().text()->isRTL(bv.buffer(), dit.bottom(), boundary_1);
bool rtl = bottom_tm.isRTL(dit.bottom(), boundary_1);
if (rtl)
x -= lastw;

View File

@ -4747,7 +4747,8 @@ bool InsetTabular::insertPlaintextString(BufferView & bv, docstring const & buf,
if (cols < columns) {
shared_ptr<InsetText> inset = loctab->getCellInset(cell);
Paragraph & par = inset->text_.getPar(0);
Font const font = inset->text_.getFont(buffer, par, 0);
Font const font = bv.textMetrics(&inset->text_).
getDisplayFont(par, 0);
inset->setText(buf.substr(op, p - op), font,
buffer.params().trackChanges);
++cols;
@ -4759,7 +4760,8 @@ bool InsetTabular::insertPlaintextString(BufferView & bv, docstring const & buf,
if (cols < columns) {
shared_ptr<InsetText> inset = tabular.getCellInset(cell);
Paragraph & par = inset->text_.getPar(0);
Font const font = inset->text_.getFont(buffer, par, 0);
Font const font = bv.textMetrics(&inset->text_).
getDisplayFont(par, 0);
inset->setText(buf.substr(op, p - op), font,
buffer.params().trackChanges);
}
@ -4776,7 +4778,7 @@ bool InsetTabular::insertPlaintextString(BufferView & bv, docstring const & buf,
if (cell < cells && op < len) {
shared_ptr<InsetText> inset = loctab->getCellInset(cell);
Paragraph & par = inset->text_.getPar(0);
Font const font = inset->text_.getFont(buffer, par, 0);
Font const font = bv.textMetrics(&inset->text_).getDisplayFont(par, 0);
inset->setText(buf.substr(op, len - op), font,
buffer.params().trackChanges);
}

View File

@ -165,7 +165,7 @@ bool InsetText::metrics(MetricsInfo & mi, Dimension & dim) const
//lyxerr << "InsetText::metrics: width: " << mi.base.textwidth << endl;
// Hand font through to contained lyxtext:
text_.font_ = mi.base.font;
tm.font_ = mi.base.font;
mi.base.textwidth -= 2 * border_;
tm.metrics(mi, dim);
mi.base.textwidth += 2 * border_;

View File

@ -123,7 +123,7 @@ void RowPainter::paintHfill(pos_type const pos, pos_type const body_pos)
void RowPainter::paintInset(Inset const * inset, pos_type const pos)
{
Font font = text_.getFont(pi_.base.bv->buffer(), par_, pos);
Font font = text_metrics_.getDisplayFont(par_, pos);
BOOST_ASSERT(inset);
// FIXME: We should always use font, see documentation of
@ -194,7 +194,7 @@ void RowPainter::paintHebrewComposeChar(pos_type & vpos, Font const & font)
if (!Encodings::isComposeChar_hebrew(c)) {
if (isPrintableNonspace(c)) {
int const width2 = pm_.singleWidth(i,
text_.getFont(pi_.base.bv->buffer(), par_, i));
text_metrics_.getDisplayFont(par_, i));
dx = (c == 0x05e8 || // resh
c == 0x05d3) // dalet
? width2 - width
@ -228,7 +228,7 @@ void RowPainter::paintArabicComposeChar(pos_type & vpos, Font const & font)
if (!Encodings::isComposeChar_arabic(c)) {
if (isPrintableNonspace(c)) {
int const width2 = pm_.singleWidth(i,
text_.getFont(pi_.base.bv->buffer(), par_, i));
text_metrics_.getDisplayFont(par_, i));
dx = (width2 - width) / 2;
}
break;
@ -348,7 +348,7 @@ void RowPainter::paintForeignMark(double orig_x, Font const & font, int desc)
void RowPainter::paintFromPos(pos_type & vpos)
{
pos_type const pos = bidi_.vis2log(vpos);
Font orig_font = text_.getFont(pi_.base.bv->buffer(), par_, pos);
Font orig_font = text_metrics_.getDisplayFont(par_, pos);
double const orig_x = x_;
// usual characters, no insets
@ -701,7 +701,6 @@ void RowPainter::paintText()
// Use font span to speed things up, see below
FontSpan font_span;
Font font;
Buffer const & buffer = pi_.base.bv->buffer();
// If the last logical character is a separator, don't paint it, unless
// it's in the last row of a paragraph; see skipped_sep_vpos declaration
@ -728,7 +727,7 @@ void RowPainter::paintText()
// Use font span to speed things up, see above
if (vpos < font_span.first || vpos > font_span.last) {
font_span = par_.fontSpan(vpos);
font = text_.getFont(buffer, par_, vpos);
font = text_metrics_.getDisplayFont(par_, vpos);
}
const int width_pos = pm_.singleWidth(pos, font);
@ -773,7 +772,7 @@ void RowPainter::paintText()
++vpos;
} else if (par_.isSeparator(pos)) {
Font orig_font = text_.getFont(buffer, par_, pos);
Font orig_font = text_metrics_.getDisplayFont(par_, pos);
double const orig_x = x_;
x_ += width_pos;
if (pos >= body_pos)