Implement support for font options

This revives a patch by Uwe and extends it. Additional options to font
packages/fontspec can now be entered in Document Settings.
This is principally also true for TeX fonts, if the new TeXFont tag
MoreOptions is set. For the time being, I have only done this for
MinionPro, as a model and prove of concept.

Note that adding more TeXFonts requires a file format change,
respectively, and changes to tex2lyx (in the same way as I've done for
MinionPro).

This addresses #8226
This commit is contained in:
Juergen Spitzmueller 2019-07-11 20:28:34 +02:00
parent 9ca2f90bf5
commit c3c2815092
14 changed files with 757 additions and 331 deletions

View File

@ -7,6 +7,14 @@ changes happened in particular if possible. A good example would be
-----------------------
2019-07-11 Uwe Stöhr <uwestoehr@web.de>
Jürgen Spitzmüller <spitz@lyx.org>
* Format incremented to 580: support for document font options
New buffer parameters
- \fonts_roman_opts
- \fonts_sans_opts
- \fonts_typewriter_opts
2019-07-11 Jürgen Spitzmüller <spitz@lyx.org>
* Format incremented to 579: Add support for \babelfont.

View File

@ -22,6 +22,7 @@
# ScOption <option for true smallcaps support>
# OsfScOption <option for combined osf and true smallcaps support>
# ScaleOption <option for font scaling>
# MoreOptions <0|1>
# Provides <features provided by the font packages (comma-separated)>
# Preamble
# <some arbitrary LaTeX code to be issued in the preamble>
@ -70,6 +71,8 @@
# default and provide an option for lining figures. Pass this option
# to OsfOption.
# * ScaleOption supports the placeholder $$val for the scale value.
# * If MoreOptions is true, then the user can insert additional options to
# the font package via the Document Settings.
# * The Preamble code is output immediately after the respective font
# loading command.
#
@ -342,6 +345,7 @@ Font minionpro
Package MinionPro
Provides amssymb,amsfonts
NoMathFont minionpro-nomath
MoreOptions 1
EndFont
AltFont minionpro-nomath

View File

