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