]> git.lyx.org Git - lyx.git/blob - src/Bullet.C
fix typo that put too many include paths for most people
[lyx.git] / src / Bullet.C
1 /* Completes the implementation of the Bullet class
2  * It defines the various LaTeX commands etc. required to
3  * generate the bullets in the bullet-panel's.
4  *
5  * This file is part of
6  * ======================================================
7  *
8  *           LyX, The Document Processor
9  *
10  *           Copyright 1997-1998 Allan Rae
11  *           and the LyX Team
12  *
13  * ====================================================== */
14
15 #include <config.h>
16
17 #ifdef __GNUG__
18 #pragma implementation
19 #endif
20
21 #include "Bullet.h"
22 #include "support/LAssert.h"
23
24 /** The four LaTeX itemize environment default bullets
25  */
26 extern
27 Bullet const ITEMIZE_DEFAULTS[4] = { Bullet(0, 8),//"\\(\\bullet\\)"
28                                      Bullet(0, 0),//"\\normalfont\\bfseries{--}"
29                                      Bullet(0, 6),//"\\(\\ast\\)"
30                                      Bullet(0, 10) };//"\\(\\cdot\\)"
31
32 // will need these later if still using full text as below
33 // \usepackage{latexsym,pifont,amssymb}
34 // and wasysym when that panel is created
35
36
37 Bullet::Bullet(int f, int c, int s)
38   : font(f), character(c), size(s), user_text(0)
39 {
40         if (f < MIN || f >= FONTMAX) {
41                 font = MIN;
42         }
43         if (c < MIN || c >= CHARMAX) {
44                 character = MIN;
45         }
46         if (s < MIN || s >= SIZEMAX) {
47                 size = MIN;
48         }
49         generateText();
50 #ifdef ENABLE_ASSERTIONS
51         testInvariant();
52 #endif
53 }
54
55
56
57 Bullet::Bullet(string const & t)
58         :  font(MIN), character(MIN), size(MIN), user_text(1), text(t)
59 {
60 #ifdef ENABLE_ASSERTIONS
61         testInvariant();
62 #endif
63 }
64
65
66 void Bullet::setCharacter(int c)
67 {
68         if (c < MIN || c >= CHARMAX) {
69                 character = MIN;
70         } else {
71                 character = c;
72         }
73         user_text = 0;
74 #ifdef ENABLE_ASSERTIONS
75         testInvariant();
76 #endif
77 }
78
79
80 void Bullet::setFont(int f)
81 {
82         if (f < MIN || f >= FONTMAX) {
83                 font = MIN;
84         } else {
85                 font = f;
86         }
87         user_text = 0;
88 #ifdef ENABLE_ASSERTIONS
89         testInvariant();
90 #endif
91 }
92
93
94 void Bullet::setSize(int s)
95 {
96         if (s < MIN || s >= SIZEMAX) {
97                 size = MIN;
98         } else {
99                 size = s;
100         }
101         user_text = 0;
102 #ifdef ENABLE_ASSERTIONS
103         testInvariant();
104 #endif
105 }
106
107
108 void Bullet::setText(string const & t)
109 {
110         font = character = size = MIN;
111         user_text = 1;
112         text = t;
113 #ifdef ENABLE_ASSERTIONS
114         testInvariant();
115 #endif
116 }
117
118
119 int Bullet::getCharacter() const
120 {
121         return character;
122 }
123
124
125 int Bullet::getFont() const
126 {
127         return font;
128 }
129
130
131 int Bullet::getSize() const
132 {
133         return size;
134 }
135
136
137 Bullet & Bullet::operator=(Bullet const & b)
138 {
139 #ifdef ENABLE_ASSERTIONS
140         b.testInvariant();
141 #endif
142         font = b.font;
143         character = b.character;
144         size = b.size;
145         user_text = b.user_text;
146         text = b.text;
147 #ifdef ENABLE_ASSERTIONS
148         this->testInvariant();
149 #endif
150         return *this;
151 }
152
153
154 string const & Bullet::getText() const
155 {
156         if (user_text == 0) {
157                 generateText();
158         }
159         return text;
160 }
161
162
163 bool operator==(const Bullet & b1, const Bullet & b2)
164 {
165         bool result = false;
166
167         if (b1.user_text && b2.user_text) {
168                 /* both have valid text */
169                 if (b1.text == b2.text) {
170                         result = true;
171                 }
172         } else if (((b1.character == b2.character) &&
173                           (b1.font == b2.font)) &&
174                          (b1.size == b2.size)) {
175                 result = true;
176         }
177         return result;
178 }
179
180
181 /*--------------------Private Member Functions-------------------*/
182
183
184 void Bullet::generateText() const
185 {
186         // Assumption:
187         // user hasn't defined their own text and/or I haven't generated
188         // the text for the current font/character settings yet
189         // thus the calling member function should say:
190         //    if (user_text == 0) {
191         //       generateText();
192         //    }
193         // Since a function call is more expensive than a conditional
194         // this is more efficient. Besides this function is internal to
195         // the class so it's only the class author that has access --
196         // external users thus can't make mistakes.
197
198         if ((font >= 0) && (character >= 0)) {
199                 text = bulletEntry(font, character);
200                 if (size >= 0) {
201                         text = bulletSize(size) + text;
202                 }
203                 user_text = -1;
204                 // text is now defined and doesn't need to be recalculated
205                 // unless font/character or text is modified
206         }
207 }
208
209
210 string const Bullet::bulletSize(int s)
211 {
212         // use a parameter rather than hard code `size' in here
213         // in case some future function may want to retrieve
214         // an arbitrary entry.
215         // See additional comments in bulletEntry() below.
216
217         static char const * BulletSize[SIZEMAX] = {
218                 "\\tiny",  "\\scriptsize", "\\footnotesize", "\\small", "\\normalsize",
219                 "\\large", "\\Large",      "\\LARGE",        "\\huge",  "\\Huge"
220         };
221
222         return BulletSize[s];
223 }
224
225
226 string const Bullet::bulletEntry(int f, int c)
227 {
228         // Despite how this may at first appear the static local variables
229         // are only initialized once..
230         // This is a work-around to avoid the "Static Initialization Problem"
231         // and should work for all compilers. See "C++ FAQs" by Cline and Lomow,
232         // Addison-Wesley, 1994, FAQ-180 pp169-171 for an explanation.
233         // Doing things this way also makes it possible to generate `text' at
234         // the time of construction.  It also encapsulates the conversion
235         // of font, character and size entries to text.
236
237         // The single 2-dim array had to be changed to multiple 1-dim arrays
238         // to get around a compiler bug in an earler version of gcc (< 2.7.2.1)
239         // static string const BulletPanels[FONTMAX][CHARMAX] = {
240         static char const * BulletPanel0[CHARMAX] = {
241                 /* standard */
242                 "\\normalfont\\bfseries{--}", "\\(\\vdash\\)",
243                 "\\(\\dashv\\)", "\\(\\flat\\)", "\\(\\natural\\)",
244                 "\\(\\sharp\\)", "\\(\\ast\\)", "\\(\\star\\)",
245                 "\\(\\bullet\\)", "\\(\\circ\\)", "\\(\\cdot\\)",
246                 "\\(\\dagger\\)", "\\(\\bigtriangleup\\)",
247                 "\\(\\bigtriangledown\\)", "\\(\\triangleleft\\)",
248                 "\\(\\triangleright\\)", "\\(\\lhd\\)", "\\(\\rhd\\)",
249                 "\\(\\oplus\\)", "\\(\\ominus\\)", "\\(\\otimes\\)",
250                 "\\(\\oslash\\)", "\\(\\odot\\)", "\\(\\spadesuit\\)",
251                 "\\(\\diamond\\)", "\\(\\Diamond\\)", "\\(\\Box\\)",
252                 "\\(\\diamondsuit\\)", "\\(\\heartsuit\\)",
253                 "\\(\\clubsuit\\)", "\\(\\rightarrow\\)", "\\(\\leadsto\\)",
254                 "\\(\\rightharpoonup\\)", "\\(\\rightharpoondown\\)",
255                 "\\(\\Rightarrow\\)", "\\(\\succ\\)"
256         };
257         static char const * BulletPanel1[CHARMAX] = {
258                 /* amssymb */
259                 "\\(\\Rrightarrow\\)", "\\(\\rightarrowtail\\)",
260                 "\\(\\twoheadrightarrow\\)", "\\(\\rightsquigarrow\\)",
261                 "\\(\\looparrowright\\)", "\\(\\multimap\\)",
262                 "\\(\\boxtimes\\)", "\\(\\boxplus\\)", "\\(\\boxminus\\)",
263                 "\\(\\boxdot\\)", "\\(\\divideontimes\\)", "\\(\\Vvdash\\)",
264                 "\\(\\lessdot\\)", "\\(\\gtrdot\\)", "\\(\\maltese\\)",
265                 "\\(\\bigstar\\)", "\\(\\checkmark\\)", "\\(\\Vdash\\)",
266                 "\\(\\backsim\\)", "\\(\\thicksim\\)",
267                 "\\(\\centerdot\\)", "\\(\\circleddash\\)",
268                 "\\(\\circledast\\)", "\\(\\circledcirc\\)",
269                 "\\(\\vartriangleleft\\)", "\\(\\vartriangleright\\)",
270                 "\\(\\vartriangle\\)", "\\(\\triangledown\\)",
271                 "\\(\\lozenge\\)", "\\(\\square\\)", "\\(\\blacktriangleleft\\)",
272                 "\\(\\blacktriangleright\\)", "\\(\\blacktriangle\\)",
273                 "\\(\\blacktriangledown\\)", "\\(\\blacklozenge\\)",
274                 "\\(\\blacksquare\\)"
275         };
276         static char const * BulletPanel2[CHARMAX] = {
277                 /* psnfss1 */
278                 "\\ding{108}", "\\ding{109}",
279                 "\\ding{119}", "\\Pisymbol{psy}{197}",
280                 "\\Pisymbol{psy}{196}", "\\Pisymbol{psy}{183}",
281                 "\\ding{71}", "\\ding{70}",
282                 "\\ding{118}", "\\ding{117}",
283                 "\\Pisymbol{psy}{224}", "\\Pisymbol{psy}{215}",
284                 "\\ding{111}", "\\ding{112}",
285                 "\\ding{113}", "\\ding{114}",
286                 "\\Pisymbol{psy}{68}", "\\Pisymbol{psy}{209}",
287                 "\\ding{120}", "\\ding{121}",
288                 "\\ding{122}", "\\ding{110}",
289                 "\\ding{115}", "\\ding{116}",
290                 "\\Pisymbol{psy}{42}", "\\ding{67}",
291                 "\\ding{66}", "\\ding{82}",
292                 "\\ding{81}", "\\ding{228}",
293                 "\\ding{162}", "\\ding{163}",
294                 "\\ding{166}", "\\ding{167}",
295                 "\\ding{226}", "\\ding{227}"
296         };
297         static char const * BulletPanel3[CHARMAX] = {
298                 /* psnfss2 */
299                 "\\ding{37}", "\\ding{38}",
300                 "\\ding{34}", "\\ding{36}",
301                 "\\ding{39}", "\\ding{40}",
302                 "\\ding{41}", "\\ding{42}",
303                 "\\ding{43}", "\\ding{44}",
304                 "\\ding{45}", "\\ding{47}",
305                 "\\ding{53}", "\\ding{54}",
306                 "\\ding{59}", "\\ding{57}",
307                 "\\ding{62}", "\\ding{61}",
308                 "\\ding{55}", "\\ding{56}",
309                 "\\ding{58}", "\\ding{60}",
310                 "\\ding{63}", "\\ding{64}",
311                 "\\ding{51}", "\\ding{52}",
312                 "\\Pisymbol{psy}{170}", "\\Pisymbol{psy}{167}",
313                 "\\Pisymbol{psy}{168}", "\\Pisymbol{psy}{169}",
314                 "\\ding{164}", "\\ding{165}",
315                 "\\ding{171}", "\\ding{168}",
316                 "\\ding{169}", "\\ding{170}"
317         };
318         static char const * BulletPanel4[CHARMAX] = {
319                 /* psnfss3 */
320                 "\\ding{65}", "\\ding{76}",
321                 "\\ding{75}", "\\ding{72}",
322                 "\\ding{80}", "\\ding{74}",
323                 "\\ding{78}", "\\ding{77}",
324                 "\\ding{79}", "\\ding{85}",
325                 "\\ding{90}", "\\ding{98}",
326                 "\\ding{83}", "\\ding{84}",
327                 "\\ding{86}", "\\ding{87}",
328                 "\\ding{88}", "\\ding{89}",
329                 "\\ding{92}", "\\ding{91}",
330                 "\\ding{93}", "\\ding{105}",
331                 "\\ding{94}", "\\ding{99}",
332                 "\\ding{103}", "\\ding{104}",
333                 "\\ding{106}", "\\ding{107}",
334                 "\\ding{68}", "\\ding{69}",
335                 "\\ding{100}", "\\ding{101}",
336                 "\\ding{102}", "\\ding{96}",
337                 "\\ding{95}", "\\ding{97}"
338         };
339         static char const * BulletPanel5[CHARMAX] = {
340                 /* psnfss4 */
341                 "\\ding{223}", "\\ding{224}",
342                 "\\ding{225}", "\\ding{232}",
343                 "\\ding{229}", "\\ding{230}",
344                 "\\ding{238}", "\\ding{237}",
345                 "\\ding{236}", "\\ding{235}",
346                 "\\ding{234}", "\\ding{233}",
347                 "\\ding{239}", "\\ding{241}",
348                 "\\ding{250}", "\\ding{251}",
349                 "\\ding{49}", "\\ding{50}",
350                 "\\ding{217}", "\\ding{245}",
351                 "\\ding{243}", "\\ding{248}",
352                 "\\ding{252}", "\\ding{253}",
353                 "\\ding{219}", "\\ding{213}",
354                 "\\ding{221}", "\\ding{222}",
355                 "\\ding{220}", "\\ding{212}",
356                 "\\Pisymbol{psy}{174}", "\\Pisymbol{psy}{222}",
357                 "\\ding{254}", "\\ding{242}",
358                 "\\ding{231}", "\\Pisymbol{psy}{45}"
359         };  /* string const BulletPanels[][] */
360
361         static char const ** BulletPanels[FONTMAX] = {
362                 BulletPanel0, BulletPanel1,
363                 BulletPanel2, BulletPanel3,
364                 BulletPanel4, BulletPanel5
365         };
366
367         return BulletPanels[f][c];
368 }
369
370 #ifdef ENABLE_ASSERTIONS
371 void Bullet::testInvariant() const {
372         lyx::Assert(font >= MIN);
373         lyx::Assert(font < FONTMAX);
374         lyx::Assert(character >= MIN);
375         lyx::Assert(character < CHARMAX);
376         lyx::Assert(size >= MIN);
377         lyx::Assert(size < SIZEMAX);
378         lyx::Assert(user_text >= -1);
379         lyx::Assert(user_text <= 1);
380         // now some relational/operational tests
381         if (user_text == 1) {
382                 lyx::Assert(font == -1 && (character == -1 && size == -1));
383                 //        Assert(!text.empty()); // this isn't necessarily an error
384         }
385         //      else if (user_text == -1) {
386         //        Assert(!text.empty()); // this also isn't necessarily an error
387         //      }
388         //      else {
389         //        // user_text == 0
390         //        Assert(text.empty()); // not usually true
391         //      }
392 }
393 #endif