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