]> git.lyx.org Git - lyx.git/blob - src/FontInfo.cpp
Update it.po
[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 "ColorSet.h"
18 #include "FontInfo.h"
19 #include "Lexer.h"
20 #include "LyXRC.h"
21
22 #include "support/convert.h"
23 #include "support/debug.h"
24 #include "support/docstring.h"
25 #include "support/lstrings.h"
26 #include "support/RefChanger.h"
27
28 #include <algorithm>
29 #include <ostream>
30 #include <sstream>
31
32 using namespace std;
33 using namespace lyx::support;
34
35 namespace lyx {
36
37 //
38 // Strings used to read and write .lyx format files
39 //
40 char const * LyXFamilyNames[NUM_FAMILIES + 2 /* default & error */] =
41 { "roman", "sans", "typewriter", "symbol",
42   "cmr", "cmsy", "cmm", "cmex", "msa", "msb", "eufrak", "rsfs", "stmry",
43   "wasy", "esint", "default", "error" };
44
45 char const * LyXSeriesNames[NUM_SERIES + 2 /* default & error */] =
46 { "medium", "bold", "default", "error" };
47
48 char const * LyXShapeNames[NUM_SHAPE + 2 /* default & error */] =
49 { "up", "italic", "slanted", "smallcaps", "default", "error" };
50
51 char const * LyXSizeNames[NUM_SIZE + 4 /* increase, decrease, default & error */] =
52 { "tiny", "scriptsize", "footnotesize", "small", "normal", "large",
53   "larger", "largest", "huge", "giant",
54   "increase", "decrease", "default", "error" };
55
56 char const * LyXMiscNames[5] =
57 { "off", "on", "toggle", "default", "error" };
58
59
60 FontInfo const sane_font(
61         ROMAN_FAMILY,
62         MEDIUM_SERIES,
63         UP_SHAPE,
64         FONT_SIZE_NORMAL,
65         Color_none,
66         Color_background,
67         FONT_OFF,
68         FONT_OFF,
69         FONT_OFF,
70         FONT_OFF,
71         FONT_OFF,
72         FONT_OFF,
73         FONT_OFF,
74         FONT_OFF);
75
76 FontInfo const inherit_font(
77         INHERIT_FAMILY,
78         INHERIT_SERIES,
79         INHERIT_SHAPE,
80         FONT_SIZE_INHERIT,
81         Color_inherit,
82         Color_inherit,
83         FONT_INHERIT,
84         FONT_INHERIT,
85         FONT_INHERIT,
86         FONT_INHERIT,
87         FONT_INHERIT,
88         FONT_INHERIT,
89         FONT_INHERIT,
90         FONT_OFF);
91
92 FontInfo const ignore_font(
93         IGNORE_FAMILY,
94         IGNORE_SERIES,
95         IGNORE_SHAPE,
96         FONT_SIZE_IGNORE,
97         Color_ignore,
98         Color_ignore,
99         FONT_IGNORE,
100         FONT_IGNORE,
101         FONT_IGNORE,
102         FONT_IGNORE,
103         FONT_IGNORE,
104         FONT_IGNORE,
105         FONT_IGNORE,
106         FONT_IGNORE);
107
108
109 FontInfo::FontInfo()
110 {
111         *this = sane_font;
112 }
113
114
115 /// Decreases font size_ by one
116 FontInfo & FontInfo::decSize()
117 {
118         switch (size_) {
119         case FONT_SIZE_HUGER:        size_ = FONT_SIZE_HUGE;     break;
120         case FONT_SIZE_HUGE:         size_ = FONT_SIZE_LARGEST;  break;
121         case FONT_SIZE_LARGEST:      size_ = FONT_SIZE_LARGER;   break;
122         case FONT_SIZE_LARGER:       size_ = FONT_SIZE_LARGE;    break;
123         case FONT_SIZE_LARGE:        size_ = FONT_SIZE_NORMAL;   break;
124         case FONT_SIZE_NORMAL:       size_ = FONT_SIZE_SMALL;    break;
125         case FONT_SIZE_SMALL:        size_ = FONT_SIZE_FOOTNOTE; break;
126         case FONT_SIZE_FOOTNOTE:     size_ = FONT_SIZE_SCRIPT;   break;
127         case FONT_SIZE_SCRIPT:       size_ = FONT_SIZE_TINY;     break;
128         case FONT_SIZE_TINY:         break;
129         case FONT_SIZE_INCREASE:
130                 LYXERR0("Can't FontInfo::decSize on FONT_SIZE_INCREASE");
131                 break;
132         case FONT_SIZE_DECREASE:
133                 LYXERR0("Can't FontInfo::decSize on FONT_SIZE_DECREASE");
134                 break;
135         case FONT_SIZE_INHERIT:
136                 LYXERR0("Can't FontInfo::decSize on FONT_SIZE_INHERIT");
137                 break;
138         case FONT_SIZE_IGNORE:
139                 LYXERR0("Can't FontInfo::decSize on FONT_SIZE_IGNORE");
140                 break;
141         }
142         return *this;
143 }
144
145
146 /// Increases font size_ by one
147 FontInfo & FontInfo::incSize()
148 {
149         switch (size_) {
150         case FONT_SIZE_HUGER:   break;
151         case FONT_SIZE_HUGE:         size_ = FONT_SIZE_HUGER;    break;
152         case FONT_SIZE_LARGEST:      size_ = FONT_SIZE_HUGE;     break;
153         case FONT_SIZE_LARGER:       size_ = FONT_SIZE_LARGEST;  break;
154         case FONT_SIZE_LARGE:        size_ = FONT_SIZE_LARGER;   break;
155         case FONT_SIZE_NORMAL:       size_ = FONT_SIZE_LARGE;    break;
156         case FONT_SIZE_SMALL:        size_ = FONT_SIZE_NORMAL;   break;
157         case FONT_SIZE_FOOTNOTE:     size_ = FONT_SIZE_SMALL;    break;
158         case FONT_SIZE_SCRIPT:       size_ = FONT_SIZE_FOOTNOTE; break;
159         case FONT_SIZE_TINY:         size_ = FONT_SIZE_SCRIPT;   break;
160         case FONT_SIZE_INCREASE:
161                 LYXERR0("Can't FontInfo::incSize on FONT_SIZE_INCREASE");
162                 break;
163         case FONT_SIZE_DECREASE:
164                 LYXERR0("Can't FontInfo::incSize on FONT_SIZE_DECREASE");
165                 break;
166         case FONT_SIZE_INHERIT:
167                 LYXERR0("Can't FontInfo::incSize on FONT_SIZE_INHERIT");
168                 break;
169         case FONT_SIZE_IGNORE:
170                 LYXERR0("Can't FontInfo::incSize on FONT_SIZE_IGNORE");
171                 break;
172         }
173         return *this;
174 }
175
176
177 double FontInfo::realSize() const
178 {
179         double d = convert<double>(lyxrc.font_sizes[size()]);
180         // The following is according to the average of the values in the
181         // definitions of \defaultscriptratio and \defaultscriptscriptratio in LaTeX
182         // font packages. No attempt is made to implement the actual values from
183         // \DefineMathSizes.
184         switch (style()) {
185         case LM_ST_DISPLAY:
186         case LM_ST_TEXT:
187                 break;
188         case LM_ST_SCRIPT:
189                 d *= .73;
190                 break;
191         case LM_ST_SCRIPTSCRIPT:
192                 d *= .55;
193                 break;
194         }
195         // Never go below the smallest size
196         return max(d, convert<double>(lyxrc.font_sizes[FONT_SIZE_TINY]));
197 }
198
199
200 /// Reduce font to fall back to template where possible
201 void FontInfo::reduce(FontInfo const & tmplt)
202 {
203         if (family_ == tmplt.family_)
204                 family_ = INHERIT_FAMILY;
205         if (series_ == tmplt.series_)
206                 series_ = INHERIT_SERIES;
207         if (shape_ == tmplt.shape_)
208                 shape_ = INHERIT_SHAPE;
209         if (size_ == tmplt.size_)
210                 size_ = FONT_SIZE_INHERIT;
211         if (emph_ == tmplt.emph_)
212                 emph_ = FONT_INHERIT;
213         if (underbar_ == tmplt.underbar_)
214                 underbar_ = FONT_INHERIT;
215         if (strikeout_ == tmplt.strikeout_)
216                 strikeout_ = FONT_INHERIT;
217         if (xout_ == tmplt.xout_)
218                 xout_ = FONT_INHERIT;
219         if (uuline_ == tmplt.uuline_)
220                 uuline_ = FONT_INHERIT;
221         if (uwave_ == tmplt.uwave_)
222                 uwave_ = FONT_INHERIT;
223         if (noun_ == tmplt.noun_)
224                 noun_ = FONT_INHERIT;
225         if (color_ == tmplt.color_)
226                 color_ = Color_inherit;
227         if (background_ == tmplt.background_)
228                 background_ = Color_inherit;
229 }
230
231
232 /// Realize font from a template
233 FontInfo & FontInfo::realize(FontInfo const & tmplt)
234 {
235         if ((*this) == inherit_font) {
236                 operator=(tmplt);
237                 return *this;
238         }
239
240         if (family_ == INHERIT_FAMILY)
241                 family_ = tmplt.family_;
242
243         if (series_ == INHERIT_SERIES)
244                 series_ = tmplt.series_;
245
246         if (shape_ == INHERIT_SHAPE)
247                 shape_ = tmplt.shape_;
248
249         if (size_ == FONT_SIZE_INHERIT)
250                 size_ = tmplt.size_;
251
252         if (emph_ == FONT_INHERIT)
253                 emph_ = tmplt.emph_;
254
255         if (underbar_ == FONT_INHERIT)
256                 underbar_ = tmplt.underbar_;
257
258         if (strikeout_ == FONT_INHERIT)
259                 strikeout_ = tmplt.strikeout_;
260
261         if (xout_ == FONT_INHERIT)
262                 xout_ = tmplt.xout_;
263
264         if (uuline_ == FONT_INHERIT)
265                 uuline_ = tmplt.uuline_;
266
267         if (uwave_ == FONT_INHERIT)
268                 uwave_ = tmplt.uwave_;
269
270         if (noun_ == FONT_INHERIT)
271                 noun_ = tmplt.noun_;
272
273         if (color_ == Color_inherit)
274                 color_ = tmplt.color_;
275
276         if (background_ == Color_inherit)
277                 background_ = tmplt.background_;
278
279         return *this;
280 }
281
282
283 Changer FontInfo::changeColor(ColorCode const color)
284 {
285         return make_change(color_, color);
286 }
287
288
289 Changer FontInfo::changeShape(FontShape const shape)
290 {
291         return make_change(shape_, shape);
292 }
293
294
295 Changer FontInfo::changeStyle(MathStyle const new_style)
296 {
297         return make_change(style_, new_style);
298 }
299
300
301 Changer FontInfo::change(FontInfo font, bool realiz)
302 {
303         if (realiz)
304                 font.realize(*this);
305         return make_change(*this, font);
306 }
307
308
309 /// Updates a misc setting according to request
310 static FontState setMisc(FontState newfont,
311         FontState org)
312 {
313         if (newfont == FONT_TOGGLE) {
314                 if (org == FONT_ON)
315                         return FONT_OFF;
316                 else if (org == FONT_OFF)
317                         return FONT_ON;
318                 else {
319                         LYXERR0("Font::setMisc: Need state"
320                                 " FONT_ON or FONT_OFF to toggle. Setting to FONT_ON");
321                         return FONT_ON;
322                 }
323         } else if (newfont == FONT_IGNORE)
324                 return org;
325         else
326                 return newfont;
327 }
328
329 /// Updates font settings according to request
330 void FontInfo::update(FontInfo const & newfont, bool toggleall)
331 {
332         if (newfont.family_ == family_ && toggleall)
333                 setFamily(INHERIT_FAMILY); // toggle 'back'
334         else if (newfont.family_ != IGNORE_FAMILY)
335                 setFamily(newfont.family_);
336         // else it's IGNORE_SHAPE
337
338         // "Old" behaviour: "Setting" bold will toggle bold on/off.
339         switch (newfont.series_) {
340         case BOLD_SERIES:
341                 // We toggle...
342                 if (series_ == BOLD_SERIES && toggleall)
343                         setSeries(MEDIUM_SERIES);
344                 else
345                         setSeries(BOLD_SERIES);
346                 break;
347         case MEDIUM_SERIES:
348         case INHERIT_SERIES:
349                 setSeries(newfont.series_);
350                 break;
351         case IGNORE_SERIES:
352                 break;
353         }
354
355         if (newfont.shape_ == shape_ && toggleall)
356                 shape_ = INHERIT_SHAPE; // toggle 'back'
357         else if (newfont.shape_ != IGNORE_SHAPE)
358                 shape_ = newfont.shape_;
359         // else it's IGNORE_SHAPE
360
361         if (newfont.size_ != FONT_SIZE_IGNORE) {
362                 if (newfont.size_ == FONT_SIZE_INCREASE)
363                         incSize();
364                 else if (newfont.size_ == FONT_SIZE_DECREASE)
365                         decSize();
366                 else
367                         size_ = newfont.size_;
368         }
369
370         setEmph(setMisc(newfont.emph_, emph_));
371         setUnderbar(setMisc(newfont.underbar_, underbar_));
372         setStrikeout(setMisc(newfont.strikeout_, strikeout_));
373         setXout(setMisc(newfont.xout_, xout_));
374         setUuline(setMisc(newfont.uuline_, uuline_));
375         setUwave(setMisc(newfont.uwave_, uwave_));
376         setNoun(setMisc(newfont.noun_, noun_));
377         setNumber(setMisc(newfont.number_, number_));
378
379         if (newfont.color_ == color_ && toggleall)
380                 setColor(Color_inherit); // toggle 'back'
381         else if (newfont.color_ != Color_ignore)
382                 setColor(newfont.color_);
383
384         if (newfont.background_ == background_ && toggleall)
385                 setBackground(Color_inherit); // toggle 'back'
386         else if (newfont.background_ != Color_ignore)
387                 setBackground(newfont.background_);
388 }
389
390 /// Is font resolved?
391 bool FontInfo::resolved() const
392 {
393         return (family_ != INHERIT_FAMILY && series_ != INHERIT_SERIES
394                 && shape_ != INHERIT_SHAPE && size_ != FONT_SIZE_INHERIT
395                 && emph_ != FONT_INHERIT && underbar_ != FONT_INHERIT
396                 && uuline_ != FONT_INHERIT && uwave_ != FONT_INHERIT
397                 && strikeout_ != FONT_INHERIT && xout_ != FONT_INHERIT
398                 && noun_ != FONT_INHERIT && color_ != Color_inherit
399                 && background_ != Color_inherit);
400 }
401
402
403 Color FontInfo::realColor() const
404 {
405         if (paint_color_ != Color_none)
406                 return paint_color_;
407         if (color_ == Color_none)
408                 return Color_foreground;
409         return color_;
410 }
411
412
413 namespace {
414
415 void appendSep(string & s1, string const & s2)
416 {
417         if (s2.empty())
418                 return;
419         s1 += s1.empty() ? "" : "\n";
420         s1 += s2;
421 }
422
423
424 string makeCSSTag(string const & key, string const & val)
425 {
426         return key + ": " + val + ";";
427 }
428
429
430 string getFamilyCSS(FontFamily const & f)
431 {
432         switch (f) {
433         case ROMAN_FAMILY:
434                 return "serif";
435         case SANS_FAMILY:
436                 return "sans-serif";
437         case TYPEWRITER_FAMILY:
438                 return "monospace";
439         case SYMBOL_FAMILY:
440         case CMR_FAMILY:
441         case CMSY_FAMILY:
442         case CMM_FAMILY:
443         case CMEX_FAMILY:
444         case MSA_FAMILY:
445         case MSB_FAMILY:
446         case EUFRAK_FAMILY:
447         case RSFS_FAMILY:
448         case STMARY_FAMILY:
449         case WASY_FAMILY:
450         case ESINT_FAMILY:
451         case INHERIT_FAMILY:
452         case IGNORE_FAMILY:
453                 break;
454         }
455         return "";
456 }
457
458
459 string getSeriesCSS(FontSeries const & s)
460 {
461         switch (s) {
462         case MEDIUM_SERIES:
463                 return "normal";
464         case BOLD_SERIES:
465                 return "bold";
466         case INHERIT_SERIES:
467         case IGNORE_SERIES:
468                 break;
469         }
470         return "";
471 }
472
473
474 string getShapeCSS(FontShape const & s)
475 {
476         string fs = "normal";
477         string fv = "normal";
478         switch (s) {
479         case UP_SHAPE: break;
480         case ITALIC_SHAPE: fs = "italic"; break;
481         case SLANTED_SHAPE: fs = "oblique"; break;
482         case SMALLCAPS_SHAPE: fv = "small-caps"; break;
483         case IGNORE_SHAPE:
484         case INHERIT_SHAPE:
485                 fs = ""; fv = ""; break;
486         }
487         string retval;
488         if (!fs.empty())
489                 appendSep(retval, makeCSSTag("font-style", fs));
490         if (!fv.empty())
491                 appendSep(retval, makeCSSTag("font-variant", fv));
492         return retval;
493 }
494
495
496 string getSizeCSS(FontSize const & s)
497 {
498         switch (s) {
499         case FONT_SIZE_TINY:
500                 return "xx-small";
501         case FONT_SIZE_SCRIPT:
502                 return "x-small";
503         case FONT_SIZE_FOOTNOTE:
504         case FONT_SIZE_SMALL:
505                 return "small";
506         case FONT_SIZE_NORMAL:
507                 return "medium";
508         case FONT_SIZE_LARGE:
509                 return "large";
510         case FONT_SIZE_LARGER:
511         case FONT_SIZE_LARGEST:
512                 return "x-large";
513         case FONT_SIZE_HUGE:
514         case FONT_SIZE_HUGER:
515                 return "xx-large";
516         case FONT_SIZE_INCREASE:
517                 return "larger";
518         case FONT_SIZE_DECREASE:
519                 return "smaller";
520         case FONT_SIZE_IGNORE:
521         case FONT_SIZE_INHERIT:
522                 break;
523         }
524         return "";
525 }
526
527 } // namespace
528
529
530 // FIXME This does not yet handle color
531 docstring FontInfo::asCSS() const
532 {
533         string retval;
534         string tmp = getFamilyCSS(family_);
535         if (!tmp.empty())
536                 appendSep(retval, makeCSSTag("font-family", tmp));
537         tmp = getSeriesCSS(series_);
538         if (!tmp.empty())
539                 appendSep(retval, makeCSSTag("font-weight", tmp));
540         appendSep(retval, getShapeCSS(shape_));
541         tmp = getSizeCSS(size_);
542         if (!tmp.empty())
543                 appendSep(retval, makeCSSTag("font-size", tmp));
544         return from_ascii(retval);
545 }
546
547
548 // Set family according to lyx format string
549 void setLyXFamily(string const & fam, FontInfo & f)
550 {
551         string const s = ascii_lowercase(fam);
552
553         int i = 0;
554         while (LyXFamilyNames[i] != s &&
555                LyXFamilyNames[i] != string("error"))
556                 ++i;
557         if (s == LyXFamilyNames[i])
558                 f.setFamily(FontFamily(i));
559         else
560                 LYXERR0("Unknown family `" << s << '\'');
561 }
562
563
564 // Set series according to lyx format string
565 void setLyXSeries(string const & ser, FontInfo & f)
566 {
567         string const s = ascii_lowercase(ser);
568
569         int i = 0;
570         while (LyXSeriesNames[i] != s &&
571                LyXSeriesNames[i] != string("error")) ++i;
572         if (s == LyXSeriesNames[i]) {
573                 f.setSeries(FontSeries(i));
574         } else
575                 LYXERR0("Unknown series `" << s << '\'');
576 }
577
578
579 // Set shape according to lyx format string
580 void setLyXShape(string const & sha, FontInfo & f)
581 {
582         string const s = ascii_lowercase(sha);
583
584         int i = 0;
585         while (LyXShapeNames[i] != s && LyXShapeNames[i] != string("error"))
586                         ++i;
587         if (s == LyXShapeNames[i])
588                 f.setShape(FontShape(i));
589         else
590                 LYXERR0("Unknown shape `" << s << '\'');
591 }
592
593
594 // Set size according to lyx format string
595 void setLyXSize(string const & siz, FontInfo & f)
596 {
597         string const s = ascii_lowercase(siz);
598         int i = 0;
599         while (LyXSizeNames[i] != s && LyXSizeNames[i] != string("error"))
600                 ++i;
601         if (s == LyXSizeNames[i]) {
602                 f.setSize(FontSize(i));
603         } else
604                 LYXERR0("Unknown size `" << s << '\'');
605 }
606
607
608 // Set size according to lyx format string
609 FontState setLyXMisc(string const & siz)
610 {
611         string const s = ascii_lowercase(siz);
612         int i = 0;
613         while (LyXMiscNames[i] != s &&
614                LyXMiscNames[i] != string("error")) ++i;
615         if (s == LyXMiscNames[i])
616                 return FontState(i);
617         LYXERR0("Unknown misc flag `" << s << '\'');
618         return FONT_OFF;
619 }
620
621
622 /// Sets color after LyX text format
623 void setLyXColor(string const & col, FontInfo & f)
624 {
625         f.setColor(lcolor.getFromLyXName(col));
626 }
627
628
629 // Read a font definition from given file in lyx format
630 // Used for layouts
631 FontInfo lyxRead(Lexer & lex, FontInfo const & fi)
632 {
633         FontInfo f = fi;
634         bool error = false;
635         bool finished = false;
636         while (!finished && lex.isOK() && !error) {
637                 lex.next();
638                 string const tok = ascii_lowercase(lex.getString());
639
640                 if (tok.empty()) {
641                         continue;
642                 } else if (tok == "endfont") {
643                         finished = true;
644                 } else if (tok == "family") {
645                         lex.next();
646                         string const ttok = lex.getString();
647                         setLyXFamily(ttok, f);
648                 } else if (tok == "series") {
649                         lex.next();
650                         string const ttok = lex.getString();
651                         setLyXSeries(ttok, f);
652                 } else if (tok == "shape") {
653                         lex.next();
654                         string const ttok = lex.getString();
655                         setLyXShape(ttok, f);
656                 } else if (tok == "size") {
657                         lex.next();
658                         string const ttok = lex.getString();
659                         setLyXSize(ttok, f);
660                 } else if (tok == "misc") {
661                         lex.next();
662                         string const ttok = ascii_lowercase(lex.getString());
663
664                         if (ttok == "no_bar") {
665                                 f.setUnderbar(FONT_OFF);
666                         } else if (ttok == "no_strikeout") {
667                                 f.setStrikeout(FONT_OFF);
668                         } else if (ttok == "no_xout") {
669                                 f.setXout(FONT_OFF);
670                         } else if (ttok == "no_uuline") {
671                                 f.setUuline(FONT_OFF);
672                         } else if (ttok == "no_uwave") {
673                                 f.setUwave(FONT_OFF);
674                         } else if (ttok == "no_emph") {
675                                 f.setEmph(FONT_OFF);
676                         } else if (ttok == "no_noun") {
677                                 f.setNoun(FONT_OFF);
678                         } else if (ttok == "emph") {
679                                 f.setEmph(FONT_ON);
680                         } else if (ttok == "underbar") {
681                                 f.setUnderbar(FONT_ON);
682                         } else if (ttok == "strikeout") {
683                                 f.setStrikeout(FONT_ON);
684                         } else if (ttok == "xout") {
685                                 f.setXout(FONT_ON);
686                         } else if (ttok == "uuline") {
687                                 f.setUuline(FONT_ON);
688                         } else if (ttok == "uwave") {
689                                 f.setUwave(FONT_ON);
690                         } else if (ttok == "noun") {
691                                 f.setNoun(FONT_ON);
692                         } else {
693                                 lex.printError("Illegal misc type");
694                         }
695                 } else if (tok == "color") {
696                         lex.next();
697                         string const ttok = lex.getString();
698                         setLyXColor(ttok, f);
699                 } else {
700                         lex.printError("Unknown tag");
701                         error = true;
702                 }
703         }
704         return f;
705 }
706
707
708 void lyxWrite(ostream & os, FontInfo const & f, string const & start, int level)
709 {
710         string indent;
711         for (int i = 0; i < level; ++i)
712                 indent += '\t';
713         ostringstream oss;
714         if (f.family() != INHERIT_FAMILY)
715                 oss << indent << "\tFamily " << LyXFamilyNames[f.family()]
716                     << '\n';
717         if (f.series() != INHERIT_SERIES)
718                 oss << indent << "\tSeries " << LyXSeriesNames[f.series()]
719                     << '\n';
720         if (f.shape() != INHERIT_SHAPE)
721                 oss << indent << "\tShape " << LyXShapeNames[f.shape()]
722                     << '\n';
723         if (f.size() != FONT_SIZE_INHERIT)
724                 oss << indent << "\tSize " << LyXSizeNames[f.size()]
725                     << '\n';
726         if (f.underbar() == FONT_ON)
727                 oss << indent << "\tMisc Underbar\n";
728         else if (f.underbar() == FONT_OFF)
729                 oss << indent << "\tMisc No_Bar\n";
730         if (f.strikeout() == FONT_ON)
731                 oss << indent << "\tMisc Strikeout\n";
732         else if (f.strikeout() == FONT_OFF)
733                 oss << indent << "\tMisc No_Strikeout\n";
734         if (f.xout() == FONT_ON)
735                 oss << indent << "\tMisc Xout\n";
736         else if (f.xout() == FONT_OFF)
737                 oss << indent << "\tMisc No_Xout\n";
738         if (f.uuline() == FONT_ON)
739                 oss << indent << "\tMisc Uuline\n";
740         else if (f.uuline() == FONT_OFF)
741                 oss << indent << "\tMisc No_Uuline\n";
742         if (f.uwave() == FONT_ON)
743                 oss << indent << "\tMisc Uwave\n";
744         else if (f.uwave() == FONT_OFF)
745                 oss << indent << "\tMisc No_Uwave\n";
746         if (f.emph() == FONT_ON)
747                 oss << indent << "\tMisc Emph\n";
748         else if (f.emph() == FONT_OFF)
749                 oss << indent << "\tMisc No_Emph\n";
750         if (f.noun() == FONT_ON)
751                 oss << indent << "\tMisc Noun\n";
752         else if (f.noun() == FONT_OFF)
753                 oss << indent << "\tMisc No_Noun\n";
754         if (f.color() != Color_inherit && f.color() != Color_none)
755                 oss << indent << "\tColor " << lcolor.getLyXName(f.color())
756                     << '\n';
757         if (!oss.str().empty()) {
758                 os << indent << start << '\n'
759                    << oss.str()
760                    << indent << "EndFont\n";
761         }
762 }
763
764
765 } // namespace lyx