lyx_mirror/src/lyxfont.C
Georg Baum bcb1654b15 Make the output of \inputencoding commands (and the change of output
encodings) more fine grained: From paragraph level to individual character
level. The inputenc package supports that since at least 2000.

	* src/insets/insetbase.h
	(latex): Document the differences between output to a string stream
	and a file stream

	* src/buffer.h
	(writeLaTeXSource): ditto

	* src/output_latex.h
	(latexParagraphs): ditto
	(switchEncoding): new function to change the encoding of a stream
	(and output \inputencoding commands)

	* src/paragraph_pimpl.C
	(Paragraph::Pimpl::simpleTeXSpecialC): Adjust to latexWriteEndChanges
	changes

	* src/support/docstream.[Ch]
	(setEncoding, operator<<): New stream modifier that changes the
	encoding of file streams

	* src/lyxfont.[Ch]
	(LyXFont::latexWriteStartChanges): Change stream encoding if needed
	(LyXFont::latexWriteEndChanges): Change stream encoding if needed

	* src/lyxfont.h
	(public:):

	* src/paragraph.C
	(Paragraph::simpleTeXOnePar): Adjust to latexWriteStartChanges and latexWriteEndChanges changes
	(bool Paragraph::simpleTeXOnePar):
	(bool Paragraph::simpleTeXOnePar):
	(bool Paragraph::simpleTeXOnePar):
	(bool Paragraph::simpleTeXOnePar):
	(bool Paragraph::simpleTeXOnePar):

	* src/output_latex.C
	(TeXOnePar): Remove the ugly hack to for wencoding changes and use
	switchEncoding instead. A nice side effect is that the old hack would
	not work if the main language encoding is latin1 and a character
	would be mapped to a cedilla in the "fake ucs4" encoding, because
	iconv refuses to convert such a character to latin1, although it
	exists in latin1 (it wants to attach it to a base character).


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@16633 a592a061-630c-0410-9148-cb99ea01b6c8
2007-01-09 19:25:40 +00:00

