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