]> git.lyx.org Git - lyx.git/blobdiff - src/insets/InsetIPAMacro.cpp
Fix bug #12795
[lyx.git] / src / insets / InsetIPAMacro.cpp
index 6e0591f7dd8f6c3fede40ee19f4579851bacf412..2d4b1fb13c2d25e516f66fb462f5862c2dde3bd1 100644 (file)
 #include "BufferParams.h"
 #include "Dimension.h"
 #include "Encoding.h"
-#include "Font.h"
+#include "FontInfo.h"
 #include "FuncRequest.h"
 #include "FuncStatus.h"
+#include "InsetLayout.h"
 #include "LaTeXFeatures.h"
 #include "Lexer.h"
 #include "MetricsInfo.h"
-#include "output_xhtml.h"
+#include "xml.h"
+#include "texstream.h"
 
 #include "frontends/FontMetrics.h"
 #include "frontends/Painter.h"
@@ -59,14 +61,16 @@ IPADecoTranslatorLoc const init_ipadecotranslator_loc()
 
 IPADecoTranslator const & ipadecotranslator()
 {
-       static IPADecoTranslator decotranslator = init_ipadecotranslator();
+       static IPADecoTranslator const decotranslator =
+                       init_ipadecotranslator();
        return decotranslator;
 }
 
 
 IPADecoTranslatorLoc const & ipadecotranslator_loc()
 {
-       static IPADecoTranslatorLoc translator = init_ipadecotranslator_loc();
+       static IPADecoTranslatorLoc const translator =
+           init_ipadecotranslator_loc();
        return translator;
 }
 
@@ -86,11 +90,12 @@ IPACharTranslator const init_ipachartranslator()
 
 IPACharTranslator const & ipachartranslator()
 {
-       static IPACharTranslator chartranslator = init_ipachartranslator();
+       static IPACharTranslator const chartranslator =
+           init_ipachartranslator();
        return chartranslator;
 }
 
-} // anon
+} // namespace
 
 
 InsetIPADecoParams::InsetIPADecoParams()
@@ -121,7 +126,7 @@ void InsetIPADecoParams::read(Lexer & lex)
 /////////////////////////////////////////////////////////////////////
 
 InsetIPADeco::InsetIPADeco(Buffer * buf, string const & label)
