]> git.lyx.org Git - lyx.git/blob - src/mathed/InsetMathRoot.cpp
Improve drawing of math roots (\sqrt and \root)
[lyx.git] / src / mathed / InsetMathRoot.cpp
1 /**
2  * \file InsetMathRoot.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Alejandro Aguilar Sierra
7  * \author André Pönitz
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "InsetMathRoot.h"
15
16 #include "MathData.h"
17 #include "MathStream.h"
18 #include "MathSupport.h"
19
20 #include "Cursor.h"
21 #include "LaTeXFeatures.h"
22 #include "MetricsInfo.h"
23
24 #include "frontends/Painter.h"
25
26
27 using namespace std;
28
29 namespace lyx {
30
31
32 InsetMathRoot::InsetMathRoot(Buffer * buf)
33         : InsetMathNest(buf, 2)
34 {}
35
36
37 Inset * InsetMathRoot::clone() const
38 {
39         return new InsetMathRoot(*this);
40 }
41
42
43 void InsetMathRoot::metrics(MetricsInfo & mi, Dimension & dim) const
44 {
45         Changer dummy = mi.base.changeEnsureMath();
46         Dimension dim0;
47         {
48                 Changer script = mi.base.font.changeStyle(LM_ST_SCRIPTSCRIPT);
49                 cell(0).metrics(mi, dim0);
50                 // make sure that the dim is high enough for any character
51                 Dimension fontDim;
52                 math_font_max_dim(mi.base.font, fontDim.asc, fontDim.des);
53                 dim0 += fontDim;
54         }
55
56         Dimension dim1;
57         cell(1).metrics(mi, dim1);
58         // make sure that the dim is high enough for any character
59         Dimension fontDim;
60         math_font_max_dim(mi.base.font, fontDim.asc, fontDim.des);
61         dim1 += fontDim;
62
63         dim.asc = max(dim0.ascent()  + 5, dim1.ascent()) + 1;
64         dim.des = max(dim0.descent() - 5, dim1.descent());
65         dim.wid = dim0.width() + dim1.width() + 4;
66 }
67
68
69 void InsetMathRoot::draw(PainterInfo & pi, int x, int y) const
70 {
71         Changer dummy = pi.base.changeEnsureMath();
72         Dimension const dim = dimension(*pi.base.bv);
73         int const a = dim.ascent();
74         int const d = dim.descent();
75         Dimension const & dim0 = cell(0).dimension(*pi.base.bv);
76         int const w = dim0.width();
77         // the "exponent"
78         {
79                 Changer script = pi.base.font.changeStyle(LM_ST_SCRIPTSCRIPT);
80                 cell(0).draw(pi, x, y + (d - a)/2 - dim0.descent());
81         }
82         // the "base"
83         cell(1).draw(pi, x + w + 4, y);
84         int xp[4];
85         int yp[4];
86         pi.pain.line(x + dim.width(), y - a + 1,
87                                 x + w + 4, y - a + 1, pi.base.font.color());
88         xp[0] = x + w + 4;         yp[0] = y - a + 1;
89         xp[1] = x + w;             yp[1] = y + d;
90         xp[2] = x + w - 2;         yp[2] = y + (d - a)/2 + 2;
91         xp[3] = x + w - 5;         yp[3] = y + (d - a)/2 + 4;
92         pi.pain.lines(xp, yp, 4, pi.base.font.color());
93 }
94
95
96 void InsetMathRoot::write(WriteStream & os) const
97 {
98         MathEnsurer ensurer(os);
99         os << "\\sqrt[" << cell(0) << "]{" << cell(1) << '}';
100 }
101
102
103 void InsetMathRoot::normalize(NormalStream & os) const
104 {
105         os << "[root " << cell(0) << ' ' << cell(1) << ']';
106 }
107
108
109 bool InsetMathRoot::idxUpDown(Cursor & cur, bool up) const
110 {
111         Cursor::idx_type const target = up ? 0 : 1;
112         if (cur.idx() == target)
113                 return false;
114         cur.idx() = target;
115         cur.pos() = up ? cur.lastpos() : 0;
116         return true;
117 }
118
119
120 void InsetMathRoot::maple(MapleStream & os) const
121 {
122         os << '(' << cell(1) << ")^(1/(" << cell(0) <<"))";
123 }
124
125
126 void InsetMathRoot::mathematica(MathematicaStream & os) const
127 {
128         os << '(' << cell(1) << ")^(1/(" << cell(0) <<"))";
129 }
130
131
132 void InsetMathRoot::octave(OctaveStream & os) const
133 {
134         os << '(' << cell(1) << ")^(1/(" << cell(0) <<"))";
135 }
136
137
138 void InsetMathRoot::mathmlize(MathStream & os) const
139 {
140         os << MTag("mroot") << cell(1) << cell(0) << ETag("mroot");
141 }
142
143
144 void InsetMathRoot::htmlize(HtmlStream & os) const
145 {
146         os << MTag("span", "class='root'")
147            << MTag("sup") << cell(0) << ETag("sup")
148            << from_ascii("&radic;") 
149            << MTag("span", "class='rootof'")    << cell(1) << ETag("span") 
150                  << ETag("span");
151 }
152
153
154 void InsetMathRoot::validate(LaTeXFeatures & features) const
155 {
156         if (features.runparams().math_flavor == OutputParams::MathAsHTML)
157                 features.addCSSSnippet(
158                         "span.rootof{border-top: thin solid black;}\n"
159                         "span.root sup{font-size: 75%;}");
160         InsetMathNest::validate(features);
161 }
162
163 } // namespace lyx