]> git.lyx.org Git - lyx.git/blob - src/mathed/math_charinset.C
Fix to bug 2362: Deleting superscript also deletes subscript.
[lyx.git] / src / mathed / math_charinset.C
1 /**
2  * \file math_charinset.C
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 "math_charinset.h"
15 #include "math_support.h"
16 #include "math_mathmlstream.h"
17
18 #include "debug.h"
19 #include "dimension.h"
20 #include "support/lstrings.h"
21 #include "textpainter.h"
22
23 using std::auto_ptr;
24
25 extern bool has_math_fonts;
26
27 namespace {
28
29         bool isBinaryOp(char c)
30         {
31                 return lyx::support::contains("+-<>=/*", c);
32         }
33
34
35         bool slanted(char c)
36         {
37                 return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');
38         }
39
40 }
41
42
43 MathCharInset::MathCharInset(char c)
44         : char_(c)
45 {}
46
47
48
49 auto_ptr<InsetBase> MathCharInset::doClone() const
50 {
51         return auto_ptr<InsetBase>(new MathCharInset(*this));
52 }
53
54
55 void MathCharInset::metrics(MetricsInfo & mi, Dimension & dim) const
56 {
57 #if 1
58         if (char_ == '=' && has_math_fonts) {
59                 FontSetChanger dummy(mi.base, "cmr");
60                 mathed_char_dim(mi.base.font, char_, dim);
61         } else if ((char_ == '>' || char_ == '<') && has_math_fonts) {
62                 FontSetChanger dummy(mi.base, "cmm");
63                 mathed_char_dim(mi.base.font, char_, dim);
64         } else if (!slanted(char_) && mi.base.fontname == "mathnormal") {
65                 ShapeChanger dummy(mi.base.font, LyXFont::UP_SHAPE);
66                 mathed_char_dim(mi.base.font, char_, dim);
67         } else {
68                 mathed_char_dim(mi.base.font, char_, dim);
69         }
70         int const em = mathed_char_width(mi.base.font, 'M');
71         if (isBinaryOp(char_))
72                 dim.wid += static_cast<int>(0.5*em+0.5);
73         else if (char_ == '\'')
74                 dim.wid += static_cast<int>(0.1667*em+0.5);
75 #else
76         whichFont(font_, code_, mi);
77         mathed_char_dim(font_, char_, dim_);
78         if (isBinaryOp(char_, code_))
79                 width_ += 2 * font_metrics::width(' ', font_);
80         lyxerr << "MathCharInset::metrics: " << dim << endl;
81 #endif
82         width_ = dim.wid;
83 }
84
85
86 void MathCharInset::draw(PainterInfo & pi, int x, int y) const
87 {
88         //lyxerr << "drawing '" << char_ << "' font: " << pi.base.fontname << endl;
89         int const em = mathed_char_width(pi.base.font, 'M');
90         if (isBinaryOp(char_))
91                 x += static_cast<int>(0.25*em+0.5);
92         else if (char_ == '\'')
93                 x += static_cast<int>(0.0833*em+0.5);
94 #if 1
95         if (char_ == '=' && has_math_fonts) {
96                 FontSetChanger dummy(pi.base, "cmr");
97                 pi.draw(x, y, char_);
98         } else if ((char_ == '>' || char_ == '<') && has_math_fonts) {
99                 FontSetChanger dummy(pi.base, "cmm");
100                 pi.draw(x, y, char_);
101         } else if (!slanted(char_) && pi.base.fontname == "mathnormal") {
102                 ShapeChanger dummy(pi.base.font, LyXFont::UP_SHAPE);
103                 pi.draw(x, y, char_);
104         } else {
105                 pi.draw(x, y, char_);
106         }
107 #else
108         drawChar(pain, font_, x, y, char_);
109 #endif
110 }
111
112
113 void MathCharInset::metricsT(TextMetricsInfo const &, Dimension & dim) const
114 {
115         dim.wid = 1;
116         dim.asc = 1;
117         dim.des = 0;
118 }
119
120
121 void MathCharInset::drawT(TextPainter & pain, int x, int y) const
122 {
123         //lyxerr << "drawing text '" << char_ << "' code: " << code_ << endl;
124         pain.draw(x, y, char_);
125 }
126
127
128 void MathCharInset::write(WriteStream & os) const
129 {
130         os << char_;
131 }
132
133
134 void MathCharInset::normalize(NormalStream & os) const
135 {
136         os << "[char " << char_ << " mathalpha]";
137 }
138
139
140 void MathCharInset::octave(OctaveStream & os) const
141 {
142         os << char_;
143 }
144
145
146 void MathCharInset::mathmlize(MathMLStream & ms) const
147 {
148         switch (char_) {
149                 case '<': ms << "&lt;"; break;
150                 case '>': ms << "&gt;"; break;
151                 case '&': ms << "&amp;"; break;
152                 default: ms << char_; break;
153         }
154 }
155
156
157 bool MathCharInset::isRelOp() const
158 {
159         return char_ == '=' || char_ == '<' || char_ == '>';
160 }