lyx_mirror/src/FontInfo.cpp

870 lines
22 KiB
C++
Raw Normal View History

/**
* \file src/FontInfo.cpp
* 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 "ColorSet.h"
#include "FontInfo.h"
#include "Lexer.h"
#include "LyXRC.h"
#include "support/convert.h"
#include "support/debug.h"
#include "support/docstring.h"
#include "support/gettext.h"
#include "support/lstrings.h"
#include "support/RefChanger.h"
2016-11-23 18:16:18 +00:00
#include <algorithm>
#include <ostream>
#include <sstream>
using namespace std;
using namespace lyx::support;
namespace lyx {
//
// Names for the GUI
//
char const * GUIFamilyNames[NUM_FAMILIES + 2 /* default & error */] =
{ N_("Roman"), N_("Sans Serif"), N_("Typewriter"), N_("Symbol"),
"cmr", "cmsy", "cmm", "cmex", "msa", "msb", "eufrak", "rsfs", "stmry",
"wasy", "esint", N_("Inherit"), N_("Ignore") };
char const * GUISeriesNames[NUM_SERIES + 2 /* default & error */] =
{ N_("Medium"), N_("Bold"), N_("Inherit"), N_("Ignore") };
char const * GUIShapeNames[NUM_SHAPE + 2 /* default & error */] =
{ N_("Upright"), N_("Italic"), N_("Slanted"), N_("Smallcaps"), N_("Inherit"),
N_("Ignore") };
char const * GUISizeNames[NUM_SIZE + 4 /* increase, decrease, default & error */] =
{ 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[NUM_FAMILIES + 2 /* default & error */] =
{ "roman", "sans", "typewriter", "symbol",
"cmr", "cmsy", "cmm", "cmex", "msa", "msb", "eufrak", "rsfs", "stmry",
"wasy", "esint", "default", "error" };
char const * LyXSeriesNames[NUM_SERIES + 2 /* default & error */] =
{ "medium", "bold", "default", "error" };
char const * LyXShapeNames[NUM_SHAPE + 2 /* default & error */] =
{ "up", "italic", "slanted", "smallcaps", "default", "error" };
char const * LyXSizeNames[NUM_SIZE + 4 /* increase, decrease, default & error */] =
{ "tiny", "scriptsize", "footnotesize", "small", "normal", "large",
"larger", "largest", "huge", "giant",
"increase", "decrease", "default", "error" };
char const * LyXMiscNames[5] =
{ "off", "on", "toggle", "default", "error" };
FontInfo const sane_font(
ROMAN_FAMILY,
MEDIUM_SERIES,
UP_SHAPE,
FONT_SIZE_NORMAL,
LM_ST_TEXT,
Color_none,
Color_background,
FONT_OFF,
FONT_OFF,
FONT_OFF,
FONT_OFF,
FONT_OFF,
FONT_OFF,
FONT_OFF,
FONT_OFF,
FONT_OFF);
FontInfo const inherit_font(
INHERIT_FAMILY,
INHERIT_SERIES,
INHERIT_SHAPE,
FONT_SIZE_INHERIT,
LM_ST_INHERIT,
Color_inherit,
Color_inherit,
FONT_INHERIT,
FONT_INHERIT,
FONT_INHERIT,
FONT_INHERIT,
FONT_INHERIT,
FONT_INHERIT,
FONT_INHERIT,
FONT_OFF,
FONT_INHERIT);
FontInfo const ignore_font(
IGNORE_FAMILY,
IGNORE_SERIES,
IGNORE_SHAPE,
FONT_SIZE_IGNORE,
LM_ST_IGNORE,
Color_ignore,
Color_ignore,
FONT_IGNORE,
FONT_IGNORE,
FONT_IGNORE,
FONT_IGNORE,
FONT_IGNORE,
FONT_IGNORE,
FONT_IGNORE,
FONT_IGNORE,
FONT_IGNORE);
FontInfo::FontInfo()
{
*this = sane_font;
}
/// Decreases font size_ by one
FontInfo & FontInfo::decSize()
{
switch (size_) {
case FONT_SIZE_HUGER: size_ = FONT_SIZE_HUGE; break;
case FONT_SIZE_HUGE: size_ = FONT_SIZE_LARGEST; break;
case FONT_SIZE_LARGEST: size_ = FONT_SIZE_LARGER; break;
case FONT_SIZE_LARGER: size_ = FONT_SIZE_LARGE; break;
case FONT_SIZE_LARGE: size_ = FONT_SIZE_NORMAL; break;
case FONT_SIZE_NORMAL: size_ = FONT_SIZE_SMALL; break;
case FONT_SIZE_SMALL: size_ = FONT_SIZE_FOOTNOTE; break;
case FONT_SIZE_FOOTNOTE: size_ = FONT_SIZE_SCRIPT; break;
case FONT_SIZE_SCRIPT: size_ = FONT_SIZE_TINY; break;
case FONT_SIZE_TINY: break;
case FONT_SIZE_INCREASE:
LYXERR0("Can't FontInfo::decSize on FONT_SIZE_INCREASE");
break;
case FONT_SIZE_DECREASE:
LYXERR0("Can't FontInfo::decSize on FONT_SIZE_DECREASE");
break;
case FONT_SIZE_INHERIT:
LYXERR0("Can't FontInfo::decSize on FONT_SIZE_INHERIT");
break;
case FONT_SIZE_IGNORE:
LYXERR0("Can't FontInfo::decSize on FONT_SIZE_IGNORE");
break;
}
return *this;
}
/// Increases font size_ by one
FontInfo & FontInfo::incSize()
{
switch (size_) {
case FONT_SIZE_HUGER: break;
case FONT_SIZE_HUGE: size_ = FONT_SIZE_HUGER; break;
case FONT_SIZE_LARGEST: size_ = FONT_SIZE_HUGE; break;
case FONT_SIZE_LARGER: size_ = FONT_SIZE_LARGEST; break;
case FONT_SIZE_LARGE: size_ = FONT_SIZE_LARGER; break;
case FONT_SIZE_NORMAL: size_ = FONT_SIZE_LARGE; break;
case FONT_SIZE_SMALL: size_ = FONT_SIZE_NORMAL; break;
case FONT_SIZE_FOOTNOTE: size_ = FONT_SIZE_SMALL; break;
case FONT_SIZE_SCRIPT: size_ = FONT_SIZE_FOOTNOTE; break;
case FONT_SIZE_TINY: size_ = FONT_SIZE_SCRIPT; break;
case FONT_SIZE_INCREASE:
LYXERR0("Can't FontInfo::incSize on FONT_SIZE_INCREASE");
break;
case FONT_SIZE_DECREASE:
LYXERR0("Can't FontInfo::incSize on FONT_SIZE_DECREASE");
break;
case FONT_SIZE_INHERIT:
LYXERR0("Can't FontInfo::incSize on FONT_SIZE_INHERIT");
break;
case FONT_SIZE_IGNORE:
LYXERR0("Can't FontInfo::incSize on FONT_SIZE_IGNORE");
break;
}
return *this;
}
double FontInfo::realSize() const
{
double d = convert<double>(lyxrc.font_sizes[size()]);
// The following is according to the average of the values in the
// definitions of \defaultscriptratio and \defaultscriptscriptratio in LaTeX
// font packages. No attempt is made to implement the actual values from
// \DefineMathSizes.
switch (style()) {
case LM_ST_DISPLAY:
case LM_ST_TEXT:
case LM_ST_INHERIT:
case LM_ST_IGNORE:
break;
case LM_ST_SCRIPT:
d *= .73;
break;
case LM_ST_SCRIPTSCRIPT:
d *= .55;
break;
}
// Never go below the smallest size
return max(d, convert<double>(lyxrc.font_sizes[FONT_SIZE_TINY]));
}
/// Reduce font to fall back to template where possible
void FontInfo::reduce(FontInfo const & tmplt)
{
if (family_ == tmplt.family_)
family_ = INHERIT_FAMILY;
if (series_ == tmplt.series_)
series_ = INHERIT_SERIES;
if (shape_ == tmplt.shape_)
shape_ = INHERIT_SHAPE;
if (size_ == tmplt.size_)
size_ = FONT_SIZE_INHERIT;
if (style_ == tmplt.style_)
style_ = LM_ST_INHERIT;
if (emph_ == tmplt.emph_)
emph_ = FONT_INHERIT;
if (underbar_ == tmplt.underbar_)
underbar_ = FONT_INHERIT;
if (strikeout_ == tmplt.strikeout_)
strikeout_ = FONT_INHERIT;
if (xout_ == tmplt.xout_)
xout_ = FONT_INHERIT;
if (uuline_ == tmplt.uuline_)
uuline_ = FONT_INHERIT;
if (uwave_ == tmplt.uwave_)
uwave_ = FONT_INHERIT;
if (noun_ == tmplt.noun_)
noun_ = FONT_INHERIT;
if (color_ == tmplt.color_)
color_ = Color_inherit;
if (background_ == tmplt.background_)
background_ = Color_inherit;
if (nospellcheck_ == tmplt.nospellcheck_)
2018-05-07 08:15:23 +00:00
nospellcheck_ = FONT_INHERIT;
}
/// Realize font from a template
FontInfo & FontInfo::realize(FontInfo const & tmplt)
{
if ((*this) == inherit_font) {
operator=(tmplt);
return *this;
}
if (family_ == INHERIT_FAMILY)
family_ = tmplt.family_;
if (series_ == INHERIT_SERIES)
series_ = tmplt.series_;
if (shape_ == INHERIT_SHAPE)
shape_ = tmplt.shape_;
if (size_ == FONT_SIZE_INHERIT)
size_ = tmplt.size_;
if (style_ == LM_ST_INHERIT)
style_ = tmplt.style_;
if (emph_ == FONT_INHERIT)
emph_ = tmplt.emph_;
if (underbar_ == FONT_INHERIT)
underbar_ = tmplt.underbar_;
if (strikeout_ == FONT_INHERIT)
strikeout_ = tmplt.strikeout_;
if (xout_ == FONT_INHERIT)
xout_ = tmplt.xout_;
if (uuline_ == FONT_INHERIT)
uuline_ = tmplt.uuline_;
if (uwave_ == FONT_INHERIT)
uwave_ = tmplt.uwave_;
if (noun_ == FONT_INHERIT)
noun_ = tmplt.noun_;
if (color_ == Color_inherit)
color_ = tmplt.color_;
if (background_ == Color_inherit)
background_ = tmplt.background_;
if (nospellcheck_ == FONT_INHERIT)
nospellcheck_ = tmplt.nospellcheck_;
return *this;
}
Changer FontInfo::changeColor(ColorCode const color)
{
return make_change(color_, color);
}
Changer FontInfo::changeShape(FontShape const shape)
{
return make_change(shape_, shape);
}
Changer FontInfo::changeStyle(MathStyle const new_style)
{
return make_change(style_, new_style);
}
Changer FontInfo::change(FontInfo font, bool realiz)
{
if (realiz)
font.realize(*this);
return make_change(*this, font);
}
/// Updates a misc setting according to request
static FontState setMisc(FontState newfont,
FontState org)
{
if (newfont == FONT_TOGGLE) {
if (org == FONT_ON)
return FONT_OFF;
else if (org == FONT_OFF)
return FONT_ON;
else {
LYXERR0("Font::setMisc: Need state"
" FONT_ON or FONT_OFF to toggle. Setting to FONT_ON");
return FONT_ON;
}
} else if (newfont == FONT_IGNORE)
return org;
else
return newfont;
}
/// Updates font settings according to request
void FontInfo::update(FontInfo const & newfont, 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)
shape_ = INHERIT_SHAPE; // toggle 'back'
else if (newfont.shape_ != IGNORE_SHAPE)
shape_ = newfont.shape_;
// else it's IGNORE_SHAPE
if (newfont.size_ != FONT_SIZE_IGNORE) {
if (newfont.size_ == FONT_SIZE_INCREASE)
incSize();
else if (newfont.size_ == FONT_SIZE_DECREASE)
decSize();
else
size_ = newfont.size_;
}
if (newfont.style_ != LM_ST_IGNORE) {
style_ = newfont.style_;
}
setEmph(setMisc(newfont.emph_, emph_));
setUnderbar(setMisc(newfont.underbar_, underbar_));
setStrikeout(setMisc(newfont.strikeout_, strikeout_));
setXout(setMisc(newfont.xout_, xout_));
setUuline(setMisc(newfont.uuline_, uuline_));
setUwave(setMisc(newfont.uwave_, uwave_));
setNoun(setMisc(newfont.noun_, noun_));
setNumber(setMisc(newfont.number_, number_));
setNoSpellcheck(setMisc(newfont.nospellcheck_, nospellcheck_));
if (newfont.color_ == color_ && toggleall)
setColor(Color_inherit); // toggle 'back'
else if (newfont.color_ != Color_ignore)
setColor(newfont.color_);
if (newfont.background_ == background_ && toggleall)
setBackground(Color_inherit); // toggle 'back'
else if (newfont.background_ != Color_ignore)
setBackground(newfont.background_);
}
/// Is font resolved?
bool FontInfo::resolved() const
{
return (family_ != INHERIT_FAMILY && series_ != INHERIT_SERIES
&& shape_ != INHERIT_SHAPE && size_ != FONT_SIZE_INHERIT
&& style_ != LM_ST_INHERIT
&& emph_ != FONT_INHERIT && underbar_ != FONT_INHERIT
&& uuline_ != FONT_INHERIT && uwave_ != FONT_INHERIT
&& strikeout_ != FONT_INHERIT && xout_ != FONT_INHERIT
&& noun_ != FONT_INHERIT && color_ != Color_inherit
&& background_ != Color_inherit && nospellcheck_ != FONT_INHERIT);
}
Color FontInfo::realColor() const
{
if (paint_color_ != Color_none)
return paint_color_;
if (color_ == Color_none)
return Color_foreground;
return color_;
}
namespace {
void appendSep(string & s1, string const & s2)
{
if (s2.empty())
return;
s1 += s1.empty() ? "" : "\n";
s1 += s2;
}
string makeCSSTag(string const & key, string const & val)
{
return key + ": " + val + ";";
}
string getFamilyCSS(FontFamily const & f)
{
switch (f) {
case ROMAN_FAMILY:
return "serif";
case SANS_FAMILY:
return "sans-serif";
case TYPEWRITER_FAMILY:
return "monospace";
case SYMBOL_FAMILY:
case CMR_FAMILY:
case CMSY_FAMILY:
case CMM_FAMILY:
case CMEX_FAMILY:
case MSA_FAMILY:
case MSB_FAMILY:
case EUFRAK_FAMILY:
case RSFS_FAMILY:
case STMARY_FAMILY:
case WASY_FAMILY:
case ESINT_FAMILY:
case INHERIT_FAMILY:
case IGNORE_FAMILY:
break;
}
return "";
}
string getSeriesCSS(FontSeries const & s)
{
switch (s) {
case MEDIUM_SERIES:
return "normal";
case BOLD_SERIES:
return "bold";
case INHERIT_SERIES:
case IGNORE_SERIES:
break;
}
return "";
}
string getShapeCSS(FontShape const & s)
{
string fs = "normal";
string fv = "normal";
switch (s) {
case UP_SHAPE: break;
case ITALIC_SHAPE: fs = "italic"; break;
case SLANTED_SHAPE: fs = "oblique"; break;
case SMALLCAPS_SHAPE: fv = "small-caps"; break;
case IGNORE_SHAPE:
case INHERIT_SHAPE:
fs = ""; fv = ""; break;
}
string retval;
if (!fs.empty())
appendSep(retval, makeCSSTag("font-style", fs));
if (!fv.empty())
appendSep(retval, makeCSSTag("font-variant", fv));
return retval;
}
string getSizeCSS(FontSize const & s)
{
switch (s) {
case FONT_SIZE_TINY:
return "xx-small";
case FONT_SIZE_SCRIPT:
return "x-small";
case FONT_SIZE_FOOTNOTE:
case FONT_SIZE_SMALL:
return "small";
case FONT_SIZE_NORMAL:
return "medium";
case FONT_SIZE_LARGE:
return "large";
case FONT_SIZE_LARGER:
case FONT_SIZE_LARGEST:
return "x-large";
case FONT_SIZE_HUGE:
case FONT_SIZE_HUGER:
return "xx-large";
case FONT_SIZE_INCREASE:
return "larger";
case FONT_SIZE_DECREASE:
return "smaller";
case FONT_SIZE_IGNORE:
case FONT_SIZE_INHERIT:
break;
}
return "";
}
2017-07-03 17:53:14 +00:00
Bulk cleanup/fix incorrect annotation at the end of namespaces. This commit does a bulk fix of incorrect annotations (comments) at the end of namespaces. The commit was generated by initially running clang-format, and then from the diff of the result extracting the hunks corresponding to fixes of namespace comments. The changes being applied and all the results have been manually reviewed. The source code successfully builds on macOS. Further details on the steps below, in case they're of interest to someone else in the future. 1. Checkout a fresh and up to date version of src/ git pull && git checkout -- src && git status src 2. Ensure there's a suitable .clang-format in place, i.e. with options to fix the comment at the end of namespaces, including: FixNamespaceComments: true SpacesBeforeTrailingComments: 1 and that clang-format is >= 5.0.0, by doing e.g.: clang-format -dump-config | grep Comments: clang-format --version 3. Apply clang-format to the source: clang-format -i $(find src -name "*.cpp" -or -name "*.h") 4. Create and filter out hunks related to fixing the namespace git diff -U0 src > tmp.patch grepdiff '^} // namespace' --output-matching=hunk tmp.patch > fix_namespace.patch 5. Filter out hunks corresponding to simple fixes into to a separate patch: pcregrep -M -e '^diff[^\n]+\nindex[^\n]+\n--- [^\n]+\n\+\+\+ [^\n]+\n' \ -e '^@@ -[0-9]+ \+[0-9]+ @@[^\n]*\n-\}[^\n]*\n\+\}[^\n]*\n' \ fix_namespace.patch > fix_namespace_simple.patch 6. Manually review the simple patch and then apply it, after first restoring the source. git checkout -- src patch -p1 < fix_namespace_simple.path 7. Manually review the (simple) changes and then stage the changes git diff src git add src 8. Again apply clang-format and filter out hunks related to any remaining fixes to the namespace, this time filter with more context. There will be fewer hunks as all the simple cases have already been handled: clang-format -i $(find src -name "*.cpp" -or -name "*.h") git diff src > tmp.patch grepdiff '^} // namespace' --output-matching=hunk tmp.patch > fix_namespace2.patch 9. Manually review/edit the resulting patch file to remove hunks for files which need to be dealt with manually, noting the file names and line numbers. Then restore files to as before applying clang-format and apply the patch: git checkout src patch -p1 < fix_namespace2.patch 10. Manually fix the files noted in the previous step. Stage files, review changes and commit.
2017-07-23 11:11:54 +00:00
} // namespace
// FIXME This does not yet handle color
2017-07-03 17:53:14 +00:00
docstring FontInfo::asCSS() const
{
string retval;
string tmp = getFamilyCSS(family_);
if (!tmp.empty())
appendSep(retval, makeCSSTag("font-family", tmp));
tmp = getSeriesCSS(series_);
if (!tmp.empty())
appendSep(retval, makeCSSTag("font-weight", tmp));
appendSep(retval, getShapeCSS(shape_));
tmp = getSizeCSS(size_);
if (!tmp.empty())
appendSep(retval, makeCSSTag("font-size", tmp));
2017-07-03 17:53:14 +00:00
return from_ascii(retval);
}
docstring const FontInfo::stateText(bool const terse) const
{
odocstringstream os;
if (family() != INHERIT_FAMILY && (!terse || family() != IGNORE_FAMILY))
os << _(GUIFamilyNames[family()]) << ", ";
if (series() != INHERIT_SERIES && (!terse || series() != IGNORE_SERIES))
os << _(GUISeriesNames[series()]) << ", ";
if (shape() != INHERIT_SHAPE && (!terse || shape() != IGNORE_SHAPE))
os << _(GUIShapeNames[shape()]) << ", ";
if (size() != FONT_SIZE_INHERIT && (!terse || size() != FONT_SIZE_IGNORE))
os << _(GUISizeNames[size()]) << ", ";
// FIXME: shall style be handled there? Probably not.
if (color() != Color_inherit && (!terse || color() != Color_ignore))
os << lcolor.getGUIName(color()) << ", ";
// FIXME: uncomment this when we support background.
//if (background() != Color_inherit)
// os << lcolor.getGUIName(background()) << ", ";
if (emph() != FONT_INHERIT && (!terse || emph() != FONT_IGNORE))
os << bformat(_("Emphasis %1$s, "),
_(GUIMiscNames[emph()]));
if (underbar() != FONT_INHERIT && (!terse || underbar() == FONT_ON))
os << bformat(_("Underline %1$s, "),
_(GUIMiscNames[underbar()]));
if (uuline() != FONT_INHERIT && (!terse || uuline() == FONT_ON))
os << bformat(_("Double underline %1$s, "),
_(GUIMiscNames[uuline()]));
if (uwave() != FONT_INHERIT && (!terse || uwave() == FONT_ON))
os << bformat(_("Wavy underline %1$s, "),
_(GUIMiscNames[uwave()]));
if (strikeout() != FONT_INHERIT && (!terse || strikeout() == FONT_ON))
os << bformat(_("Strike out %1$s, "),
_(GUIMiscNames[strikeout()]));
if (xout() != FONT_INHERIT && (!terse || xout() == FONT_ON))
os << bformat(_("Cross out %1$s, "),
_(GUIMiscNames[xout()]));
if (noun() != FONT_INHERIT && (!terse || noun() != FONT_IGNORE))
os << bformat(_("Noun %1$s, "),
_(GUIMiscNames[noun()]));
if (*this == inherit_font)
os << _("Default") << ", ";
return os.str();
}
// Set family according to lyx format string
void setLyXFamily(string const & fam, FontInfo & f)
{
string const s = ascii_lowercase(fam);
int i = 0;
while (LyXFamilyNames[i] != s &&
LyXFamilyNames[i] != string("error"))
++i;
if (s == LyXFamilyNames[i])
f.setFamily(FontFamily(i));
else
LYXERR0("Unknown family `" << s << '\'');
}
// Set series according to lyx format string
void setLyXSeries(string const & ser, FontInfo & f)
{
string const s = ascii_lowercase(ser);
int i = 0;
while (LyXSeriesNames[i] != s &&
LyXSeriesNames[i] != string("error")) ++i;
if (s == LyXSeriesNames[i]) {
f.setSeries(FontSeries(i));
} else
LYXERR0("Unknown series `" << s << '\'');
}
// Set shape according to lyx format string
void setLyXShape(string const & sha, FontInfo & f)
{
string const s = ascii_lowercase(sha);
int i = 0;
while (LyXShapeNames[i] != s && LyXShapeNames[i] != string("error"))
++i;
if (s == LyXShapeNames[i])
f.setShape(FontShape(i));
else
LYXERR0("Unknown shape `" << s << '\'');
}
// Set size according to lyx format string
void setLyXSize(string const & siz, FontInfo & f)
{
string const s = ascii_lowercase(siz);
int i = 0;
while (LyXSizeNames[i] != s && LyXSizeNames[i] != string("error"))
++i;
if (s == LyXSizeNames[i]) {
f.setSize(FontSize(i));
} else
LYXERR0("Unknown size `" << s << '\'');
}
// Set size according to lyx format string
FontState 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 FontState(i);
LYXERR0("Unknown misc flag `" << s << '\'');
return FONT_OFF;
}
/// Sets color after LyX text format
void setLyXColor(string const & col, FontInfo & f)
{
f.setColor(lcolor.getFromLyXName(col));
}
// Read a font definition from given file in lyx format
// Used for layouts
FontInfo lyxRead(Lexer & lex, FontInfo const & fi)
{
FontInfo f = fi;
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, f);
} else if (tok == "series") {
lex.next();
string const ttok = lex.getString();
setLyXSeries(ttok, f);
} else if (tok == "shape") {
lex.next();
string const ttok = lex.getString();
setLyXShape(ttok, f);
} else if (tok == "size") {
lex.next();
string const ttok = lex.getString();
setLyXSize(ttok, f);
} else if (tok == "misc") {
lex.next();
string const ttok = ascii_lowercase(lex.getString());
if (ttok == "no_bar") {
f.setUnderbar(FONT_OFF);
} else if (ttok == "no_strikeout") {
f.setStrikeout(FONT_OFF);
} else if (ttok == "no_xout") {
f.setXout(FONT_OFF);
} else if (ttok == "no_uuline") {
f.setUuline(FONT_OFF);
} else if (ttok == "no_uwave") {
f.setUwave(FONT_OFF);
} else if (ttok == "no_emph") {
f.setEmph(FONT_OFF);
} else if (ttok == "no_noun") {
f.setNoun(FONT_OFF);
} else if (ttok == "emph") {
f.setEmph(FONT_ON);
} else if (ttok == "underbar") {
f.setUnderbar(FONT_ON);
} else if (ttok == "strikeout") {
f.setStrikeout(FONT_ON);
} else if (ttok == "xout") {
f.setXout(FONT_ON);
} else if (ttok == "uuline") {
f.setUuline(FONT_ON);
} else if (ttok == "uwave") {
f.setUwave(FONT_ON);
} else if (ttok == "noun") {
f.setNoun(FONT_ON);
} else if (ttok == "nospellcheck") {
f.setNoSpellcheck(FONT_ON);
} else if (ttok == "no_nospellcheck") {
f.setNoSpellcheck(FONT_OFF);
} else {
lex.printError("Illegal misc type");
}
} else if (tok == "color") {
lex.next();
string const ttok = lex.getString();
setLyXColor(ttok, f);
} else {
lex.printError("Unknown tag");
error = true;
}
}
return f;
}
void lyxWrite(ostream & os, FontInfo const & f, string const & start, int level)
{
string indent;
for (int i = 0; i < level; ++i)
indent += '\t';
ostringstream oss;
if (f.family() != INHERIT_FAMILY)
oss << indent << "\tFamily " << LyXFamilyNames[f.family()]
<< '\n';
if (f.series() != INHERIT_SERIES)
oss << indent << "\tSeries " << LyXSeriesNames[f.series()]
<< '\n';
if (f.shape() != INHERIT_SHAPE)
oss << indent << "\tShape " << LyXShapeNames[f.shape()]
<< '\n';
if (f.size() != FONT_SIZE_INHERIT)
oss << indent << "\tSize " << LyXSizeNames[f.size()]
<< '\n';
//FIXME: shall style be handled here? Probably not.
if (f.underbar() == FONT_ON)
oss << indent << "\tMisc Underbar\n";
else if (f.underbar() == FONT_OFF)
oss << indent << "\tMisc No_Bar\n";
if (f.strikeout() == FONT_ON)
oss << indent << "\tMisc Strikeout\n";
else if (f.strikeout() == FONT_OFF)
oss << indent << "\tMisc No_Strikeout\n";
if (f.xout() == FONT_ON)
oss << indent << "\tMisc Xout\n";
else if (f.xout() == FONT_OFF)
oss << indent << "\tMisc No_Xout\n";
if (f.uuline() == FONT_ON)
oss << indent << "\tMisc Uuline\n";
else if (f.uuline() == FONT_OFF)
oss << indent << "\tMisc No_Uuline\n";
if (f.uwave() == FONT_ON)
oss << indent << "\tMisc Uwave\n";
else if (f.uwave() == FONT_OFF)
oss << indent << "\tMisc No_Uwave\n";
if (f.emph() == FONT_ON)
oss << indent << "\tMisc Emph\n";
else if (f.emph() == FONT_OFF)
oss << indent << "\tMisc No_Emph\n";
if (f.noun() == FONT_ON)
oss << indent << "\tMisc Noun\n";
else if (f.noun() == FONT_OFF)
oss << indent << "\tMisc No_Noun\n";
if (f.nospellcheck() == FONT_ON)
oss << indent << "\tMisc NoSpellcheck\n";
else if (f.nospellcheck() == FONT_OFF)
oss << indent << "\tMisc No_NoSpellcheck\n";
if (f.color() != Color_inherit && f.color() != Color_none)
oss << indent << "\tColor " << lcolor.getLyXName(f.color())
<< '\n';
if (!oss.str().empty()) {
os << indent << start << '\n'
<< oss.str()
<< indent << "EndFont\n";
}
}
} // namespace lyx