]> git.lyx.org Git - lyx.git/commitdiff
Allow using the text properties dialog in mathed
authorEnrico Forestieri <forenr@lyx.org>
Mon, 6 Nov 2023 17:04:44 +0000 (18:04 +0100)
committerEnrico Forestieri <forenr@lyx.org>
Mon, 6 Nov 2023 17:04:44 +0000 (18:04 +0100)
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

20 files changed:
lib/symbols
src/Cursor.cpp
src/DocIterator.cpp
src/DocIterator.h
src/Makefile.am
src/MetricsInfo.cpp
src/MetricsInfo.h
src/insets/Inset.cpp
src/insets/InsetCode.h
src/mathed/InsetMath.h
src/mathed/InsetMathBrace.cpp
src/mathed/InsetMathBrace.h
src/mathed/InsetMathDecoration.cpp
src/mathed/InsetMathDecoration.h
src/mathed/InsetMathNest.cpp
src/mathed/InsetMathTextsize.cpp [new file with mode: 0644]
src/mathed/InsetMathTextsize.h [new file with mode: 0644]
src/mathed/MathFactory.cpp
src/mathed/MathParser.cpp
src/mathed/MathSupport.cpp

index abdafd01f3f1def3318963c083d76f777cc57c15..f1fa587e3fe76686f778e2cd2f17a59d413e7071 100644 (file)
@@ -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
index 18b0e7f50aefb553595b440f73c2861641d8a884..8cd445bcb7b48d4f5af6ea6ace2ea7c308335baa 100644 (file)
@@ -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;
 
index 31a5bffcafe0f47630b2da56ce009df69c61b6ef..ace4498a56e91d6f4e8af525f77c567ec74544b0 100644 (file)
@@ -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
index cfb31f487f248e3c33404456da79f1a24917e3e8..9475fcfb78e44c18d795816f6f438bbcd9017fb0 100644 (file)
@@ -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;
index 6713bc1ec0ddb2deaa9cad8c63b878ce98b60ec1..86a90bb2bba225910c80d73020800167c981b4a5 100644 (file)
@@ -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 \
index ab55bb524d3f93d5e4b9f528188bb68ae82803ed..844c1c13f392ca51ab5fc5306453f95dd09e2313 100644 (file)
@@ -21,6 +21,8 @@
 #include "frontends/FontMetrics.h"
 #include "frontends/Painter.h"
 
+#include <map>
+
 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<string, FontSize> 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<MetricsBase> 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) {
index 29000034db6d1b1ec09fc298f4a26702dd238b82..6f1d404822f2fca5d268a9fa7c388d3422e17d3f 100644 (file)
@@ -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
index 6ffb407e06ceacf372ac7e8ea179d263b7ed8f4e..165df396573de0097260705d151494a537a5bf64 100644 (file)
@@ -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");
index 0b60ebfb8fc34f365478ba9af0418c76255e8303..a3d3e8f671a16705b67a299770d45e5134dc27ba 100644 (file)
@@ -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,
        ///
index c872316abfbf5bc38613f991d9c0a562b8f9699b..7ea8a7cfc19d37a32fa0838e130d555ddc34bc25 100644 (file)
@@ -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; }
index b0ce242f07b82db4af4e0005d2327d10ae03582e..b98d29a7e8627210d29df52654ef6e1574fa2789 100644 (file)
@@ -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<Buffer *>(ar.buffer()), 1)
+       : InsetMathNest(const_cast<Buffer *>(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('{');
index 273a9edabc9570eee4f1d2aa127497a728e7bc2c..cde1967761eea418d441307bee654029ed42604d 100644 (file)
@@ -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_;
 };
 
 
index 96323bf6d911ab514ea0ba54cbac0f013b032f01..614904c4bc8b8a48490fdbb79a2fabea98b4cff2 100644 (file)
@@ -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, "&#x00AF;");
                t["overrightarrow"] = Attributes(true, "&#x27F6;");
                t["tilde"] = Attributes(true, "&#x02DC;");
+               t["uline"] = Attributes(false, "&#x00AF;");
                t["underbar"] = Attributes(false, "&#x0332;");
                t["underbrace"] = Attributes(false, "&#x23DF;");
                t["underleftarrow"] = Attributes(false, "&#x27F5;");
@@ -224,6 +251,8 @@ namespace {
                t["underrightarrow"] = Attributes(false, "&#x27F6;");
                t["undertilde"] = Attributes(false, "&#x223C;");
                t["utilde"] = Attributes(false, "&#x223C;");
+               t["uuline"] = Attributes(false, "&#x2017;");
+               t["uwave"] = Attributes(false, "&#x223C;");
                t["vec"] = Attributes(true, "&#x2192;");
                t["widehat"] = Attributes(true, "&#x005E;");
                t["widetilde"] = Attributes(true, "&#x223C;");
@@ -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(
index e71b54b83db64466a6f767e5097d20da528b1c6b..7ba7e51ba0dd4c3745d7fc988909c45ad769ebb2 100644 (file)
@@ -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
index 8bd05679c335cd83a1d3aa84e9bb4f78c9deccce..c8f5e1496ab197da7744697643b062f0779cf868 100644 (file)
 #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 (file)
index 0000000..97d8234
--- /dev/null
@@ -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 <config.h>
+
+#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 <ostream>
+
+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 (file)
index 0000000..91b7cbc
--- /dev/null
@@ -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
index 792a603b09862293bdb8810693f62aef1fcb5ebc..66535beb8d5e1e0aa5b360ef87624cbb62fbdffe 100644 (file)
@@ -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")
index 1958900e3d2f0155e64609f5fa1ab3273b59bd3b..e94b6cea32ed7dc055e4e3a30cea497d4c5831e1 100644 (file)
@@ -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));
index b71c46ee8f4b6409173973d48f8ac573778f841c..57e8c6ee4e4f7f5381a411e356ad1bea48f82b27 100644 (file)
@@ -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++]);