]> git.lyx.org Git - lyx.git/blob - src/insets/insetspace.C
two-phase-drawing for InsetText & InsetTabular
[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 Juergen Spitzmueller
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 "dimension.h"
20 #include "LaTeXFeatures.h"
21 #include "latexrunparams.h"
22 #include "BufferView.h"
23 #include "frontends/Painter.h"
24 #include "frontends/font_metrics.h"
25 #include "lyxlex.h"
26 #include "lyxfont.h"
27 #include "metricsinfo.h"
28
29 using std::ostream;
30 using std::max;
31
32
33 InsetSpace::InsetSpace()
34 {}
35
36
37 InsetSpace::InsetSpace(Kind k)
38         : kind_(k)
39 {}
40
41
42 InsetSpace::Kind InsetSpace::kind() const
43 {
44         return kind_;
45 }
46
47
48 void InsetSpace::metrics(MetricsInfo & mi, Dimension & dim) const
49 {
50         LyXFont & font = mi.base.font;
51         dim.asc = font_metrics::maxAscent(font);
52         dim.des = font_metrics::maxDescent(font);
53
54         switch (kind_) {
55                 case THIN:
56                 case NEGTHIN:
57                         dim.wid = font_metrics::width("x", font) / 3;
58                         break;
59                 case PROTECTED:
60                 case NORMAL:
61                         dim.wid = font_metrics::width("x", font);
62                         break;
63                 case QUAD:
64                         dim.wid = 20;
65                         break;
66                 case QQUAD:
67                         dim.wid = 40;
68                         break;
69                 case ENSPACE:
70                 case ENSKIP:
71                         dim.wid = 10;
72                         break;
73         }
74         dim_ = dim;
75 }
76
77
78 void InsetSpace::draw(PainterInfo & pi, int x, int y) const
79 {
80         int const w = width();
81         int const h = font_metrics::ascent('x', pi.base.font);
82         int xp[4], yp[4];
83
84         xp[0] = x;
85         yp[0] = y - max(h / 4, 1);
86         if (kind_ == NORMAL) {
87                 xp[1] = x;     yp[1] = y;
88                 xp[2] = x + w; yp[2] = y;
89         } else {
90                 xp[1] = x;     yp[1] = y + max(h / 4, 1);
91                 xp[2] = x + w; yp[2] = y + max(h / 4, 1);
92         }
93         xp[3] = x + w;
94         yp[3] = y - max(h / 4, 1);
95
96         if (kind_ == PROTECTED || kind_ == ENSPACE || kind_ == NEGTHIN)
97                 pi.pain.lines(xp, yp, 4, LColor::latex);
98         else
99                 pi.pain.lines(xp, yp, 4, LColor::special);
100 }
101
102
103 void InsetSpace::write(Buffer const *, ostream & os) const
104 {
105         string command;
106         switch (kind_) {
107         case NORMAL:
108                 command = "\\space";
109                 break;
110         case PROTECTED:
111                 command = "~";
112                 break;
113         case THIN:
114                 command = "\\,";
115                 break;
116         case QUAD:
117                 command = "\\quad{}";
118                 break;
119         case QQUAD:
120                 command = "\\qquad{}";
121                 break;
122         case ENSPACE:
123                 command = "\\enspace{}";
124                 break;
125         case ENSKIP:
126                 command = "\\enskip{}";
127                 break;
128         case NEGTHIN:
129                 command = "\\negthinspace{}";
130                 break;
131         }
132         os << "\\InsetSpace " << command << "\n";
133 }
134
135
136 // This function will not be necessary when lyx3
137 void InsetSpace::read(Buffer const *, LyXLex & lex)
138 {
139         lex.nextToken();
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 == "\\,")
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                       LatexRunParams 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::ascii(Buffer const *, ostream & os, int) const
197 {
198         switch (kind_) {
199         case NORMAL:
200         case PROTECTED:
201         case THIN:
202         case QUAD:
203         case QQUAD:
204         case ENSPACE:
205         case ENSKIP:
206         case NEGTHIN:
207                 os << ' ';
208                 break;
209         }
210         return 0;
211 }
212
213
214 int InsetSpace::linuxdoc(Buffer const *, ostream & os) const
215 {
216         switch (kind_) {
217         case NORMAL:
218         case QUAD:
219         case QQUAD:
220         case ENSKIP:
221                 os << " ";
222                 break;
223         case PROTECTED:
224         case ENSPACE:
225         case THIN:
226         case NEGTHIN:
227                 os << "&nbsp;";
228                 break;
229         }
230         return 0;
231 }
232
233
234 int InsetSpace::docbook(Buffer const *, ostream & os, bool) const
235 {
236         switch (kind_) {
237         case NORMAL:
238         case QUAD:
239         case QQUAD:
240         case ENSKIP:
241                 os << " ";
242                 break;
243         case PROTECTED:
244         case ENSPACE:
245         case THIN:
246         case NEGTHIN:
247                 os << "&nbsp;";
248                 break;
249         }
250         return 0;
251 }
252
253
254 InsetBase * InsetSpace::clone() const
255 {
256         return new InsetSpace(kind_);
257 }
258
259
260 bool InsetSpace::isChar() const
261 {
262         return true;
263 }
264
265 bool InsetSpace::isLetter() const
266 {
267         return false;
268 }
269
270 bool InsetSpace::isSpace() const
271 {
272         return true;
273 }
274
275 bool InsetSpace::isLineSeparator() const
276 {
277         return false;
278 }