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