3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Lars Gullik Bjønnes
7 * \author Jean-Marc Lasgouttes
8 * \author Angus Leeming
12 * Full author contact details are available in file CREDITS.
19 #include "BufferParams.h" // stateText
23 #include "LaTeXFeatures.h"
26 #include "output_latex.h"
27 #include "OutputParams.h"
29 #include "support/lassert.h"
30 #include "support/convert.h"
31 #include "support/debug.h"
32 #include "support/gettext.h"
33 #include "support/lstrings.h"
38 using namespace lyx::support
;
48 char const * GUIFamilyNames
[NUM_FAMILIES
+ 2 /* default & error */] =
49 { N_("Roman"), N_("Sans Serif"), N_("Typewriter"), N_("Symbol"),
50 "cmr", "cmsy", "cmm", "cmex", "msa", "msb", "eufrak", "wasy", "esint",
51 N_("Inherit"), N_("Ignore") };
53 char const * GUISeriesNames
[4] =
54 { N_("Medium"), N_("Bold"), N_("Inherit"), N_("Ignore") };
56 char const * GUIShapeNames
[6] =
57 { N_("Upright"), N_("Italic"), N_("Slanted"), N_("Smallcaps"), N_("Inherit"),
60 char const * GUISizeNames
[14] =
61 { N_("Tiny"), N_("Smallest"), N_("Smaller"), N_("Small"), N_("Normal"), N_("Large"),
62 N_("Larger"), N_("Largest"), N_("Huge"), N_("Huger"), N_("Increase"), N_("Decrease"),
63 N_("Inherit"), N_("Ignore") };
65 char const * GUIMiscNames
[5] =
66 { N_("Off"), N_("On"), N_("Toggle"), N_("Inherit"), N_("Ignore") };
70 // Strings used to read and write .lyx format files
72 char const * LyXFamilyNames
[NUM_FAMILIES
+ 2 /* default & error */] =
73 { "roman", "sans", "typewriter", "symbol",
74 "cmr", "cmsy", "cmm", "cmex", "msa", "msb", "eufrak", "wasy", "esint",
77 char const * LyXSeriesNames
[4] =
78 { "medium", "bold", "default", "error" };
80 char const * LyXShapeNames
[6] =
81 { "up", "italic", "slanted", "smallcaps", "default", "error" };
83 char const * LyXSizeNames
[14] =
84 { "tiny", "scriptsize", "footnotesize", "small", "normal", "large",
85 "larger", "largest", "huge", "giant",
86 "increase", "decrease", "default", "error" };
88 char const * LyXMiscNames
[5] =
89 { "off", "on", "toggle", "default", "error" };
92 // Strings used to write LaTeX files
94 char const * LaTeXFamilyNames
[6] =
95 { "textrm", "textsf", "texttt", "error1", "error2", "error3" };
97 char const * LaTeXSeriesNames
[4] =
98 { "textmd", "textbf", "error4", "error5" };
100 char const * LaTeXShapeNames
[6] =
101 { "textup", "textit", "textsl", "textsc", "error6", "error7" };
103 char const * LaTeXSizeNames
[14] =
104 { "tiny", "scriptsize", "footnotesize", "small", "normalsize", "large",
105 "Large", "LARGE", "huge", "Huge", "error8", "error9", "error10", "error11" };
110 Font::Font(FontInfo bits
, Language
const * l
)
111 : bits_(bits
), lang_(l
), misspelled_(false), open_encoding_(false)
114 lang_
= default_language
;
118 bool Font::isRightToLeft() const
120 return lang_
->rightToLeft();
124 bool Font::isVisibleRightToLeft() const
126 return (lang_
->rightToLeft() &&
127 bits_
.number() != FONT_ON
);
131 void Font::setLanguage(Language
const * l
)
137 /// Updates font settings according to request
138 void Font::update(Font
const & newfont
,
139 Language
const * document_language
,
142 bits_
.update(newfont
.fontInfo(), toggleall
);
144 if (newfont
.language() == language() && toggleall
)
145 if (language() == document_language
)
146 setLanguage(default_language
);
148 setLanguage(document_language
);
149 else if (newfont
.language() == reset_language
)
150 setLanguage(document_language
);
151 else if (newfont
.language() != ignore_language
)
152 setLanguage(newfont
.language());
156 docstring
const stateText(FontInfo
const & f
)
159 if (f
.family() != INHERIT_FAMILY
)
160 os
<< _(GUIFamilyNames
[f
.family()]) << ", ";
161 if (f
.series() != INHERIT_SERIES
)
162 os
<< _(GUISeriesNames
[f
.series()]) << ", ";
163 if (f
.shape() != INHERIT_SHAPE
)
164 os
<< _(GUIShapeNames
[f
.shape()]) << ", ";
165 if (f
.size() != FONT_SIZE_INHERIT
)
166 os
<< _(GUISizeNames
[f
.size()]) << ", ";
167 if (f
.color() != Color_inherit
)
168 os
<< lcolor
.getGUIName(f
.color()) << ", ";
169 // FIXME: uncomment this when we support background.
170 //if (f.background() != Color_inherit)
171 // os << lcolor.getGUIName(f.background()) << ", ";
172 if (f
.emph() != FONT_INHERIT
)
173 os
<< bformat(_("Emphasis %1$s, "),
174 _(GUIMiscNames
[f
.emph()]));
175 if (f
.underbar() != FONT_INHERIT
)
176 os
<< bformat(_("Underline %1$s, "),
177 _(GUIMiscNames
[f
.underbar()]));
178 if (f
.strikeout() != FONT_INHERIT
)
179 os
<< bformat(_("Strikeout %1$s, "),
180 _(GUIMiscNames
[f
.strikeout()]));
181 if (f
.uuline() != FONT_INHERIT
)
182 os
<< bformat(_("Double underline %1$s, "),
183 _(GUIMiscNames
[f
.uuline()]));
184 if (f
.uwave() != FONT_INHERIT
)
185 os
<< bformat(_("Wavy underline %1$s, "),
186 _(GUIMiscNames
[f
.uwave()]));
187 if (f
.noun() != FONT_INHERIT
)
188 os
<< bformat(_("Noun %1$s, "),
189 _(GUIMiscNames
[f
.noun()]));
190 if (f
== inherit_font
)
191 os
<< _("Default") << ", ";
197 docstring
const Font::stateText(BufferParams
* params
) const
200 os
<< lyx::stateText(bits_
);
201 if (!params
|| (language() != params
->language
))
202 os
<< bformat(_("Language: %1$s, "),
203 _(language()->display()));
204 if (bits_
.number() != FONT_OFF
)
205 os
<< bformat(_(" Number %1$s"),
206 _(GUIMiscNames
[bits_
.number()]));
207 return rtrim(os
.str(), ", ");
211 // Set family according to lyx format string
212 void setLyXFamily(string
const & fam
, FontInfo
& f
)
214 string
const s
= ascii_lowercase(fam
);
217 while (LyXFamilyNames
[i
] != s
&&
218 LyXFamilyNames
[i
] != string("error"))
220 if (s
== LyXFamilyNames
[i
])
221 f
.setFamily(FontFamily(i
));
223 lyxerr
<< "setLyXFamily: Unknown family `"
224 << s
<< '\'' << endl
;
228 // Set series according to lyx format string
229 void setLyXSeries(string
const & ser
, FontInfo
& f
)
231 string
const s
= ascii_lowercase(ser
);
234 while (LyXSeriesNames
[i
] != s
&&
235 LyXSeriesNames
[i
] != string("error")) ++i
;
236 if (s
== LyXSeriesNames
[i
]) {
237 f
.setSeries(FontSeries(i
));
239 lyxerr
<< "setLyXSeries: Unknown series `"
240 << s
<< '\'' << endl
;
244 // Set shape according to lyx format string
245 void setLyXShape(string
const & sha
, FontInfo
& f
)
247 string
const s
= ascii_lowercase(sha
);
250 while (LyXShapeNames
[i
] != s
&& LyXShapeNames
[i
] != string("error"))
252 if (s
== LyXShapeNames
[i
])
253 f
.setShape(FontShape(i
));
255 lyxerr
<< "Font::setLyXShape: Unknown shape `"
256 << s
<< '\'' << endl
;
260 // Set size according to lyx format string
261 void setLyXSize(string
const & siz
, FontInfo
& f
)
263 string
const s
= ascii_lowercase(siz
);
265 while (LyXSizeNames
[i
] != s
&& LyXSizeNames
[i
] != string("error"))
267 if (s
== LyXSizeNames
[i
]) {
268 f
.setSize(FontSize(i
));
270 lyxerr
<< "Font::setLyXSize: Unknown size `"
271 << s
<< '\'' << endl
;
275 // Set size according to lyx format string
276 FontState
Font::setLyXMisc(string
const & siz
)
278 string
const s
= ascii_lowercase(siz
);
280 while (LyXMiscNames
[i
] != s
&&
281 LyXMiscNames
[i
] != string("error")) ++i
;
282 if (s
== LyXMiscNames
[i
])
284 lyxerr
<< "Font::setLyXMisc: Unknown misc flag `"
285 << s
<< '\'' << endl
;
290 /// Sets color after LyX text format
291 void setLyXColor(string
const & col
, FontInfo
& f
)
293 f
.setColor(lcolor
.getFromLyXName(col
));
297 // Returns size in latex format
298 string
const Font::latexSize() const
300 return LaTeXSizeNames
[bits_
.size()];
304 // Read a font definition from given file in lyx format
306 FontInfo
lyxRead(Lexer
& lex
, FontInfo
const & fi
)
310 bool finished
= false;
311 while (!finished
&& lex
.isOK() && !error
) {
313 string
const tok
= ascii_lowercase(lex
.getString());
317 } else if (tok
== "endfont") {
319 } else if (tok
== "family") {
321 string
const ttok
= lex
.getString();
322 setLyXFamily(ttok
, f
);
323 } else if (tok
== "series") {
325 string
const ttok
= lex
.getString();
326 setLyXSeries(ttok
, f
);
327 } else if (tok
== "shape") {
329 string
const ttok
= lex
.getString();
330 setLyXShape(ttok
, f
);
331 } else if (tok
== "size") {
333 string
const ttok
= lex
.getString();
335 } else if (tok
== "misc") {
337 string
const ttok
= ascii_lowercase(lex
.getString());
339 if (ttok
== "no_bar") {
340 f
.setUnderbar(FONT_OFF
);
341 } else if (ttok
== "no_strikeout") {
342 f
.setStrikeout(FONT_OFF
);
343 } else if (ttok
== "no_uuline") {
344 f
.setUuline(FONT_OFF
);
345 } else if (ttok
== "no_uwave") {
346 f
.setUwave(FONT_OFF
);
347 } else if (ttok
== "no_emph") {
349 } else if (ttok
== "no_noun") {
351 } else if (ttok
== "emph") {
353 } else if (ttok
== "underbar") {
354 f
.setUnderbar(FONT_ON
);
355 } else if (ttok
== "strikeout") {
356 f
.setStrikeout(FONT_ON
);
357 } else if (ttok
== "uuline") {
358 f
.setUuline(FONT_ON
);
359 } else if (ttok
== "uwave") {
361 } else if (ttok
== "noun") {
364 lex
.printError("Illegal misc type");
366 } else if (tok
== "color") {
368 string
const ttok
= lex
.getString();
369 setLyXColor(ttok
, f
);
371 lex
.printError("Unknown tag");
379 /// Writes the changes from this font to orgfont in .lyx format in file
380 void Font::lyxWriteChanges(Font
const & orgfont
,
384 if (orgfont
.fontInfo().family() != bits_
.family())
385 os
<< "\\family " << LyXFamilyNames
[bits_
.family()] << "\n";
386 if (orgfont
.fontInfo().series() != bits_
.series())
387 os
<< "\\series " << LyXSeriesNames
[bits_
.series()] << "\n";
388 if (orgfont
.fontInfo().shape() != bits_
.shape())
389 os
<< "\\shape " << LyXShapeNames
[bits_
.shape()] << "\n";
390 if (orgfont
.fontInfo().size() != bits_
.size())
391 os
<< "\\size " << LyXSizeNames
[bits_
.size()] << "\n";
392 if (orgfont
.fontInfo().emph() != bits_
.emph())
393 os
<< "\\emph " << LyXMiscNames
[bits_
.emph()] << "\n";
394 if (orgfont
.fontInfo().number() != bits_
.number())
395 os
<< "\\numeric " << LyXMiscNames
[bits_
.number()] << "\n";
396 if (orgfont
.fontInfo().underbar() != bits_
.underbar()) {
397 // This is only for backwards compatibility
398 switch (bits_
.underbar()) {
399 case FONT_OFF
: os
<< "\\bar no\n"; break;
400 case FONT_ON
: os
<< "\\bar under\n"; break;
401 case FONT_TOGGLE
: lyxerr
<< "Font::lyxWriteFontChanges: "
402 "FONT_TOGGLE should not appear here!"
405 case FONT_INHERIT
: os
<< "\\bar default\n"; break;
406 case FONT_IGNORE
: lyxerr
<< "Font::lyxWriteFontChanges: "
407 "IGNORE should not appear here!"
412 if (orgfont
.fontInfo().strikeout() != bits_
.strikeout()) {
413 os
<< "\\strikeout " << LyXMiscNames
[bits_
.strikeout()] << "\n";
415 if (orgfont
.fontInfo().uuline() != bits_
.uuline()) {
416 os
<< "\\uuline " << LyXMiscNames
[bits_
.uuline()] << "\n";
418 if (orgfont
.fontInfo().uwave() != bits_
.uwave()) {
419 os
<< "\\uwave " << LyXMiscNames
[bits_
.uwave()] << "\n";
421 if (orgfont
.fontInfo().noun() != bits_
.noun()) {
422 os
<< "\\noun " << LyXMiscNames
[bits_
.noun()] << "\n";
424 if (orgfont
.fontInfo().color() != bits_
.color())
425 os
<< "\\color " << lcolor
.getLyXName(bits_
.color()) << '\n';
426 // FIXME: uncomment this when we support background.
427 //if (orgfont.fontInfo().background() != bits_.background())
428 // os << "\\color " << lcolor.getLyXName(bits_.background()) << '\n';
429 if (orgfont
.language() != language() &&
430 language() != latex_language
) {
432 os
<< "\\lang " << language()->lang() << "\n";
434 os
<< "\\lang unknown\n";
439 /// Writes the head of the LaTeX needed to impose this font
440 // Returns number of chars written.
441 int Font::latexWriteStartChanges(odocstream
& os
, BufferParams
const & bparams
,
442 OutputParams
const & runparams
,
444 Font
const & prev
) const
449 if (language()->babel() != base
.language()->babel() &&
450 language() != prev
.language()) {
451 if (language()->lang() == "farsi") {
454 } else if (!isRightToLeft() &&
455 base
.language()->lang() == "farsi") {
458 } else if (language()->lang() == "arabic_arabi") {
461 } else if (!isRightToLeft() &&
462 base
.language()->lang() == "arabic_arabi") {
465 // currently the remaining RTL languages are arabic_arabtex and hebrew
466 } else if (isRightToLeft() != prev
.isRightToLeft()) {
467 if (isRightToLeft()) {
474 } else if (!language()->babel().empty()) {
476 subst(lyxrc
.language_command_local
,
477 "$$lang", language()->babel());
478 os
<< from_ascii(tmp
);
479 count
+= tmp
.length();
486 if (language()->encoding()->package() == Encoding::CJK
) {
487 pair
<bool, int> const c
= switchEncoding(os
, bparams
,
488 runparams
, *(language()->encoding()));
490 open_encoding_
= true;
492 runparams
.encoding
= language()->encoding();
496 // When the current language is Hebrew, Arabic, or Farsi
497 // the numbers are written Left-to-Right. ArabTeX package
498 // reorders the number automatically but the packages used
499 // for Hebrew and Farsi (Arabi) do not.
500 if (bits_
.number() == FONT_ON
&& prev
.fontInfo().number() != FONT_ON
501 && (language()->lang() == "hebrew"
502 || language()->lang() == "farsi"
503 || language()->lang() == "arabic_arabi")) {
509 f
.reduce(base
.bits_
);
511 if (f
.family() != INHERIT_FAMILY
) {
513 << LaTeXFamilyNames
[f
.family()]
515 count
+= strlen(LaTeXFamilyNames
[f
.family()]) + 2;
516 env
= true; //We have opened a new environment
518 if (f
.series() != INHERIT_SERIES
) {
520 << LaTeXSeriesNames
[f
.series()]
522 count
+= strlen(LaTeXSeriesNames
[f
.series()]) + 2;
523 env
= true; //We have opened a new environment
525 if (f
.shape() != INHERIT_SHAPE
) {
527 << LaTeXShapeNames
[f
.shape()]
529 count
+= strlen(LaTeXShapeNames
[f
.shape()]) + 2;
530 env
= true; //We have opened a new environment
532 if (f
.color() != Color_inherit
&& f
.color() != Color_ignore
) {
534 << from_ascii(lcolor
.getLaTeXName(f
.color()))
536 count
+= lcolor
.getLaTeXName(f
.color()).length() + 13;
537 env
= true; //We have opened a new environment
539 // FIXME: uncomment this when we support background.
541 if (f.background() != Color_inherit && f.background() != Color_ignore) {
543 << from_ascii(lcolor.getLaTeXName(f.background()))
545 count += lcolor.getLaTeXName(f.background()).length() + 13;
546 env = true; //We have opened a new environment
549 if (f
.emph() == FONT_ON
) {
552 env
= true; //We have opened a new environment
554 if (f
.underbar() == FONT_ON
) {
557 runparams
.inulemcmd
= true;
558 env
= true; //We have opened a new environment
560 if (f
.strikeout() == FONT_ON
) {
563 runparams
.inulemcmd
= true;
564 env
= true; //We have opened a new environment
566 if (f
.uuline() == FONT_ON
) {
569 runparams
.inulemcmd
= true;
570 env
= true; //We have opened a new environment
572 if (f
.uwave() == FONT_ON
) {
575 runparams
.inulemcmd
= true;
576 env
= true; //We have opened a new environment
578 // \noun{} is a LyX special macro
579 if (f
.noun() == FONT_ON
) {
582 env
= true; //We have opened a new environment
584 if (f
.size() != FONT_SIZE_INHERIT
) {
585 // If we didn't open an environment above, we open one here
591 << LaTeXSizeNames
[f
.size()]
593 count
+= strlen(LaTeXSizeNames
[f
.size()]) + 2;
599 /// Writes ending block of LaTeX needed to close use of this font
600 // Returns number of chars written
601 // This one corresponds to latexWriteStartChanges(). (Asger)
602 int Font::latexWriteEndChanges(odocstream
& os
, BufferParams
const & bparams
,
603 OutputParams
const & runparams
,
606 bool const & closeLanguage
) const
611 // reduce the current font to changes against the base
612 // font (of the layout). We use a temporary for this to
613 // avoid changing this font instance, as that would break
615 f
.reduce(base
.bits_
);
617 if (f
.family() != INHERIT_FAMILY
) {
620 env
= true; // Size change need not bother about closing env.
622 if (f
.series() != INHERIT_SERIES
) {
625 env
= true; // Size change need not bother about closing env.
627 if (f
.shape() != INHERIT_SHAPE
) {
630 env
= true; // Size change need not bother about closing env.
632 if (f
.color() != Color_inherit
&& f
.color() != Color_ignore
) {
635 env
= true; // Size change need not bother about closing env.
637 if (f
.emph() == FONT_ON
) {
640 env
= true; // Size change need not bother about closing env.
642 if (f
.underbar() == FONT_ON
) {
645 runparams
.inulemcmd
= false;
646 env
= true; // Size change need not bother about closing env.
648 if (f
.strikeout() == FONT_ON
) {
651 runparams
.inulemcmd
= false;
652 env
= true; // Size change need not bother about closing env.
654 if (f
.uuline() == FONT_ON
) {
657 runparams
.inulemcmd
= false;
658 env
= true; // Size change need not bother about closing env.
660 if (f
.uwave() == FONT_ON
) {
663 runparams
.inulemcmd
= false;
664 env
= true; // Size change need not bother about closing env.
666 if (f
.noun() == FONT_ON
) {
669 env
= true; // Size change need not bother about closing env.
671 if (f
.size() != FONT_SIZE_INHERIT
) {
672 // We only have to close if only size changed
679 // When the current language is Hebrew, Arabic, or Farsi
680 // the numbers are written Left-to-Right. ArabTeX package
681 // reorders the number automatically but the packages used
682 // for Hebrew and Farsi (Arabi) do not.
683 if (bits_
.number() == FONT_ON
&& next
.fontInfo().number() != FONT_ON
684 && (language()->lang() == "hebrew"
685 || language()->lang() == "farsi"
686 || language()->lang() == "arabic_arabi")) {
691 if (open_encoding_
) {
692 // We need to close the encoding even if it does not change
693 // to do correct environment nesting
694 Encoding
const * const ascii
= encodings
.fromLyXName("ascii");
695 pair
<bool, int> const c
= switchEncoding(os
, bparams
,
697 LASSERT(c
.first
, /**/);
699 runparams
.encoding
= ascii
;
700 open_encoding_
= false;
704 language() != base
.language() && language() != next
.language()) {
713 string
Font::toString(bool const toggle
) const
715 string
const lang
= (language() == reset_language
)
716 ? "reset" : language()->lang();
719 os
<< "family " << bits_
.family() << '\n'
720 << "series " << bits_
.series() << '\n'
721 << "shape " << bits_
.shape() << '\n'
722 << "size " << bits_
.size() << '\n'
723 << "emph " << bits_
.emph() << '\n'
724 << "underbar " << bits_
.underbar() << '\n'
725 << "strikeout " << bits_
.strikeout() << '\n'
726 << "uuline " << bits_
.uuline() << '\n'
727 << "uwave " << bits_
.uwave() << '\n'
728 << "noun " << bits_
.noun() << '\n'
729 << "number " << bits_
.number() << '\n'
730 << "color " << bits_
.color() << '\n'
731 << "language " << lang
<< '\n'
732 << "toggleall " << convert
<string
>(toggle
);
737 bool Font::fromString(string
const & data
, bool & toggle
)
739 istringstream
is(data
);
747 token
= lex
.getString();
749 if (token
.empty() || !lex
.next())
752 if (token
== "family") {
753 int const next
= lex
.getInteger();
754 bits_
.setFamily(FontFamily(next
));
756 } else if (token
== "series") {
757 int const next
= lex
.getInteger();
758 bits_
.setSeries(FontSeries(next
));
760 } else if (token
== "shape") {
761 int const next
= lex
.getInteger();
762 bits_
.setShape(FontShape(next
));
764 } else if (token
== "size") {
765 int const next
= lex
.getInteger();
766 bits_
.setSize(FontSize(next
));
768 } else if (token
== "emph" || token
== "underbar" ||
769 token
== "noun" || token
== "number" ||
770 token
== "uuline" || token
== "uwave" ||
771 token
== "strikeout") {
773 int const next
= lex
.getInteger();
774 FontState
const misc
= FontState(next
);
778 else if (token
== "underbar")
779 bits_
.setUnderbar(misc
);
780 else if (token
== "strikeout")
781 bits_
.setStrikeout(misc
);
782 else if (token
== "uuline")
783 bits_
.setUuline(misc
);
784 else if (token
== "uwave")
785 bits_
.setUwave(misc
);
786 else if (token
== "noun")
788 else if (token
== "number")
789 bits_
.setNumber(misc
);
791 } else if (token
== "color") {
792 int const next
= lex
.getInteger();
793 bits_
.setColor(ColorCode(next
));
796 } else if (token == "background") {
797 int const next = lex.getInteger();
798 bits_.setBackground(ColorCode(next));
801 } else if (token
== "language") {
802 string
const next
= lex
.getString();
803 setLanguage(languages
.getLanguage(next
));
805 } else if (token
== "toggleall") {
806 toggle
= lex
.getBool();
809 // Unrecognised token
819 void Font::validate(LaTeXFeatures
& features
) const
821 BufferParams
const & bparams
= features
.bufferParams();
822 Language
const * doc_language
= bparams
.language
;
824 if (bits_
.noun() == FONT_ON
) {
825 LYXERR(Debug::LATEX
, "font.noun: " << bits_
.noun());
826 features
.require("noun");
827 LYXERR(Debug::LATEX
, "Noun enabled. Font: " << to_utf8(stateText(0)));
829 if (bits_
.underbar() == FONT_ON
) {
830 LYXERR(Debug::LATEX
, "font.underline: " << bits_
.underbar());
831 features
.require("ulem");
832 LYXERR(Debug::LATEX
, "Underline enabled. Font: " << to_utf8(stateText(0)));
834 if (bits_
.strikeout() == FONT_ON
) {
835 LYXERR(Debug::LATEX
, "font.strikeout: " << bits_
.strikeout());
836 features
.require("ulem");
837 LYXERR(Debug::LATEX
, "Strikeout enabled. Font: " << to_utf8(stateText(0)));
839 if (bits_
.uuline() == FONT_ON
) {
840 LYXERR(Debug::LATEX
, "font.uuline: " << bits_
.uuline());
841 features
.require("ulem");
842 LYXERR(Debug::LATEX
, "Double underline enabled. Font: " << to_utf8(stateText(0)));
844 if (bits_
.uwave() == FONT_ON
) {
845 LYXERR(Debug::LATEX
, "font.uwave: " << bits_
.uwave());
846 features
.require("ulem");
847 LYXERR(Debug::LATEX
, "Wavy underline enabled. Font: " << to_utf8(stateText(0)));
849 switch (bits_
.color()) {
853 // probably we should put here all interface colors used for
854 // font displaying! For now I just add this ones I know of (Jug)
856 case Color_notelabel
:
859 features
.require("color");
860 LYXERR(Debug::LATEX
, "Color enabled. Font: " << to_utf8(stateText(0)));
863 // FIXME: Do something for background and soul package?
865 if (lang_
->babel() != doc_language
->babel() &&
866 lang_
!= ignore_language
&&
867 lang_
!= latex_language
)
869 features
.useLanguage(lang_
);
870 LYXERR(Debug::LATEX
, "Found language " << lang_
->lang());
875 ostream
& operator<<(ostream
& os
, FontState fms
)
877 return os
<< int(fms
);
881 ostream
& operator<<(ostream
& os
, FontInfo
const & f
)
884 << " family " << f
.family()
885 << " series " << f
.series()
886 << " shape " << f
.shape()
887 << " size " << f
.size()
888 << " color " << f
.color()
889 // FIXME: uncomment this when we support background.
890 //<< " background " << f.background()
891 << " emph " << f
.emph()
892 << " underbar " << f
.underbar()
893 << " strikeout " << f
.strikeout()
894 << " uuline " << f
.uuline()
895 << " uwave " << f
.uwave()
896 << " noun " << f
.noun()
897 << " number " << f
.number();
901 ostream
& operator<<(ostream
& os
, Font
const & font
)
903 return os
<< font
.bits_
904 << " lang: " << (font
.lang_
? font
.lang_
->lang() : 0);