]> git.lyx.org Git - features.git/blob - src/lyxfont.h
several small and larger changes, read the Changelog
[features.git] / src / lyxfont.h
1 // -*- C++ -*-
2 /* This file is part of
3  * ======================================================
4  * 
5  *           LyX, The Document Processor
6  *       
7  *          Copyright 1995 Matthias Ettrich
8  *
9  * ====================================================== */
10
11 #ifndef LYXFONT_H
12 #define LYXFONT_H
13
14 #ifdef __GNUG__
15 #pragma interface
16 #endif
17
18 #include FORMS_H_LOCATION
19 #include "LString.h"
20 #include "debug.h"
21 #include "direction.h"
22
23 // It might happen that locale.h defines ON and OFF. This is not good
24 // for us, since we use these names below. But of course this is due
25 // to some old compilers. Than is broken when it comes to C++ scoping.
26 #include "gettext.h" // so that we are sure tht it won't be included
27 // later. 
28 #ifdef ON
29 #undef ON
30 #endif
31
32 #ifdef OFF
33 #undef OFF
34 #endif
35
36 class LyXLex;
37
38 ///
39 class LyXFont {
40 public:
41         /** The value INHERIT_* means that the font attribute is
42             inherited from the layout. In the case of layout fonts, the
43             attribute is inherited from the default font.
44             The value IGNORE_* is used with LyXFont::update() when the
45             attribute should not be changed.
46         */
47         enum FONT_FAMILY {
48                 ///
49                 ROMAN_FAMILY, // fontstruct rely on this to be 0
50                 ///
51                 SANS_FAMILY,
52                 ///
53                 TYPEWRITER_FAMILY,
54                 ///
55                 SYMBOL_FAMILY,
56                 ///
57                 INHERIT_FAMILY,
58                 ///
59                 IGNORE_FAMILY
60         };
61
62         ///
63         enum FONT_SERIES {
64                 ///
65                 MEDIUM_SERIES, // fontstruct rely on this to be 0
66                 ///
67                 BOLD_SERIES,
68                 ///
69                 INHERIT_SERIES,
70                 ///
71                 IGNORE_SERIES
72         };
73
74         ///
75         enum FONT_SHAPE {
76                 ///
77                 UP_SHAPE, // fontstruct rely on this to be 0
78                 ///
79                 ITALIC_SHAPE,
80                 ///
81                 SLANTED_SHAPE,
82                 ///
83                 SMALLCAPS_SHAPE,
84                 ///
85                 INHERIT_SHAPE,
86                 ///
87                 IGNORE_SHAPE
88         };
89
90         ///
91         enum FONT_SIZE {
92                 ///
93                 SIZE_TINY, // fontstruct rely on this to be 0
94                 ///
95                 SIZE_SCRIPT,
96                 ///
97                 SIZE_FOOTNOTE,
98                 ///
99                 SIZE_SMALL,
100                 ///
101                 SIZE_NORMAL,
102                 ///
103                 SIZE_LARGE,
104                 ///
105                 SIZE_LARGER,
106                 ///
107                 SIZE_LARGEST,
108                 ///
109                 SIZE_HUGE,
110                 ///
111                 SIZE_HUGER,
112                 ///
113                 INCREASE_SIZE,
114                 ///
115                 DECREASE_SIZE,
116                 ///
117                 INHERIT_SIZE,
118                 ///
119                 IGNORE_SIZE
120         };
121  
122         enum FONT_DIRECTION {
123                 ///
124                 LTR_DIR,
125                 ///
126                 RTL_DIR,
127                 ///
128                 TOGGLE_DIR,
129                 ///
130                 INHERIT_DIR,
131                 ///
132                 IGNORE_DIR
133         };
134
135         /// Used for emph, underbar, noun and latex toggles
136         enum FONT_MISC_STATE {
137                 ///
138                 OFF,
139                 ///
140                 ON,
141                 ///
142                 TOGGLE,
143                 ///
144                 INHERIT,
145                 ///
146                 IGNORE
147         };
148  
149         ///
150         enum FONT_COLOR {
151                 ///
152                 NONE,
153                 ///
154                 BLACK,
155                 ///
156                 WHITE,
157                 ///
158                 RED,
159                 ///
160                 GREEN,
161                 ///
162                 BLUE,
163                 ///
164                 CYAN,
165                 ///
166                 MAGENTA,
167                 ///
168                 YELLOW,
169                 ///
170                 MATH,
171                 ///
172                 INSET,
173                 ///
174                 INHERIT_COLOR,
175                 ///
176                 IGNORE_COLOR
177         };
178
179         /// Trick to overload constructor and make it megafast
180         enum FONT_INIT1 {
181                 ///
182                 ALL_INHERIT
183         };
184         ///
185         enum FONT_INIT2 {
186                 ///
187                 ALL_IGNORE
188         };
189         ///
190         enum FONT_INIT3 {
191                 ///
192                 ALL_SANE
193         };
194
195         ///
196         LyXFont();
197
198         /// LyXFont x(LyXFont ...) and LyXFont x = LyXFont ...
199         LyXFont(LyXFont const & x);
200  
201         /// Shortcut initialization
202         LyXFont(LyXFont::FONT_INIT1);
203         /// Shortcut initialization
204         LyXFont(LyXFont::FONT_INIT2);
205         /// Shortcut initialization
206         LyXFont(LyXFont::FONT_INIT3);
207
208         /// LyXFont x, y; x = y;
209         LyXFont& operator=(LyXFont const & x);
210  
211         /// Decreases font size by one
212         LyXFont & decSize();
213  
214         /// Increases font size by one
215         LyXFont & incSize();
216  
217         ///
218         FONT_FAMILY family() const;
219  
220         ///
221         FONT_SERIES series() const;
222  
223         ///
224         FONT_SHAPE shape() const;
225  
226         ///
227         FONT_SIZE size() const;
228  
229         ///
230         FONT_MISC_STATE emph() const;
231  
232         ///
233         FONT_MISC_STATE underbar() const;
234  
235         ///
236         FONT_MISC_STATE noun() const;
237
238         ///
239         FONT_MISC_STATE latex() const;
240  
241         ///
242         FONT_COLOR color() const;
243
244         ///
245         FONT_DIRECTION direction() const;
246
247         ///
248         LyXDirection getFontDirection() const;
249         
250         ///
251         LyXFont & setFamily(LyXFont::FONT_FAMILY f);
252         ///
253         LyXFont & setSeries(LyXFont::FONT_SERIES s);
254         ///
255         LyXFont & setShape(LyXFont::FONT_SHAPE s);
256         ///
257         LyXFont & setSize(LyXFont::FONT_SIZE s);
258         ///
259         LyXFont & setEmph(LyXFont::FONT_MISC_STATE e);
260         ///
261         LyXFont & setUnderbar(LyXFont::FONT_MISC_STATE u);
262         ///
263         LyXFont & setNoun(LyXFont::FONT_MISC_STATE n);
264         ///
265         LyXFont & setLatex(LyXFont::FONT_MISC_STATE l);
266         ///
267         LyXFont & setColor(LyXFont::FONT_COLOR c);
268         ///
269         LyXFont & setDirection(LyXFont::FONT_DIRECTION d);
270
271         /// Set family after LyX text format
272         LyXFont & setLyXFamily(string const &);
273  
274         /// Set series after LyX text format
275         LyXFont & setLyXSeries(string const &);
276  
277         /// Set shape after LyX text format
278         LyXFont & setLyXShape(string const &);
279  
280         /// Set size after LyX text format
281         LyXFont & setLyXSize(string const &);
282  
283         /// Returns misc flag after LyX text format
284         LyXFont::FONT_MISC_STATE setLyXMisc(string const &);
285
286         /// Sets color after LyX text format
287         LyXFont & setLyXColor(string const &);
288  
289         /// Sets size after GUI name
290         LyXFont & setGUISize(string const &);
291  
292         /// Returns size of font in LaTeX text notation
293         string latexSize() const;
294  
295         /** Updates font settings according to request. If an
296             attribute is IGNORE, the attribute is left as it is. */
297         /* 
298          * When toggleall = true, all properties that matches the font in use
299          * will have the effect that the properties is reset to the
300          * default.  If we have a text that is TYPEWRITER_FAMILY, and is
301          * update()'ed with TYPEWRITER_FAMILY, the operation will be as if
302          * a INHERIT_FAMILY was asked for.  This is necessary for the
303          * toggle-user-defined-style button on the toolbar.
304          */
305         void update(LyXFont const & newfont, bool toggleall = false);
306  
307         /** Reduce font to fall back to template where possible.
308             Equal fields are reduced to INHERIT */
309         void reduce(LyXFont const & tmplt);
310  
311         /// Realize font from a template (INHERIT are realized)
312         LyXFont & realize(LyXFont const & tmplt);
313
314         /// Is a given font fully resolved?
315         bool resolved() const;
316  
317         /// Read a font specification from LyXLex. Used for layout files.
318         LyXFont & lyxRead(LyXLex&);
319  
320         /// Writes the changes from this font to orgfont in .lyx format in file
321         void lyxWriteChanges(LyXFont const & orgfont, ostream &) const;
322
323         /** Writes the head of the LaTeX needed to change to this font.
324             Writes to string, the head of the LaTeX needed to change
325             to this font. Returns number of chars written. Base is the
326             font state active now.
327         */
328         int latexWriteStartChanges(string &, LyXFont const & base,
329                                    LyXFont const & prev) const;
330
331         /** Writes tha tail of the LaTeX needed to chagne to this font.
332             Returns number of chars written. Base is the font state we want
333             to achieve.
334         */
335         int latexWriteEndChanges(string &, LyXFont const & base,
336                                  LyXFont const & next) const;
337  
338         /// Build GUI description of font state
339         string stateText() const;
340
341         ///
342         int maxAscent() const; 
343
344         ///
345         int maxDescent() const;
346
347         ///
348         int ascent(char c) const;
349
350         ///
351         int descent(char c) const;
352
353         ///
354         int width(char c) const;
355
356         ///
357         int lbearing(char c) const;
358
359         ///
360         int rbearing(char c) const;
361         
362         ///
363         int textWidth(char const *s, int n) const;
364
365         ///
366         int stringWidth(string const & s) const;
367
368         ///
369         int signedStringWidth(string const & s) const;
370
371         /// Draws text and returns width of text
372         int drawText(char const*, int n, Pixmap, int baseline, int x) const;
373
374         ///
375         int drawString(string const &, Pixmap pm, int baseline, int x) const;
376
377         ///
378         GC getGC() const;
379
380         ///
381         friend inline
382         bool operator==(LyXFont const & font1, LyXFont const & font2) {
383                 return font1.bits == font2.bits;
384         }
385
386         ///
387         friend inline
388         bool operator!=(LyXFont const & font1, LyXFont const & font2) {
389                 return font1.bits != font2.bits;
390         }
391
392         /// compares two fonts, ignoring the setting of the Latex part.
393         bool equalExceptLatex(LyXFont const &) const;
394
395 private:
396         /// This have to be at least 32 bits, but 64 or more does not hurt
397         typedef unsigned int ui32;
398
399         /** Representation: bit table
400             Layout of bit table:
401             11 1111 111 122 222 222 2233
402             Bit 012 34 567 8901 2345 678 901 234 567 8901
403             FFF SS SSS SSSS CCCC EEE UUU NNN LLL
404             aaa ee hhh iiii oooo mmm nnn ooo aaa
405             mmm rr aaa zzzz llll ppp ddd uuu ttt
406
407             Some might think this is a dirty representation, but it gives
408             us at least 25% speed-up, so why not?
409         */
410         ui32 bits;
411
412         ///
413         enum FONT_POSITION {
414                 ///
415                 Fam_Pos =  0,
416                 ///
417                 Ser_Pos =  3,
418                 ///
419                 Sha_Pos =  5,
420                 ///
421                 Siz_Pos =  8,
422                 ///
423                 Col_Pos = 12,
424                 ///
425                 Emp_Pos = 16,
426                 ///
427                 Und_Pos = 19,
428                 ///
429                 Nou_Pos = 22,
430                 ///
431                 Lat_Pos = 25,
432                 ///
433                 Dir_Pos = 28
434         };
435
436         ///
437         enum FONT_MASK {
438                 ///
439                 Fam_Mask = 0x07,
440                 ///
441                 Ser_Mask = 0x03,
442                 ///
443                 Sha_Mask = 0x07,
444                 ///
445                 Siz_Mask = 0x0f,
446                 ///
447                 Col_Mask = 0x0f,
448                 ///
449                 Dir_Mask = 0x07,
450                 ///
451                 Misc_Mask = 0x07
452         };
453  
454         /// Sane font
455         enum {  sane = ui32(ROMAN_FAMILY) << Fam_Pos
456                 | ui32(MEDIUM_SERIES) << Ser_Pos
457                 | ui32(UP_SHAPE) << Sha_Pos
458                 | ui32(SIZE_NORMAL) << Siz_Pos
459                 | ui32(NONE) << Col_Pos
460                 | ui32(OFF) << Emp_Pos
461                 | ui32(OFF) << Und_Pos
462                 | ui32(OFF) << Nou_Pos
463                 | ui32(OFF) << Lat_Pos
464                 | ui32(LTR_DIR) << Dir_Pos};
465  
466         /// All inherit font
467         enum{ inherit = ui32(INHERIT_FAMILY) << Fam_Pos
468                       | ui32(INHERIT_SERIES) << Ser_Pos
469                       | ui32(INHERIT_SHAPE) << Sha_Pos
470                       | ui32(INHERIT_SIZE) << Siz_Pos
471                       | ui32(INHERIT_COLOR) << Col_Pos
472                       | ui32(INHERIT) << Emp_Pos
473                       | ui32(INHERIT) << Und_Pos
474                       | ui32(INHERIT) << Nou_Pos
475                       | ui32(INHERIT) << Lat_Pos
476                       | ui32(INHERIT_DIR) << Dir_Pos};
477  
478         /// All ignore font
479         enum{ ignore = ui32(IGNORE_FAMILY) << Fam_Pos
480                       | ui32(IGNORE_SERIES) << Ser_Pos
481                       | ui32(IGNORE_SHAPE) << Sha_Pos
482                       | ui32(IGNORE_SIZE) << Siz_Pos
483                       | ui32(IGNORE_COLOR) << Col_Pos
484                       | ui32(IGNORE) << Emp_Pos
485                       | ui32(IGNORE) << Und_Pos
486                       | ui32(IGNORE) << Nou_Pos
487                       | ui32(IGNORE) << Lat_Pos
488                       | ui32(IGNORE_DIR) << Dir_Pos};
489  
490         /// Updates a misc setting according to request
491         LyXFont::FONT_MISC_STATE setMisc(LyXFont::FONT_MISC_STATE newfont,
492                                          LyXFont::FONT_MISC_STATE org);
493
494         /// Converts logical attributes to concrete shape attribute
495         LyXFont::FONT_SHAPE realShape() const;
496
497         ///
498         XFontStruct* getXFontstruct() const;
499 };
500
501 ostream & operator<<(ostream &, LyXFont::FONT_MISC_STATE);
502
503 inline LyXFont::LyXFont()
504 {
505         bits = sane;
506 }
507
508
509 inline LyXFont::LyXFont(LyXFont const & x)
510 {
511         bits = x.bits;
512 }
513
514
515 inline LyXFont::LyXFont(LyXFont::FONT_INIT1)
516 {
517         bits = inherit;
518 }
519
520
521 inline LyXFont::LyXFont(LyXFont::FONT_INIT2)
522 {
523         bits = ignore;
524 }
525
526
527 inline LyXFont::LyXFont(LyXFont::FONT_INIT3)
528 {
529         bits = sane;
530 }
531
532
533 inline LyXFont & LyXFont::operator=(LyXFont const & x) 
534 {
535         bits = x.bits;
536         return *this;
537 }
538
539
540 // You don't have to understand the stuff below :-)
541 // It works, and it's bloody fast. (Asger)
542 inline LyXFont::FONT_FAMILY LyXFont::family() const 
543 {
544         return LyXFont::FONT_FAMILY((bits >> Fam_Pos) & Fam_Mask);
545 }
546
547
548 inline LyXFont::FONT_SERIES LyXFont::series() const
549 {
550         return LyXFont::FONT_SERIES((bits >> Ser_Pos) & Ser_Mask);
551 }
552
553
554 inline LyXFont::FONT_SHAPE LyXFont::shape() const
555 {
556         return LyXFont::FONT_SHAPE((bits >> Sha_Pos) & Sha_Mask);
557 }
558
559
560 inline LyXFont::FONT_SIZE LyXFont::size() const
561 {
562         return LyXFont::FONT_SIZE((bits >> Siz_Pos) & Siz_Mask);
563 }
564
565
566 inline LyXFont::FONT_MISC_STATE LyXFont::emph() const
567 {
568         return LyXFont::FONT_MISC_STATE((bits >> Emp_Pos) & Misc_Mask);
569 }
570
571
572 inline LyXFont::FONT_MISC_STATE LyXFont::underbar() const
573 {
574         return LyXFont::FONT_MISC_STATE((bits >> Und_Pos) & Misc_Mask);
575 }
576
577
578 inline LyXFont::FONT_MISC_STATE LyXFont::noun() const
579 {
580         return LyXFont::FONT_MISC_STATE((bits >> Nou_Pos) & Misc_Mask);
581 }
582
583
584 inline LyXFont::FONT_MISC_STATE LyXFont::latex() const 
585 {
586         return LyXFont::FONT_MISC_STATE((bits >> Lat_Pos) & Misc_Mask);
587 }
588
589
590 inline LyXFont::FONT_COLOR LyXFont::color() const 
591 {
592         return LyXFont::FONT_COLOR((bits >> Col_Pos) & Col_Mask);
593 }
594
595 inline LyXFont::FONT_DIRECTION LyXFont::direction() const 
596 {
597         return LyXFont::FONT_DIRECTION((bits >> Dir_Pos) & Dir_Mask);
598 }
599
600 inline LyXFont & LyXFont::setFamily(LyXFont::FONT_FAMILY f)
601 {
602         bits &= ~(Fam_Mask << Fam_Pos);
603         bits |= ui32(f) << Fam_Pos;
604         return *this;
605 }
606
607
608 inline LyXFont & LyXFont::setSeries(LyXFont::FONT_SERIES s)
609 {
610         bits &= ~(Ser_Mask << Ser_Pos);
611         bits |= ui32(s) << Ser_Pos;
612         return *this;
613 }
614
615
616 inline LyXFont & LyXFont::setShape(LyXFont::FONT_SHAPE s)
617 {
618         bits &= ~(Sha_Mask << Sha_Pos);
619         bits |= ui32(s) << Sha_Pos;
620         return *this;
621 }
622
623
624 inline LyXFont & LyXFont::setSize(LyXFont::FONT_SIZE s)
625 {
626         bits &= ~(Siz_Mask << Siz_Pos);
627         bits |= ui32(s) << Siz_Pos;
628         return *this;
629 }
630
631
632 inline LyXFont & LyXFont::setEmph(LyXFont::FONT_MISC_STATE e)
633 {
634         bits &= ~(Misc_Mask << Emp_Pos);
635         bits |= ui32(e) << Emp_Pos;
636         return *this;
637 }
638
639
640 inline LyXFont & LyXFont::setUnderbar(LyXFont::FONT_MISC_STATE u)
641 {
642         bits &= ~(Misc_Mask << Und_Pos);
643         bits |= ui32(u) << Und_Pos;
644         return *this;
645 }
646
647
648 inline LyXFont & LyXFont::setNoun(LyXFont::FONT_MISC_STATE n)
649 {
650         bits &= ~(Misc_Mask << Nou_Pos);
651         bits |= ui32(n) << Nou_Pos;
652         return *this;
653 }
654
655 inline LyXFont & LyXFont::setLatex(LyXFont::FONT_MISC_STATE l)
656 {
657         bits &= ~(Misc_Mask << Lat_Pos);
658         bits |= ui32(l) << Lat_Pos;
659         return *this;
660 }
661
662
663 inline LyXFont & LyXFont::setColor(LyXFont::FONT_COLOR c)
664 {
665         bits &= ~(Col_Mask << Col_Pos);
666         bits |= ui32(c) << Col_Pos;
667         return *this;
668 }
669
670 inline LyXFont & LyXFont::setDirection(LyXFont::FONT_DIRECTION d)
671 {
672         bits &= ~(Dir_Mask << Dir_Pos);
673         bits |= ui32(d) << Dir_Pos;
674         return *this;
675 }
676
677 #endif