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