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