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