Correctly set font decorations for multipar insets

Font decorations such as underline cannot be set for a whole inset
that allows paragraph breaks. This commit allows to still set the
font main properties for the whole inset but decorations are applied
to each paragraph inside the inset.
This commit is contained in:
Enrico Forestieri 2020-08-14 12:04:23 +02:00
parent 4c3139314b
commit 5791b8bff8
3 changed files with 63 additions and 42 deletions

View File

@ -112,6 +112,15 @@ void Font::setLanguage(Language const * l)
}
void Font::setProperties(FontInfo const & f)
{
bits_.setFamily(f.family());
bits_.setSeries(f.series());
bits_.setShape(f.shape());
bits_.setSize(f.size());
}
/// Updates font settings according to request
void Font::update(Font const & newfont,
Language const * document_language,
@ -228,7 +237,7 @@ int Font::latexWriteStartChanges(otexstream & os, BufferParams const & bparams,
OutputParams const & runparams,
Font const & base,
Font const & prev,
bool const & non_inherit_inset,
bool const & multipar_inset,
bool const & needs_cprotection) const
{
int count = 0;
@ -343,7 +352,7 @@ int Font::latexWriteStartChanges(otexstream & os, BufferParams const & bparams,
count += strlen(LaTeXSizeSwitchNames[f.size()]) + 1;
}
if (f.family() != INHERIT_FAMILY) {
if (non_inherit_inset) {
if (multipar_inset) {
os << '{';
++count;
os << '\\' << LaTeXFamilySwitchNames[f.family()] << termcmd;
@ -360,7 +369,7 @@ int Font::latexWriteStartChanges(otexstream & os, BufferParams const & bparams,
}
}
if (f.series() != INHERIT_SERIES) {
if (non_inherit_inset) {
if (multipar_inset) {
os << '{';
++count;
os << '\\' << LaTeXSeriesSwitchNames[f.series()] << termcmd;
@ -377,7 +386,7 @@ int Font::latexWriteStartChanges(otexstream & os, BufferParams const & bparams,
}
}
if (f.shape() != INHERIT_SHAPE) {
if (non_inherit_inset) {
if (multipar_inset) {
os << '{';
++count;
os << '\\' << LaTeXShapeSwitchNames[f.shape()] << termcmd;
@ -393,7 +402,7 @@ int Font::latexWriteStartChanges(otexstream & os, BufferParams const & bparams,
count += strlen(LaTeXShapeCommandNames[f.shape()]) + 2;
}
}
if (f.color() != Color_inherit && f.color() != Color_ignore) {
if (f.color() != Color_inherit && f.color() != Color_ignore && !multipar_inset) {
if (f.color() == Color_none && p.color() != Color_none) {
// Color none: Close previous color, if any
os << '}';
@ -439,7 +448,7 @@ int Font::latexWriteStartChanges(otexstream & os, BufferParams const & bparams,
count += 9;
}
}
if (f.emph() == FONT_ON) {
if (f.emph() == FONT_ON && !multipar_inset) {
if (needs_cprotection) {
os << "\\cprotect";
count += 9;
@ -448,7 +457,7 @@ int Font::latexWriteStartChanges(otexstream & os, BufferParams const & bparams,
count += 6;
}
// \noun{} is a LyX special macro
if (f.noun() == FONT_ON) {
if (f.noun() == FONT_ON && !multipar_inset) {
if (needs_cprotection) {
os << "\\cprotect";
count += 9;
@ -459,7 +468,7 @@ int Font::latexWriteStartChanges(otexstream & os, BufferParams const & bparams,
// The ulem commands need to be on the deepest nesting level
// because ulem puts every nested group or macro in a box,
// which prevents linebreaks (#8424, #8733)
if (f.underbar() == FONT_ON) {
if (f.underbar() == FONT_ON && !multipar_inset) {
if (needs_cprotection) {
os << "\\cprotect";
count += 9;
@ -468,7 +477,7 @@ int Font::latexWriteStartChanges(otexstream & os, BufferParams const & bparams,
count += 7;
++runparams.inulemcmd;
}
if (f.uuline() == FONT_ON) {
if (f.uuline() == FONT_ON && !multipar_inset) {
if (needs_cprotection) {
os << "\\cprotect";
count += 9;
@ -477,7 +486,7 @@ int Font::latexWriteStartChanges(otexstream & os, BufferParams const & bparams,
count += 8;
++runparams.inulemcmd;
}
if (f.strikeout() == FONT_ON) {
if (f.strikeout() == FONT_ON && !multipar_inset) {
if (needs_cprotection) {
os << "\\cprotect";
count += 9;
@ -486,7 +495,7 @@ int Font::latexWriteStartChanges(otexstream & os, BufferParams const & bparams,
count += 6;
++runparams.inulemcmd;
}
if (f.xout() == FONT_ON) {
if (f.xout() == FONT_ON && !multipar_inset) {
if (needs_cprotection) {
os << "\\cprotect";
count += 9;
@ -495,7 +504,7 @@ int Font::latexWriteStartChanges(otexstream & os, BufferParams const & bparams,
count += 6;
++runparams.inulemcmd;
}
if (f.uwave() == FONT_ON) {
if (f.uwave() == FONT_ON && !multipar_inset) {
if (runparams.inulemcmd) {
// needed with nested uwave in xout
// see https://tex.stackexchange.com/a/263042
@ -522,7 +531,8 @@ int Font::latexWriteEndChanges(otexstream & os, BufferParams const & bparams,
Font const & base,
Font const & next,
bool & needPar,
bool const & closeLanguage) const
bool const & closeLanguage,
bool const & multipar_inset) const
{
int count = 0;
@ -532,15 +542,15 @@ int Font::latexWriteEndChanges(otexstream & os, BufferParams const & bparams,
FontInfo f = bits_;
f.reduce(base.bits_);
if (f.family() != INHERIT_FAMILY) {
if (f.family() != INHERIT_FAMILY && !multipar_inset) {
os << '}';
++count;
}
if (f.series() != INHERIT_SERIES) {
if (f.series() != INHERIT_SERIES && !multipar_inset) {
os << '}';
++count;
}
if (f.shape() != INHERIT_SHAPE) {
if (f.shape() != INHERIT_SHAPE && !multipar_inset) {
os << '}';
++count;
}
@ -558,15 +568,17 @@ int Font::latexWriteEndChanges(otexstream & os, BufferParams const & bparams,
}
if (f.size() != INHERIT_SIZE) {
// We do not close size group in front of
// insets with InheritFont() false (as opposed
// insets with allowMultiPar() true (as opposed
// to all other font properties) (#8384)
if (needPar && !closeLanguage) {
os << "\\par";
count += 4;
needPar = false;
if (!multipar_inset) {
if (needPar && !closeLanguage) {
os << "\\par";
count += 4;
needPar = false;
}
os << '}';
++count;
}
os << '}';
++count;
}
if (f.underbar() == FONT_ON) {
os << '}';

View File

@ -47,6 +47,8 @@ public:
bool isVisibleRightToLeft() const;
///
void setLanguage(Language const * l);
///
void setProperties(FontInfo const & f);
/// Returns size of font in LaTeX text notation
std::string const latexSize() const;
@ -88,7 +90,8 @@ public:
Font const & base,
Font const & next,
bool & needPar,
bool const & closeLanguage = true) const;
bool const & closeLanguage = true,
bool const & multipar_inset = false) const;
/// Build GUI description of font state

View File

@ -1067,9 +1067,10 @@ void Paragraph::Private::latexInset(BufferParams const & bparams,
? textinset->hasCProtectContent(runparams.moving_arg)
&& !textinset->text().isMainText()
: false;
bool const multipar_inset = inset->allowMultiPar();
unsigned int count2 = running_font.latexWriteStartChanges(os, bparams,
runparams, basefont,
running_font, true,
running_font, multipar_inset,
cprotect);
column += count2;
// Update the running_font, making sure, however,
@ -2413,10 +2414,11 @@ void Paragraph::latex(BufferParams const & bparams,
pos_type body_pos = beginOfBody();
unsigned int column = 0;
// If we are inside an non inheritFont() inset, the real outerfont is local_font
Font const real_outerfont = (!inInset().inheritFont()
&& runparams.local_font != nullptr)
? Font(runparams.local_font->fontInfo()) : outerfont;
Font real_outerfont = outerfont;
// If we are inside an non inheritFont() inset, the real main
// properties of the outerfont are those of the local_font
if (!inInset().inheritFont() && runparams.local_font != nullptr)
real_outerfont.setProperties(runparams.local_font->fontInfo());
if (body_pos > 0) {
// the optional argument is kept in curly brackets in
@ -2463,6 +2465,8 @@ void Paragraph::latex(BufferParams const & bparams,
// Yes if greater than 0. This has to be static.
THREAD_LOCAL_STATIC int parInline = 0;
bool multipar_inset = false;
for (pos_type i = 0; i < size(); ++i) {
// First char in paragraph or after label?
if (i == body_pos) {
@ -2471,7 +2475,8 @@ void Paragraph::latex(BufferParams const & bparams,
bool needPar = false;
column += running_font.latexWriteEndChanges(
os, bparams, runparams,
basefont, basefont, needPar);
basefont, basefont, needPar,
multipar_inset);
open_font = false;
}
basefont = getLayoutFont(bparams, real_outerfont);
@ -2538,7 +2543,7 @@ void Paragraph::latex(BufferParams const & bparams,
bool needPar = false;
column += running_font.latexWriteEndChanges(
os, bparams, rp, basefont,
basefont, needPar);
basefont, needPar, multipar_inset);
open_font = false;
}
basefont = (body_pos > i) ? getLabelFont(bparams, real_outerfont)
@ -2559,7 +2564,8 @@ void Paragraph::latex(BufferParams const & bparams,
bool needPar = false;
column += running_font.latexWriteEndChanges(
os, bparams, runparams,
basefont, basefont, needPar);
basefont, basefont, needPar,
multipar_inset);
open_font = false;
}
basefont = (body_pos > i) ? getLabelFont(bparams, real_outerfont)
@ -2590,7 +2596,7 @@ void Paragraph::latex(BufferParams const & bparams,
&& runningChange == change
&& change.type == Change::DELETED
&& !os.afterParbreak());
bool const multipar_inset =
multipar_inset =
(c == META_INSET && getInset(i) && getInset(i)->allowMultiPar());
// Do we need to close the previous font?
@ -2617,7 +2623,7 @@ void Paragraph::latex(BufferParams const & bparams,
column += running_font.latexWriteEndChanges(
os, bparams, runparams, basefont,
(i == body_pos-1) ? basefont : current_font,
needPar);
needPar, multipar_inset);
if (in_ct_deletion) {
// We have to close and then reopen \lyxdeleted,
// as strikeout needs to be on lowest level.
@ -2680,7 +2686,7 @@ void Paragraph::latex(BufferParams const & bparams,
OutputParams rp = runparams;
column += running_font.latexWriteEndChanges(
os, bparams, rp, basefont,
basefont, needPar);
basefont, needPar, multipar_inset);
os << '}';
column += 1;
}
@ -2785,16 +2791,16 @@ void Paragraph::latex(BufferParams const & bparams,
incremented = true;
}
}
// We need to restore these after insets with
// allowMultiPar() true
Font const save_running_font = running_font;
Font const save_basefont = basefont;
// We need to restore the main properties of
// these fonts after allowMultiPar() insets
FontInfo const running_font_info = running_font.fontInfo();
FontInfo const basefont_info = basefont.fontInfo();
d->latexInset(bparams, os, rp, running_font,
basefont, real_outerfont, open_font,
runningChange, style, i, column);
if (multipar_inset) {
running_font = save_running_font;
basefont = save_basefont;
running_font.setProperties(running_font_info);
basefont.setProperties(basefont_info);
}
if (incremented)
--parInline;
@ -2917,7 +2923,7 @@ void Paragraph::latex(BufferParams const & bparams,
//FIXME: there as we start another \selectlanguage with the next paragraph if
//FIXME: we are in need of this. This should be fixed sometime (Jug)
running_font.latexWriteEndChanges(os, bparams, runparams,
basefont, basefont, needPar);
basefont, basefont, needPar, multipar_inset);
#endif
if (needPar) {
// The \par could not be inserted at the same nesting