mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-23 05:25:26 +00:00
* 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:
parent
80a05b1eb5
commit
d35d25460b
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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_;
|
||||
///
|
||||
|
17
src/Text.cpp
17
src/Text.cpp
@ -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);
|
||||
}
|
||||
|
27
src/Text.h
27
src/Text.h
@ -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:
|
||||
|
115
src/Text2.cpp
115
src/Text2.cpp
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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_;
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user