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