]> git.lyx.org Git - lyx.git/blob - src/FontInfo.cpp
2623f2ea232f1eb9a0fda85a84b93a1ae2ac1a61
[lyx.git] / src / FontInfo.cpp
1 /**
2  * \file src/FontInfo.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 Jean-Marc Lasgouttes
8  * \author Angus Leeming
9  * \author André Pönitz
10  * \author Dekel Tsur
11  *
12  * Full author contact details are available in file CREDITS.
13  */
14
15 #include <config.h>
16
17 #include "FontInfo.h"
18
19 #include "support/debug.h"
20
21 #include <ostream>
22
23 using namespace std;
24
25 namespace lyx {
26
27 FontInfo const sane_font(
28         ROMAN_FAMILY,
29         MEDIUM_SERIES,
30         UP_SHAPE,
31         FONT_SIZE_NORMAL,
32         Color_none,
33         Color_background,
34         FONT_OFF,
35         FONT_OFF,
36         FONT_OFF,
37         FONT_OFF);
38
39 FontInfo const inherit_font(
40         INHERIT_FAMILY,
41         INHERIT_SERIES,
42         INHERIT_SHAPE,
43         FONT_SIZE_INHERIT,
44         Color_inherit,
45         Color_inherit,
46         FONT_INHERIT,
47         FONT_INHERIT,
48         FONT_INHERIT,
49         FONT_OFF);
50
51 FontInfo const ignore_font(
52         IGNORE_FAMILY,
53         IGNORE_SERIES,
54         IGNORE_SHAPE,
55         FONT_SIZE_IGNORE,
56         Color_ignore,
57         Color_ignore,
58         FONT_IGNORE,
59         FONT_IGNORE,
60         FONT_IGNORE,
61         FONT_IGNORE);
62
63
64 FontInfo::FontInfo()
65 {
66         *this = sane_font;
67 }
68
69 /// Decreases font size_ by one
70 FontInfo & FontInfo::decSize()
71 {
72         switch (size_) {
73         case FONT_SIZE_HUGER:        size_ = FONT_SIZE_HUGE;     break;
74         case FONT_SIZE_HUGE:         size_ = FONT_SIZE_LARGEST;  break;
75         case FONT_SIZE_LARGEST:      size_ = FONT_SIZE_LARGER;   break;
76         case FONT_SIZE_LARGER:       size_ = FONT_SIZE_LARGE;    break;
77         case FONT_SIZE_LARGE:        size_ = FONT_SIZE_NORMAL;   break;
78         case FONT_SIZE_NORMAL:       size_ = FONT_SIZE_SMALL;    break;
79         case FONT_SIZE_SMALL:        size_ = FONT_SIZE_FOOTNOTE; break;
80         case FONT_SIZE_FOOTNOTE:     size_ = FONT_SIZE_SCRIPT;   break;
81         case FONT_SIZE_SCRIPT:       size_ = FONT_SIZE_TINY;     break;
82         case FONT_SIZE_TINY:         break;
83         case FONT_SIZE_INCREASE:
84                 lyxerr << "Can't FontInfo::decSize on FONT_SIZE_INCREASE" << endl;
85                 break;
86         case FONT_SIZE_DECREASE:
87                 lyxerr <<"Can't FontInfo::decSize on FONT_SIZE_DECREASE" << endl;
88                 break;
89         case FONT_SIZE_INHERIT:
90                 lyxerr <<"Can't FontInfo::decSize on FONT_SIZE_INHERIT" << endl;
91                 break;
92         case FONT_SIZE_IGNORE:
93                 lyxerr <<"Can't FontInfo::decSize on FONT_SIZE_IGNORE" << endl;
94                 break;
95         }
96         return *this;
97 }
98
99
100 /// Increases font size_ by one
101 FontInfo & FontInfo::incSize()
102 {
103         switch (size_) {
104         case FONT_SIZE_HUGER:   break;
105         case FONT_SIZE_HUGE:         size_ = FONT_SIZE_HUGER;    break;
106         case FONT_SIZE_LARGEST:      size_ = FONT_SIZE_HUGE;     break;
107         case FONT_SIZE_LARGER:       size_ = FONT_SIZE_LARGEST;  break;
108         case FONT_SIZE_LARGE:        size_ = FONT_SIZE_LARGER;   break;
109         case FONT_SIZE_NORMAL:       size_ = FONT_SIZE_LARGE;    break;
110         case FONT_SIZE_SMALL:        size_ = FONT_SIZE_NORMAL;   break;
111         case FONT_SIZE_FOOTNOTE:     size_ = FONT_SIZE_SMALL;    break;
112         case FONT_SIZE_SCRIPT:       size_ = FONT_SIZE_FOOTNOTE; break;
113         case FONT_SIZE_TINY:         size_ = FONT_SIZE_SCRIPT;   break;
114         case FONT_SIZE_INCREASE:
115                 lyxerr <<"Can't FontInfo::incSize on FONT_SIZE_INCREASE" << endl;
116                 break;
117         case FONT_SIZE_DECREASE:
118                 lyxerr <<"Can't FontInfo::incSize on FONT_SIZE_DECREASE" << endl;
119                 break;
120         case FONT_SIZE_INHERIT:
121                 lyxerr <<"Can't FontInfo::incSize on FONT_SIZE_INHERIT" << endl;
122                 break;
123         case FONT_SIZE_IGNORE:
124                 lyxerr <<"Can't FontInfo::incSize on FONT_SIZE_IGNORE" << endl;
125                 break;
126         }
127         return *this;
128 }
129
130
131 /// Reduce font to fall back to template where possible
132 void FontInfo::reduce(FontInfo const & tmplt)
133 {
134         if (family_ == tmplt.family_)
135                 family_ = INHERIT_FAMILY;
136         if (series_ == tmplt.series_)
137                 series_ = INHERIT_SERIES;
138         if (shape_ == tmplt.shape_)
139                 shape_ = INHERIT_SHAPE;
140         if (size_ == tmplt.size_)
141                 size_ = FONT_SIZE_INHERIT;
142         if (emph_ == tmplt.emph_)
143                 emph_ = FONT_INHERIT;
144         if (underbar_ == tmplt.underbar_)
145                 underbar_ = FONT_INHERIT;
146         if (noun_ == tmplt.noun_)
147                 noun_ = FONT_INHERIT;
148         if (color_ == tmplt.color_)
149                 color_ = Color_inherit;
150         if (background_ == tmplt.background_)
151                 background_ = Color_inherit;
152 }
153
154
155 /// Realize font from a template
156 FontInfo & FontInfo::realize(FontInfo const & tmplt)
157 {
158         if ((*this) == inherit_font) {
159                 operator=(tmplt);
160                 return *this;
161         }
162
163         if (family_ == INHERIT_FAMILY)
164                 family_ = tmplt.family_;
165
166         if (series_ == INHERIT_SERIES)
167                 series_ = tmplt.series_;
168
169         if (shape_ == INHERIT_SHAPE)
170                 shape_ = tmplt.shape_;
171
172         if (size_ == FONT_SIZE_INHERIT)
173                 size_ = tmplt.size_;
174
175         if (emph_ == FONT_INHERIT)
176                 emph_ = tmplt.emph_;
177
178         if (underbar_ == FONT_INHERIT)
179                 underbar_ = tmplt.underbar_;
180
181         if (noun_ == FONT_INHERIT)
182                 noun_ = tmplt.noun_;
183
184         if (color_ == Color_inherit)
185                 color_ = tmplt.color_;
186
187         if (background_ == Color_inherit)
188                 background_ = tmplt.background_;
189
190         return *this;
191 }
192
193
194 /// Updates a misc setting according to request
195 static FontState setMisc(FontState newfont,
196         FontState org)
197 {
198         if (newfont == FONT_TOGGLE) {
199                 if (org == FONT_ON)
200                         return FONT_OFF;
201                 else if (org == FONT_OFF)
202                         return FONT_ON;
203                 else {
204                         LYXERR0("Font::setMisc: Need state"
205                                 " FONT_ON or FONT_OFF to toggle. Setting to FONT_ON");
206                         return FONT_ON;
207                 }
208         } else if (newfont == FONT_IGNORE)
209                 return org;
210         else
211                 return newfont;
212 }
213
214 /// Updates font settings according to request
215 void FontInfo::update(FontInfo const & newfont, bool toggleall)
216 {
217         if (newfont.family_ == family_ && toggleall)
218                 setFamily(INHERIT_FAMILY); // toggle 'back'
219         else if (newfont.family_ != IGNORE_FAMILY)
220                 setFamily(newfont.family_);
221         // else it's IGNORE_SHAPE
222
223         // "Old" behaviour: "Setting" bold will toggle bold on/off.
224         switch (newfont.series_) {
225         case BOLD_SERIES:
226                 // We toggle...
227                 if (series_ == BOLD_SERIES && toggleall)
228                         setSeries(MEDIUM_SERIES);
229                 else
230                         setSeries(BOLD_SERIES);
231                 break;
232         case MEDIUM_SERIES:
233         case INHERIT_SERIES:
234                 setSeries(newfont.series_);
235                 break;
236         case IGNORE_SERIES:
237                 break;
238         }
239
240         if (newfont.shape_ == shape_ && toggleall)
241                 shape_ = INHERIT_SHAPE; // toggle 'back'
242         else if (newfont.shape_ != IGNORE_SHAPE)
243                 shape_ = newfont.shape_;
244         // else it's IGNORE_SHAPE
245
246         if (newfont.size_ != FONT_SIZE_IGNORE) {
247                 if (newfont.size_ == FONT_SIZE_INCREASE)
248                         incSize();
249                 else if (newfont.size_ == FONT_SIZE_DECREASE)
250                         decSize();
251                 else
252                         size_ = newfont.size_;
253         }
254
255         setEmph(setMisc(newfont.emph_, emph_));
256         setUnderbar(setMisc(newfont.underbar_, underbar_));
257         setNoun(setMisc(newfont.noun_, noun_));
258         setNumber(setMisc(newfont.number_, number_));
259
260         if (newfont.color_ == color_ && toggleall)
261                 setColor(Color_inherit); // toggle 'back'
262         else if (newfont.color_ != Color_ignore)
263                 setColor(newfont.color_);
264
265         if (newfont.background_ == background_ && toggleall)
266                 setBackground(Color_inherit); // toggle 'back'
267         else if (newfont.background_ != Color_ignore)
268                 setBackground(newfont.background_);
269 }
270
271 /// Is font resolved?
272 bool FontInfo::resolved() const
273 {
274         return (family_ != INHERIT_FAMILY && series_ != INHERIT_SERIES
275                 && shape_ != INHERIT_SHAPE && size_ != FONT_SIZE_INHERIT
276                 && emph_ != FONT_INHERIT && underbar_ != FONT_INHERIT
277                 && noun_ != FONT_INHERIT
278                 && color_ != Color_inherit
279                 && background_ != Color_inherit);
280 }
281
282
283 ColorCode FontInfo::realColor() const
284 {
285         if (color_ == Color_none)
286                 return Color_foreground;
287         return color_;
288 }
289
290 } // namespace lyx