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++]);