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