942 lines
22 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* \file src/lyxfont.C
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Lars Gullik Bjønnes
* \author Jean-Marc Lasgouttes
* \author Angus Leeming
* \author André Pönitz
* \author Dekel Tsur
*
* Full author contact details are available in file CREDITS.
*/
#include <config.h>
#include "lyxfont.h"
#include "bufferparams.h" // stateText
#include "debug.h"
#include "gettext.h"
#include "language.h"
#include "LColor.h"
#include "lyxlex.h"
#include "lyxrc.h"
#include "output_latex.h"
#include "support/lstrings.h"
namespace lyx {
using support::ascii_lowercase;
using support::bformat;
using support::rtrim;
using support::subst;
using std::endl;
using std::string;
using std::ostream;
#ifndef CXX_GLOBAL_CSTD
using std::strlen;
#endif
//
// Names for the GUI
//
namespace {
char const * GUIFamilyNames[LyXFont::NUM_FAMILIES + 2 /* default & error */] =
{ N_("Roman"), N_("Sans Serif"), N_("Typewriter"), N_("Symbol"),
"cmr", "cmsy", "cmm", "cmex", "msa", "msb", "eufrak", "wasy", "esint",
N_("Inherit"), N_("Ignore") };
char const * GUISeriesNames[4] =
{ N_("Medium"), N_("Bold"), N_("Inherit"), N_("Ignore") };
char const * GUIShapeNames[6] =
{ N_("Upright"), N_("Italic"), N_("Slanted"), N_("Smallcaps"), N_("Inherit"),
N_("Ignore") };
char const * GUISizeNames[14] =
{ N_("Tiny"), N_("Smallest"), N_("Smaller"), N_("Small"), N_("Normal"), N_("Large"),
N_("Larger"), N_("Largest"), N_("Huge"), N_("Huger"), N_("Increase"), N_("Decrease"),
N_("Inherit"), N_("Ignore") };
char const * GUIMiscNames[5] =
{ N_("Off"), N_("On"), N_("Toggle"), N_("Inherit"), N_("Ignore") };
//
// Strings used to read and write .lyx format files
//
char const * LyXFamilyNames[LyXFont::NUM_FAMILIES + 2 /* default & error */] =
{ "roman", "sans", "typewriter", "symbol",
"cmr", "cmsy", "cmm", "cmex", "msa", "msb", "eufrak", "wasy", "esint",
"default", "error" };
char const * LyXSeriesNames[4] =
{ "medium", "bold", "default", "error" };
char const * LyXShapeNames[6] =
{ "up", "italic", "slanted", "smallcaps", "default", "error" };
char const * LyXSizeNames[14] =
{ "tiny", "scriptsize", "footnotesize", "small", "normal", "large",
"larger", "largest", "huge", "giant",
"increase", "decrease", "default", "error" };
char const * LyXMiscNames[5] =
{ "off", "on", "toggle", "default", "error" };
//
// Strings used to write LaTeX files
//
char const * LaTeXFamilyNames[6] =
{ "textrm", "textsf", "texttt", "error1", "error2", "error3" };
char const * LaTeXSeriesNames[4] =
{ "textmd", "textbf", "error4", "error5" };
char const * LaTeXShapeNames[6] =
{ "textup", "textit", "textsl", "textsc", "error6", "error7" };
char const * LaTeXSizeNames[14] =
{ "tiny", "scriptsize", "footnotesize", "small", "normalsize", "large",
"Large", "LARGE", "huge", "Huge", "error8", "error9", "error10", "error11" };
} // namespace anon
// Initialize static member
LyXFont::FontBits LyXFont::sane = {
ROMAN_FAMILY,
MEDIUM_SERIES,
UP_SHAPE,
SIZE_NORMAL,
LColor::none,
OFF,
OFF,
OFF,
OFF };
// Initialize static member
LyXFont::FontBits LyXFont::inherit = {
INHERIT_FAMILY,
INHERIT_SERIES,
INHERIT_SHAPE,
INHERIT_SIZE,
LColor::inherit,
INHERIT,
INHERIT,
INHERIT,
OFF };
// Initialize static member
LyXFont::FontBits LyXFont::ignore = {
IGNORE_FAMILY,
IGNORE_SERIES,
IGNORE_SHAPE,
IGNORE_SIZE,
LColor::ignore,
IGNORE,
IGNORE,
IGNORE,
IGNORE };
bool operator==(LyXFont::FontBits const & lhs,
LyXFont::FontBits const & rhs)
{
return lhs.family == rhs.family &&
lhs.series == rhs.series &&
lhs.shape == rhs.shape &&
lhs.size == rhs.size &&
lhs.color == rhs.color &&
lhs.emph == rhs.emph &&
lhs.underbar == rhs.underbar &&
lhs.noun == rhs.noun &&
lhs.number == rhs.number;
}
LyXFont::LyXFont()
: bits(sane), lang(default_language)
{}
LyXFont::LyXFont(LyXFont::FONT_INIT1)
: bits(inherit), lang(default_language)
{}
LyXFont::LyXFont(LyXFont::FONT_INIT2)
: bits(ignore), lang(ignore_language)
{}
LyXFont::LyXFont(LyXFont::FONT_INIT3)
: bits(sane), lang(default_language)
{}
LyXFont::LyXFont(LyXFont::FONT_INIT1, Language const * l)
: bits(inherit), lang(l)
{}
LyXFont::LyXFont(LyXFont::FONT_INIT2, Language const * l)
: bits(ignore), lang(l)
{}
LyXFont::LyXFont(LyXFont::FONT_INIT3, Language const * l)
: bits(sane), lang(l)
{}
LColor_color LyXFont::color() const
{
return LColor::color(bits.color);
}
bool LyXFont::isRightToLeft() const
{
return lang->rightToLeft();
}
bool LyXFont::isVisibleRightToLeft() const
{
return (lang->rightToLeft() &&
number() != ON);
}
void LyXFont::setFamily(LyXFont::FONT_FAMILY f)
{
bits.family = f;
}
void LyXFont::setSeries(LyXFont::FONT_SERIES s)
{
bits.series = s;
}
void LyXFont::setShape(LyXFont::FONT_SHAPE s)
{
bits.shape = s;
}
void LyXFont::setSize(LyXFont::FONT_SIZE s)
{
bits.size = s;
}
void LyXFont::setEmph(LyXFont::FONT_MISC_STATE e)
{
bits.emph = e;
}
void LyXFont::setUnderbar(LyXFont::FONT_MISC_STATE u)
{
bits.underbar = u;
}
void LyXFont::setNoun(LyXFont::FONT_MISC_STATE n)
{
bits.noun = n;
}
void LyXFont::setColor(LColor_color c)
{
bits.color = int(c);
}
void LyXFont::setLanguage(Language const * l)
{
lang = l;
}
void LyXFont::setNumber(LyXFont::FONT_MISC_STATE n)
{
bits.number = n;
}
/// Decreases font size by one
LyXFont & LyXFont::decSize()
{
switch (size()) {
case SIZE_HUGER: setSize(SIZE_HUGE); break;
case SIZE_HUGE: setSize(SIZE_LARGEST); break;
case SIZE_LARGEST: setSize(SIZE_LARGER); break;
case SIZE_LARGER: setSize(SIZE_LARGE); break;
case SIZE_LARGE: setSize(SIZE_NORMAL); break;
case SIZE_NORMAL: setSize(SIZE_SMALL); break;
case SIZE_SMALL: setSize(SIZE_FOOTNOTE); break;
case SIZE_FOOTNOTE: setSize(SIZE_SCRIPT); break;
case SIZE_SCRIPT: setSize(SIZE_TINY); break;
case SIZE_TINY: break;
case INCREASE_SIZE:
lyxerr << "Can't LyXFont::decSize on INCREASE_SIZE" << endl;
break;
case DECREASE_SIZE:
lyxerr <<"Can't LyXFont::decSize on DECREASE_SIZE" << endl;
break;
case INHERIT_SIZE:
lyxerr <<"Can't LyXFont::decSize on INHERIT_SIZE" << endl;
break;
case IGNORE_SIZE:
lyxerr <<"Can't LyXFont::decSize on IGNORE_SIZE" << endl;
break;
}
return *this;
}
/// Increases font size by one
LyXFont & LyXFont::incSize()
{
switch (size()) {
case SIZE_HUGER: break;
case SIZE_HUGE: setSize(SIZE_HUGER); break;
case SIZE_LARGEST: setSize(SIZE_HUGE); break;
case SIZE_LARGER: setSize(SIZE_LARGEST); break;
case SIZE_LARGE: setSize(SIZE_LARGER); break;
case SIZE_NORMAL: setSize(SIZE_LARGE); break;
case SIZE_SMALL: setSize(SIZE_NORMAL); break;
case SIZE_FOOTNOTE: setSize(SIZE_SMALL); break;
case SIZE_SCRIPT: setSize(SIZE_FOOTNOTE); break;
case SIZE_TINY: setSize(SIZE_SCRIPT); break;
case INCREASE_SIZE:
lyxerr <<"Can't LyXFont::incSize on INCREASE_SIZE" << endl;
break;
case DECREASE_SIZE:
lyxerr <<"Can't LyXFont::incSize on DECREASE_SIZE" << endl;
break;
case INHERIT_SIZE:
lyxerr <<"Can't LyXFont::incSize on INHERIT_SIZE" << endl;
break;
case IGNORE_SIZE:
lyxerr <<"Can't LyXFont::incSize on IGNORE_SIZE" << endl;
break;
}
return *this;
}
/// Updates a misc setting according to request
LyXFont::FONT_MISC_STATE LyXFont::setMisc(FONT_MISC_STATE newfont,
FONT_MISC_STATE org)
{
if (newfont == TOGGLE) {
if (org == ON)
return OFF;
else if (org == OFF)
return ON;
else {
lyxerr <<"LyXFont::setMisc: Need state"
" ON or OFF to toggle. Setting to ON" << endl;
return ON;
}
} else if (newfont == IGNORE)
return org;
else
return newfont;
}
/// Updates font settings according to request
void LyXFont::update(LyXFont const & newfont,
Language const * document_language,
bool toggleall)
{
if (newfont.family() == family() && toggleall)
setFamily(INHERIT_FAMILY); // toggle 'back'
else if (newfont.family() != IGNORE_FAMILY)
setFamily(newfont.family());
// else it's IGNORE_SHAPE
// "Old" behaviour: "Setting" bold will toggle bold on/off.
switch (newfont.series()) {
case BOLD_SERIES:
// We toggle...
if (series() == BOLD_SERIES && toggleall)
setSeries(MEDIUM_SERIES);
else
setSeries(BOLD_SERIES);
break;
case MEDIUM_SERIES:
case INHERIT_SERIES:
setSeries(newfont.series());
break;
case IGNORE_SERIES:
break;
}
if (newfont.shape() == shape() && toggleall)
setShape(INHERIT_SHAPE); // toggle 'back'
else if (newfont.shape() != IGNORE_SHAPE)
setShape(newfont.shape());
// else it's IGNORE_SHAPE
if (newfont.size() != IGNORE_SIZE) {
if (newfont.size() == INCREASE_SIZE)
incSize();
else if (newfont.size() == DECREASE_SIZE)
decSize();
else
setSize(newfont.size());
}
setEmph(setMisc(newfont.emph(), emph()));
setUnderbar(setMisc(newfont.underbar(), underbar()));
setNoun(setMisc(newfont.noun(), noun()));
setNumber(setMisc(newfont.number(), number()));
if (newfont.language() == language() && toggleall)
if (language() == document_language)
setLanguage(default_language);
else
setLanguage(document_language);
else if (newfont.language() != ignore_language)
setLanguage(newfont.language());
if (newfont.color() == color() && toggleall)
setColor(LColor::inherit); // toggle 'back'
else if (newfont.color() != LColor::ignore)
setColor(newfont.color());
}
/// Reduce font to fall back to template where possible
void LyXFont::reduce(LyXFont const & tmplt)
{
if (family() == tmplt.family())
setFamily(INHERIT_FAMILY);
if (series() == tmplt.series())
setSeries(INHERIT_SERIES);
if (shape() == tmplt.shape())
setShape(INHERIT_SHAPE);
if (size() == tmplt.size())
setSize(INHERIT_SIZE);
if (emph() == tmplt.emph())
setEmph(INHERIT);
if (underbar() == tmplt.underbar())
setUnderbar(INHERIT);
if (noun() == tmplt.noun())
setNoun(INHERIT);
if (color() == tmplt.color())
setColor(LColor::inherit);
}
/// Realize font from a template
LyXFont & LyXFont::realize(LyXFont const & tmplt)
{
if (bits == inherit) {
bits = tmplt.bits;
return *this;
}
if (bits.family == INHERIT_FAMILY)
bits.family = tmplt.bits.family;
if (bits.series == INHERIT_SERIES)
bits.series = tmplt.bits.series;
if (bits.shape == INHERIT_SHAPE)
bits.shape = tmplt.bits.shape;
if (bits.size == INHERIT_SIZE)
bits.size = tmplt.bits.size;
if (bits.emph == INHERIT)
bits.emph = tmplt.bits.emph;
if (bits.underbar == INHERIT)
bits.underbar = tmplt.bits.underbar;
if (bits.noun == INHERIT)
bits.noun = tmplt.bits.noun;
if (bits.color == LColor::inherit)
bits.color = tmplt.bits.color;
return *this;
}
/// Is font resolved?
bool LyXFont::resolved() const
{
return (family() != INHERIT_FAMILY && series() != INHERIT_SERIES &&
shape() != INHERIT_SHAPE && size() != INHERIT_SIZE &&
emph() != INHERIT && underbar() != INHERIT &&
noun() != INHERIT &&
color() != LColor::inherit);
}
docstring const LyXFont::stateText(BufferParams * params) const
{
odocstringstream os;
if (family() != INHERIT_FAMILY)
os << _(GUIFamilyNames[family()]) << ", ";
if (series() != INHERIT_SERIES)
os << _(GUISeriesNames[series()]) << ", ";
if (shape() != INHERIT_SHAPE)
os << _(GUIShapeNames[shape()]) << ", ";
if (size() != INHERIT_SIZE)
os << _(GUISizeNames[size()]) << ", ";
if (color() != LColor::inherit)
os << lcolor.getGUIName(color()) << ", ";
if (emph() != INHERIT)
os << bformat(_("Emphasis %1$s, "),
_(GUIMiscNames[emph()]));
if (underbar() != INHERIT)
os << bformat(_("Underline %1$s, "),
_(GUIMiscNames[underbar()]));
if (noun() != INHERIT)
os << bformat(_("Noun %1$s, "),
_(GUIMiscNames[noun()]));
if (bits == inherit)
os << _("Default") << ", ";
if (!params || (language() != params->language))
os << bformat(_("Language: %1$s, "),
_(language()->display()));
if (number() != OFF)
os << bformat(_(" Number %1$s"),
_(GUIMiscNames[number()]));
return rtrim(os.str(), ", ");
}
// Set family according to lyx format string
LyXFont & LyXFont::setLyXFamily(string const & fam)
{
string const s = ascii_lowercase(fam);
int i = 0;
while (LyXFamilyNames[i] != s &&
LyXFamilyNames[i] != string("error"))
++i;
if (s == LyXFamilyNames[i])
setFamily(LyXFont::FONT_FAMILY(i));
else
lyxerr << "LyXFont::setLyXFamily: Unknown family `"
<< s << '\'' << endl;
return *this;
}
// Set series according to lyx format string
LyXFont & LyXFont::setLyXSeries(string const & ser)
{
string const s = ascii_lowercase(ser);
int i = 0;
while (LyXSeriesNames[i] != s &&
LyXSeriesNames[i] != string("error")) ++i;
if (s == LyXSeriesNames[i]) {
setSeries(LyXFont::FONT_SERIES(i));
} else
lyxerr << "LyXFont::setLyXSeries: Unknown series `"
<< s << '\'' << endl;
return *this;
}
// Set shape according to lyx format string
LyXFont & LyXFont::setLyXShape(string const & sha)
{
string const s = ascii_lowercase(sha);
int i = 0;
while (LyXShapeNames[i] != s && LyXShapeNames[i] != string("error"))
++i;
if (s == LyXShapeNames[i])
setShape(LyXFont::FONT_SHAPE(i));
else
lyxerr << "LyXFont::setLyXShape: Unknown shape `"
<< s << '\'' << endl;
return *this;
}
// Set size according to lyx format string
LyXFont & LyXFont::setLyXSize(string const & siz)
{
string const s = ascii_lowercase(siz);
int i = 0;
while (LyXSizeNames[i] != s && LyXSizeNames[i] != string("error"))
++i;
if (s == LyXSizeNames[i]) {
setSize(LyXFont::FONT_SIZE(i));
} else
lyxerr << "LyXFont::setLyXSize: Unknown size `"
<< s << '\'' << endl;
return *this;
}
// Set size according to lyx format string
LyXFont::FONT_MISC_STATE LyXFont::setLyXMisc(string const & siz)
{
string const s = ascii_lowercase(siz);
int i = 0;
while (LyXMiscNames[i] != s &&
LyXMiscNames[i] != string("error")) ++i;
if (s == LyXMiscNames[i])
return FONT_MISC_STATE(i);
lyxerr << "LyXFont::setLyXMisc: Unknown misc flag `"
<< s << '\'' << endl;
return OFF;
}
/// Sets color after LyX text format
LyXFont & LyXFont::setLyXColor(string const & col)
{
setColor(lcolor.getFromLyXName(col));
return *this;
}
// Returns size in latex format
string const LyXFont::latexSize() const
{
return LaTeXSizeNames[size()];
}
// Read a font definition from given file in lyx format
// Used for layouts
LyXFont & LyXFont::lyxRead(LyXLex & lex)
{
bool error = false;
bool finished = false;
while (!finished && lex.isOK() && !error) {
lex.next();
string const tok = ascii_lowercase(lex.getString());
if (tok.empty()) {
continue;
} else if (tok == "endfont") {
finished = true;
} else if (tok == "family") {
lex.next();
string const ttok = lex.getString();
setLyXFamily(ttok);
} else if (tok == "series") {
lex.next();
string const ttok = lex.getString();
setLyXSeries(ttok);
} else if (tok == "shape") {
lex.next();
string const ttok = lex.getString();
setLyXShape(ttok);
} else if (tok == "size") {
lex.next();
string const ttok = lex.getString();
setLyXSize(ttok);
} else if (tok == "misc") {
lex.next();
string const ttok = ascii_lowercase(lex.getString());
if (ttok == "no_bar") {
setUnderbar(OFF);
} else if (ttok == "no_emph") {
setEmph(OFF);
} else if (ttok == "no_noun") {
setNoun(OFF);
} else if (ttok == "emph") {
setEmph(ON);
} else if (ttok == "underbar") {
setUnderbar(ON);
} else if (ttok == "noun") {
setNoun(ON);
} else {
lex.printError("Illegal misc type `$$Token´");
}
} else if (tok == "color") {
lex.next();
string const ttok = lex.getString();
setLyXColor(ttok);
} else {
lex.printError("Unknown tag `$$Token'");
error = true;
}
}
return *this;
}
/// Writes the changes from this font to orgfont in .lyx format in file
void LyXFont::lyxWriteChanges(LyXFont const & orgfont,
ostream & os) const
{
os << "\n";
if (orgfont.family() != family())
os << "\\family " << LyXFamilyNames[family()] << "\n";
if (orgfont.series() != series())
os << "\\series " << LyXSeriesNames[series()] << "\n";
if (orgfont.shape() != shape())
os << "\\shape " << LyXShapeNames[shape()] << "\n";
if (orgfont.size() != size())
os << "\\size " << LyXSizeNames[size()] << "\n";
if (orgfont.emph() != emph())
os << "\\emph " << LyXMiscNames[emph()] << "\n";
if (orgfont.number() != number())
os << "\\numeric " << LyXMiscNames[number()] << "\n";
if (orgfont.underbar() != underbar()) {
// This is only for backwards compatibility
switch (underbar()) {
case OFF: os << "\\bar no\n"; break;
case ON: os << "\\bar under\n"; break;
case TOGGLE: lyxerr << "LyXFont::lyxWriteFontChanges: "
"TOGGLE should not appear here!"
<< endl;
break;
case INHERIT: os << "\\bar default\n"; break;
case IGNORE: lyxerr << "LyXFont::lyxWriteFontChanges: "
"IGNORE should not appear here!"
<< endl;
break;
}
}
if (orgfont.noun() != noun()) {
os << "\\noun " << LyXMiscNames[noun()] << "\n";
}
if (orgfont.color() != color())
os << "\\color " << lcolor.getLyXName(color()) << '\n';
if (orgfont.language() != language() &&
language() != latex_language) {
if (language())
os << "\\lang " << language()->lang() << "\n";
else
os << "\\lang unknown\n";
}
}
/// Writes the head of the LaTeX needed to impose this font
// Returns number of chars written.
int LyXFont::latexWriteStartChanges(odocstream & os, LyXFont const & base,
LyXFont const & prev,
BufferParams const & bparams) const
{
bool env = false;
int count = switchEncoding(os, bparams, *(prev.language()->encoding()),
*(language()->encoding()));
if (language()->babel() != base.language()->babel() &&
language() != prev.language()) {
if (isRightToLeft() != prev.isRightToLeft()) {
if (isRightToLeft()) {
os << "\\R{";
count += 3;
} else {
os << "\\L{";
count += 3;
}
} else {
string const tmp =
subst(lyxrc.language_command_local,
"$$lang", language()->babel());
os << from_ascii(tmp);
count += tmp.length();
}
}
if (number() == ON && prev.number() != ON &&
language()->lang() == "hebrew") {
os << "{\\beginL ";
count += 9;
}
LyXFont f = *this;
f.reduce(base);
if (f.family() != INHERIT_FAMILY) {
os << '\\'
<< LaTeXFamilyNames[f.family()]
<< '{';
count += strlen(LaTeXFamilyNames[f.family()]) + 2;
env = true; //We have opened a new environment
}
if (f.series() != INHERIT_SERIES) {
os << '\\'
<< LaTeXSeriesNames[f.series()]
<< '{';
count += strlen(LaTeXSeriesNames[f.series()]) + 2;
env = true; //We have opened a new environment
}
if (f.shape() != INHERIT_SHAPE) {
os << '\\'
<< LaTeXShapeNames[f.shape()]
<< '{';
count += strlen(LaTeXShapeNames[f.shape()]) + 2;
env = true; //We have opened a new environment
}
if (f.color() != LColor::inherit && f.color() != LColor::ignore) {
os << "\\textcolor{"
<< from_ascii(lcolor.getLaTeXName(f.color()))
<< "}{";
count += lcolor.getLaTeXName(f.color()).length() + 13;
env = true; //We have opened a new environment
}
if (f.emph() == ON) {
os << "\\emph{";
count += 6;
env = true; //We have opened a new environment
}
if (f.underbar() == ON) {
os << "\\underbar{";
count += 10;
env = true; //We have opened a new environment
}
// \noun{} is a LyX special macro
if (f.noun() == ON) {
os << "\\noun{";
count += 6;
env = true; //We have opened a new environment
}
if (f.size() != INHERIT_SIZE) {
// If we didn't open an environment above, we open one here
if (!env) {
os << '{';
++count;
}
os << '\\'
<< LaTeXSizeNames[f.size()]
<< ' ';
count += strlen(LaTeXSizeNames[f.size()]) + 2;
}
return count;
}
/// Writes ending block of LaTeX needed to close use of this font
// Returns number of chars written
// This one corresponds to latexWriteStartChanges(). (Asger)
int LyXFont::latexWriteEndChanges(odocstream & os, LyXFont const & base,
LyXFont const & next,
BufferParams const & bparams) const
{
int count = 0;
bool env = false;
// reduce the current font to changes against the base
// font (of the layout). We use a temporary for this to
// avoid changing this font instance, as that would break
LyXFont f = *this;
f.reduce(base);
if (f.family() != INHERIT_FAMILY) {
os << '}';
++count;
env = true; // Size change need not bother about closing env.
}
if (f.series() != INHERIT_SERIES) {
os << '}';
++count;
env = true; // Size change need not bother about closing env.
}
if (f.shape() != INHERIT_SHAPE) {
os << '}';
++count;
env = true; // Size change need not bother about closing env.
}
if (f.color() != LColor::inherit && f.color() != LColor::ignore) {
os << '}';
++count;
env = true; // Size change need not bother about closing env.
}
if (f.emph() == ON) {
os << '}';
++count;
env = true; // Size change need not bother about closing env.
}
if (f.underbar() == ON) {
os << '}';
++count;
env = true; // Size change need not bother about closing env.
}
if (f.noun() == ON) {
os << '}';
++count;
env = true; // Size change need not bother about closing env.
}
if (f.size() != INHERIT_SIZE) {
// We only have to close if only size changed
if (!env) {
os << '}';
++count;
}
}
if (number() == ON && next.number() != ON &&
language()->lang() == "hebrew") {
os << "\\endL}";
count += 6;
}
if (language() != base.language() && language() != next.language()) {
os << '}';
++count;
}
count += switchEncoding(os, bparams, *(language()->encoding()),
*(next.language()->encoding()));
return count;
}
LColor_color LyXFont::realColor() const
{
if (color() == LColor::none)
return LColor::foreground;
return color();
}
ostream & operator<<(ostream & os, LyXFont::FONT_MISC_STATE fms)
{
return os << int(fms);
}
std::ostream & operator<<(std::ostream & os, LyXFont const & font)
{
return os << "font:"
<< " family " << font.bits.family
<< " series " << font.bits.series
<< " shape " << font.bits.shape
<< " size " << font.bits.size
<< " color " << font.bits.color
<< " emph " << font.bits.emph
<< " underbar " << font.bits.underbar
<< " noun " << font.bits.noun
<< " number " << font.bits.number
<< " lang: " << (font.lang ? font.lang->lang() : 0);
}
} // namespace lyx