X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fmathed%2FInsetMathRoot.cpp;h=348b4e9cab67743b8be4275fe125424935d7a04e;hb=c8230ab0d0a919530c43c29395f4d9961498bf15;hp=5442fd1be4d1b41e6478c0d3c609eb25e3906045;hpb=96860ffe93637bd7698706c3bb85b65bd0d8a979;p=lyx.git diff --git a/src/mathed/InsetMathRoot.cpp b/src/mathed/InsetMathRoot.cpp index 5442fd1be4..348b4e9cab 100644 --- a/src/mathed/InsetMathRoot.cpp +++ b/src/mathed/InsetMathRoot.cpp @@ -4,7 +4,7 @@ * Licence details can be found in the file COPYING. * * \author Alejandro Aguilar Sierra - * \author André Pönitz + * \author André Pönitz * * Full author contact details are available in file CREDITS. */ @@ -12,70 +12,135 @@ #include #include "InsetMathRoot.h" -#include "MathData.h" + #include "MathStream.h" +#include "MathSupport.h" + #include "Cursor.h" -#include "Color.h" +#include "LaTeXFeatures.h" +#include "MetricsInfo.h" #include "frontends/Painter.h" +using namespace std; + namespace lyx { -using std::max; -using std::auto_ptr; +using namespace frontend; +InsetMathRoot::InsetMathRoot(Buffer * buf) + : InsetMathNest(buf, 2) +{} -InsetMathRoot::InsetMathRoot() - : InsetMathNest(2) -{} +Inset * InsetMathRoot::clone() const +{ + return new InsetMathRoot(*this); +} -auto_ptr InsetMathRoot::doClone() const +void mathed_root_metrics(MetricsInfo & mi, MathData const & nucleus, + MathData const * root, Dimension & dim) { - return auto_ptr(new InsetMathRoot(*this)); + Changer dummy = mi.base.changeEnsureMath(); + Dimension dimr; + if (root) { + Changer script = mi.base.font.changeStyle(LM_ST_SCRIPTSCRIPT); + root->metrics(mi, dimr); + // make sure that the dim is high enough for any character + Dimension fontDim; + math_font_max_dim(mi.base.font, fontDim.asc, fontDim.des); + dimr += fontDim; + } + + Dimension dimn; + nucleus.metrics(mi, dimn); + // make sure that the dim is high enough for any character + // Dimension fontDim; + // math_font_max_dim(mi.base.font, fontDim.asc, fontDim.des); + // dimn += fontDim; + + // Some room for the decoration + // The width of left decoration was 9 pixels with a 10em font + int const w = 9 * mathed_font_em(mi.base.font) / 10; + /* See rule 11 in Appendix G of Rhe TeXbook for the computation of the spacing + * above nucleus. + * FIXME more work is needed to implement properly rule 11. + * * Ideally, we should use sqrt glyphs from the math fonts. Note + that then we would get rule thickness from there. + * * The positioning of the root MathData is arbitrary. It should + * follow the definition of \root...\of... in The Texbook in + * Apprendix B page 360. + * + */ + int const t = mi.base.solidLineThickness(); + int const x_height = mathed_font_x_height(mi.base.font); + int const phi = (mi.base.font.style() == LM_ST_DISPLAY) ? x_height : t; + // first part is the spacing, second part is the line width + // itself, and last one is the spacing above. + int const space_above = (t + phi / 4) + t + t; + int const a = dimn.ascent(); + int const d = dimn.descent(); + // Not sure what the 1 stands for, it is needed to have some spacing at small sizes. + dim.asc = max(dimr.ascent() + (d - a) / 2, a + space_above) + 1; + dim.des = max(dimr.descent() - (d - a) / 2, d); + dim.wid = max(dimr.width() + 3 * w / 8, w) + dimn.width(); } -bool InsetMathRoot::metrics(MetricsInfo & mi, Dimension & dim) const +void InsetMathRoot::metrics(MetricsInfo & mi, Dimension & dim) const { - InsetMathNest::metrics(mi); - dim.asc = max(cell(0).ascent() + 5, cell(1).ascent()) + 2; - dim.des = max(cell(0).descent() - 5, cell(1).descent()) + 2; - dim.wid = cell(0).width() + cell(1).width() + 10; - metricsMarkers(dim); - if (dim_ == dim) - return false; - dim_ = dim; - return true; + mathed_root_metrics(mi, cell(1), &cell(0), dim); } -void InsetMathRoot::draw(PainterInfo & pi, int x, int y) const +void mathed_draw_root(PainterInfo & pi, int x, int y, MathData const & nucleus, + MathData const * root, Dimension const & dim) { - int const w = cell(0).width(); + Changer dummy = pi.base.changeEnsureMath(); + // The width of left decoration was 9 pixels with a 10em font + int const w = 9 * mathed_font_em(pi.base.font) / 10; + // the height of the hook was 5 with a 10em font + int const h = 5 * mathed_font_em(pi.base.font) / 10; + int const a = dim.ascent(); + int const d = dim.descent(); + int const t = pi.base.solidLineThickness(); + Dimension const dimn = nucleus.dimension(*pi.base.bv); + // the width of the left part of the root + int const wl = dim.width() - dimn.width(); // the "exponent" - cell(0).draw(pi, x, y - 5 - cell(0).descent()); + if (root) { + Changer script = pi.base.font.changeStyle(LM_ST_SCRIPTSCRIPT); + Dimension const dimr = root->dimension(*pi.base.bv); + int const root_offset = wl - 3 * w / 8 - dimr.width(); + root->draw(pi, x + root_offset, y + (d - a)/2); + } // the "base" - cell(1).draw(pi, x + w + 8, y); - int const a = dim_.ascent(); - int const d = dim_.descent(); + nucleus.draw(pi, x + wl, y); int xp[4]; int yp[4]; - pi.pain.line(x + dim_.width(), y - a + 1, - x + w + 4, y - a + 1, Color::math); - xp[0] = x + w + 4; yp[0] = y - a + 1; - xp[1] = x + w; yp[1] = y + d; - xp[2] = x + w - 2; yp[2] = y + (d - a)/2 + 2; - xp[3] = x + w - 5; yp[3] = y + (d - a)/2 + 4; - pi.pain.lines(xp, yp, 4, Color::math); - drawMarkers(pi, x, y); + pi.pain.line(x + dim.width(), y - a + 2 * t, + x + wl, y - a + 2 * t, pi.base.font.color(), + Painter::line_solid, t); + xp[0] = x + wl; yp[0] = y - a + 2 * t + 1; + xp[1] = x + wl - w / 2; yp[1] = y + d; + xp[2] = x + wl - w + h / 4; yp[2] = y + d - h; + xp[3] = x + wl - w; yp[3] = y + d - h + h / 4; + pi.pain.lines(xp, yp, 4, pi.base.font.color(), + Painter::fill_none, Painter::line_solid, t); +} + + +void InsetMathRoot::draw(PainterInfo & pi, int x, int y) const +{ + mathed_draw_root(pi, x, y, cell(1), &cell(0), dimension(*pi.base.bv)); } void InsetMathRoot::write(WriteStream & os) const { + MathEnsurer ensurer(os); os << "\\sqrt[" << cell(0) << "]{" << cell(1) << '}'; } @@ -121,4 +186,23 @@ void InsetMathRoot::mathmlize(MathStream & os) const } +void InsetMathRoot::htmlize(HtmlStream & os) const +{ + os << MTag("span", "class='root'") + << MTag("sup") << cell(0) << ETag("sup") + << from_ascii("√") + << MTag("span", "class='rootof'") << cell(1) << ETag("span") + << ETag("span"); +} + + +void InsetMathRoot::validate(LaTeXFeatures & features) const +{ + if (features.runparams().math_flavor == OutputParams::MathAsHTML) + features.addCSSSnippet( + "span.rootof{border-top: thin solid black;}\n" + "span.root sup{font-size: 75%;}"); + InsetMathNest::validate(features); +} + } // namespace lyx