]> git.lyx.org Git - lyx.git/blob - src/insets/insetspecialchar.C
The speed patch: redraw only rows that have changed
[lyx.git] / src / insets / insetspecialchar.C
1 /**
2  * \file insetspecialchar.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  *
10  * Full author contact details are available in file CREDITS.
11  */
12
13 #include <config.h>
14
15 #include "insetspecialchar.h"
16
17 #include "debug.h"
18 #include "LaTeXFeatures.h"
19 #include "LColor.h"
20 #include "lyxlex.h"
21 #include "metricsinfo.h"
22
23 #include "frontends/font_metrics.h"
24 #include "frontends/Painter.h"
25
26
27 using std::string;
28 using std::auto_ptr;
29 using std::ostream;
30
31
32 InsetSpecialChar::InsetSpecialChar(Kind k)
33         : kind_(k)
34 {}
35
36
37 InsetSpecialChar::Kind InsetSpecialChar::kind() const
38 {
39         return kind_;
40 }
41
42
43 void InsetSpecialChar::metrics(MetricsInfo & mi, Dimension & dim) const
44 {
45         LyXFont & font = mi.base.font;
46         dim.asc = font_metrics::maxAscent(font);
47         dim.des = font_metrics::maxDescent(font);
48
49         string s;
50         switch (kind_) {
51                 case LIGATURE_BREAK:      s = "|";     break;
52                 case END_OF_SENTENCE:     s = ".";     break;
53                 case LDOTS:               s = ". . ."; break;
54                 case MENU_SEPARATOR:      s = " x ";   break;
55                 case HYPHENATION:      s = "-";   break;
56         }
57         dim.wid = font_metrics::width(s, font);
58         if (kind_ == HYPHENATION && dim.wid > 5)
59                 dim.wid -= 2; // to make it look shorter
60         dim_ = dim;
61 }
62
63
64 void InsetSpecialChar::draw(PainterInfo & pi, int x, int y) const
65 {
66         LyXFont font = pi.base.font;
67
68         switch (kind_) {
69         case HYPHENATION:
70         {
71                 font.setColor(LColor::special);
72                 pi.pain.text(x, y, '-', font);
73                 break;
74         }
75         case LIGATURE_BREAK:
76         {
77                 font.setColor(LColor::special);
78                 pi.pain.text(x, y, '|', font);
79                 break;
80         }
81         case END_OF_SENTENCE:
82         {
83                 font.setColor(LColor::special);
84                 pi.pain.text(x, y, '.', font);
85                 break;
86         }
87         case LDOTS:
88         {
89                 font.setColor(LColor::special);
90                 pi.pain.text(x, y, ". . .", font);
91                 break;
92         }
93         case MENU_SEPARATOR:
94         {
95                 // A triangle the width and height of an 'x'
96                 int w = font_metrics::width('x', font);
97                 int ox = font_metrics::width(' ', font) + x;
98                 int h = font_metrics::ascent('x', font);
99                 int xp[4], yp[4];
100
101                 xp[0] = ox;     yp[0] = y;
102                 xp[1] = ox;     yp[1] = y - h;
103                 xp[2] = ox + w; yp[2] = y - h/2;
104                 xp[3] = ox;     yp[3] = y;
105
106                 pi.pain.lines(xp, yp, 4, LColor::special);
107                 break;
108         }
109         }
110 }
111
112
113 // In lyxf3 this will be just LaTeX
114 void InsetSpecialChar::write(Buffer const &, ostream & os) const
115 {
116         string command;
117         switch (kind_) {
118         case HYPHENATION:
119                 command = "\\-";
120                 break;
121         case LIGATURE_BREAK:
122                 command = "\\textcompwordmark{}";
123                 break;
124         case END_OF_SENTENCE:
125                 command = "\\@.";
126                 break;
127         case LDOTS:
128                 command = "\\ldots{}";
129                 break;
130         case MENU_SEPARATOR:
131                 command = "\\menuseparator";
132                 break;
133         }
134         os << "\\SpecialChar " << command << "\n";
135 }
136
137
138 // This function will not be necessary when lyx3
139 void InsetSpecialChar::read(Buffer const &, LyXLex & lex)
140 {
141         lex.next();
142         string const command = lex.getString();
143
144         if (command == "\\-")
145                 kind_ = HYPHENATION;
146         else if (command == "\\textcompwordmark{}")
147                 kind_ = LIGATURE_BREAK;
148         else if (command == "\\@.")
149                 kind_ = END_OF_SENTENCE;
150         else if (command == "\\ldots{}")
151                 kind_ = LDOTS;
152         else if (command == "\\menuseparator")
153                 kind_ = MENU_SEPARATOR;
154         else
155                 lex.printError("InsetSpecialChar: Unknown kind: `$$Token'");
156 }
157
158
159 int InsetSpecialChar::latex(Buffer const &, ostream & os,
160                             OutputParams const &) const
161 {
162         switch (kind_) {
163         case HYPHENATION:
164                 os << "\\-";
165                 break;
166         case LIGATURE_BREAK:
167                 os << "\\textcompwordmark{}";
168                 break;
169         case END_OF_SENTENCE:
170                 os << "\\@.";
171                 break;
172         case LDOTS:
173                 os << "\\ldots{}";
174                 break;
175         case MENU_SEPARATOR:
176                 os << "\\lyxarrow{}";
177                 break;
178         }
179         return 0;
180 }
181
182
183 int InsetSpecialChar::plaintext(Buffer const &, ostream & os,
184                             OutputParams const &) const
185 {
186         switch (kind_) {
187         case HYPHENATION:
188         case LIGATURE_BREAK:
189                 break;
190         case END_OF_SENTENCE:
191                 os << '.';
192                 break;
193         case LDOTS:
194                 os << "...";
195                 break;
196         case MENU_SEPARATOR:
197                 os << "->";
198                 break;
199         }
200         return 0;
201 }
202
203
204 int InsetSpecialChar::linuxdoc(Buffer const &, ostream & os,
205                                OutputParams const &) const
206 {
207         switch (kind_) {
208         case HYPHENATION:
209         case LIGATURE_BREAK:
210                 break;
211         case END_OF_SENTENCE:
212                 os << '.';
213                 break;
214         case LDOTS:
215                 os << "...";
216                 break;
217         case MENU_SEPARATOR:
218                 os << "&lyxarrow;";
219                 break;
220         }
221         return 0;
222 }
223
224
225 int InsetSpecialChar::docbook(Buffer const &, ostream & os,
226                               OutputParams const &) const
227 {
228         switch (kind_) {
229         case HYPHENATION:
230         case LIGATURE_BREAK:
231                 break;
232         case END_OF_SENTENCE:
233                 os << '.';
234                 break;
235         case LDOTS:
236                 os << "...";
237                 break;
238         case MENU_SEPARATOR:
239                 os << "&lyxarrow;";
240                 break;
241         }
242         return 0;
243 }
244
245
246 int InsetSpecialChar::textString(Buffer const & buf, ostream & os,
247                        OutputParams const & op) const
248 {
249         return plaintext(buf, os, op);
250 }
251
252
253 auto_ptr<InsetBase> InsetSpecialChar::doClone() const
254 {
255         return auto_ptr<InsetBase>(new InsetSpecialChar(kind_));
256 }
257
258
259 void InsetSpecialChar::validate(LaTeXFeatures & features) const
260 {
261         if (kind_ == MENU_SEPARATOR) {
262                 features.require("lyxarrow");
263         }
264 }
265
266
267 bool InsetSpecialChar::isChar() const
268 {
269         return true;
270 }
271
272
273 bool InsetSpecialChar::isLetter() const
274 {
275         return kind_ == HYPHENATION || kind_ == LIGATURE_BREAK;
276 }
277
278
279 bool InsetSpecialChar::isLineSeparator() const
280 {
281 #if 0
282         // this would be nice, but it does not work, since
283         // Paragraph::stripLeadingSpaces nukes the characters which
284         // have this property. I leave the code here, since it should
285         // eventually be made to work. (JMarc 20020327)
286         return kind_ == HYPHENATION || kind_ == MENU_SEPARATOR;
287 #else
288         return false;
289 #endif
290 }