@ -2282,6 +2282,169 @@ def revert_babelfont(document):
insert_to_preamble(document, pretext)
def revert_minionpro(document):
" Revert native MinionPro font definition (with extra options) to LaTeX "
i = find_token(document.header, '\\use_non_tex_fonts', 0)
if i == -1:
document.warning("Malformed LyX document: Missing \\use_non_tex_fonts.")
return
if str2bool(get_value(document.header, "\\use_non_tex_fonts", i)):
return
regexp = re.compile(r'(\\font_roman_opts)')
i = find_re(document.header, regexp, 0)
if i == -1:
return
# We need to use this regex since split() does not handle quote protection
romanopts = re.findall(r'[^"\s]\S*|".+?"', document.header[i])
opts = romanopts[1].strip('"')
del document.header[i]
i = find_token(document.header, "\\font_roman", 0)
if i == -1:
document.warning("Malformed LyX document: Missing \\font_roman.")
return
else:
# We need to use this regex since split() does not handle quote protection
romanfont = re.findall(r'[^"\s]\S*|".+?"', document.header[i])
roman = romanfont[1].strip('"')
if roman != "minionpro":
return
romanfont[1] = '"default"'
document.header[i] = " ".join(romanfont)
osf = False
j = find_token(document.header, "\\font_osf true", 0)
if j != -1:
osf = True
preamble = "\\usepackage["
if osf:
document.header[j] = "\\font_osf false"
else:
preamble += "lf,"
preamble += opts
preamble += "]{MinionPro}"
add_to_preamble(document, [preamble])
def revert_font_opts(document):
" revert font options by outputting \\setxxxfont or \\babelfont to the preamble "
i = find_token(document.header, '\\use_non_tex_fonts', 0)
if i == -1:
document.warning("Malformed LyX document: Missing \\use_non_tex_fonts.")
return
if not str2bool(get_value(document.header, "\\use_non_tex_fonts", i)):
return
i = find_token(document.header, '\\language_package', 0)
if i == -1:
document.warning("Malformed LyX document: Missing \\language_package.")
return
Babel = (get_value(document.header, "\\language_package", 0) == "babel")
# 1. Roman
regexp = re.compile(r'(\\font_roman_opts)')
i = find_re(document.header, regexp, 0)
if i != -1:
# We need to use this regex since split() does not handle quote protection
romanopts = re.findall(r'[^"\s]\S*|".+?"', document.header[i])
opts = romanopts[1].strip('"')
del document.header[i]
regexp = re.compile(r'(\\font_roman)')
i = find_re(document.header, regexp, 0)
if i != -1:
# We need to use this regex since split() does not handle quote protection
romanfont = re.findall(r'[^"\s]\S*|".+?"', document.header[i])
font = romanfont[2].strip('"')
romanfont[2] = '"default"'
document.header[i] = " ".join(romanfont)
if font != "default":
if Babel:
preamble = "\\babelfont{rm}["
else:
preamble = "\\setmainfont["
preamble += opts
preamble += ","
preamble += "Mapping=tex-text]{"
preamble += font
preamble += "}"
add_to_preamble(document, [preamble])
# 2. Sans
regexp = re.compile(r'(\\font_sans_opts)')
i = find_re(document.header, regexp, 0)
if i != -1:
scaleval = 100
# We need to use this regex since split() does not handle quote protection
sfopts = re.findall(r'[^"\s]\S*|".+?"', document.header[i])
opts = sfopts[1].strip('"')
del document.header[i]
regexp = re.compile(r'(\\font_sf_scale)')
i = find_re(document.header, regexp, 0)
if i != -1:
scaleval = get_value(document.header, "\\font_sf_scale" , i).split()[1]
regexp = re.compile(r'(\\font_sans)')
i = find_re(document.header, regexp, 0)
if i != -1:
# We need to use this regex since split() does not handle quote protection
sffont = re.findall(r'[^"\s]\S*|".+?"', document.header[i])
font = sffont[2].strip('"')
sffont[2] = '"default"'
document.header[i] = " ".join(sffont)
if font != "default":
if Babel:
preamble = "\\babelfont{sf}["
else:
preamble = "\\setsansfont["
preamble += opts
preamble += ","
if scaleval != 100:
preamble += "Scale=0."
preamble += scaleval
preamble += ","
preamble += "Mapping=tex-text]{"
preamble += font
preamble += "}"
add_to_preamble(document, [preamble])
# 3. Typewriter
regexp = re.compile(r'(\\font_typewriter_opts)')
i = find_re(document.header, regexp, 0)
if i != -1:
scaleval = 100
# We need to use this regex since split() does not handle quote protection
ttopts = re.findall(r'[^"\s]\S*|".+?"', document.header[i])
opts = ttopts[1].strip('"')
del document.header[i]
regexp = re.compile(r'(\\font_tt_scale)')
i = find_re(document.header, regexp, 0)
if i != -1:
scaleval = get_value(document.header, "\\font_tt_scale" , i).split()[1]
regexp = re.compile(r'(\\font_typewriter)')
i = find_re(document.header, regexp, 0)
if i != -1:
# We need to use this regex since split() does not handle quote protection
ttfont = re.findall(r'[^"\s]\S*|".+?"', document.header[i])
font = ttfont[2].strip('"')
ttfont[2] = '"default"'
document.header[i] = " ".join(ttfont)
if font != "default":
if Babel:
preamble = "\\babelfont{tt}["
else:
preamble = "\\setmonofont["
preamble += opts
preamble += ","
if scaleval != 100:
preamble += "Scale=0."
preamble += scaleval
preamble += ","
preamble += "Mapping=tex-text]{"
preamble += font
preamble += "}"
add_to_preamble(document, [preamble])
##
# Conversion hub
@ -2323,10 +2486,12 @@ convert = [
[576, []],
[577, [convert_linggloss]],
[578, []],
[579, []]
[579, []],
[580, []]
]
revert = [[578, [revert_babelfont]],
revert = [[579, [revert_font_opts, revert_minionpro]],
[578, [revert_babelfont]],
[577, [revert_drs]],
[576, [revert_linggloss, revert_subexarg]],
[575, [revert_new_languages]],

View File

@ -926,6 +926,9 @@ int Buffer::readHeader(Lexer & lex)
params().headsep.erase();
params().footskip.erase();
params().columnsep.erase();
params().font_roman_opts.erase();
params().font_sans_opts.erase();
params().font_typewriter_opts.erase();
params().fonts_cjk.erase();
params().listings_params.clear();
params().clearLayoutModules();

View File

@ -846,12 +846,18 @@ string BufferParams::readToken(Lexer & lex, string const & token,
lex >> fonts_expert_sc;
} else if (token == "\\font_osf") {
lex >> fonts_old_figures;
} else if (token == "\\font_roman_opts") {
lex >> font_roman_opts;
} else if (token == "\\font_sf_scale") {
lex >> fonts_sans_scale[0];
lex >> fonts_sans_scale[1];
} else if (token == "\\font_sans_opts") {
lex >> font_sans_opts;
} else if (token == "\\font_tt_scale") {
lex >> fonts_typewriter_scale[0];
lex >> fonts_typewriter_scale[1];
} else if (token == "\\font_typewriter_opts") {
lex >> font_typewriter_opts;
} else if (token == "\\font_cjk") {
lex >> fonts_cjk;
} else if (token == "\\use_microtype") {
@ -1263,15 +1269,20 @@ void BufferParams::writeFile(ostream & os, Buffer const * buf) const
<< "\n\\font_default_family " << fonts_default_family
<< "\n\\use_non_tex_fonts " << convert<string>(useNonTeXFonts)
<< "\n\\font_sc " << convert<string>(fonts_expert_sc)
<< "\n\\font_osf " << convert<string>(fonts_old_figures)
<< "\n\\font_sf_scale " << fonts_sans_scale[0]
<< ' ' << fonts_sans_scale[1]
<< "\n\\font_tt_scale " << fonts_typewriter_scale[0]
<< ' ' << fonts_typewriter_scale[1]
<< '\n';
if (!fonts_cjk.empty()) {
<< "\n\\font_osf " << convert<string>(fonts_old_figures);
if (!font_roman_opts.empty())
os << "\n\\font_roman_opts \"" << font_roman_opts << "\"";
os << "\n\\font_sf_scale " << fonts_sans_scale[0]
<< ' ' << fonts_sans_scale[1];
if (!font_sans_opts.empty())
os << "\n\\font_sans_opts \"" << font_sans_opts << "\"";
os << "\n\\font_tt_scale " << fonts_typewriter_scale[0]
<< ' ' << fonts_typewriter_scale[1];
if (!font_typewriter_opts.empty())
os << "\n\\font_typewriter_opts \"" << font_typewriter_opts << "\"";
os << '\n';
if (!fonts_cjk.empty())
os << "\\font_cjk " << fonts_cjk << '\n';
}
os << "\\use_microtype " << convert<string>(use_microtype) << '\n';
os << "\\use_dash_ligatures " << convert<string>(use_dash_ligatures) << '\n';
os << "\\graphics " << graphics_driver << '\n';
@ -3408,6 +3419,8 @@ string const BufferParams::loadFonts(LaTeXFeatures & features) const
os << "\\babelfont{rm}[";
else
os << "\\setmainfont[";
if (!font_roman_opts.empty())
os << font_roman_opts << ',';
os << texmapping;
if (fonts_old_figures)
os << ",Numbers=OldStyle";
@ -3421,14 +3434,18 @@ string const BufferParams::loadFonts(LaTeXFeatures & features) const
else
os << "\\setsansfont";
os << "[Scale="
<< float(fontsSansScale()) / 100
<< "," << texmapping << "]{"
<< float(fontsSansScale()) / 100 << ',';
if (!font_sans_opts.empty())
os << font_sans_opts << ',';
os << texmapping << "]{"
<< sans << "}\n";
} else {
if (babel)
os << "\\babelfont{sf}[";
else
os << "\\setsansfont[";
if (!font_sans_opts.empty())
os << font_sans_opts << ',';
os << texmapping << "]{"
<< sans << "}\n";
}
@ -3441,15 +3458,19 @@ string const BufferParams::loadFonts(LaTeXFeatures & features) const
else
os << "\\setmonofont";
os << "[Scale="
<< float(fontsTypewriterScale()) / 100
<< "]{"
<< float(fontsTypewriterScale()) / 100;
if (!font_typewriter_opts.empty())
os << ',' << font_typewriter_opts;
os << "]{"
<< mono << "}\n";
} else {
if (babel)
os << "\\babelfont{tt}{";
os << "\\babelfont{tt}";
else
os << "\\setmonofont{";
os << mono << "}\n";
os << "\\setmonofont";
if (!font_typewriter_opts.empty())
os << '[' << font_typewriter_opts << ']';
os << '{' << mono << "}\n";
}
}
return os.str();
@ -3464,17 +3485,17 @@ string const BufferParams::loadFonts(LaTeXFeatures & features) const
// ROMAN FONTS
os << theLaTeXFonts().getLaTeXFont(from_ascii(fontsRoman())).getLaTeXCode(
dryrun, ot1, complete, fonts_expert_sc, fonts_old_figures,
nomath);
nomath, font_roman_opts);
// SANS SERIF
os << theLaTeXFonts().getLaTeXFont(from_ascii(fontsSans())).getLaTeXCode(
dryrun, ot1, complete, fonts_expert_sc, fonts_old_figures,
nomath, fontsSansScale());
nomath, font_roman_opts, fontsSansScale());
// MONOSPACED/TYPEWRITER
os << theLaTeXFonts().getLaTeXFont(from_ascii(fontsTypewriter())).getLaTeXCode(
dryrun, ot1, complete, fonts_expert_sc, fonts_old_figures,
nomath, fontsTypewriterScale());
nomath, font_roman_opts, fontsTypewriterScale());
// MATH
os << theLaTeXFonts().getLaTeXFont(from_ascii(fontsMath())).getLaTeXCode(

View File

@ -285,14 +285,20 @@ public:
bool fonts_expert_sc;
/// use Old Style Figures
bool fonts_old_figures;
/// the options for the roman font
std::string font_roman_opts;
/// the scale factor of the sf font: [0] for TeX fonts, [1] for non-TeX fonts
int fonts_sans_scale[2];
/// the scale factor of the sf font
int fontsSansScale() const { return fonts_sans_scale[useNonTeXFonts]; }
// the options for the sans font
std::string font_sans_opts;
/// the scale factor of the tt font: [0] for TeX fonts, [1] for non-TeX fonts
int fonts_typewriter_scale[2];
/// the scale factor of the tt font
int fontsTypewriterScale() const { return fonts_typewriter_scale[useNonTeXFonts]; }
// the options for the typewriter font
std::string font_typewriter_opts;
/// the font used by the CJK command
std::string fonts_cjk;
/// use LaTeX microtype package

View File

@ -228,7 +228,7 @@ string const LaTeXFont::getAvailablePackage(bool dryrun)
string const LaTeXFont::getPackageOptions(bool ot1, bool complete, bool sc, bool osf,
int scale, bool nomath)
int scale, string const extraopts, bool nomath)
{
ostringstream os;
bool const needosfopt = (osf != osfdefault_);
@ -263,12 +263,19 @@ string const LaTeXFont::getPackageOptions(bool ot1, bool complete, bool sc, bool
os << subst(to_ascii(scaleoption_), "$$val",
convert<std::string>(float(scale) / 100));
}
if (moreopts_ && !extraopts.empty()) {
if (!os.str().empty())
os << ',';
os << extraopts;
}
return os.str();
}
string const LaTeXFont::getLaTeXCode(bool dryrun, bool ot1, bool complete, bool sc,
bool osf, bool nomath, int const & scale)
bool osf, bool nomath, string const extraopts,
int const & scale)
{
ostringstream os;
@ -276,7 +283,8 @@ string const LaTeXFont::getLaTeXCode(bool dryrun, bool ot1, bool complete, bool
if (usedfont.empty())
return string();
else if (usedfont != name_)
return altFont(usedfont).getLaTeXCode(dryrun, ot1, complete, sc, osf, nomath, scale);
return altFont(usedfont).getLaTeXCode(dryrun, ot1, complete, sc,
osf, nomath, extraopts, scale);
if (switchdefault_) {
if (family_.empty()) {
@ -294,14 +302,15 @@ string const LaTeXFont::getLaTeXCode(bool dryrun, bool ot1, bool complete, bool
} else {
string const package =
getAvailablePackage(dryrun);
string const packageopts = getPackageOptions(ot1, complete, sc, osf, scale, nomath);
string const packageopts = getPackageOptions(ot1, complete, sc, osf, scale, extraopts, nomath);
if (packageopts.empty() && !package.empty())
os << "\\usepackage{" << package << "}\n";
else if (!packageopts.empty() && !package.empty())
os << "\\usepackage[" << packageopts << "]{" << package << "}\n";
}
if (osf && providesOSF(ot1, complete, nomath) && !osffont_.empty())
os << altFont(osffont_).getLaTeXCode(dryrun, ot1, complete, sc, osf, nomath, scale);
os << altFont(osffont_).getLaTeXCode(dryrun, ot1, complete, sc, osf,
nomath, extraopts, scale);
if (!preamble_.empty())
os << to_utf8(preamble_);
@ -335,6 +344,7 @@ bool LaTeXFont::readFont(Lexer & lex)
LF_OSFOPTION,
LF_OSFSCOPTION,
LF_OT1_FONT,
LF_MOREOPTS,
LF_PACKAGE,
LF_PACKAGEOPTION,
LF_PREAMBLE,
@ -353,6 +363,7 @@ bool LaTeXFont::readFont(Lexer & lex)
{ "family", LF_FAMILY },
{ "fontencoding", LF_FONTENC },
{ "guiname", LF_GUINAME },
{ "moreoptions", LF_MOREOPTS },
{ "nomathfont", LF_NOMATHFONT },
{ "osfdefault", LF_OSFDEFAULT },
{ "osffont", LF_OSFFONT },
@ -455,6 +466,9 @@ bool LaTeXFont::readFont(Lexer & lex)
case LF_SCOPTION:
lex >> scoption_;
break;
case LF_MOREOPTS:
lex >> moreopts_;
break;
case LF_SWITCHDEFAULT:
lex >> switchdefault_;
break;
@ -473,6 +487,7 @@ bool LaTeXFont::read(Lexer & lex)
{
switchdefault_ = 0;
osfdefault_ = 0;
moreopts_ = 0;
if (!lex.next()) {
lex.printError("No name given for LaTeX font: `$$Token'.");

View File

@ -27,7 +27,7 @@ class LaTeXFont {
public:
/// TeX font
// FIXME Add fontenc tag to classes which is used if no font is specified?
LaTeXFont() : osfdefault_(false), switchdefault_(false) { fontenc_.push_back("T1"); }
LaTeXFont() : osfdefault_(false), switchdefault_(false), moreopts_(false) { fontenc_.push_back("T1"); }
/// The font name
docstring const & name() { return name_; }
/// The name to appear in the document dialog
@ -58,6 +58,8 @@ public:
docstring const & osfscoption() { return osfscoption_; }
/// A package option for font scaling
docstring const & scaleoption() { return scaleoption_; }
/// Does this provide additional options?
bool moreoptions() const { return moreopts_; }
/// Alternative requirement to test for
docstring const & requires() { return requires_; }
/// Does this font provide a given \p feature
@ -84,6 +86,7 @@ public:
/// Return the LaTeX Code
std::string const getLaTeXCode(bool dryrun, bool ot1, bool complete,
bool sc, bool osf, bool nomath,
std::string const extraopts = std::string(),
int const & scale = 100);
/// Return the actually used font
docstring const getUsedFont(bool ot1, bool complete, bool nomath);
@ -102,6 +105,7 @@ private:
bool sc,
bool osf,
int scale,
std::string const extraopts,
bool nomath);
/// Return an alternative font
LaTeXFont altFont(docstring const & name);
@ -145,6 +149,8 @@ private:
bool osfdefault_;
///
bool switchdefault_;
///
bool moreopts_;
};

View File

@ -1090,11 +1090,23 @@ GuiDocument::GuiDocument(GuiView & lv)
this, SLOT(change_adaptor()));
connect(fontModule->fontOsfCB, SIGNAL(toggled(bool)),
this, SLOT(fontOsfToggled(bool)));
connect(fontModule->fontspecRomanLE, SIGNAL(textChanged(const QString &)),
this, SLOT(change_adaptor()));
connect(fontModule->fontspecSansLE, SIGNAL(textChanged(const QString &)),
this, SLOT(change_adaptor()));
connect(fontModule->fontspecTypewriterLE, SIGNAL(textChanged(const QString &)),
this, SLOT(change_adaptor()));
fontModule->fontencLE->setValidator(new NoNewLineValidator(
fontModule->fontencLE));
fontModule->cjkFontLE->setValidator(new NoNewLineValidator(
fontModule->cjkFontLE));
fontModule->fontspecRomanLE->setValidator(new NoNewLineValidator(
fontModule->fontspecRomanLE));
fontModule->fontspecSansLE->setValidator(new NoNewLineValidator(
fontModule->fontspecSansLE));
fontModule->fontspecTypewriterLE->setValidator(new NoNewLineValidator(
fontModule->fontspecTypewriterLE));
updateFontlist();
@ -2419,16 +2431,22 @@ void GuiDocument::updateFontOptions()
{
bool const tex_fonts = !fontModule->osFontsCB->isChecked();
QString font;
if (tex_fonts)
font = fontModule->fontsRomanCO->itemData(
fontModule->fontsRomanCO->currentIndex()).toString();
bool const rm_opts = providesExtraOpts(font);
if (tex_fonts)
font = fontModule->fontsSansCO->itemData(
fontModule->fontsSansCO->currentIndex()).toString();
bool scaleable = providesScale(font);
bool const sf_opts = providesExtraOpts(font);
fontModule->scaleSansSB->setEnabled(scaleable);
fontModule->scaleSansLA->setEnabled(scaleable);
if (tex_fonts)
font = fontModule->fontsTypewriterCO->itemData(
fontModule->fontsTypewriterCO->currentIndex()).toString();
scaleable = providesScale(font);
bool const tt_opts = providesExtraOpts(font);
fontModule->scaleTypewriterSB->setEnabled(scaleable);
fontModule->scaleTypewriterLA->setEnabled(scaleable);
if (tex_fonts)
@ -2436,6 +2454,12 @@ void GuiDocument::updateFontOptions()
fontModule->fontsRomanCO->currentIndex()).toString();
fontModule->fontScCB->setEnabled(providesSC(font));
fontModule->fontOsfCB->setEnabled(providesOSF(font));
fontModule->fontspecRomanLA->setEnabled(!tex_fonts || rm_opts);
fontModule->fontspecRomanLE->setEnabled(!tex_fonts || rm_opts);
fontModule->fontspecSansLA->setEnabled(!tex_fonts || sf_opts);
fontModule->fontspecSansLE->setEnabled(!tex_fonts || sf_opts);
fontModule->fontspecTypewriterLA->setEnabled(!tex_fonts || tt_opts);
fontModule->fontspecTypewriterLE->setEnabled(!tex_fonts || tt_opts);
updateMathFonts(font);
}
@ -2613,8 +2637,11 @@ void GuiDocument::romanChanged(int item)
return;
QString const font =
fontModule->fontsRomanCO->itemData(item).toString();
bool const opts = providesExtraOpts(font);
fontModule->fontScCB->setEnabled(providesSC(font));
fontModule->fontOsfCB->setEnabled(providesOSF(font));
fontModule->fontspecRomanLA->setEnabled(opts);
fontModule->fontspecRomanLE->setEnabled(opts);
updateMathFonts(font);
}
@ -2625,9 +2652,12 @@ void GuiDocument::sansChanged(int item)
return;
QString const font =
fontModule->fontsSansCO->itemData(item).toString();
bool scaleable = providesScale(font);
bool const scaleable = providesScale(font);
bool const opts = providesExtraOpts(font);
fontModule->scaleSansSB->setEnabled(scaleable);
fontModule->scaleSansLA->setEnabled(scaleable);
fontModule->fontspecSansLA->setEnabled(opts);
fontModule->fontspecSansLE->setEnabled(opts);
}
@ -2638,8 +2668,11 @@ void GuiDocument::ttChanged(int item)
QString const font =
fontModule->fontsTypewriterCO->itemData(item).toString();
bool scaleable = providesScale(font);
bool const opts = providesExtraOpts(font);
fontModule->scaleTypewriterSB->setEnabled(scaleable);
fontModule->scaleTypewriterLA->setEnabled(scaleable);
fontModule->fontspecTypewriterLA->setEnabled(opts);
fontModule->fontspecTypewriterLE->setEnabled(opts);
}
@ -3630,16 +3663,19 @@ void GuiDocument::applyView()
fromqstr(fontModule->fontsRomanCO->
itemData(fontModule->fontsRomanCO->currentIndex()).toString());
bp_.fonts_roman[!nontexfonts] = fromqstr(fontModule->font_roman);
bp_.font_roman_opts = fromqstr(fontModule->fontspecRomanLE->text());
bp_.fonts_sans[nontexfonts] =
fromqstr(fontModule->fontsSansCO->
itemData(fontModule->fontsSansCO->currentIndex()).toString());
bp_.fonts_sans[!nontexfonts] = fromqstr(fontModule->font_sans);
bp_.font_sans_opts = fromqstr(fontModule->fontspecSansLE->text());
bp_.fonts_typewriter[nontexfonts] =
fromqstr(fontModule->fontsTypewriterCO->
itemData(fontModule->fontsTypewriterCO->currentIndex()).toString());
bp_.fonts_typewriter[!nontexfonts] = fromqstr(fontModule->font_typewriter);
bp_.font_typewriter_opts = fromqstr(fontModule->fontspecTypewriterLE->text());
bp_.fonts_math[nontexfonts] =
fromqstr(fontModule->fontsMathCO->
@ -4188,6 +4224,21 @@ void GuiDocument::paramsToDialog()
fontModule->font_sf_scale = bp_.fonts_sans_scale[!bp_.useNonTeXFonts];
fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale());
fontModule->font_tt_scale = bp_.fonts_typewriter_scale[!bp_.useNonTeXFonts];
if (!bp_.font_roman_opts.empty())
fontModule->fontspecRomanLE->setText(
toqstr(bp_.font_roman_opts));
else
fontModule->fontspecRomanLE->setText(QString());
if (!bp_.font_sans_opts.empty())
fontModule->fontspecSansLE->setText(
toqstr(bp_.font_sans_opts));
else
fontModule->fontspecSansLE->setText(QString());
if (!bp_.font_typewriter_opts.empty())
fontModule->fontspecTypewriterLE->setText(
toqstr(bp_.font_typewriter_opts));
else
fontModule->fontspecTypewriterLE->setText(QString());
nn = findToken(GuiDocument::fontfamilies, bp_.fonts_default_family);
if (nn >= 0)
@ -4901,6 +4952,15 @@ bool GuiDocument::providesScale(QString const & font) const
}
bool GuiDocument::providesExtraOpts(QString const & font) const
{
if (fontModule->osFontsCB->isChecked())
return true;
return theLaTeXFonts().getLaTeXFont(
qstring_to_ucs4(font)).moreoptions();
}
bool GuiDocument::providesNoMath(QString const & font) const
{
if (fontModule->osFontsCB->isChecked())

View File

@ -289,6 +289,8 @@ private:
bool hasMonolithicExpertSet(QString const & font) const;
/// does this font provide size adjustment?
bool providesScale(QString const & font) const;
/// does this font provide extra options?
bool providesExtraOpts(QString const & font) const;
/// does this font provide an alternative without math?
bool providesNoMath(QString const & font) const;
///

View File

@ -6,15 +6,15 @@
<rect>
<x>0</x>
<y>0</y>
<width>533</width>
<height>447</height>
<width>534</width>
<height>632</height>
</rect>
</property>
<property name="windowTitle">
<string>FontUi</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QCheckBox" name="osFontsCB">
<property name="toolTip">
<string>Use OpenType and TrueType fonts with the fontspec package (requires XeTeX or LuaTeX)</string>
@ -24,7 +24,9 @@
</property>
</widget>
</item>
<item row="1" column="0">
<item row="1" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="fontsDefaultLA">
<property name="text">
<string>&amp;Default family:</string>
@ -34,7 +36,7 @@
</property>
</widget>
</item>
<item row="1" column="1">
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QComboBox" name="fontsDefaultCO">
@ -75,7 +77,7 @@
</item>
</layout>
</item>
<item row="2" column="0">
<item row="1" column="0">
<widget class="QLabel" name="fontencLA">
<property name="text">
<string>&amp;LaTeX font encoding:</string>
@ -85,7 +87,7 @@
</property>
</widget>
</item>
<item row="2" column="1">
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QComboBox" name="fontencCO"/>
@ -99,7 +101,7 @@
</item>
</layout>
</item>
<item row="3" column="0">
<item row="2" column="0">
<widget class="QLabel" name="fontsRomanLA">
<property name="text">
<string>&amp;Roman:</string>
@ -109,13 +111,34 @@
</property>
</widget>
</item>
<item row="3" column="1">
<item row="2" column="1">
<widget class="QComboBox" name="fontsRomanCO">
<property name="toolTip">
<string>Select the roman (serif) typeface</string>
</property>
</widget>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLabel" name="fontspecRomanLA">
<property name="text">
<string>Options:</string>
</property>
<property name="buddy">
<cstring>fontspecRomanLE</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="fontspecRomanLE">
<property name="toolTip">
<string>Here you can insert additional options (as provided by the font package)</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="0">
<widget class="QLabel" name="fontsSansLA">
<property name="text">
@ -127,7 +150,7 @@
</widget>
</item>
<item row="4" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QComboBox" name="fontsSansCO">
<property name="toolTip">
@ -173,7 +196,28 @@
</item>
</layout>
</item>
<item row="5" column="0">
<item row="5" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="fontspecSansLA">
<property name="text">
<string>Options:</string>
</property>
<property name="buddy">
<cstring>fontspecSansLE</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="fontspecSansLE">
<property name="toolTip">
<string>Here you can insert additional options (as provided by the font package)</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="6" column="0">
<widget class="QLabel" name="fontsTypewriterLA">
<property name="text">
<string>&amp;Typewriter:</string>
@ -183,8 +227,8 @@
</property>
</widget>
</item>
<item row="5" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item row="6" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QComboBox" name="fontsTypewriterCO">
<property name="toolTip">
@ -230,7 +274,28 @@
</item>
</layout>
</item>
<item row="6" column="0">
<item row="7" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="fontspecTypewriterLA">
<property name="text">
<string>Options:</string>
</property>
<property name="buddy">
<cstring>fontspecTypewriterLE</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="fontspecTypewriterLE">
<property name="toolTip">
<string>Here you can insert additional options (as provided by the font package)</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="8" column="0">
<widget class="QLabel" name="fontsMathLA">
<property name="text">
<string>&amp;Math:</string>
@ -240,14 +305,14 @@
</property>
</widget>
</item>
<item row="6" column="1">
<item row="8" column="1">
<widget class="QComboBox" name="fontsMathCO">
<property name="toolTip">
<string>Select the math typeface</string>
</property>
</widget>
</item>
<item row="7" column="0">
<item row="9" column="0">
<widget class="QLabel" name="cjkFontLA">
<property name="text">
<string>C&amp;JK:</string>
@ -257,14 +322,14 @@
</property>
</widget>
</item>
<item row="7" column="1">
<item row="9" column="1">
<widget class="QLineEdit" name="cjkFontLE">
<property name="toolTip">
<string>Input the font to be used for Chinese, Japanese or Korean (CJK) script</string>
</property>
</widget>
</item>
<item row="8" column="1">
<item row="10" column="1">
<widget class="QCheckBox" name="fontScCB">
<property name="toolTip">
<string>Use a real small caps shape, if the font provides one</string>
@ -274,7 +339,7 @@
</property>
</widget>
</item>
<item row="9" column="1">
<item row="11" column="1">
<widget class="QCheckBox" name="fontOsfCB">
<property name="toolTip">
<string>Use old style instead of lining figures</string>
@ -284,7 +349,7 @@
</property>
</widget>
</item>
<item row="10" column="1">
<item row="12" column="1">
<widget class="QCheckBox" name="microtypeCB">
<property name="toolTip">
<string>Activate extensions such as character protrusion and font expansion via the microtype package</string>
@ -294,7 +359,7 @@
</property>
</widget>
</item>
<item row="11" column="1">
<item row="13" column="1">
<widget class="QCheckBox" name="dashesCB">
<property name="toolTip">
<string>By default, a line break can occur after en- and em-dashes. Checking this box prevents that.</string>
@ -304,7 +369,9 @@
</property>
</widget>
</item>
<item row="12" column="1">
</layout>
</item>
<item row="2" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>

View File

@ -535,6 +535,9 @@ Preamble::Preamble() : one_language(true), explicit_babel(false),
h_font_sf_scale[1] = "100";
h_font_tt_scale[0] = "100";
h_font_tt_scale[1] = "100";
// h_font_roman_opts;
// h_font_sans_opts;
// h_font_typewriter_opts;
//h_font_cjk
h_is_mathindent = "0";
h_math_numbering_side = "default";
@ -782,14 +785,26 @@ void Preamble::handle_package(Parser &p, string const & name,
if (name == "MinionPro") {
h_font_roman[0] = "minionpro";
if (opts.find("lf") != string::npos)
h_font_osf = "false";
else
vector<string> allopts = getVectorFromString(opts);
string xopts;
h_font_osf = "true";
if (opts.find("onlytext") != string::npos)
h_font_math[0] = "default";
else
h_font_math[0] = "auto";
for (auto const & opt : allopts) {
if (opt == "lf") {
h_font_osf = "false";
continue;
}
if (opt == "onlytext") {
h_font_math[0] = "default";
continue;
}
if (!xopts.empty())
xopts += ", ";
xopts += opt;
}
if (!xopts.empty())
h_font_roman_opts = xopts;
options.clear();
}
if (name == "mathdesign") {
@ -1423,13 +1438,19 @@ bool Preamble::writeLyXHeader(ostream & os, bool subdoc, string const & outfiled
<< "\\font_default_family " << h_font_default_family << "\n"
<< "\\use_non_tex_fonts " << (h_use_non_tex_fonts ? "true" : "false") << '\n'
<< "\\font_sc " << h_font_sc << "\n"
<< "\\font_osf " << h_font_osf << "\n"
<< "\\font_sf_scale " << h_font_sf_scale[0]
<< ' ' << h_font_sf_scale[1] << '\n'
<< "\\font_tt_scale " << h_font_tt_scale[0]
<< "\\font_osf " << h_font_osf << "\n";
if (!h_font_roman_opts.empty())
os << "\\font_roman_opts \"" << h_font_roman_opts << "\"" << '\n';
os << "\\font_sf_scale " << h_font_sf_scale[0]
<< ' ' << h_font_sf_scale[1] << '\n';
if (!h_font_sans_opts.empty())
os << "\\font_sans_opts \"" << h_font_sans_opts << "\"" << '\n';
os << "\\font_tt_scale " << h_font_tt_scale[0]
<< ' ' << h_font_tt_scale[1] << '\n';
if (!h_font_cjk.empty())
os << "\\font_cjk " << h_font_cjk << '\n';
if (!h_font_typewriter_opts.empty())
os << "\\font_typewriter_opts \"" << h_font_typewriter_opts << "\"" << '\n';
os << "\\use_microtype " << h_use_microtype << '\n'
<< "\\use_dash_ligatures " << h_use_dash_ligatures << '\n'
<< "\\graphics " << h_graphics << '\n'
@ -1683,35 +1704,58 @@ void Preamble::parse(Parser & p, string const & forceclass,
}
if (t.cs() == "setmainfont") {
// we don't care about the option
p.hasOpt() ? p.getOpt() : string();
string fontopts = p.hasOpt() ? p.getArg('[', ']') : string();
h_font_roman[1] = p.getArg('{', '}');
if (!fontopts.empty()) {
vector<string> opts = getVectorFromString(fontopts);
fontopts.clear();
for (auto const & opt : opts) {
if (opt == "Mapping=tex-text" || opt == "Ligatures=TeX")
// ignore
continue;
if (!fontopts.empty())
fontopts += ", ";
fontopts += opt;
}
h_font_roman_opts = fontopts;
}
continue;
}
if (t.cs() == "setsansfont" || t.cs() == "setmonofont") {
// LyX currently only supports the scale option
string scale;
string scale, fontopts;
if (p.hasOpt()) {
string fontopts = p.getArg('[', ']');
// check if the option contains a scaling, if yes, extract it
string::size_type pos = fontopts.find("Scale");
if (pos != string::npos) {
string::size_type i = fontopts.find(',', pos);
if (i == string::npos)
scale_as_percentage(fontopts.substr(pos + 1), scale);
else
scale_as_percentage(fontopts.substr(pos, i - pos), scale);
fontopts = p.getArg('[', ']');
if (!fontopts.empty()) {
vector<string> opts = getVectorFromString(fontopts);
fontopts.clear();
for (auto const & opt : opts) {
if (opt == "Mapping=tex-text" || opt == "Ligatures=TeX")
// ignore
continue;
if (prefixIs(opt, "Scale=")) {
scale_as_percentage(opt, scale);
continue;
}
if (!fontopts.empty())
fontopts += ", ";
fontopts += opt;
}
}
}
if (t.cs() == "setsansfont") {
if (!scale.empty())
h_font_sf_scale[1] = scale;
h_font_sans[1] = p.getArg('{', '}');
if (!fontopts.empty())
h_font_sans_opts = fontopts;
} else {
if (!scale.empty())
h_font_tt_scale[1] = scale;
h_font_typewriter[1] = p.getArg('{', '}');
if (!fontopts.empty())
h_font_typewriter_opts = fontopts;
}
continue;
}
@ -1725,33 +1769,55 @@ void Preamble::parse(Parser & p, string const & forceclass,
// we don't care about the lang option
string const lang = p.hasOpt() ? p.getArg('[', ']') : string();
string const family = p.getArg('{', '}');
string const fontopts = p.hasOpt() ? p.getArg('[', ']') : string();
string fontopts = p.hasOpt() ? p.getArg('[', ']') : string();
string const fontname = p.getArg('{', '}');
if (lang.empty() && family == "rm") {
h_font_roman[1] = fontname;
if (!fontopts.empty()) {
vector<string> opts = getVectorFromString(fontopts);
fontopts.clear();
for (auto const & opt : opts) {
if (opt == "Mapping=tex-text" || opt == "Ligatures=TeX")
// ignore
continue;
if (!fontopts.empty())
fontopts += ", ";
fontopts += opt;
}
h_font_roman_opts = fontopts;
}
continue;
} else if (lang.empty() && (family == "sf" || family == "tt")) {
// LyX currently only supports the scale option
string scale;
if (!fontopts.empty()) {
// check if the option contains a scaling, if yes, extract it
string::size_type pos = fontopts.find("Scale");
if (pos != string::npos) {
string::size_type i = fontopts.find(',', pos);
if (i == string::npos)
scale_as_percentage(fontopts.substr(pos + 1), scale);
else
scale_as_percentage(fontopts.substr(pos, i - pos), scale);
vector<string> opts = getVectorFromString(fontopts);
fontopts.clear();
for (auto const & opt : opts) {
if (opt == "Mapping=tex-text" || opt == "Ligatures=TeX")
// ignore
continue;
if (prefixIs(opt, "Scale=")) {
scale_as_percentage(opt, scale);
continue;
}
if (!fontopts.empty())
fontopts += ", ";
fontopts += opt;
}
}
if (family == "sf") {
if (!scale.empty())
h_font_sf_scale[1] = scale;
h_font_sans[1] = fontname;
if (!fontopts.empty())
h_font_sans_opts = fontopts;
} else {
if (!scale.empty())
h_font_tt_scale[1] = scale;
h_font_typewriter[1] = fontname;
if (!fontopts.empty())
h_font_typewriter_opts = fontopts;
}
continue;
} else {

View File

@ -166,6 +166,9 @@ private:
std::string h_font_roman[2];
std::string h_font_sans[2];
std::string h_font_typewriter[2];
std::string h_font_roman_opts;
std::string h_font_sans_opts;
std::string h_font_typewriter_opts;
std::string h_font_default_family;
bool h_use_non_tex_fonts;
std::string h_font_sc;

View File

@ -32,8 +32,8 @@ extern char const * const lyx_version_info;
// Do not remove the comment below, so we get merge conflict in
// independent branches. Instead add your own.
#define LYX_FORMAT_LYX 579 // spitz: babelfont
#define LYX_FORMAT_TEX2LYX 579
#define LYX_FORMAT_LYX 580 // spitz/uwestoehr: support for fontspec options
#define LYX_FORMAT_TEX2LYX 580
#if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX
#ifndef _MSC_VER