-       : InsetCollapsable(buf)
+       : InsetCollapsible(buf)
 {
        setDrawFrame(true);
        setFrameColor(Color_insetframe);
@@ -142,7 +147,7 @@ docstring InsetIPADeco::layoutName() const
 void InsetIPADeco::metrics(MetricsInfo & mi, Dimension & dim) const
 {
        InsetText::metrics(mi, dim);
-       
+
        if (params_.type == InsetIPADecoParams::Toptiebar) {
                // consider width of the inset label
                FontInfo font(getLayout().labelfont());
@@ -154,7 +159,7 @@ void InsetIPADeco::metrics(MetricsInfo & mi, Dimension & dim) const
                int d = 0;
                docstring const label(1, char_type(0x2040));
                theFontMetrics(font).rectText(label, w, a, d);
-               dim.asc += a * 0.5;
+               dim.asc += int(a * 0.5);
        }
        if (params_.type == InsetIPADecoParams::Bottomtiebar) {
                // consider width of the inset label
@@ -167,23 +172,20 @@ void InsetIPADeco::metrics(MetricsInfo & mi, Dimension & dim) const
                int d = 0;
                docstring const label(1, char_type(0x203f));
                theFontMetrics(font).rectText(label, w, a, d);
-               dim.des += d * 1.5;
+               dim.des += int(d * 1.5);
        }
-
-       // cache the inset dimension
-       setDimCache(mi, dim);
 }
 
 
 void InsetIPADeco::draw(PainterInfo & pi, int x, int y) const
 {
        // draw the text
-       InsetCollapsable::draw(pi, x, y);
+       InsetCollapsible::draw(pi, x, y);
 
        // draw the inset marker
        drawMarkers(pi, x, y);
 
-       Dimension const dim = Inset::dimension(*pi.base.bv);
+       Dimension const dim = dimension(*pi.base.bv);
 
        if (params_.type == InsetIPADecoParams::Toptiebar) {
                FontInfo font(getLayout().labelfont());
@@ -197,7 +199,7 @@ void InsetIPADeco::draw(PainterInfo & pi, int x, int y) const
                docstring const label(1, char_type(0x2040));
                theFontMetrics(font).rectText(label, w, a, d);
                int const ww = max(dim.wid, w);
-               pi.pain.rectText(x + (ww - w) / 2, y - (asc / 2.5),
+               pi.pain.rectText(x + (ww - w) / 2, y - int(asc / 2.5),
                        label, font, Color_none, Color_none);
        }
 
@@ -213,7 +215,7 @@ void InsetIPADeco::draw(PainterInfo & pi, int x, int y) const
                docstring const label(1, char_type(0x203f));
                theFontMetrics(font).rectText(label, w, a, d);
                int const ww = max(dim.wid, w);
-               pi.pain.rectText(x + (ww - w) / 2, y + (desc / 1.5),
+               pi.pain.rectText(x + (ww - w) / 2, y + int(desc / 1.5),
                        label, font, Color_none, Color_none);
        }
 }
@@ -222,14 +224,14 @@ void InsetIPADeco::draw(PainterInfo & pi, int x, int y) const
 void InsetIPADeco::write(ostream & os) const
 {
        params_.write(os);
-       InsetCollapsable::write(os);
+       InsetCollapsible::write(os);
 }
 
 
 void InsetIPADeco::read(Lexer & lex)
 {
        params_.read(lex);
-       InsetCollapsable::read(lex);
+       InsetCollapsible::read(lex);
 }
 
 
@@ -276,30 +278,70 @@ void InsetIPADeco::latex(otexstream & os, OutputParams const & runparams) const
                os << "\\texttoptiebar{";
        else if (params_.type == InsetIPADecoParams::Bottomtiebar)
                os << "\\textbottomtiebar{";
-       InsetCollapsable::latex(os, runparams);
+       InsetCollapsible::latex(os, runparams);
        os << "}";
 }
 
 
-int InsetIPADeco::plaintext(odocstream & os,
-                           OutputParams const & runparams) const
+namespace {
+std::pair<docstring, docstring> splitPlainTextInHalves(
+               const InsetIPADeco * inset, OutputParams const & runparams,
+               size_t max_length = INT_MAX)
 {
-       // FIXME: Any plaintext option here?
-       return InsetCollapsable::plaintext(os, runparams);
+       odocstringstream ods;
+       int h = inset->InsetCollapsible::plaintext(ods, runparams, max_length) / 2;
+       docstring result = ods.str();
+       docstring const before = result.substr(0, h);
+       docstring const after = result.substr(h, result.size());
+       return {before, after};
+}
 }
 
 
-int InsetIPADeco::docbook(odocstream & os, OutputParams const & runparams) const
+int InsetIPADeco::plaintext(odocstringstream & os,
+                           OutputParams const & runparams, size_t max_length) const
 {
-       // FIXME: Any docbook option here?
-       return InsetCollapsable::docbook(os, runparams);
+       docstring before;
+       docstring after;
+       tie(before, after) = splitPlainTextInHalves(this, runparams, max_length);
+
+       if (params_.type == InsetIPADecoParams::Toptiebar) {
+               os << before;
+               os.put(0x0361);
+               os << after;
+       }
+       else if (params_.type == InsetIPADecoParams::Bottomtiebar) {
+               os << before;
+               os.put(0x035c);
+               os << after;
+       }
+       return before.size() + after.size();
 }
 
 
-docstring InsetIPADeco::xhtml(XHTMLStream & xs, OutputParams const & runparams) const
+void InsetIPADeco::docbook(XMLStream & xs, OutputParams const & runparams) const
 {
-       // FIXME: Any xhtml option here?
-       return InsetCollapsable::xhtml(xs, runparams);
+       // The special combining character must be put in the middle, between the two other characters.
+       // It will not work if there is anything else than two pure characters, so going back to plaintext.
+       docstring before;
+       docstring after;
+       tie(before, after) = splitPlainTextInHalves(this, runparams);
+
+       xs << XMLStream::ESCAPE_NONE << before;
+       if (params_.type == InsetIPADecoParams::Toptiebar)
+               xs << XMLStream::ESCAPE_NONE << "&#x0361;";
+       else if (params_.type == InsetIPADecoParams::Bottomtiebar)
+               xs << XMLStream::ESCAPE_NONE << "&#x035c;";
+       xs << XMLStream::ESCAPE_NONE << after;
+}
+
+
+docstring InsetIPADeco::xhtml(XMLStream & xs, OutputParams const & runparams) const
+{
+       // The DocBook encoding for this inset has no DocBook tag, but sheer XML (relying on a plaintext
+       // transformation of the inset).
+       docbook(xs, runparams);
+       return docstring();
 }
 
 
@@ -337,8 +379,7 @@ void InsetIPADeco::string2params(string const & in, InsetIPADecoParams & params)
 
 void InsetIPADeco::validate(LaTeXFeatures & features) const
 {
-       if (!buffer_->params().useNonTeXFonts)
-               features.require("tipa");
+       features.require("tipa");
        InsetText::validate(features);
 }
 
@@ -364,7 +405,7 @@ bool InsetIPADeco::insetAllowed(InsetCode code) const
 
 
 InsetIPAChar::InsetIPAChar(Kind k)
-       : Inset(0), kind_(k)
+       : Inset(nullptr), kind_(k)
 {}
 
 
@@ -393,7 +434,6 @@ void InsetIPAChar::metrics(MetricsInfo & mi, Dimension & dim) const
        }
        docstring ds(s.begin(), s.end());
        dim.wid = fm.width(ds);
