]> git.lyx.org Git - lyx.git/blob - src/FontInfo.cpp
Provide proper fallback if a bibliography processor is not found
[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", "ds", "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 DS_FAMILY:
447         case EUFRAK_FAMILY:
448         case RSFS_FAMILY:
449         case STMARY_FAMILY:
450         case WASY_FAMILY:
451         case ESINT_FAMILY:
452         case INHERIT_FAMILY:
453         case IGNORE_FAMILY:
454                 break;
455         }
456         return "";
457 }
458
459
460 string getSeriesCSS(FontSeries const & s)
461 {
462         switch (s) {
463         case MEDIUM_SERIES:
464                 return "normal";
465         case BOLD_SERIES:
466                 return "bold";
467         case INHERIT_SERIES:
468         case IGNORE_SERIES:
469                 break;
470         }
471         return "";
472 }
473
474
475 string getShapeCSS(FontShape const & s)
476 {
477         string fs = "normal";
478         string fv = "normal";
479         switch (s) {
480         case UP_SHAPE: break;
481         case ITALIC_SHAPE: fs = "italic"; break;
482         case SLANTED_SHAPE: fs = "oblique"; break;
483         case SMALLCAPS_SHAPE: fv = "small-caps"; break;
484         case IGNORE_SHAPE:
485         case INHERIT_SHAPE:
486                 fs = ""; fv = ""; break;
487         }
488         string retval;
489         if (!fs.empty())
490                 appendSep(retval, makeCSSTag("font-style", fs));
491         if (!fv.empty())
492                 appendSep(retval, makeCSSTag("font-variant", fv));
493         return retval;
494 }
495
496
497 string getSizeCSS(FontSize const & s)
498 {
499         switch (s) {
500         case FONT_SIZE_TINY:
501                 return "xx-small";
502         case FONT_SIZE_SCRIPT:
503                 return "x-small";
504         case FONT_SIZE_FOOTNOTE:
505         case FONT_SIZE_SMALL:
506                 return "small";
507         case FONT_SIZE_NORMAL:
508                 return "medium";
509         case FONT_SIZE_LARGE:
510                 return "large";
511         case FONT_SIZE_LARGER:
512         case FONT_SIZE_LARGEST:
513                 return "x-large";
514         case FONT_SIZE_HUGE:
515         case FONT_SIZE_HUGER:
516                 return "xx-large";
517         case FONT_SIZE_INCREASE:
518                 return "larger";
519         case FONT_SIZE_DECREASE:
520                 return "smaller";
521         case FONT_SIZE_IGNORE:
522         case FONT_SIZE_INHERIT:
523                 break;
524         }
525         return "";
526 }
527
528 } // namespace
529
530
531 // FIXME This does not yet handle color
532 docstring FontInfo::asCSS() const
533 {
534         string retval;
535         string tmp = getFamilyCSS(family_);
536         if (!tmp.empty())
537                 appendSep(retval, makeCSSTag("font-family", tmp));
538         tmp = getSeriesCSS(series_);
539         if (!tmp.empty())
540                 appendSep(retval, makeCSSTag("font-weight", tmp));
541         appendSep(retval, getShapeCSS(shape_));
542         tmp = getSizeCSS(size_);
543         if (!tmp.empty())
544                 appendSep(retval, makeCSSTag("font-size", tmp));
545         return from_ascii(retval);
546 }
547
548
549 // Set family according to lyx format string
550 void setLyXFamily(string const & fam, FontInfo & f)
551 {
552         string const s = ascii_lowercase(fam);
553
554         int i = 0;
555         while (LyXFamilyNames[i] != s &&
556                LyXFamilyNames[i] != string("error"))
557                 ++i;
558         if (s == LyXFamilyNames[i])
559                 f.setFamily(FontFamily(i));
560         else
561                 LYXERR0("Unknown family `" << s << '\'');
562 }
563
564
565 // Set series according to lyx format string
566 void setLyXSeries(string const & ser, FontInfo & f)
567 {
568         string const s = ascii_lowercase(ser);
569
570         int i = 0;
571         while (LyXSeriesNames[i] != s &&
572                LyXSeriesNames[i] != string("error")) ++i;
573         if (s == LyXSeriesNames[i]) {
574                 f.setSeries(FontSeries(i));
575         } else
576                 LYXERR0("Unknown series `" << s << '\'');
577 }
578
579
580 // Set shape according to lyx format string
581 void setLyXShape(string const & sha, FontInfo & f)
582 {
583         string const s = ascii_lowercase(sha);
584
585         int i = 0;
586         while (LyXShapeNames[i] != s && LyXShapeNames[i] != string("error"))
587                         ++i;
588         if (s == LyXShapeNames[i])
589                 f.setShape(FontShape(i));
590         else
591                 LYXERR0("Unknown shape `" << s << '\'');
592 }
593
594
595 // Set size according to lyx format string
596 void setLyXSize(string const & siz, FontInfo & f)
597 {
598         string const s = ascii_lowercase(siz);
599         int i = 0;
600         while (LyXSizeNames[i] != s && LyXSizeNames[i] != string("error"))
601                 ++i;
602         if (s == LyXSizeNames[i]) {
603                 f.setSize(FontSize(i));
604         } else
605                 LYXERR0("Unknown size `" << s << '\'');
606 }
607
608
609 // Set size according to lyx format string
610 FontState setLyXMisc(string const & siz)
611 {
612         string const s = ascii_lowercase(siz);
613         int i = 0;
614         while (LyXMiscNames[i] != s &&
615                LyXMiscNames[i] != string("error")) ++i;
616         if (s == LyXMiscNames[i])
617                 return FontState(i);
618         LYXERR0("Unknown misc flag `" << s << '\'');
619         return FONT_OFF;
620 }
621
622
623 /// Sets color after LyX text format
624 void setLyXColor(string const & col, FontInfo & f)
625 {
626         f.setColor(lcolor.getFromLyXName(col));
627 }
628
629
630 // Read a font definition from given file in lyx format
631 // Used for layouts
632 FontInfo lyxRead(Lexer & lex, FontInfo const & fi)
633 {
634         FontInfo f = fi;
635         bool error = false;
636         bool finished = false;
637         while (!finished && lex.isOK() && !error) {
638                 lex.next();
639                 string const tok = ascii_lowercase(lex.getString());
640
641                 if (tok.empty()) {
642                         continue;
643                 } else if (tok == "endfont") {
644                         finished = true;
645                 } else if (tok == "family") {
646                         lex.next();
647                         string const ttok = lex.getString();
648                         setLyXFamily(ttok, f);
649                 } else if (tok == "series") {
650                         lex.next();
651                         string const ttok = lex.getString();
652                         setLyXSeries(ttok, f);
653                 } else if (tok == "shape") {
654                         lex.next();
655                         string const ttok = lex.getString();
656                         setLyXShape(ttok, f);
657                 } else if (tok == "size") {
658                         lex.next();
659                         string const ttok = lex.getString();
660                         setLyXSize(ttok, f);
661                 } else if (tok == "misc") {
662                         lex.next();
663                         string const ttok = ascii_lowercase(lex.getString());
664
665                         if (ttok == "no_bar") {
666                                 f.setUnderbar(FONT_OFF);
667                         } else if (ttok == "no_strikeout") {
668                                 f.setStrikeout(FONT_OFF);
669                         } else if (ttok == "no_xout") {
670                                 f.setXout(FONT_OFF);
671                         } else if (ttok == "no_uuline") {
672                                 f.setUuline(FONT_OFF);
673                         } else if (ttok == "no_uwave") {
674                                 f.setUwave(FONT_OFF);
675                         } else if (ttok == "no_emph") {
676                                 f.setEmph(FONT_OFF);
677                         } else if (ttok == "no_noun") {
678                                 f.setNoun(FONT_OFF);
679                         } else if (ttok == "emph") {
680                                 f.setEmph(FONT_ON);
681                         } else if (ttok == "underbar") {
682                                 f.setUnderbar(FONT_ON);
683                         } else if (ttok == "strikeout") {
684                                 f.setStrikeout(FONT_ON);
685                         } else if (ttok == "xout") {
686                                 f.setXout(FONT_ON);
687                         } else if (ttok == "uuline") {
688                                 f.setUuline(FONT_ON);
689                         } else if (ttok == "uwave") {
690                                 f.setUwave(FONT_ON);
691                         } else if (ttok == "noun") {
692                                 f.setNoun(FONT_ON);
693                         } else {
694                                 lex.printError("Illegal misc type");
695                         }
696                 } else if (tok == "color") {
697                         lex.next();
698                         string const ttok = lex.getString();
699                         setLyXColor(ttok, f);
700                 } else {
701                         lex.printError("Unknown tag");
702                         error = true;
703                 }
704         }
705         return f;
706 }
707
708
709 void lyxWrite(ostream & os, FontInfo const & f, string const & start, int level)
710 {
711         string indent;
712         for (int i = 0; i < level; ++i)
713                 indent += '\t';
714         ostringstream oss;
715         if (f.family() != INHERIT_FAMILY)
716                 oss << indent << "\tFamily " << LyXFamilyNames[f.family()]
717                     << '\n';
718         if (f.series() != INHERIT_SERIES)
719                 oss << indent << "\tSeries " << LyXSeriesNames[f.series()]
720                     << '\n';
721         if (f.shape() != INHERIT_SHAPE)
722                 oss << indent << "\tShape " << LyXShapeNames[f.shape()]
723                     << '\n';
724         if (f.size() != FONT_SIZE_INHERIT)
725                 oss << indent << "\tSize " << LyXSizeNames[f.size()]
726                     << '\n';
727         if (f.underbar() == FONT_ON)
728                 oss << indent << "\tMisc Underbar\n";
729         else if (f.underbar() == FONT_OFF)
730                 oss << indent << "\tMisc No_Bar\n";
731         if (f.strikeout() == FONT_ON)
732                 oss << indent << "\tMisc Strikeout\n";
733         else if (f.strikeout() == FONT_OFF)
734                 oss << indent << "\tMisc No_Strikeout\n";
735         if (f.xout() == FONT_ON)
736                 oss << indent << "\tMisc Xout\n";
737         else if (f.xout() == FONT_OFF)
738                 oss << indent << "\tMisc No_Xout\n";
739         if (f.uuline() == FONT_ON)
740                 oss << indent << "\tMisc Uuline\n";
741         else if (f.uuline() == FONT_OFF)
742                 oss << indent << "\tMisc No_Uuline\n";
743         if (f.uwave() == FONT_ON)
744                 oss << indent << "\tMisc Uwave\n";
745         else if (f.uwave() == FONT_OFF)
746                 oss << indent << "\tMisc No_Uwave\n";
747         if (f.emph() == FONT_ON)
748                 oss << indent << "\tMisc Emph\n";
749         else if (f.emph() == FONT_OFF)
750                 oss << indent << "\tMisc No_Emph\n";
751         if (f.noun() == FONT_ON)
752                 oss << indent << "\tMisc Noun\n";
753         else if (f.noun() == FONT_OFF)
754                 oss << indent << "\tMisc No_Noun\n";
755         if (f.color() != Color_inherit && f.color() != Color_none)
756                 oss << indent << "\tColor " << lcolor.getLyXName(f.color())
757                     << '\n';
758         if (!oss.str().empty()) {
759                 os << indent << start << '\n'
760                    << oss.str()
761                    << indent << "EndFont\n";
762         }
763 }
764
765
766 } // namespace lyx