From 58103cf214cc5e9e5d0f4aaa03f4250ee011e55a Mon Sep 17 00:00:00 2001 From: Enrico Forestieri Date: Mon, 6 Nov 2023 18:04:44 +0100 Subject: [PATCH] Allow using the text properties dialog in mathed Until now only the color of the text could be changed by using the text properties dialog. This commit allows changing all other properties except for strikethrough. It is possible to also add underlining with the limitation that the changes accumulate. This requires other work but I think that underlining and strikethrough are not so important in mathed and can be refined at a later time. Fixes #12958 --- lib/symbols | 15 ++ src/Cursor.cpp | 1 + src/DocIterator.cpp | 3 - src/DocIterator.h | 3 +- src/Makefile.am | 2 + src/MetricsInfo.cpp | 31 +++- src/MetricsInfo.h | 2 + src/insets/Inset.cpp | 1 + src/insets/InsetCode.h | 14 +- src/mathed/InsetMath.h | 3 + src/mathed/InsetMathBrace.cpp | 11 +- src/mathed/InsetMathBrace.h | 4 + src/mathed/InsetMathDecoration.cpp | 43 ++++- src/mathed/InsetMathDecoration.h | 8 + src/mathed/InsetMathNest.cpp | 255 ++++++++++++++++++++++++++++- src/mathed/InsetMathTextsize.cpp | 97 +++++++++++ src/mathed/InsetMathTextsize.h | 61 +++++++ src/mathed/MathFactory.cpp | 3 + src/mathed/MathParser.cpp | 2 +- src/mathed/MathSupport.cpp | 31 +++- 20 files changed, 564 insertions(+), 26 deletions(-) create mode 100644 src/mathed/InsetMathTextsize.cpp create mode 100644 src/mathed/InsetMathTextsize.h diff --git a/lib/symbols b/lib/symbols index abdafd01f3..f1fa587e3f 100644 --- a/lib/symbols +++ b/lib/symbols @@ -57,6 +57,7 @@ overleftrightarrow decoration none amsmath overline decoration none overrightarrow decoration none tilde decoration none +uline decoration none ulem underbar decoration none underbrace decoration none underleftarrow decoration none amsmath @@ -68,6 +69,8 @@ underrightarrow decoration none amsmath #undertilde decoration none accents undertilde decoration none hiddensymbol utilde decoration none undertilde +uuline decoration none ulem +uwave decoration none ulem vec decoration none widehat decoration none widetilde decoration none @@ -157,6 +160,18 @@ it oldfont none hiddensymbol rm oldfont none hiddensymbol tt oldfont none hiddensymbol +# textsize commands +tiny textsize none hiddensymbol +scriptsize textsize none hiddensymbol +footnotesize textsize none hiddensymbol +small textsize none hiddensymbol +normalsize textsize none hiddensymbol +large textsize none hiddensymbol +Large textsize none hiddensymbol +LARGE textsize none hiddensymbol +huge textsize none hiddensymbol +Huge textsize none hiddensymbol + # matrix environments Bmatrix matrix none Vmatrix matrix none diff --git a/src/Cursor.cpp b/src/Cursor.cpp index 18b0e7f50a..8cd445bcb7 100644 --- a/src/Cursor.cpp +++ b/src/Cursor.cpp @@ -1812,6 +1812,7 @@ bool Cursor::macroModeClose(bool cancel) bool keep_mathmode = user_macro || (it != words.end() && (it->second.inset == "font" || it->second.inset == "oldfont" + || it->second.inset == "textsize" || it->second.inset == "mbox")); bool ert_macro = !user_macro && it == words.end() && atomAsMacro; diff --git a/src/DocIterator.cpp b/src/DocIterator.cpp index 31a5bffcaf..ace4498a56 100644 --- a/src/DocIterator.cpp +++ b/src/DocIterator.cpp @@ -495,8 +495,6 @@ void DocIterator::backwardPosIgnoreCollapsed() } -#if 0 -// works, but currently not needed void DocIterator::backwardInset() { backwardPos(); @@ -514,7 +512,6 @@ void DocIterator::backwardInset() backwardPos(); } } -#endif bool DocIterator::hasPart(DocIterator const & it) const diff --git a/src/DocIterator.h b/src/DocIterator.h index cfb31f487f..9475fcfb78 100644 --- a/src/DocIterator.h +++ b/src/DocIterator.h @@ -215,8 +215,7 @@ public: /// move backward one paragraph void backwardPar(); /// move backward one inset - /// not used currently, uncomment if you need it - //void backwardInset(); + void backwardInset(); /// are we some 'extension' (i.e. deeper nested) of the given iterator bool hasPart(DocIterator const & it) const; diff --git a/src/Makefile.am b/src/Makefile.am index 6713bc1ec0..86a90bb2bb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -432,6 +432,7 @@ SOURCEFILESMATHED = \ mathed/InsetMathSubstack.cpp \ mathed/InsetMathSymbol.cpp \ mathed/InsetMathTabular.cpp \ + mathed/InsetMathTextsize.cpp \ mathed/InsetMathUnderset.cpp \ mathed/InsetMathUnknown.cpp \ mathed/InsetMathXArrow.cpp \ @@ -503,6 +504,7 @@ HEADERFILESMATHED = \ mathed/InsetMathSubstack.h \ mathed/InsetMathSymbol.h \ mathed/InsetMathTabular.h \ + mathed/InsetMathTextsize.h \ mathed/InsetMathUnderset.h \ mathed/InsetMathUnknown.h \ mathed/InsetMathXArrow.h \ diff --git a/src/MetricsInfo.cpp b/src/MetricsInfo.cpp index ab55bb524d..844c1c13f3 100644 --- a/src/MetricsInfo.cpp +++ b/src/MetricsInfo.cpp @@ -21,6 +21,8 @@ #include "frontends/FontMetrics.h" #include "frontends/Painter.h" +#include + using namespace std; @@ -63,7 +65,10 @@ Changer MetricsBase::changeFontSet(string const & name) if (isMathFont(name) || isMathFont(oldname)) font = isTextFont(name) ? outer_font : sane_font; augmentFont(font, name); - font.setSize(rc->old.font.size()); + if (isTextFont(name) && isMathFont(oldname)) + font.setSize(rc->old.outer_font.size()); + else + font.setSize(rc->old.font.size()); font.setStyle(rc->old.font.style()); if (name == "emph") { font.setColor(oldcolor); @@ -85,6 +90,30 @@ Changer MetricsBase::changeFontSet(string const & name) } +Changer MetricsBase::changeFontSize(string const & size, bool mathmode) +{ + map sizes = { + {"tiny", TINY_SIZE}, + {"scriptsize", SCRIPT_SIZE}, + {"footnotesize", FOOTNOTE_SIZE}, + {"small", SMALL_SIZE}, + {"normalsize", NORMAL_SIZE}, + {"large", LARGE_SIZE}, + {"Large", LARGER_SIZE}, + {"LARGE", LARGEST_SIZE}, + {"huge", HUGE_SIZE}, + {"Huge", HUGER_SIZE} + }; + RefChanger rc = make_save(*this); + // In math mode we only record the size in outer_font + if (mathmode) + outer_font.setSize(sizes[size]); + else + font.setSize(sizes[size]); + return rc; +} + + Changer MetricsBase::changeEnsureMath(Inset::mode_type mode) { switch (mode) { diff --git a/src/MetricsInfo.h b/src/MetricsInfo.h index 29000034db..6f1d404822 100644 --- a/src/MetricsInfo.h +++ b/src/MetricsInfo.h @@ -58,6 +58,8 @@ public: /// Temporarily change a full font. Changer changeFontSet(std::string const & name); + /// Temporarily change font size in text mode, only record it in math mode. + Changer changeFontSize(std::string const & fontsize, bool mathmode); /// Temporarily change the font to math if needed. Changer changeEnsureMath(Inset::mode_type mode = Inset::MATH_MODE); // Temporarily change to the style suitable for use in fractions diff --git a/src/insets/Inset.cpp b/src/insets/Inset.cpp index 6ffb407e06..165df39657 100644 --- a/src/insets/Inset.cpp +++ b/src/insets/Inset.cpp @@ -173,6 +173,7 @@ static void build_translator() insetnames[MATH_SUBSTACK_CODE] = InsetName("mathsubstack"); insetnames[MATH_SYMBOL_CODE] = InsetName("mathsymbol"); insetnames[MATH_TABULAR_CODE] = InsetName("mathtabular"); + insetnames[MATH_TEXTSIZE_CODE] = InsetName("mathtextsize"); insetnames[MATH_UNDERSET_CODE] = InsetName("mathunderset"); insetnames[MATH_UNKNOWN_CODE] = InsetName("mathunknown"); insetnames[MATH_XARROW_CODE] = InsetName("mathxarrow"); diff --git a/src/insets/InsetCode.h b/src/insets/InsetCode.h index 0b60ebfb8f..a3d3e8f671 100644 --- a/src/insets/InsetCode.h +++ b/src/insets/InsetCode.h @@ -211,15 +211,17 @@ enum InsetCode { /// MATH_TABULAR_CODE, // 95 /// + MATH_TEXTSIZE_CODE, + /// MATH_UNDERSET_CODE, /// MATH_UNKNOWN_CODE, /// MATH_XARROW_CODE, /// - MATH_XYMATRIX_CODE, + MATH_XYMATRIX_CODE, // 100 /// - MATH_MACRO_CODE, // 100 + MATH_MACRO_CODE, /// ARGUMENT_PROXY_CODE, /// @@ -227,9 +229,9 @@ enum InsetCode { /// MATH_DIAGRAM_CODE, /// - SCRIPT_CODE, + SCRIPT_CODE, // 105 /// - IPA_CODE, // 105 + IPA_CODE, /// IPACHAR_CODE, /// @@ -237,9 +239,9 @@ enum InsetCode { /// MATH_CLASS_CODE, /// - COUNTER_CODE, + COUNTER_CODE, // 110 /// - INDEXMACRO_CODE, // 110 + INDEXMACRO_CODE, /// INDEXMACRO_SORTKEY_CODE, /// diff --git a/src/mathed/InsetMath.h b/src/mathed/InsetMath.h index c872316abf..7ea8a7cfc1 100644 --- a/src/mathed/InsetMath.h +++ b/src/mathed/InsetMath.h @@ -81,6 +81,7 @@ class InsetMathAMSArray; class InsetMathBrace; class InsetMathChar; class InsetMathClass; +class InsetMathDecoration; class InsetMathDelim; class InsetMathFracBase; class InsetMathFrac; @@ -155,6 +156,8 @@ public: virtual InsetMathBrace const * asBraceInset() const { return nullptr; } virtual InsetMathChar const * asCharInset() const { return nullptr; } virtual InsetMathClass const * asClassInset() const { return nullptr; } + virtual InsetMathDecoration * asDecorationInset() { return nullptr; } + virtual InsetMathDecoration const * asDecorationInset() const { return nullptr; } virtual InsetMathDelim * asDelimInset() { return nullptr; } virtual InsetMathDelim const * asDelimInset() const { return nullptr; } virtual InsetMathFracBase * asFracBaseInset() { return nullptr; } diff --git a/src/mathed/InsetMathBrace.cpp b/src/mathed/InsetMathBrace.cpp index b0ce242f07..b98d29a7e8 100644 --- a/src/mathed/InsetMathBrace.cpp +++ b/src/mathed/InsetMathBrace.cpp @@ -28,12 +28,13 @@ using namespace std; namespace lyx { InsetMathBrace::InsetMathBrace(Buffer * buf) - : InsetMathNest(buf, 1) + : InsetMathNest(buf, 1), current_mode_(UNDECIDED_MODE) {} InsetMathBrace::InsetMathBrace(MathData const & ar) - : InsetMathNest(const_cast(ar.buffer()), 1) + : InsetMathNest(const_cast(ar.buffer()), 1), + current_mode_(UNDECIDED_MODE) { cell(0) = ar; } @@ -47,10 +48,11 @@ Inset * InsetMathBrace::clone() const void InsetMathBrace::metrics(MetricsInfo & mi, Dimension & dim) const { + current_mode_ = isTextFont(mi.base.fontname) ? TEXT_MODE : MATH_MODE; Dimension dim0; cell(0).metrics(mi, dim0); FontInfo font = mi.base.font; - augmentFont(font, "mathnormal"); + augmentFont(font, current_mode_ == MATH_MODE ? "mathnormal" : "text"); Dimension t = theFontMetrics(font).dimension('{'); dim.asc = max(dim0.asc, t.asc); dim.des = max(dim0.des, t.des); @@ -60,8 +62,9 @@ void InsetMathBrace::metrics(MetricsInfo & mi, Dimension & dim) const void InsetMathBrace::draw(PainterInfo & pi, int x, int y) const { + current_mode_ = isTextFont(pi.base.fontname) ? TEXT_MODE : MATH_MODE; FontInfo font = pi.base.font; - augmentFont(font, "mathnormal"); + augmentFont(font, current_mode_ == MATH_MODE ? "mathnormal" : "text"); font.setShape(UP_SHAPE); font.setColor(Color_latex); Dimension t = theFontMetrics(font).dimension('{'); diff --git a/src/mathed/InsetMathBrace.h b/src/mathed/InsetMathBrace.h index 273a9edabc..cde1967761 100644 --- a/src/mathed/InsetMathBrace.h +++ b/src/mathed/InsetMathBrace.h @@ -33,6 +33,8 @@ public: void metrics(MetricsInfo & mi, Dimension & dim) const override; /// void draw(PainterInfo &, int x, int y) const override; + /// we inherit the mode + mode_type currentMode() const override { return current_mode_; } /// void write(TeXMathStream & os) const override; /// write normalized content @@ -53,6 +55,8 @@ public: InsetCode lyxCode() const override { return MATH_BRACE_CODE; } private: Inset * clone() const override; + /// the inherited mode + mutable mode_type current_mode_; }; diff --git a/src/mathed/InsetMathDecoration.cpp b/src/mathed/InsetMathDecoration.cpp index 96323bf6d9..614904c4bc 100644 --- a/src/mathed/InsetMathDecoration.cpp +++ b/src/mathed/InsetMathDecoration.cpp @@ -40,7 +40,7 @@ namespace lyx { InsetMathDecoration::InsetMathDecoration(Buffer * buf, latexkeys const * key) - : InsetMathNest(buf, 1), key_(key) + : InsetMathNest(buf, 1), key_(key), outer_mode_(UNDECIDED_MODE) { // lyxerr << " creating deco " << key->name << endl; } @@ -54,7 +54,11 @@ Inset * InsetMathDecoration::clone() const bool InsetMathDecoration::upper() const { - return key_->name.substr(0, 5) != "under" && key_->name != "utilde"; + return key_->name.substr(0, 5) != "under" && + key_->name != "utilde" && + key_->name != "uline" && + key_->name != "uuline" && + key_->name != "uwave"; } @@ -94,6 +98,9 @@ bool InsetMathDecoration::wide() const return key_->name == "overline" || key_->name == "underline" || + key_->name == "uline" || + key_->name == "uuline" || + key_->name == "uwave" || key_->name == "overbrace" || key_->name == "underbrace" || key_->name == "overleftarrow" || @@ -111,12 +118,21 @@ bool InsetMathDecoration::wide() const InsetMath::mode_type InsetMathDecoration::currentMode() const { - return key_->name == "underbar" ? TEXT_MODE : MATH_MODE; + if (key_->name == "underbar") + return TEXT_MODE; + + if (key_->name == "uline" || key_->name == "uuline" || + key_->name == "uwave") + return outer_mode_; + + return MATH_MODE; } void InsetMathDecoration::metrics(MetricsInfo & mi, Dimension & dim) const { + outer_mode_ = isTextFont(mi.base.fontname) ? TEXT_MODE : MATH_MODE; + Changer dummy = mi.base.changeEnsureMath(currentMode()); cell(0).metrics(mi, dim); @@ -140,6 +156,8 @@ void InsetMathDecoration::metrics(MetricsInfo & mi, Dimension & dim) const void InsetMathDecoration::draw(PainterInfo & pi, int x, int y) const { + outer_mode_ = isTextFont(pi.base.fontname) ? TEXT_MODE : MATH_MODE; + Changer dummy = pi.base.changeEnsureMath(currentMode()); cell(0).draw(pi, x, y); @@ -163,7 +181,9 @@ void InsetMathDecoration::draw(PainterInfo & pi, int x, int y) const void InsetMathDecoration::write(TeXMathStream & os) const { - MathEnsurer ensurer(os); + bool needs_mathmode = currentMode() == MATH_MODE; + bool textmode_macro = currentMode() == TEXT_MODE; + MathEnsurer ensurer(os, needs_mathmode, true, textmode_macro); if (os.fragile() && protect()) os << "\\protect"; os << '\\' << key_->name << '{'; @@ -179,6 +199,12 @@ void InsetMathDecoration::normalize(NormalStream & os) const } +docstring InsetMathDecoration::name() const +{ + return key_->name; +} + + void InsetMathDecoration::infoize(odocstream & os) const { os << bformat(_("Decoration: %1$s"), key_->name); @@ -215,6 +241,7 @@ namespace { t["overline"] = Attributes(true, "¯"); t["overrightarrow"] = Attributes(true, "⟶"); t["tilde"] = Attributes(true, "˜"); + t["uline"] = Attributes(false, "¯"); t["underbar"] = Attributes(false, "̲"); t["underbrace"] = Attributes(false, "⏟"); t["underleftarrow"] = Attributes(false, "⟵"); @@ -224,6 +251,8 @@ namespace { t["underrightarrow"] = Attributes(false, "⟶"); t["undertilde"] = Attributes(false, "∼"); t["utilde"] = Attributes(false, "∼"); + t["uuline"] = Attributes(false, "‗"); + t["uwave"] = Attributes(false, "∼"); t["vec"] = Attributes(true, "→"); t["widehat"] = Attributes(true, "^"); t["widetilde"] = Attributes(true, "∼"); @@ -261,7 +290,8 @@ void InsetMathDecoration::htmlize(HtmlStream & os) const return; } - if (name == "underbar" || name == "underline") { + if (name == "underbar" || name == "underline" || name == "uline" + || name == "uuline" || name == "uwave") { os << MTag("span", "class='underbar'") << cell(0) << ETag("span"); return; } @@ -295,7 +325,8 @@ void InsetMathDecoration::validate(LaTeXFeatures & features) const string const name = to_utf8(key_->name); if (name == "bar") { features.addCSSSnippet("span.overbar{border-top: thin black solid;}"); - } else if (name == "underbar" || name == "underline") { + } else if (name == "underbar" || name == "underline" || + name == "uline" || name == "uuline" || name == "uwave") { features.addCSSSnippet("span.underbar{border-bottom: thin black solid;}"); } else { features.addCSSSnippet( diff --git a/src/mathed/InsetMathDecoration.h b/src/mathed/InsetMathDecoration.h index e71b54b83d..7ba7e51ba0 100644 --- a/src/mathed/InsetMathDecoration.h +++ b/src/mathed/InsetMathDecoration.h @@ -26,6 +26,10 @@ public: /// explicit InsetMathDecoration(Buffer * buf, latexkeys const * key); /// + InsetMathDecoration * asDecorationInset() override { return this; } + /// + InsetMathDecoration const * asDecorationInset() const override { return this; } + /// mode_type currentMode() const override; /// void draw(PainterInfo &, int x, int y) const override; @@ -50,6 +54,8 @@ public: /// InsetCode lyxCode() const override { return MATH_DECORATION_CODE; } /// + docstring name() const override; + /// void mathmlize(MathMLStream &) const override; /// void htmlize(HtmlStream &) const override; @@ -73,6 +79,8 @@ private: mutable int dy_ = 0; /// width for non-wide deco mutable int dw_ = 0; + /// mode of the containing inset + mutable mode_type outer_mode_; }; } // namespace lyx diff --git a/src/mathed/InsetMathNest.cpp b/src/mathed/InsetMathNest.cpp index 8bd05679c3..c8f5e1496a 100644 --- a/src/mathed/InsetMathNest.cpp +++ b/src/mathed/InsetMathNest.cpp @@ -20,8 +20,10 @@ #include "InsetMathChar.h" #include "InsetMathColor.h" #include "InsetMathComment.h" +#include "InsetMathDecoration.h" #include "InsetMathDelim.h" #include "InsetMathEnsureMath.h" +#include "InsetMathFont.h" #include "InsetMathHull.h" #include "InsetMathRef.h" #include "InsetMathScript.h" @@ -509,13 +511,264 @@ void InsetMathNest::handleNest(Cursor & cur, MathAtom const & nest, void InsetMathNest::handleFont2(Cursor & cur, docstring const & arg) { + bool font_changed = false; cur.recordUndoSelection(); Font font; bool b; font.fromString(to_utf8(arg), b); if (font.fontInfo().color() != Color_inherit && - font.fontInfo().color() != Color_ignore) + font.fontInfo().color() != Color_ignore) { handleNest(cur, MathAtom(new InsetMathColor(buffer_, true, font.fontInfo().color()))); + font_changed = true; + } + + docstring im; + InsetMathFont const * f = asFontInset(); + + switch(font.fontInfo().family()) { + case ROMAN_FAMILY: + if (!f || (f->name() != "textrm" && f->name() != "mathrm")) + im = currentMode() != MATH_MODE ? from_ascii("textrm") + : from_ascii("mathrm"); + break; + case SANS_FAMILY: + if (!f || (f->name() != "textsf" && f->name() != "mathsf")) + im = currentMode() != MATH_MODE ? from_ascii("textsf") + : from_ascii("mathsf"); + break; + case TYPEWRITER_FAMILY: + if (!f || (f->name() != "texttt" && f->name() != "mathtt")) + im = currentMode() != MATH_MODE ? from_ascii("texttt") + : from_ascii("mathtt"); + break; + case SYMBOL_FAMILY: + case CMR_FAMILY: + case CMSY_FAMILY: + case CMM_FAMILY: + case CMEX_FAMILY: + case MSA_FAMILY: + case MSB_FAMILY: + case DS_FAMILY: + case EUFRAK_FAMILY: + case RSFS_FAMILY: + case STMARY_FAMILY: + case ESINT_FAMILY: + case INHERIT_FAMILY: + case IGNORE_FAMILY: + break; + } + if (!im.empty()) { + if (font_changed) { + Cursor oldcur = cur; + cur.backwardInset(); + cur.resetAnchor(); + cur = oldcur; + cur.setSelection(); + } + handleNest(cur, createInsetMath(im, cur.buffer())); + im.clear(); + font_changed = true; + } + + switch(font.fontInfo().series()) { + case MEDIUM_SERIES: + if (!f || (f->name() != "textmd" && f->name() != "mathrm")) + im = currentMode() != MATH_MODE ? from_ascii("textmd") + : from_ascii("mathrm"); + break; + case BOLD_SERIES: + if (!f || (f->name() != "textbf" && f->name() != "mathbf")) + im = currentMode() != MATH_MODE ? from_ascii("textbf") + : from_ascii("mathbf"); + break; + case INHERIT_SERIES: + case IGNORE_SERIES: + break; + } + if (!im.empty()) { + if (font_changed) { + Cursor oldcur = cur; + cur.backwardInset(); + cur.resetAnchor(); + cur = oldcur; + cur.setSelection(); + } + handleNest(cur, createInsetMath(im, cur.buffer())); + im.clear(); + font_changed = true; + } + + switch(font.fontInfo().shape()) { + case UP_SHAPE: + if (!f || (f->name() != "textup" && f->name() != "mathrm")) + im = currentMode() != MATH_MODE ? from_ascii("textup") + : from_ascii("mathrm"); + break; + case ITALIC_SHAPE: + if (!f || (f->name() != "textit" && f->name() != "mathit")) + im = currentMode() != MATH_MODE ? from_ascii("textit") + : from_ascii("mathit"); + break; + case SLANTED_SHAPE: + if (!f || f->name() != "textsl") + im = currentMode() != MATH_MODE ? from_ascii("textsl") + : from_ascii("error"); + break; + case SMALLCAPS_SHAPE: + if (!f || f->name() != "textsc") + im = currentMode() != MATH_MODE ? from_ascii("textsc") + : from_ascii("error"); + break; + case INHERIT_SHAPE: + case IGNORE_SHAPE: + break; + } + if (!im.empty() && im != "error") { + if (font_changed) { + Cursor oldcur = cur; + cur.backwardInset(); + cur.resetAnchor(); + cur = oldcur; + cur.setSelection(); + } + handleNest(cur, createInsetMath(im, cur.buffer())); + im.clear(); + font_changed = true; + } + + switch(font.fontInfo().size()) { + case TINY_SIZE: + im = from_ascii("tiny"); + break; + case SCRIPT_SIZE: + im = from_ascii("scriptsize"); + break; + case FOOTNOTE_SIZE: + im = from_ascii("footnotesize"); + break; + case SMALL_SIZE: + im = from_ascii("small"); + break; + case NORMAL_SIZE: + im = from_ascii("normalsize"); + break; + case LARGE_SIZE: + im = from_ascii("large"); + break; + case LARGER_SIZE: + im = from_ascii("Large"); + break; + case LARGEST_SIZE: + im = from_ascii("LARGE"); + break; + case HUGE_SIZE: + im = from_ascii("huge"); + break; + case HUGER_SIZE: + im = from_ascii("Huge"); + break; + case INCREASE_SIZE: + case DECREASE_SIZE: + case INHERIT_SIZE: + case IGNORE_SIZE: + break; + } + if (!im.empty()) { + if (font_changed) { + Cursor oldcur = cur; + cur.backwardInset(); + cur.resetAnchor(); + cur = oldcur; + cur.setSelection(); + } + handleNest(cur, createInsetMath(im, cur.buffer())); + im.clear(); + font_changed = true; + } + + InsetMathDecoration const * d = asDecorationInset(); + + if (font.fontInfo().underbar() == FONT_OFF && d && d->name() == "uline") { + lyxerr << "Remove uline" << endl; + } + if (font.fontInfo().uuline() == FONT_OFF && d && d->name() == "uuline") { + lyxerr << "Remove uuline" << endl; + } + if (font.fontInfo().uwave() == FONT_OFF && d && d->name() == "uwave") { + lyxerr << "Remove uwave" << endl; + } + + switch(font.fontInfo().underbar()) { + case FONT_ON: + if (!d || d->name() != "uline") + im = from_ascii("uline"); + break; + case FONT_OFF: + case FONT_TOGGLE: + case FONT_INHERIT: + case FONT_IGNORE: + break; + } + if (!im.empty()) { + if (font_changed) { + Cursor oldcur = cur; + cur.backwardInset(); + cur.resetAnchor(); + cur = oldcur; + cur.setSelection(); + } + handleNest(cur, createInsetMath(im, cur.buffer())); + im.clear(); + font_changed = true; + } + + switch(font.fontInfo().uuline()) { + case FONT_ON: + if (!d || d->name() != "uuline") + im = from_ascii("uuline"); + break; + case FONT_OFF: + case FONT_TOGGLE: + case FONT_INHERIT: + case FONT_IGNORE: + break; + } + if (!im.empty()) { + if (font_changed) { + Cursor oldcur = cur; + cur.backwardInset(); + cur.resetAnchor(); + cur = oldcur; + cur.setSelection(); + } + handleNest(cur, createInsetMath(im, cur.buffer())); + im.clear(); + font_changed = true; + } + + switch(font.fontInfo().uwave()) { + case FONT_ON: + if (!d || d->name() != "uwave") + im = from_ascii("uwave"); + break; + case FONT_OFF: + case FONT_TOGGLE: + case FONT_INHERIT: + case FONT_IGNORE: + break; + } + if (!im.empty()) { + if (font_changed) { + Cursor oldcur = cur; + cur.backwardInset(); + cur.resetAnchor(); + cur = oldcur; + cur.setSelection(); + } + handleNest(cur, createInsetMath(im, cur.buffer())); + im.clear(); + font_changed = true; + } // FIXME: support other font changes here as well? } diff --git a/src/mathed/InsetMathTextsize.cpp b/src/mathed/InsetMathTextsize.cpp new file mode 100644 index 0000000000..97d8234476 --- /dev/null +++ b/src/mathed/InsetMathTextsize.cpp @@ -0,0 +1,97 @@ +/** + * \file InsetMathFontOld.cpp + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Enrico Forestieri + * + * Full author contact details are available in file CREDITS. + */ + +#include + +#include "InsetMathTextsize.h" + +#include "MathData.h" +#include "MathParser.h" +#include "MathStream.h" +#include "MathSupport.h" +#include "MetricsInfo.h" + +#include "support/gettext.h" +#include "support/lassert.h" +#include "support/lstrings.h" + +#include + +using namespace lyx::support; + +namespace lyx { + +InsetMathTextsize::InsetMathTextsize(Buffer * buf, latexkeys const * key) + : InsetMathNest(buf, 1), key_(key), current_mode_(TEXT_MODE) +{ +} + + +Inset * InsetMathTextsize::clone() const +{ + return new InsetMathTextsize(*this); +} + + +void InsetMathTextsize::metrics(MetricsInfo & mi, Dimension & dim) const +{ + current_mode_ = isTextFont(mi.base.fontname) ? TEXT_MODE : MATH_MODE; + + // size changing commands are noops in math mode + bool mathmode = current_mode_ == MATH_MODE; + + Changer dummy = mi.base.changeFontSize(to_ascii(key_->name), mathmode); + cell(0).metrics(mi, dim); +} + + +void InsetMathTextsize::draw(PainterInfo & pi, int x, int y) const +{ + current_mode_ = isTextFont(pi.base.fontname) ? TEXT_MODE : MATH_MODE; + + // size changing commands are noops in math mode + bool mathmode = current_mode_ == MATH_MODE; + + Changer dummy = pi.base.changeFontSize(to_ascii(key_->name), mathmode); + cell(0).draw(pi, x, y); +} + + +void InsetMathTextsize::metricsT(TextMetricsInfo const & mi, Dimension & dim) const +{ + cell(0).metricsT(mi, dim); +} + + +void InsetMathTextsize::drawT(TextPainter & pain, int x, int y) const +{ + cell(0).drawT(pain, x, y); +} + + +void InsetMathTextsize::write(TeXMathStream & os) const +{ + os << "{\\" << key_->name << ' ' << cell(0) << '}'; +} + + +void InsetMathTextsize::normalize(NormalStream & os) const +{ + os << "[font " << key_->name << ' ' << cell(0) << ']'; +} + + +void InsetMathTextsize::infoize(odocstream & os) const +{ + os << bformat(_("Size: %1$s"), key_->name); +} + + +} // namespace lyx diff --git a/src/mathed/InsetMathTextsize.h b/src/mathed/InsetMathTextsize.h new file mode 100644 index 0000000000..91b7cbcfed --- /dev/null +++ b/src/mathed/InsetMathTextsize.h @@ -0,0 +1,61 @@ +// -*- C++ -*- +/** + * \file InsetMathTextsize.h + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Enrico Forestieri + * + * Full author contact details are available in file CREDITS. + */ + +#ifndef MATH_TEXTSIZEINSET_H +#define MATH_TEXTSIZEINSET_H + +#include "InsetMathNest.h" + + +namespace lyx { + + +class latexkeys; + +/// text-in-math font size changes +class InsetMathTextsize : public InsetMathNest { +public: + /// + explicit InsetMathTextsize(Buffer * buf, latexkeys const * key); + /// we inherit the mode + mode_type currentMode() const override { return current_mode_; } + /// we write extra braces in any case... + bool extraBraces() const override { return true; } + /// + void metrics(MetricsInfo & mi, Dimension & dim) const override; + /// + void draw(PainterInfo & pi, int x, int y) const override; + /// + void metricsT(TextMetricsInfo const & mi, Dimension & dim) const override; + /// + void drawT(TextPainter & pi, int x, int y) const override; + /// + void write(TeXMathStream & os) const override; + /// + void normalize(NormalStream &) const override; + /// + void infoize(odocstream & os) const override; + /// + int kerning(BufferView const * bv) const override { return cell(0).kerning(bv); } + /// + InsetCode lyxCode() const override { return MATH_TEXTSIZE_CODE; } + +private: + Inset * clone() const override; + /// the text-in-math font size to be used on screen + latexkeys const * key_; + /// the inherited mode + mutable mode_type current_mode_; +}; + + +} // namespace lyx +#endif diff --git a/src/mathed/MathFactory.cpp b/src/mathed/MathFactory.cpp index 792a603b09..66535beb8d 100644 --- a/src/mathed/MathFactory.cpp +++ b/src/mathed/MathFactory.cpp @@ -43,6 +43,7 @@ #include "InsetMathSubstack.h" #include "InsetMathSymbol.h" #include "InsetMathTabular.h" +#include "InsetMathTextsize.h" #include "InsetMathUnderset.h" #include "InsetMathUnknown.h" #include "InsetMathHull.h" @@ -488,6 +489,8 @@ MathAtom createInsetMath(docstring const & s, Buffer * buf) return MathAtom(new InsetMathFont(buf, l)); if (inset == "oldfont") return MathAtom(new InsetMathFontOld(buf, l)); + if (inset == "textsize") + return MathAtom(new InsetMathTextsize(buf, l)); if (inset == "matrix") return MathAtom(new InsetMathAMSArray(buf, s)); if (inset == "split") diff --git a/src/mathed/MathParser.cpp b/src/mathed/MathParser.cpp index 1958900e3d..e94b6cea32 100644 --- a/src/mathed/MathParser.cpp +++ b/src/mathed/MathParser.cpp @@ -2007,7 +2007,7 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags, FLAG_ITEM, asMode(mode, l->extra)); } - else if (l->inset == "oldfont") { + else if (l->inset == "oldfont" || l->inset == "textsize") { cell->push_back(createInsetMath(t.cs(), buf)); parse(cell->back().nucleus()->cell(0), flags | FLAG_ALIGN, asMode(mode, l->extra)); diff --git a/src/mathed/MathSupport.cpp b/src/mathed/MathSupport.cpp index b71c46ee8f..57e8c6ee4e 100644 --- a/src/mathed/MathSupport.cpp +++ b/src/mathed/MathSupport.cpp @@ -332,6 +332,13 @@ double const hline[] = { }; +double const hline2[] = { + 1, 0.00, 0.2, 1.0, 0.2, + 1, 0.00, 0.5, 1.0, 0.5, + 0 +}; + + double const dot[] = { 5, 0.5, 0.5, 0.1, 0.1, 0 @@ -409,6 +416,23 @@ double const tilde[] = { }; +double const wave[] = { + 2, 61, + 0.00, 0.40, + 0.01, 0.39, 0.04, 0.21, 0.05, 0.20, 0.06, 0.21, 0.09, 0.39, 0.10, 0.40, + 0.11, 0.39, 0.14, 0.21, 0.15, 0.20, 0.16, 0.21, 0.19, 0.39, 0.20, 0.40, + 0.21, 0.39, 0.24, 0.21, 0.25, 0.20, 0.26, 0.21, 0.29, 0.39, 0.30, 0.40, + 0.31, 0.39, 0.34, 0.21, 0.35, 0.20, 0.36, 0.21, 0.39, 0.39, 0.40, 0.40, + 0.41, 0.39, 0.44, 0.21, 0.45, 0.20, 0.46, 0.21, 0.49, 0.39, 0.50, 0.40, + 0.51, 0.39, 0.54, 0.21, 0.55, 0.20, 0.56, 0.21, 0.59, 0.39, 0.60, 0.40, + 0.61, 0.39, 0.64, 0.21, 0.65, 0.20, 0.66, 0.21, 0.69, 0.39, 0.70, 0.40, + 0.71, 0.39, 0.74, 0.21, 0.75, 0.20, 0.76, 0.21, 0.79, 0.39, 0.80, 0.40, + 0.81, 0.39, 0.84, 0.21, 0.85, 0.20, 0.86, 0.21, 0.89, 0.39, 0.90, 0.40, + 0.91, 0.39, 0.94, 0.21, 0.95, 0.20, 0.96, 0.21, 0.99, 0.39, 1.00, 0.40, + 0 +}; + + struct deco_struct { double const * data; int angle; @@ -426,6 +450,9 @@ named_deco_struct deco_table[] = { {"widetilde", tilde, 0 }, {"underbar", hline, 0 }, {"underline", hline, 0 }, + {"uline", hline, 0 }, + {"uuline", hline2, 0 }, + {"uwave", wave, 0 }, {"overline", hline, 0 }, {"underbrace", brace, 1 }, {"overbrace", brace, 3 }, @@ -703,8 +730,8 @@ void mathed_draw_deco(PainterInfo & pi, int x, int y, int w, int h, pi.pain.ellipse(xc, yc, rx, ry, pi.base.font.color(), Painter::fill_winding); } else { - int xp[32]; - int yp[32]; + int xp[64]; + int yp[64]; double xshift = (code == 6 ? d[i++] : 0.0); double yshift = (code == 6 ? d[i++] : 0.0); int const n2 = int(d[i++]);