X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2FInsetSpecialChar.cpp;h=1294d1791efa92899534776e0bb053bc1266cc5e;hb=e30db1e44474ee379bedb0d1c752297541156497;hp=9e7346ffbf6c307fb2064a991438ab294ea8338a;hpb=f483fb8e9d1e994b33e9b08d2515dc4100126531;p=lyx.git diff --git a/src/insets/InsetSpecialChar.cpp b/src/insets/InsetSpecialChar.cpp index 9e7346ffbf..1294d1791e 100644 --- a/src/insets/InsetSpecialChar.cpp +++ b/src/insets/InsetSpecialChar.cpp @@ -43,46 +43,168 @@ InsetSpecialChar::Kind InsetSpecialChar::kind() const } +namespace { + +int logoWidth(FontInfo const & font, InsetSpecialChar::Kind kind) { + frontend::FontMetrics const & fm = theFontMetrics(font); + double const em = fm.width('M'); + int width = 0; + // See drawlogo() below to understand what this does. + switch (kind) { + case InsetSpecialChar::PHRASE_LYX: + width = fm.width(from_ascii("L")) - 0.16667 * em + + fm.width(from_ascii("Y")) - 0.125 * em + + fm.width(from_ascii("X")); + break; + + case InsetSpecialChar::PHRASE_TEX: + width = fm.width(from_ascii("T")) - 0.16667 * em + + fm.width(from_ascii("E")) - 0.125 * em + + fm.width(from_ascii("X")); + break; + + case InsetSpecialChar::PHRASE_LATEX2E: + width = logoWidth(font, InsetSpecialChar::PHRASE_LATEX) + + 0.15 * em + + fm.width(from_ascii("2") + char_type(0x03b5)); + break; + case InsetSpecialChar::PHRASE_LATEX: { + FontInfo smaller = font; + smaller.decSize().decSize(); + width = fm.width(from_ascii("L")) - 0.36 * em + + theFontMetrics(smaller).width(from_ascii("A")) - 0.15 * em + + logoWidth(font, InsetSpecialChar::PHRASE_TEX); + break; + } + default: + LYXERR0("No information for computing width of logo " << kind); + } + + return width; +} + +} + + void InsetSpecialChar::metrics(MetricsInfo & mi, Dimension & dim) const { frontend::FontMetrics const & fm = theFontMetrics(mi.base.font); dim.asc = fm.maxAscent(); dim.des = fm.maxDescent(); + dim.wid = 0; - string s; + docstring s; switch (kind_) { case LIGATURE_BREAK: - s = "|"; + s = from_ascii("|"); break; case END_OF_SENTENCE: - s = "."; + s = from_ascii("."); break; case LDOTS: - s = ". . ."; + s = from_ascii(". . ."); break; case MENU_SEPARATOR: - s = " x "; + s = from_ascii(" x "); break; case HYPHENATION: - s = "-"; + dim.wid = fm.width(from_ascii("-")); + if (dim.wid > 5) + dim.wid -= 2; // to make it look shorter break; case SLASH: - s = "/"; + s = from_ascii("/"); break; case NOBREAKDASH: - s = "-"; + s = from_ascii("-"); + break; + case PHRASE_LYX: + case PHRASE_TEX: + case PHRASE_LATEX2E: + case PHRASE_LATEX: + dim.wid = logoWidth(mi.base.font, kind_); break; } - docstring ds(s.begin(), s.end()); - dim.wid = fm.width(ds); - if (kind_ == HYPHENATION && dim.wid > 5) - dim.wid -= 2; // to make it look shorter - + if (dim.wid == 0) + dim.wid = fm.width(s); + setDimCache(mi, dim); } +namespace { + +void drawLogo(PainterInfo & pi, InsetSpecialChar::Kind kind, int & x, int & y) { + FontInfo const & font = pi.base.font; + // FIXME: this definition of em is bogus, but there is a need + // for a big refactoring of the code around this issue anyway. + double const em = theFontMetrics(font).width('M'); + switch (kind) { + case InsetSpecialChar::PHRASE_LYX: + /** Reference macro: + * \providecommand{\LyX}{L\kern-.1667em\lower.25em\hbox{Y}\kern-.125emX\\@}; + */ + x += pi.pain.text(x, y, from_ascii("L"), font); + x -= 0.16667 * em; + x += pi.pain.text(x, y + 0.25 * em, from_ascii("Y"), font); + x -= 0.125 * em; + x += pi.pain.text(x, y, from_ascii("X"), font); + break; + + case InsetSpecialChar::PHRASE_TEX: { + /** Reference macro: + * \def\TeX{T\kern-.1667em\lower.5ex\hbox{E}\kern-.125emX\@} + */ + double const ex = theFontMetrics(font).ascent('x'); + x += pi.pain.text(x, y, from_ascii("T"), font); + x -= 0.16667 * em; + x += pi.pain.text(x, y + 0.5 * ex, from_ascii("E"), font); + x -= 0.125 * em; + x += pi.pain.text(x, y, from_ascii("X"), font); + break; + } + case InsetSpecialChar::PHRASE_LATEX2E: + /** Reference macro: + * \DeclareRobustCommand{\LaTeXe}{\mbox{\m@th + * \if b\expandafter\@car\f@series\@nil\boldmath\fi + * \LaTeX\kern.15em2$_{\textstyle\varepsilon}$}} + */ + drawLogo(pi, InsetSpecialChar::PHRASE_LATEX, x, y); + x += 0.15 * em; + x += pi.pain.text(x, y, from_ascii("2"), font); + x += pi.pain.text(x, y + 0.25 * em, char_type(0x03b5), font); + break; + + case InsetSpecialChar::PHRASE_LATEX: { + /** Reference macro: + * \DeclareRobustCommand{\LaTeX}{L\kern-.36em% + * {\sbox\z@ T% + * \vbox to\ht\z@{\hbox{\check@mathfonts + * \fontsize\sf@size\z@ + * \math@fontsfalse\selectfont + * A}% + * \vss}% + * }% + * \kern-.15em% + * \TeX} + */ + x += pi.pain.text(x, y, from_ascii("L"), font); + x -= 0.36 * em; + FontInfo smaller = font; + smaller.decSize().decSize(); + x += pi.pain.text(x, y - 0.2 * em, from_ascii("A"), smaller); + x -= 0.15 * em; + drawLogo(pi, InsetSpecialChar::PHRASE_TEX, x, y); + break; + } + default: + LYXERR0("No information for drawing logo " << kind); + } +} + +} + void InsetSpecialChar::draw(PainterInfo & pi, int x, int y) const { FontInfo font = pi.base.font; @@ -145,6 +267,12 @@ void InsetSpecialChar::draw(PainterInfo & pi, int x, int y) const pi.pain.text(x, y, char_type('-'), font); break; } + case PHRASE_LYX: + case PHRASE_TEX: + case PHRASE_LATEX2E: + case PHRASE_LATEX: + drawLogo(pi, kind_, x, y); + break; } } @@ -175,6 +303,18 @@ void InsetSpecialChar::write(ostream & os) const case NOBREAKDASH: command = "\\nobreakdash-"; break; + case PHRASE_LYX: + command = "\\LyX"; + break; + case PHRASE_TEX: + command = "\\TeX"; + break; + case PHRASE_LATEX2E: + command = "\\LaTeX2e"; + break; + case PHRASE_LATEX: + command = "\\LaTeX"; + break; } os << "\\SpecialChar " << command << "\n"; } @@ -200,6 +340,14 @@ void InsetSpecialChar::read(Lexer & lex) kind_ = SLASH; else if (command == "\\nobreakdash-") kind_ = NOBREAKDASH; + else if (command == "\\LyX") + kind_ = PHRASE_LYX; + else if (command == "\\TeX") + kind_ = PHRASE_TEX; + else if (command == "\\LaTeX2e") + kind_ = PHRASE_LATEX2E; + else if (command == "\\LaTeX") + kind_ = PHRASE_LATEX; else lex.printError("InsetSpecialChar: Unknown kind: `$$Token'"); } @@ -235,11 +383,32 @@ void InsetSpecialChar::latex(otexstream & os, os << "\\protect"; os << "\\nobreakdash-"; break; + case PHRASE_LYX: + if (rp.moving_arg) + os << "\\protect"; + os << "\\LyX{}"; + break; + case PHRASE_TEX: + if (rp.moving_arg) + os << "\\protect"; + os << "\\TeX{}"; + break; + case PHRASE_LATEX2E: + if (rp.moving_arg) + os << "\\protect"; + os << "\\LaTeX2e{}"; + break; + case PHRASE_LATEX: + if (rp.moving_arg) + os << "\\protect"; + os << "\\LaTeX{}"; + break; } } -int InsetSpecialChar::plaintext(odocstream & os, OutputParams const &) const +int InsetSpecialChar::plaintext(odocstringstream & os, + OutputParams const &, size_t) const { switch (kind_) { case HYPHENATION: @@ -251,8 +420,8 @@ int InsetSpecialChar::plaintext(odocstream & os, OutputParams const &) const os << '.'; return 1; case LDOTS: - os << "..."; - return 3; + os.put(0x2026); + return 1; case MENU_SEPARATOR: os << "->"; return 2; @@ -262,6 +431,19 @@ int InsetSpecialChar::plaintext(odocstream & os, OutputParams const &) const case NOBREAKDASH: os.put(0x2011); return 1; + case PHRASE_LYX: + os << "LyX"; + return 3; + case PHRASE_TEX: + os << "TeX"; + return 3; + case PHRASE_LATEX2E: + os << "LaTeX2"; + os.put(0x03b5); + return 7; + case PHRASE_LATEX: + os << "LaTeX"; + return 5; } return 0; } @@ -277,7 +459,7 @@ int InsetSpecialChar::docbook(odocstream & os, OutputParams const &) const os << '.'; break; case LDOTS: - os << "..."; + os << "…"; break; case MENU_SEPARATOR: os << "&lyxarrow;"; @@ -288,6 +470,19 @@ int InsetSpecialChar::docbook(odocstream & os, OutputParams const &) const case NOBREAKDASH: os << '-'; break; + case PHRASE_LYX: + os << "LyX"; + break; + case PHRASE_TEX: + os << "TeX"; + break; + case PHRASE_LATEX2E: + os << "LaTeX2"; + os.put(0x03b5); + break; + case PHRASE_LATEX: + os << "LaTeX"; + break; } return 0; } @@ -316,6 +511,18 @@ docstring InsetSpecialChar::xhtml(XHTMLStream & xs, OutputParams const &) const case NOBREAKDASH: xs << XHTMLStream::ESCAPE_NONE << "‑"; break; + case PHRASE_LYX: + xs << "LyX"; + break; + case PHRASE_TEX: + xs << "TeX"; + break; + case PHRASE_LATEX2E: + xs << "LaTeX2" << XHTMLStream::ESCAPE_NONE << "ε"; + break; + case PHRASE_LATEX: + xs << "LaTeX"; + break; } return docstring(); } @@ -323,11 +530,21 @@ docstring InsetSpecialChar::xhtml(XHTMLStream & xs, OutputParams const &) const void InsetSpecialChar::toString(odocstream & os) const { - plaintext(os, OutputParams(0)); + switch (kind_) { + case LIGATURE_BREAK: + // Do not output ZERO WIDTH NON JOINER here + // Spell checker would choke on it. + return; + default: + break; + } + odocstringstream ods; + plaintext(ods, OutputParams(0)); + os << ods.str(); } -void InsetSpecialChar::forToc(docstring & os, size_t) const +void InsetSpecialChar::forOutliner(docstring & os, size_t) const { odocstringstream ods; plaintext(ods, OutputParams(0)); @@ -341,6 +558,8 @@ void InsetSpecialChar::validate(LaTeXFeatures & features) const features.require("lyxarrow"); if (kind_ == NOBREAKDASH) features.require("amsmath"); + if (kind_ == PHRASE_LYX) + features.require("LyX"); }