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