]> git.lyx.org Git - lyx.git/blob - src/insets/InsetSpace.cpp
This should be the last of the commits refactoring the InsetLayout code.
[lyx.git] / src / insets / InsetSpace.cpp
1 /**
2  * \file InsetSpace.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Asger Alstrup Nielsen
7  * \author Jean-Marc Lasgouttes
8  * \author Lars Gullik Bjønnes
9  * \author Jürgen Spitzmüller
10  *
11  * Full author contact details are available in file CREDITS.
12  */
13
14 #include <config.h>
15
16 #include "InsetSpace.h"
17
18 #include "Dimension.h"
19 #include "Lexer.h"
20 #include "MetricsInfo.h"
21 #include "OutputParams.h"
22
23 #include "frontends/FontMetrics.h"
24 #include "frontends/Painter.h"
25
26 #include "support/debug.h"
27 #include "support/docstream.h"
28
29 using namespace std;
30
31 namespace lyx {
32
33
34 InsetSpace::InsetSpace()
35 {}
36
37
38 InsetSpace::InsetSpace(Kind k)
39         : kind_(k)
40 {}
41
42
43 InsetSpace::Kind InsetSpace::kind() const
44 {
45         return kind_;
46 }
47
48
49 void InsetSpace::metrics(MetricsInfo & mi, Dimension & dim) const
50 {
51         frontend::FontMetrics const & fm = theFontMetrics(mi.base.font);
52         dim.asc = fm.maxAscent();
53         dim.des = fm.maxDescent();
54
55         switch (kind_) {
56                 case THIN:
57                 case NEGTHIN:
58                     dim.wid = fm.width(char_type('M')) / 6;
59                         break;
60                 case PROTECTED:
61                 case NORMAL:
62                     dim.wid = fm.width(char_type(' '));
63                         break;
64                 case QUAD:
65                         dim.wid = fm.width(char_type('M'));
66                         break;
67                 case QQUAD:
68                         dim.wid = 2 * fm.width(char_type('M'));
69                         break;
70                 case ENSPACE:
71                 case ENSKIP:
72                         dim.wid = int(0.5 * fm.width(char_type('M')));
73                         break;
74         }
75         // Cache the inset dimension. 
76         setDimCache(mi, dim);
77 }
78
79
80 void InsetSpace::draw(PainterInfo & pi, int x, int y) const
81 {
82         Dimension const dim = dimension(*pi.base.bv);
83         int const w = dim.wid;
84         int const h = theFontMetrics(pi.base.font)
85                 .ascent('x');
86         int xp[4], yp[4];
87
88         xp[0] = x;
89         yp[0] = y - max(h / 4, 1);
90         if (kind_ == NORMAL || kind_ == PROTECTED) {
91                 xp[1] = x;     yp[1] = y;
92                 xp[2] = x + w; yp[2] = y;
93         } else {
94                 xp[1] = x;     yp[1] = y + max(h / 4, 1);
95                 xp[2] = x + w; yp[2] = y + max(h / 4, 1);
96         }
97         xp[3] = x + w;
98         yp[3] = y - max(h / 4, 1);
99
100         if (kind_ == PROTECTED || kind_ == ENSPACE || kind_ == NEGTHIN)
101                 pi.pain.lines(xp, yp, 4, Color_latex);
102         else
103                 pi.pain.lines(xp, yp, 4, Color_special);
104 }
105
106
107 void InsetSpace::write(Buffer const &, ostream & os) const
108 {
109         string command;
110         switch (kind_) {
111         case NORMAL:
112                 command = "\\space{}";
113                 break;
114         case PROTECTED:
115                 command = "~";
116                 break;
117         case THIN:
118                 command = "\\thinspace{}";
119                 break;
120         case QUAD:
121                 command = "\\quad{}";
122                 break;
123         case QQUAD:
124                 command = "\\qquad{}";
125                 break;
126         case ENSPACE:
127                 command = "\\enspace{}";
128                 break;
129         case ENSKIP:
130                 command = "\\enskip{}";
131                 break;
132         case NEGTHIN:
133                 command = "\\negthinspace{}";
134                 break;
135         }
136         os << "\\InsetSpace " << command << "\n";
137 }
138
139
140 void InsetSpace::read(Buffer const &, Lexer & lex)
141 {
142         lex.next();
143         string const command = lex.getString();
144
145         if (command == "\\space{}")
146                 kind_ = NORMAL;
147         else if (command == "~")
148                 kind_ = PROTECTED;
149         else if (command == "\\thinspace{}")
150                 kind_ = THIN;
151         else if (command == "\\quad{}")
152                 kind_ = QUAD;
153         else if (command == "\\qquad{}")
154                 kind_ = QQUAD;
155         else if (command == "\\enspace{}")
156                 kind_ = ENSPACE;
157         else if (command == "\\enskip{}")
158                 kind_ = ENSKIP;
159         else if (command == "\\negthinspace{}")
160                 kind_ = NEGTHIN;
161         else
162                 lex.printError("InsetSpace: Unknown kind: `$$Token'");
163 }
164
165
166 int InsetSpace::latex(Buffer const &, odocstream & os,
167                       OutputParams const & runparams) const
168 {
169         switch (kind_) {
170         case NORMAL:
171                 os << (runparams.free_spacing ? " " : "\\ ");
172                 break;
173         case PROTECTED:
174                 os << (runparams.free_spacing ? ' ' : '~');
175                 break;
176         case THIN:
177                 os << (runparams.free_spacing ? " " : "\\,");
178                 break;
179         case QUAD:
180                 os << (runparams.free_spacing ? " " : "\\quad{}");
181                 break;
182         case QQUAD:
183                 os << (runparams.free_spacing ? " " : "\\qquad{}");
184                 break;
185         case ENSPACE:
186                 os << (runparams.free_spacing ? " " : "\\enspace{}");
187                 break;
188         case ENSKIP:
189                 os << (runparams.free_spacing ? " " : "\\enskip{}");
190                 break;
191         case NEGTHIN:
192                 os << (runparams.free_spacing ? " " : "\\negthinspace{}");
193                 break;
194         }
195         return 0;
196 }
197
198
199 int InsetSpace::plaintext(Buffer const &, odocstream & os,
200                           OutputParams const &) const
201 {
202         os << ' ';
203         return 1;
204 }
205
206
207 int InsetSpace::docbook(Buffer const &, odocstream & os,
208                         OutputParams const &) const
209 {
210         switch (kind_) {
211         case NORMAL:
212         case QUAD:
213         case QQUAD:
214         case ENSKIP:
215                 os << " ";
216                 break;
217         case PROTECTED:
218         case ENSPACE:
219         case THIN:
220         case NEGTHIN:
221                 os << "&nbsp;";
222                 break;
223         }
224         return 0;
225 }
226
227
228 void InsetSpace::textString(Buffer const & buf, odocstream & os) const
229 {
230         plaintext(buf, os, OutputParams(0));
231 }
232
233
234 Inset * InsetSpace::clone() const
235 {
236         return new InsetSpace(kind_);
237 }
238
239
240 bool InsetSpace::isChar() const
241 {
242         return true;
243 }
244
245 bool InsetSpace::isLetter() const
246 {
247         return false;
248 }
249
250 bool InsetSpace::isSpace() const
251 {
252         return true;
253 }
254
255
256 } // namespace lyx