From 50b212043884250fcfaf34013614d0b51cf72bfe Mon Sep 17 00:00:00 2001 From: Juergen Spitzmueller Date: Wed, 29 Jul 2020 16:25:19 +0200 Subject: [PATCH] Use switches where possible around non-inheriting insets Fixes rest of #8384 --- src/Font.cpp | 84 ++++++++++++++++++++++++++++++++--------------- src/Font.h | 5 +-- src/Paragraph.cpp | 34 ++++++++++--------- 3 files changed, 80 insertions(+), 43 deletions(-) diff --git a/src/Font.cpp b/src/Font.cpp index bcfb47782f..7ec589d755 100644 --- a/src/Font.cpp +++ b/src/Font.cpp @@ -56,18 +56,29 @@ namespace { // // Strings used to write LaTeX files // -char const * LaTeXFamilyNames[NUM_FAMILIES + 2] = +char const * LaTeXFamilyCommandNames[NUM_FAMILIES + 2] = { "textrm", "textsf", "texttt", "error1", "error2", "error3", "error4", "error5", "error6", "error7", "error8", "error9", "error10", "error11", "error12", "error13", "error14" }; -char const * LaTeXSeriesNames[NUM_SERIES + 2] = +char const * LaTeXFamilySwitchNames[NUM_FAMILIES + 2] = +{ "rmfamily", "sffamily", "ttfamily", "error1", "error2", "error3", "error4", + "error5", "error6", "error7", "error8", "error9", "error10", "error11", + "error12", "error13", "error14" }; + +char const * LaTeXSeriesCommandNames[NUM_SERIES + 2] = { "textmd", "textbf", "error4", "error5" }; -char const * LaTeXShapeNames[NUM_SHAPE + 2] = +char const * LaTeXSeriesSwitchNames[NUM_SERIES + 2] = +{ "mdseries", "bfseries", "error4", "error5" }; + +char const * LaTeXShapeCommandNames[NUM_SHAPE + 2] = { "textup", "textit", "textsl", "textsc", "error6", "error7" }; -char const * LaTeXSizeNames[NUM_SIZE + 4] = +char const * LaTeXShapeSwitchNames[NUM_SHAPE + 2] = +{ "upshape", "itshape", "slshape", "scshape", "error6", "error7" }; + +char const * LaTeXSizeSwitchNames[NUM_SIZE + 4] = { "tiny", "scriptsize", "footnotesize", "small", "normalsize", "large", "Large", "LARGE", "huge", "Huge", "error8", "error9", "error10", "error11" }; @@ -141,7 +152,7 @@ docstring const Font::stateText(BufferParams * params, bool const terse) const // Returns size in latex format string const Font::latexSize() const { - return LaTeXSizeNames[bits_.size()]; + return LaTeXSizeSwitchNames[bits_.size()]; } @@ -213,10 +224,11 @@ void Font::lyxWriteChanges(Font const & orgfont, /// Writes the head of the LaTeX needed to impose this font // Returns number of chars written. -int Font::latexWriteStartChanges(odocstream & os, BufferParams const & bparams, +int Font::latexWriteStartChanges(otexstream & os, BufferParams const & bparams, OutputParams const & runparams, Font const & base, - Font const & prev) const + Font const & prev, + bool const & non_inherit_inset) const { int count = 0; @@ -281,7 +293,7 @@ int Font::latexWriteStartChanges(odocstream & os, BufferParams const & bparams, } if (language()->encoding()->package() == Encoding::CJK) { - pair const c = switchEncoding(os, bparams, + pair const c = switchEncoding(os.os(), bparams, runparams, *(language()->encoding())); if (c.first) { open_encoding_ = true; @@ -299,27 +311,47 @@ int Font::latexWriteStartChanges(odocstream & os, BufferParams const & bparams, os << '{'; ++count; os << '\\' - << LaTeXSizeNames[f.size()] - << "{}"; - count += strlen(LaTeXSizeNames[f.size()]) + 3; + << LaTeXSizeSwitchNames[f.size()] << termcmd; + count += strlen(LaTeXSizeSwitchNames[f.size()]) + 1; } if (f.family() != INHERIT_FAMILY) { - os << '\\' - << LaTeXFamilyNames[f.family()] - << '{'; - count += strlen(LaTeXFamilyNames[f.family()]) + 2; + if (non_inherit_inset) { + os << '{'; + ++count; + os << '\\' << LaTeXFamilySwitchNames[f.family()] << termcmd; + count += strlen(LaTeXFamilySwitchNames[f.family()]) + 1; + } else { + os << '\\' + << LaTeXFamilyCommandNames[f.family()] + << '{'; + count += strlen(LaTeXFamilyCommandNames[f.family()]) + 2; + } } if (f.series() != INHERIT_SERIES) { - os << '\\' - << LaTeXSeriesNames[f.series()] - << '{'; - count += strlen(LaTeXSeriesNames[f.series()]) + 2; + if (non_inherit_inset) { + os << '{'; + ++count; + os << '\\' << LaTeXSeriesSwitchNames[f.series()] << termcmd; + count += strlen(LaTeXSeriesSwitchNames[f.series()]) + 1; + } else { + os << '\\' + << LaTeXSeriesCommandNames[f.series()] + << '{'; + count += strlen(LaTeXSeriesCommandNames[f.series()]) + 2; + } } if (f.shape() != INHERIT_SHAPE) { - os << '\\' - << LaTeXShapeNames[f.shape()] - << '{'; - count += strlen(LaTeXShapeNames[f.shape()]) + 2; + if (non_inherit_inset) { + os << '{'; + ++count; + os << '\\' << LaTeXShapeSwitchNames[f.shape()] << termcmd; + count += strlen(LaTeXShapeSwitchNames[f.shape()]) + 1; + } else { + os << '\\' + << LaTeXShapeCommandNames[f.shape()] + << '{'; + count += strlen(LaTeXShapeCommandNames[f.shape()]) + 2; + } } if (f.color() != Color_inherit && f.color() != Color_ignore) { if (f.color() == Color_none && p.color() != Color_none) { @@ -429,15 +461,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 && !non_inherit_inset) { os << '}'; ++count; } - if (f.series() != INHERIT_SERIES) { + if (f.series() != INHERIT_SERIES && !non_inherit_inset) { os << '}'; ++count; } - if (f.shape() != INHERIT_SHAPE) { + if (f.shape() != INHERIT_SHAPE && !non_inherit_inset) { os << '}'; ++count; } diff --git a/src/Font.h b/src/Font.h index 40a7d28307..f623a48c75 100644 --- a/src/Font.h +++ b/src/Font.h @@ -72,10 +72,11 @@ public: to this font. Returns number of chars written. Base is the font state active now. */ - int latexWriteStartChanges(odocstream &, BufferParams const & bparams, + int latexWriteStartChanges(otexstream &, BufferParams const & bparams, OutputParams const & runparams, Font const & base, - Font const & prev) const; + Font const & prev, + bool const & non_inherit_inset = false) const; /** Writes the tail of the LaTeX needed to change to this font. Returns number of chars written. Base is the font state we want diff --git a/src/Paragraph.cpp b/src/Paragraph.cpp index 1e5b69d38d..0556e04401 100644 --- a/src/Paragraph.cpp +++ b/src/Paragraph.cpp @@ -1069,10 +1069,15 @@ void Paragraph::Private::latexInset(BufferParams const & bparams, running_font = basefont; if (!closeLanguage) running_font.setLanguage(copy_font.language()); + // For these, we use switches, so no need to close basefont.fontInfo().setSize(copy_font.fontInfo().size()); - // leave font open if language is still open + basefont.fontInfo().setFamily(copy_font.fontInfo().family()); + basefont.fontInfo().setSeries(copy_font.fontInfo().series()); + // leave font open if language or any of the switches is still open open_font = (running_font.language() == basefont.language() - || running_font.fontInfo().size() == basefont.fontInfo().size()); + || running_font.fontInfo().size() == basefont.fontInfo().size() + || running_font.fontInfo().family() == basefont.fontInfo().family() + || running_font.fontInfo().series() == basefont.fontInfo().series()); if (closeLanguage) runparams.local_font = &basefont; } @@ -2659,10 +2664,11 @@ void Paragraph::latex(BufferParams const & bparams, os << '}'; column += 1; } - odocstringstream ods; - column += current_font.latexWriteStartChanges(ods, bparams, + otexstringstream ots; + bool const non_inherit_inset = (c == META_INSET && getInset(i) && !getInset(i)->inheritFont()); + column += current_font.latexWriteStartChanges(ots, bparams, runparams, basefont, - last_font); + last_font, non_inherit_inset); // Check again for display math in ulem commands as a // font change may also occur just before a math inset. if (runparams.inDisplayMath && !deleted_display_math @@ -2674,19 +2680,17 @@ void Paragraph::latex(BufferParams const & bparams, } running_font = current_font; open_font = true; - docstring fontchange = ods.str(); + docstring fontchange = ots.str(); + os << fontchange; // check whether the fontchange ends with a \\textcolor - // modifier and the text starts with a space (bug 4473) + // modifier and the text starts with a space. If so we + // need to add } in order to prevent \\textcolor from gobbling + // the space (bug 4473). docstring const last_modifier = rsplit(fontchange, '\\'); if (prefixIs(last_modifier, from_ascii("textcolor")) && c == ' ') - os << fontchange << from_ascii("{}"); - // check if the fontchange ends with a trailing blank - // (like "\small " (see bug 3382) - else if (suffixIs(fontchange, ' ') && c == ' ') - os << fontchange.substr(0, fontchange.size() - 1) - << from_ascii("{}"); - else - os << fontchange; + os << from_ascii("{}"); + else if (ots.terminateCommand()) + os << termcmd; if (in_ct_deletion) { // We have to close and then reopen \lyxdeleted, // as strikeout needs to be on lowest level.