]> git.lyx.org Git - lyx.git/blob - src/mathed/InsetMathPhantom.cpp
Merge branch 'master' of git.lyx.org:lyx
[lyx.git] / src / mathed / InsetMathPhantom.cpp
1 /**
2  * \file InsetMathPhantom.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Georg Baum
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "InsetMathPhantom.h"
14
15 #include "LaTeXFeatures.h"
16 #include "MathStream.h"
17 #include "frontends/Painter.h"
18
19 #include <ostream>
20
21 namespace lyx {
22
23
24 InsetMathPhantom::InsetMathPhantom(Buffer * buf, Kind k)
25         : InsetMathNest(buf, 1), kind_(k)
26 {}
27
28
29 Inset * InsetMathPhantom::clone() const
30 {
31         return new InsetMathPhantom(*this);
32 }
33
34
35 void InsetMathPhantom::metrics(MetricsInfo & mi, Dimension & dim) const
36 {
37         cell(0).metrics(mi, dim);
38         metricsMarkers(dim);
39 }
40
41
42 void InsetMathPhantom::draw(PainterInfo & pi, int x, int y) const
43 {
44         static int const arrow_size = 4;
45
46         // We first draw the text and then an arrow
47         ColorCode const origcol = pi.base.font.color();
48         if (visibleContents())
49                 pi.base.font.setColor(Color_special);
50         cell(0).draw(pi, x + 1, y);
51         if (visibleContents())
52                 pi.base.font.setColor(origcol);
53         Dimension const dim = dimension(*pi.base.bv);
54
55         if (kind_ == phantom || kind_ == vphantom) {
56                 // y1---------
57                 //           / \.
58                 // y2-----  / | \.
59                 //            |
60                 //            |
61                 // y3-----  \ | /
62                 //           \ /
63                 // y4---------
64                 //          | | |
65                 //         /  |  \.
66                 //        x1  x2 x3
67
68                 int const x2 = x + dim.wid / 2;
69                 int const x1 = x2 - arrow_size;
70                 int const x3 = x2 + arrow_size;
71
72                 int const y1 = y - dim.asc;
73                 int const y2 = y1 + arrow_size;
74                 int const y4 = y + dim.des;
75                 int const y3 = y4 - arrow_size;
76
77                 // top arrow
78                 pi.pain.line(x2, y1, x1, y2, Color_added_space);
79                 pi.pain.line(x2, y1, x3, y2, Color_added_space);
80
81                 // bottom arrow
82                 pi.pain.line(x2, y4, x1, y3, Color_added_space);
83                 pi.pain.line(x2, y4, x3, y3, Color_added_space);
84
85                 // joining line
86                 pi.pain.line(x2, y1, x2, y4, Color_added_space);
87         }
88
89         if (kind_ == phantom || kind_ == hphantom) {
90                 // y1----  /            \.
91                 //        /              \.
92                 // y2--- <---------------->
93                 //        \              /
94                 // y3----  \            /
95                 //       |  |          |  |
96                 //      x1 x2         x3 x4
97
98                 int const x1 = x;
99                 int const x2 = x + arrow_size;
100                 int const x4 = x + dim.wid;
101                 int const x3 = x4 - arrow_size;
102
103                 int const y2 = y + (dim.des - dim.asc) / 2;
104                 int const y1 = y2 - arrow_size;
105                 int const y3 = y2 + arrow_size;
106
107                 // left arrow
108                 pi.pain.line(x1, y2, x2, y3, Color_added_space);
109                 pi.pain.line(x1, y2, x2, y1, Color_added_space);
110
111                 // right arrow
112                 pi.pain.line(x4, y2, x3, y3, Color_added_space);
113                 pi.pain.line(x4, y2, x3, y1, Color_added_space);
114
115                 // joining line
116                 pi.pain.line(x1, y2, x4, y2, Color_added_space);
117         }
118
119         else if (kind_ == mathclap) {
120                 // y1----      \     /
121                 //              \   /
122                 // y2--- -------->-<--------
123                 //              /   \.
124                 // y3----      /     \.
125                 //       |    |   |   |    |
126                 //      x1   x2  x3  x4   x5
127
128                 int const x1 = x;
129                 int const x5 = x + dim.wid;
130                 int const x3 = x + dim.wid / 2;
131                 int const x2 = std::max(x1, x3 - arrow_size);
132                 int const x4 = std::min(x5, x3 + arrow_size);
133
134                 int const y2 = y + (dim.des - dim.asc) / 2;
135                 int const y1 = y2 - arrow_size;
136                 int const y3 = y2 + arrow_size;
137
138                 // left arrow
139                 pi.pain.line(x2, y3, x3, y2, Color_added_space);
140                 pi.pain.line(x2, y1, x3, y2, Color_added_space);
141
142                 // right arrow
143                 pi.pain.line(x4, y3, x3, y2, Color_added_space);
144                 pi.pain.line(x4, y1, x3, y2, Color_added_space);
145
146                 // joining line
147                 pi.pain.line(x1, y2, x5, y2, Color_added_space);
148         }
149
150         else if (kind_ == mathllap) {
151                 // y1----                \.
152                 //                        \.
153                 // y2--- ------------------>
154                 //                        /
155                 // y3----                /
156                 //       |              |  |
157                 //      x1             x2 x3
158
159                 int const x1 = x;
160                 int const x3 = x + dim.wid;
161                 int const x2 = std::max(x1, x3 - arrow_size);
162
163                 int const y2 = y + (dim.des - dim.asc) / 2;
164                 int const y1 = y2 - arrow_size;
165                 int const y3 = y2 + arrow_size;
166
167                 // right arrow
168                 pi.pain.line(x3, y2, x2, y3, Color_added_space);
169                 pi.pain.line(x3, y2, x2, y1, Color_added_space);
170
171                 // joining line
172                 pi.pain.line(x1, y2, x3, y2, Color_added_space);
173         }
174
175         else if (kind_ == mathrlap) {
176                 // y1----  /
177                 //        /
178                 // y2--- <------------------
179                 //        \.
180                 // y3----  \.
181                 //       |  |              |
182                 //      x1 x2             x3
183
184                 int const x1 = x;
185                 int const x3 = x + dim.wid;
186                 int const x2 = std::min(x3, x + arrow_size);
187
188                 int const y2 = y + (dim.des - dim.asc) / 2;
189                 int const y1 = y2 - arrow_size;
190                 int const y3 = y2 + arrow_size;
191
192                 // left arrow
193                 pi.pain.line(x1, y2, x2, y3, Color_added_space);
194                 pi.pain.line(x1, y2, x2, y1, Color_added_space);
195
196                 // joining line
197                 pi.pain.line(x1, y2, x3, y2, Color_added_space);
198         }
199
200         else if (kind_ == smash) {
201                 // y1---------
202                 //            |
203                 // y2-----  \ | /
204                 //           \ /
205                 // y3-------- |
206                 //           / \.
207                 // y4-----  / | \.
208                 //            |
209                 // y5---------
210                 //          | | |
211                 //         /  |  \.
212                 //        x1  x2 x3
213
214                 int const x2 = x + dim.wid / 2;
215                 int const x1 = x2 - arrow_size;
216                 int const x3 = x2 + arrow_size;
217
218                 int const y1 = y - dim.asc;
219                 int const y5 = y + dim.des;
220                 int const y3 = y;
221                 int const y2 = std::max(y1, y3 - arrow_size);
222                 int const y4 = std::min(y5, y3 + arrow_size);
223
224                 // top arrow
225                 pi.pain.line(x1, y2, x2, y3, Color_added_space);
226                 pi.pain.line(x3, y2, x2, y3, Color_added_space);
227
228                 // bottom arrow
229                 pi.pain.line(x1, y4, x2, y3, Color_added_space);
230                 pi.pain.line(x3, y4, x2, y3, Color_added_space);
231
232                 // joining line
233                 pi.pain.line(x2, y1, x2, y5, Color_added_space);
234         }
235
236         drawMarkers(pi, x, y);
237 }
238
239
240 void InsetMathPhantom::write(WriteStream & os) const
241 {
242         MathEnsurer ensurer(os);
243         switch (kind_) {
244         case phantom:
245                 os << "\\phantom{";
246                 break;
247         case vphantom:
248                 os << "\\vphantom{";
249                 break;
250         case hphantom:
251                 os << "\\hphantom{";
252                 break;
253         case smash:
254                 os << "\\smash{";
255                 break;
256         case mathclap:
257                 os << "\\mathclap{";
258                 break;
259         case mathllap:
260                 os << "\\mathllap{";
261                 break;
262         case mathrlap:
263                 os << "\\mathrlap{";
264                 break;
265         }
266         os << cell(0) << '}';
267 }
268
269
270 void InsetMathPhantom::normalize(NormalStream & os) const
271 {
272         switch (kind_) {
273         case phantom:
274                 os << "[phantom ";
275                 break;
276         case vphantom:
277                 os << "[vphantom ";
278                 break;
279         case hphantom:
280                 os << "[hphantom ";
281                 break;
282         case smash:
283                 os << "[smash ";
284                 break;
285         case mathclap:
286                 os << "[mathclap ";
287                 break;
288         case mathllap:
289                 os << "[mathllap ";
290                 break;
291         case mathrlap:
292                 os << "[mathrlap ";
293                 break;
294         }
295         os << cell(0) << ']';
296 }
297
298
299 void InsetMathPhantom::infoize(odocstream & os) const
300 {
301         switch (kind_) {
302         case phantom:
303                 os << "Phantom";
304                 break;
305         case vphantom:
306                 os << "Vphantom";
307                 break;
308         case hphantom:
309                 os << "Hphantom";
310                 break;
311         case smash:
312                 os << "Smash";
313                 break;
314         case mathllap:
315                 os << "Mathllap";
316                 break;
317         case mathclap:
318                 os << "Mathclap";
319                 break;
320         case mathrlap:
321                 os << "Mathrlap";
322                 break;
323         }
324 }
325
326
327 void InsetMathPhantom::validate(LaTeXFeatures & features) const
328 {
329         InsetMathNest::validate(features);
330         switch (kind_) {
331         case phantom:
332         case vphantom:
333         case hphantom:
334         case smash:
335                 break;
336         case mathclap:
337         case mathllap:
338         case mathrlap:
339                 features.require("mathtools");
340                 break;
341         }
342 }
343
344
345 bool InsetMathPhantom::visibleContents() const 
346
347         return kind_ == phantom || kind_ == vphantom || kind_ == vphantom;
348 }
349
350
351 } // namespace lyx