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