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