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