]> git.lyx.org Git - lyx.git/blob - src/Bullet.cpp
Avoid full metrics computation with Update:FitCursor
[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 "support/lassert.h"
22
23 using namespace std;
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         if (c < MIN || c >= CHARMAX)
47                 character = MIN;
48         if (s < MIN || s >= SIZEMAX)
49                 size = MIN;
50         generateText();
51         testInvariant();
52 }
53
54
55
56 Bullet::Bullet(docstring const & t)
57         : font(MIN), character(MIN), size(MIN), user_text(1), text(t), label(t)
58 {
59         testInvariant();
60 }
61
62
63 void Bullet::setCharacter(int c)
64 {
65         if (c < MIN || c >= CHARMAX)
66                 character = MIN;
67         else
68                 character = c;
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         user_text = 0;
81         testInvariant();
82 }
83
84
85 void Bullet::setSize(int s)
86 {
87         if (s < MIN || s >= SIZEMAX)
88                 size = MIN;
89         else
90                 size = s;
91         user_text = 0;
92         testInvariant();
93 }
94
95
96 void Bullet::setText(docstring const & t)
97 {
98         font = character = size = MIN;
99         user_text = 1;
100         text = t;
101         label = t;
102         testInvariant();
103 }
104
105
106 int Bullet::getCharacter() const
107 {
108         return character;
109 }
110
111
112 int Bullet::getFont() const
113 {
114         return font;
115 }
116
117
118 int Bullet::getSize() const
119 {
120         return size;
121 }
122
123
124 FontSize Bullet::getFontSize() const
125 {
126         if (size >= 0)
127                 return bulletFontSize(size);
128         else
129                 return INHERIT_SIZE;
130 }
131
132
133 Bullet & Bullet::operator=(Bullet const & b)
134 {
135         b.testInvariant();
136         font = b.font;
137         character = b.character;
138         size = b.size;
139         user_text = b.user_text;
140         text = b.text;
141         label = b.label;
142         this->testInvariant();
143         return *this;
144 }
145
146
147 docstring const & Bullet::getText() const
148 {
149         if (user_text == 0)
150                 generateText();
151         return text;
152 }
153
154
155 docstring const & Bullet::getLabel() const
156 {
157         if (user_text == 0)
158                 generateText();
159         return label;
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         } else if (b1.character == b2.character && 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                 label = bulletLabel(font, character);
199                 if (size >= 0)
200                         text = bulletSize(size) + text;
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 docstring 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 from_ascii(BulletSize[s]);
221 }
222
223
224 docstring 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 from_ascii(BulletPanels[f][c]);
366 }
367
368
369 FontSize Bullet::bulletFontSize(int s)
370 {
371         // see comment at bulletSize
372         static FontSize BulletFontSize[SIZEMAX] = {
373                 TINY_SIZE, SCRIPT_SIZE, FOOTNOTE_SIZE, SMALL_SIZE, NORMAL_SIZE,
374                 LARGE_SIZE, LARGER_SIZE, LARGEST_SIZE, HUGE_SIZE, HUGER_SIZE
375         };
376
377         return BulletFontSize[s];
378 }
379
380
381 docstring const Bullet::bulletLabel(int f, int c)
382 {
383         // see comment at bulletEntry
384         static int UnicodeBulletPanel0[CHARMAX] = {
385                 /* standard */
386                 0x02013, 0x22A2,
387                 0x022A3, 0x0266D, 0x0266E,
388                 0x0266F, 0x02217, 0x022C6,
389                 0x02022, 0x02218, 0x022C5,
390                 0x02020, 0x025B3,
391                 0x025BD, 0x025C3,
392                 0x025B9, 0x025C1, 0x025B7,
393                 0x02295, 0x02296, 0x02297,
394                 0x02298, 0x02299, 0x02660,
395                 0x022C4, 0x025C7,  /* \square */ 0x025FB,
396                 0x02662, 0x02661,
397                 0x02663, 0x02192, 0x02933,
398                 0x021C0, 0x021C1,
399                 0x021D2, 0x0227B
400         };
401         static int UnicodeBulletPanel1[CHARMAX] = {
402                 /* amssymb */
403                 0x021DB, 0x021A3,
404                 0x021A0, 0x021DD,
405                 0x021AC, 0x022B8,
406                 0x022A0, 0x0229E, 0x0229F,
407                 0x022A1, 0x022C7, 0x022AA,
408                 0x022D6, 0x022D7, 0x02720,
409                 0x02605, 0x02713, 0x022A9,
410                 0x0223D, 0x0223C,
411                 0x02B1D, 0x0229D,
412                 0x0229B, 0x025CE,
413                 0x022B2, 0x022B3,
414                 0x025B3, 0x025BD,
415                 0x025CA, 0x025FB, 0x025C0,
416                 0x025B6, 0x025B4,
417                 0x025BE, 0x029EB,
418                 0x025FC
419         };
420         static int UnicodeBulletPanel2[CHARMAX] = {
421                 /* psnfss1 */
422                 0x025CF, 0x0274D,
423                 0x025D7, 0x02295,
424                 0x02297, 0x02022,
425                 0x02727, 0x02726,
426                 0x02756, 0x025C6,
427                 0x025CA, 0x022C5,
428                 0x02751, 0x02752,
429                 0x0274F, 0x02750,
430                 0x02206, 0x02207,
431                 0x02758, 0x02759,
432                 0x0275A, 0x025A0,
433                 0x025B2, 0x025BC,
434                 0x02217, 0x02723,
435                 0x02722, 0x02732,
436                 0x02731, 0x027A4,
437                 0x02762, 0x02763,
438                 0x02766, 0x02767,
439                 0x027A2, 0x027A3
440         };
441         static int UnicodeBulletPanel3[CHARMAX] = {
442                 /* psnfss2 */
443                 0x0260E, 0x02706,
444                 0x02702, 0x02704,
445                 0x02707, 0x02708,
446                 0x02709, 0x0261B,
447                 0x0261E, 0x0270C,
448                 0x0270D, 0x0270F,
449                 0x02715, 0x02716,
450                 0x0271B, 0x02719,
451                 0x0271E, 0x0271D,
452                 0x02717, 0x02718,
453                 0x0271A, 0x0271C,
454                 0x0271F, 0x02720,
455                 0x02713, 0x02714,
456                 0x02660, 0x02663,
457                 0x02666, 0x02665,
458                 0x02764, 0x02765,
459                 0x02660, 0x02663,
460                 0x02666, 0x02665
461         };
462         static int UnicodeBulletPanel4[CHARMAX] = {
463                 /* psnfss3 */
464                 0x02721, 0x0272C,
465                 0x0272B, 0x02B51,
466                 0x02730, 0x0272A,
467                 0x0272E, 0x0272D,
468                 0x0272F, 0x02735,
469                 0x0273A, 0x02742,
470                 0x02733, 0x02734,
471                 0x02736, 0x02737,
472                 0x02738, 0x02739,
473                 0x0273C, 0x0273B,
474                 0x0273D, 0x02749,
475                 0x0273E, 0x02743,
476                 0x02747, 0x02748,
477                 0x0274A, 0x0274B,
478                 0x02724, 0x02725,
479                 0x02744, 0x02745,
480                 0x02746, 0x02740,
481                 0x0273F, 0x02741
482         };
483         static int UnicodeBulletPanel5[CHARMAX] = {
484                 /* psnfss4 */
485                 0x0279F, 0x027A0,
486                 0x027A1, 0x027A8,
487                 0x027A5, 0x027A6,
488                 0x027AE, 0x027AD,
489                 0x027AC, 0x027AB,
490                 0x027AA, 0x027A9,
491                 0x027AF, 0x027B1,
492                 0x027BA, 0x027BB,
493                 0x02711, 0x02712,
494                 0x02799, 0x027B5,
495                 0x027B3, 0x027B8,
496                 0x027BC, 0x027BD,
497                 0x0279B, 0x02192,
498                 0x0279D, 0x0279E,
499                 0x0279C, 0x02794,
500                 0x02192, 0x021D2,
501                 0x027BE, 0x027B2,
502                 0x027A7, 0x02212
503         };  /* string const BulletPanels[][] */
504
505         static int * UnicodeBulletPanels[FONTMAX] = {
506                 UnicodeBulletPanel0, UnicodeBulletPanel1,
507                 UnicodeBulletPanel2, UnicodeBulletPanel3,
508                 UnicodeBulletPanel4, UnicodeBulletPanel5
509         };
510
511         return docstring(1, char_type(UnicodeBulletPanels[f][c]));
512 }
513
514
515 void Bullet::testInvariant() const
516 {
517 #ifdef ENABLE_ASSERTIONS
518         LATTEST(font >= MIN);
519         LATTEST(font < FONTMAX);
520         LATTEST(character >= MIN);
521         LATTEST(character < CHARMAX);
522         LATTEST(size >= MIN);
523         LATTEST(size < SIZEMAX);
524         LATTEST(user_text >= -1);
525         LATTEST(user_text <= 1);
526         // now some relational/operational tests
527         if (user_text == 1) {
528                 LATTEST(font == -1 && (character == -1 && size == -1));
529                 //        LATTEST(!text.empty()); // this isn't necessarily an error
530         }
531         //      else if (user_text == -1) {
532         //        LATTEST(!text.empty()); // this also isn't necessarily an error
533         //      }
534         //      else {
535         //        // user_text == 0
536         //        LATTEST(text.empty()); // not usually true
537         //      }
538 #endif
539 }
540
541
542 } // namespace lyx