-       setDimCache(mi, dim);
 }
 
 
@@ -432,7 +472,7 @@ void InsetIPAChar::draw(PainterInfo & pi, int x, int y) const
                int h = fm.ascent(char_type('M'));
                int x2 = x + w;
                int y2 = y - h;
-               int y3 = y - (h * 0.75);
+               int y3 = y - int(h * 0.75);
 
                pi.pain.line(x2, y, x2, y2, Color_foreground);
                pi.pain.line(x2, y2, x, y3, Color_foreground);
@@ -444,7 +484,7 @@ void InsetIPAChar::draw(PainterInfo & pi, int x, int y) const
                int h = fm.ascent(char_type('M'));
                int x2 = x + w;
                int y2 = y - h;
-               int y3 = y - (h * 0.25);
+               int y3 = y - int(h * 0.25);
 
                pi.pain.line(x2, y, x2, y2, Color_foreground);
                pi.pain.line(x2, y3, x, y, Color_foreground);
@@ -456,8 +496,8 @@ void InsetIPAChar::draw(PainterInfo & pi, int x, int y) const
                int h = fm.ascent(char_type('M'));
                int x2 = x + w;
                int y2 = y - h;
-               int x3 = x + (w * 0.5);
-               int y3 = y - (h * 0.75);
+               int x3 = x + int(w * 0.5);
+               int y3 = y - int(h * 0.75);
 
                pi.pain.line(x2, y, x2, y2, Color_foreground);
                pi.pain.line(x2, y3, x3, y2, Color_foreground);
@@ -495,7 +535,7 @@ void InsetIPAChar::latex(otexstream & os,
 }
 
 
