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