]> git.lyx.org Git - lyx.git/blob - src/insets/insetspecialchar.C
7979f1ff8f83490cabf8401ddb6729b79f84bdd7
[lyx.git] / src / insets / insetspecialchar.C
1 /* This file is part of
2  * ======================================================
3  * 
4  *           LyX, The Document Processor
5  *       
6  *          Copyright 1997 Asger Alstrup
7  *
8  * ====================================================== */
9
10 #include <config.h>
11
12 #ifdef __GNUG__
13 #pragma implementation
14 #endif
15
16 #include "insetspecialchar.h"
17 #include "debug.h"
18 #include "LaTeXFeatures.h"
19 #include "BufferView.h"
20 #include "Painter.h"
21 #include "font.h"
22
23 using std::ostream;
24 using std::max;
25
26 InsetSpecialChar::InsetSpecialChar(Kind k)
27         : kind(k)
28 {}
29
30
31 int InsetSpecialChar::ascent(BufferView *, LyXFont const & font) const
32 {
33         return lyxfont::maxAscent(font);
34 }
35
36
37 int InsetSpecialChar::descent(BufferView *, LyXFont const & font) const
38 {
39         return lyxfont::maxDescent(font);
40 }
41
42
43 int InsetSpecialChar::width(BufferView *, LyXFont const & font) const
44 {
45         switch (kind) {
46         case HYPHENATION:
47         {
48                 int w = lyxfont::width('-', font);
49                 if (w > 5) 
50                         w -= 2; // to make it look shorter
51                 return w;
52         }
53         case LIGATURE_BREAK:
54         {
55                 return lyxfont::width('|', font);
56         }
57         case END_OF_SENTENCE:
58         {
59                 return lyxfont::width('.', font);
60         }
61         case LDOTS:
62         {
63                 return lyxfont::width(". . .", font);
64         }
65         case MENU_SEPARATOR:
66         {
67                 return lyxfont::width(" x ", font);
68         }
69         case PROTECTED_SEPARATOR:
70         {
71                 return lyxfont::width('x', font);
72         }
73         
74         }
75         return 1; // To shut up gcc
76 }
77
78
79 void InsetSpecialChar::draw(BufferView * bv, LyXFont const & f,
80                             int baseline, float & x, bool) const
81 {
82         Painter & pain = bv->painter();
83         LyXFont font(f);
84
85         switch (kind) {
86         case HYPHENATION:
87         {
88                 font.setColor(LColor::special);
89                 pain.text(int(x), baseline, "-", font);
90                 x += width(bv, font);
91                 break;
92         }
93         case LIGATURE_BREAK:
94         {
95                 font.setColor(LColor::special);
96                 pain.text(int(x), baseline, "|", font);
97                 x += width(bv, font);
98                 break;
99         }
100         case END_OF_SENTENCE:
101         {
102                 font.setColor(LColor::special);
103                 pain.text(int(x), baseline, ".", font);
104                 x += width(bv, font);
105                 break;
106         }
107         case LDOTS:
108         {
109                 font.setColor(LColor::special);
110                 pain.text(int(x), baseline, ". . .", font);
111                 x += width(bv, font);
112                 break;
113         }
114         case MENU_SEPARATOR:
115         {
116                 // A triangle the width and height of an 'x'
117                 int w = lyxfont::width('x', font);
118                 int ox = lyxfont::width(' ', font) + int(x);
119                 int h = lyxfont::ascent('x', font);
120                 int xp[4], yp[4];
121                 
122                 xp[0] = ox;     yp[0] = baseline;
123                 xp[1] = ox;     yp[1] = baseline - h;
124                 xp[2] = ox + w; yp[2] = baseline - h/2;
125                 xp[3] = ox;     yp[3] = baseline;
126                 
127                 pain.lines(xp, yp, 4, LColor::special);
128                 x += width(bv, font);
129                 break;
130         }
131         case PROTECTED_SEPARATOR:
132         {
133                 float w = width(bv, font);
134                 int h = lyxfont::ascent('x', font);
135                 int xp[4], yp[4];
136                 
137                 xp[0] = int(x);
138                 yp[0] = baseline - max(h / 4, 1);
139
140                 xp[1] = int(x);
141                 yp[1] = baseline;
142
143                 xp[2] = int(x + w);
144                 yp[2] = baseline;
145
146                 xp[3] = int(x + w);
147                 yp[3] = baseline - max(h / 4, 1);
148                 
149                 pain.lines(xp, yp, 4, LColor::special);
150                 x += w;
151                 break;
152         }
153         }
154 }
155
156
157 // In lyxf3 this will be just LaTeX
158 void InsetSpecialChar::write(Buffer const *, ostream & os) const
159 {
160         string command;
161         switch (kind) {
162         case HYPHENATION:       
163                 command = "\\-";        
164                 break;
165         case LIGATURE_BREAK: 
166                 command = "\\textcompwordmark{}"; 
167                 break;
168         case END_OF_SENTENCE:   
169                 command = "\\@.";
170                 break;
171         case LDOTS:
172                 command = "\\ldots{}";  
173                 break;
174         case MENU_SEPARATOR:
175                 command = "\\menuseparator"; 
176                 break;
177         case PROTECTED_SEPARATOR:
178                 //command = "\\protected_separator";
179                 command = "~";
180                 break;
181         }
182         os << "\\SpecialChar " << command << "\n";
183 }
184
185
186 // This function will not be necessary when lyx3
187 void InsetSpecialChar::read(Buffer const *, LyXLex & lex)
188 {    
189         lex.nextToken();
190         string const command = lex.GetString();
191
192         if (command == "\\-")
193                 kind = HYPHENATION;
194         else if (command == "\\textcompwordmark{}")
195                 kind = LIGATURE_BREAK;
196         else if (command == "\\@.")
197                 kind = END_OF_SENTENCE;
198         else if (command == "\\ldots{}")
199                 kind = LDOTS;
200         else if (command == "\\menuseparator")
201                 kind = MENU_SEPARATOR;
202         else if (command == "\\protected_separator"
203                  || command == "~")
204                 kind = PROTECTED_SEPARATOR;
205         else
206                 lex.printError("InsetSpecialChar: Unknown kind: `$$Token'");
207 }
208
209
210 int InsetSpecialChar::latex(Buffer const *, ostream & os, bool /*fragile*/,
211                             bool free_space) const
212 {
213         switch (kind) {
214         case HYPHENATION:         
215                 os << "\\-";    
216                 break;
217         case LIGATURE_BREAK:
218                 os << "\\textcompwordmark{}";
219                 break;
220         case END_OF_SENTENCE:     
221                 os << "\\@.";   
222                 break;
223         case LDOTS:               
224                 os << "\\ldots{}";      
225                 break;
226         case MENU_SEPARATOR:      
227                 os << "\\lyxarrow{}"; 
228                 break;
229         case PROTECTED_SEPARATOR: 
230                 os << (free_space ? " " : "~"); 
231                 break;
232         }
233         return 0;
234 }
235
236
237 int InsetSpecialChar::ascii(Buffer const *, ostream & os, int) const
238 {
239         switch (kind) {
240         case HYPHENATION:
241         case LIGATURE_BREAK:
242                 break;
243         case END_OF_SENTENCE:     
244                 os << ".";      
245                 break;
246         case LDOTS:               
247                 os << "...";    
248                 break;
249         case MENU_SEPARATOR:      
250                 os << "->";   
251                 break;
252         case PROTECTED_SEPARATOR: 
253                 os << " ";
254                 break;
255         }
256         return 0;
257 }
258
259
260 int InsetSpecialChar::linuxdoc(Buffer const * buf, ostream & os) const
261 {
262         return ascii(buf, os, 0);
263 }
264
265
266 int InsetSpecialChar::docBook(Buffer const * buf, ostream & os) const
267 {
268         return ascii(buf, os, 0);
269 }
270
271
272 Inset * InsetSpecialChar::clone(Buffer const &, bool) const
273 {
274         return new InsetSpecialChar(kind);
275 }
276
277
278 void InsetSpecialChar::validate(LaTeXFeatures & features) const
279 {
280         if (kind == MENU_SEPARATOR) {
281                 features.lyxarrow = true;
282         }
283 }