-int InsetIPAChar::plaintext(odocstream & os, OutputParams const &) const
+int InsetIPAChar::plaintext(odocstringstream & os, OutputParams const &, size_t) const
 {
        switch (kind_) {
        case TONE_FALLING:
@@ -524,57 +564,47 @@ int InsetIPAChar::plaintext(odocstream & os, OutputParams const &) const
 }
 
 
-int InsetIPAChar::docbook(odocstream & /*os*/, OutputParams const &) const
-{
-       switch (kind_) {
-       // FIXME
-       case TONE_FALLING:
-       case TONE_RISING:
-       case TONE_HIGH_RISING:
-       case TONE_LOW_RISING:
-       case TONE_HIGH_RISING_FALLING:
-               break;
+namespace {
+std::string ipaCharToXMLEntity(InsetIPAChar::Kind kind) {
+       switch (kind) {
+       case InsetIPAChar::Kind::TONE_FALLING:
+               return "&#x2e5;&#x2e9;";
+       case InsetIPAChar::Kind::TONE_RISING:
+               return "&#x2e9;&#x2e5;";
+       case InsetIPAChar::Kind::TONE_HIGH_RISING:
+               return "&#x2e7;&#x2e5;";
+       case InsetIPAChar::Kind::TONE_LOW_RISING:
+               return "&#x2e9;&#x2e7;";
+       case InsetIPAChar::Kind::TONE_HIGH_RISING_FALLING:
+               return "&#x2e8;&#x2e5;&#x2e8;";
        }
-       return 0;
+       return "";
+}
 }
 
 
-docstring InsetIPAChar::xhtml(XHTMLStream & xs, OutputParams const &) const
+void InsetIPAChar::docbook(XMLStream & xs, OutputParams const &) const
 {
-       switch (kind_) {
-       case TONE_FALLING:
-               xs << XHTMLStream::ESCAPE_NONE << "&#x2e5;"
-                  << XHTMLStream::ESCAPE_NONE << "&#x2e9;";
-               break;
-       case TONE_RISING:
-               xs << XHTMLStream::ESCAPE_NONE << "&#x2e9;"
-                  << XHTMLStream::ESCAPE_NONE << "&#x2e5;";
-               break;
-       case TONE_HIGH_RISING:
-               xs << XHTMLStream::ESCAPE_NONE << "&#x2e7;"
-                  << XHTMLStream::ESCAPE_NONE << "&#x2e5;";
-               break;
-       case TONE_LOW_RISING:
-               xs << XHTMLStream::ESCAPE_NONE << "&#x2e9;"
-                  << XHTMLStream::ESCAPE_NONE << "&#x2e7;";
-               break;
-       case TONE_HIGH_RISING_FALLING:
-               xs << XHTMLStream::ESCAPE_NONE << "&#x2e8;"
-                  << XHTMLStream::ESCAPE_NONE << "&#x2e5;"
-                  << XHTMLStream::ESCAPE_NONE << "&#x2e8;";
-               break;
-       }
+       xs << XMLStream::ESCAPE_NONE << from_ascii(ipaCharToXMLEntity(kind()));
+}
+
+
+docstring InsetIPAChar::xhtml(XMLStream & xs, OutputParams const &) const
+{
+       xs << XMLStream::ESCAPE_NONE << from_ascii(ipaCharToXMLEntity(kind()));
        return docstring();
 }
 
 
 void InsetIPAChar::toString(odocstream & os) const
 {
-       plaintext(os, OutputParams(0));
+       odocstringstream ods;
+       plaintext(ods, OutputParams(0));
+       os << ods.str();
 }
 
 
-void InsetIPAChar::forToc(docstring & os, size_t) const
+void InsetIPAChar::forOutliner(docstring & os, size_t const, bool const) const
 {
        odocstringstream ods;
        plaintext(ods, OutputParams(0));
@@ -590,8 +620,7 @@ void InsetIPAChar::validate(LaTeXFeatures & features) const
        case TONE_HIGH_RISING:
        case TONE_LOW_RISING:
        case TONE_HIGH_RISING_FALLING:
-               if (!buffer_->params().useNonTeXFonts)
-                       features.require("tone");
+               features.require("tone");
                break;
        default:
                break;
@@ -599,16 +628,4 @@ void InsetIPAChar::validate(LaTeXFeatures & features) const
 }
 
 
-bool InsetIPAChar::isLetter() const
-{
-       return true;
-}
-
-
-bool InsetIPAChar::isLineSeparator() const
-{
-       return false;
-}
-
-
 } // namespace lyx