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