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