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