X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FLaTeXFonts.cpp;h=862e47451646798447ccf1fd8784f939705373ed;hb=28be7d552f62cc02fa86d7f79201d089bfb2d7b5;hp=70c500543b68dc0e52cd0fb982f539697d86725a;hpb=f4261030e208e9af74a38ed35fa809c90f920758;p=lyx.git diff --git a/src/LaTeXFonts.cpp b/src/LaTeXFonts.cpp index 70c500543b..862e474516 100644 --- a/src/LaTeXFonts.cpp +++ b/src/LaTeXFonts.cpp @@ -19,6 +19,7 @@ #include "support/convert.h" #include "support/debug.h" +#include "support/docstream.h" #include "support/FileName.h" #include "support/filetools.h" #include "support/gettext.h" @@ -34,54 +35,119 @@ namespace lyx { LaTeXFonts latexfonts; -bool LaTeXFont::available(bool ot1) const +LaTeXFont LaTeXFont::altFont(docstring const & name) { - return ot1 ? available_ot1_ : available_; + return theLaTeXFonts().getAltFont(name); } -bool LaTeXFont::providesOSF(bool ot1) const +bool LaTeXFont::available(bool ot1, bool nomath) { - if (!osfpackage_.empty()) - return LaTeXFeatures::isAvailable(to_ascii(osfpackage_)); + if (nomath && !nomathfont_.empty()) + return altFont(nomathfont_).available(ot1, nomath); + else if (ot1 && !ot1font_.empty()) + return (ot1font_ == "none") ? + true : altFont(ot1font_).available(ot1, nomath); + else if (requires_.empty() && package_.empty()) + return true; + else if (!requires_.empty() + && LaTeXFeatures::isAvailable(to_ascii(requires_))) + return true; + else if (requires_.empty() && !package_.empty() + && LaTeXFeatures::isAvailable(to_ascii(package_))) + return true; + else if (!altfonts_.empty()) { + for (size_t i = 0; i < altfonts_.size(); ++i) { + if (altFont(altfonts_[i]).available(ot1, nomath)) + return true; + } + } + return false; +} + - if (ot1 && !ot1package_.empty() && ot1package_ != "none") +bool LaTeXFont::providesNoMath(bool ot1, bool complete) +{ + docstring const usedfont = getUsedFont(ot1, complete, false); + + if (usedfont.empty()) return false; + else if (usedfont != name_) + return altFont(usedfont).providesNoMath(ot1, complete); + + return (!nomathfont_.empty() && available(ot1, true)); +} - if (!package_.empty() && !LaTeXFeatures::isAvailable(to_ascii(package_))) + +bool LaTeXFont::providesOSF(bool ot1, bool complete, bool nomath) +{ + docstring const usedfont = getUsedFont(ot1, complete, nomath); + + if (usedfont.empty()) + return false; + else if (usedfont != name_) + return altFont(usedfont).providesOSF(ot1, complete, nomath); + else if (!osffont_.empty()) + return altFont(osffont_).available(ot1, nomath); + else if (!available(ot1, nomath)) return false; return (!osfoption_.empty() || !osfscoption_.empty()); } -bool LaTeXFont::providesSC(bool ot1) const +bool LaTeXFont::providesSC(bool ot1, bool complete, bool nomath) { - if (ot1 && !ot1package_.empty() && ot1package_ != "none") - return false; + docstring const usedfont = getUsedFont(ot1, complete, nomath); - if (!package_.empty() && !LaTeXFeatures::isAvailable(to_ascii(package_))) + if (usedfont.empty()) + return false; + else if (usedfont != name_) + return altFont(usedfont).providesSC(ot1, complete, nomath); + else if (!available(ot1, nomath)) return false; return (!scoption_.empty() || !osfscoption_.empty()); } -bool LaTeXFont::providesScale(bool ot1) const +bool LaTeXFont::hasMonolithicExpertSet(bool ot1, bool complete, bool nomath) { - if (ot1 && !ot1package_.empty() && ot1package_ != "none") - return false; + docstring const usedfont = getUsedFont(ot1, complete, nomath); - if (!package_.empty() && !LaTeXFeatures::isAvailable(to_ascii(package_))) + if (usedfont.empty()) return false; + else if (usedfont != name_) + return altFont(usedfont).hasMonolithicExpertSet(ot1, complete, nomath); + return (!osfoption_.empty() && !scoption_.empty() && osfoption_ == scoption_) + || (osfoption_.empty() && scoption_.empty() && !osfscoption_.empty()); +} + +bool LaTeXFont::providesScale(bool ot1, bool complete, bool nomath) +{ + docstring const usedfont = getUsedFont(ot1, complete, nomath); + + if (usedfont.empty()) + return false; + else if (usedfont != name_) + return altFont(usedfont).providesScale(ot1, complete, nomath); + else if (!available(ot1, nomath)) + return false; return (!scaleoption_.empty()); } -bool LaTeXFont::provides(std::string const & name) const +bool LaTeXFont::provides(std::string const & name, bool ot1, bool complete, bool nomath) { - if (provides_.empty()) + docstring const usedfont = getUsedFont(ot1, complete, nomath); + + if (usedfont.empty()) return false; + else if (usedfont != name_) + return altFont(usedfont).provides(name, ot1, complete, nomath); + else if (provides_.empty()) + return false; + for (size_t i = 0; i < provides_.size(); ++i) { if (provides_[i] == name) return true; @@ -90,74 +156,108 @@ bool LaTeXFont::provides(std::string const & name) const } -string const LaTeXFont::getAvailablePackage(bool dryrun, bool ot1, bool complete, bool & alt) +docstring const LaTeXFont::getUsedFont(bool ot1, bool complete, bool nomath) { - if (ot1 && !ot1package_.empty()) { - if (ot1package_ != "none" - && (LaTeXFeatures::isAvailable(to_ascii(ot1package_)) || dryrun)) - return to_ascii(ot1package_); - if (!dryrun && ot1package_ != "none") - frontend::Alert::warning(_("Font not available"), - bformat(_("The LaTeX package `%1$s' needed for the font `%2$s'\n" - "is not available on your system. LyX will fall back to the default font."), - ot1package_, guiname_), true); - return string(); + if (nomath && !nomathfont_.empty() && available(ot1, true)) + return nomathfont_; + else if (ot1 && !ot1font_.empty()) + return (ot1font_ == "none") ? docstring() : ot1font_; + else if (family_ == "rm" && complete && !completefont_.empty() + && altFont(completefont_).available(ot1, nomath)) + return completefont_; + else if (switchdefault_) { + if (requires_.empty() + || (!requires_.empty() + && LaTeXFeatures::isAvailable(to_ascii(requires_)))) + return name_; } - if (family_ == "rm" && complete && !completepackage_.empty()) { - if (LaTeXFeatures::isAvailable(to_ascii(completepackage_)) || dryrun) - return to_ascii(completepackage_); + else if (!requires_.empty() + && LaTeXFeatures::isAvailable(to_ascii(requires_))) + return name_; + else if (!package_.empty() + && LaTeXFeatures::isAvailable(to_ascii(package_))) + return name_; + else if (!preamble_.empty() && package_.empty() + && requires_.empty() && !switchdefault_ + && altfonts_.empty()) { + return name_; } - if (!package_.empty()) { - if (!requires_.empty() && LaTeXFeatures::isAvailable(to_ascii(requires_))) - return to_ascii(package_); - if (LaTeXFeatures::isAvailable(to_ascii(package_))) - return to_ascii(package_); - else if (!altpackages_.empty()) { - for (size_t i = 0; i < altpackages_.size(); ++i) { - if (LaTeXFeatures::isAvailable(to_ascii(altpackages_[i]))) { - alt = true; - return to_ascii(altpackages_[i]); - } - } + else if (!altfonts_.empty()) { + for (size_t i = 0; i < altfonts_.size(); ++i) { + LaTeXFont altf = altFont(altfonts_[i]); + if (altf.available(ot1, nomath)) + return altf.getUsedFont(ot1, complete, nomath); } - // Output unavailable packages in source preview - if (dryrun) - return to_ascii(package_); - docstring const req = requires_.empty() ? package_ : requires_; - frontend::Alert::warning(_("Font not available"), - bformat(_("The LaTeX package `%1$s' needed for the font `%2$s'\n" - "is not available on your system. LyX will fall back to the default font."), - req, guiname_), true); } - return string(); + + return docstring(); +} + + +docstring const LaTeXFont::getUsedPackage(bool ot1, bool complete, bool nomath) +{ + docstring const usedfont = getUsedFont(ot1, complete, nomath); + if (usedfont.empty()) + return docstring(); + return theLaTeXFonts().getLaTeXFont(usedfont).package(); } -string const LaTeXFont::getPackageOptions(bool ot1, bool sc, bool osf, int scale) +string const LaTeXFont::getAvailablePackage(bool dryrun) { - if (ot1 && !ot1package_.empty()) + if (package_.empty()) return string(); + string const package = to_ascii(package_); + if (!requires_.empty() && LaTeXFeatures::isAvailable(to_ascii(requires_))) + return package; + else if (LaTeXFeatures::isAvailable(package)) + return package; + // Output unavailable packages in source preview + else if (dryrun) + return package; + + docstring const req = requires_.empty() ? package_ : requires_; + frontend::Alert::warning(_("Font not available"), + bformat(_("The LaTeX package `%1$s' needed for the font `%2$s'\n" + "is not available on your system. LyX will fall back to the default font."), + req, guiname_), true); + + return string(); +} + + +string const LaTeXFont::getPackageOptions(bool ot1, bool complete, bool sc, bool osf, + int scale, bool nomath) +{ ostringstream os; + bool const needosfopt = (osf != osfdefault_); + bool const has_osf = providesOSF(ot1, complete, nomath); + bool const has_sc = providesSC(ot1, complete, nomath); + if (!packageoption_.empty()) os << to_ascii(packageoption_); - if (sc && osf && providesOSF() && providesSC()) { + + if (sc && needosfopt && has_osf && has_sc) { if (!os.str().empty()) os << ','; if (!osfscoption_.empty()) os << to_ascii(osfscoption_); else - os << to_ascii(osfoption_) << ',' << to_ascii(scoption_); - } else if (osf && providesOSF()) { + os << to_ascii(osfoption_) + << ',' << to_ascii(scoption_); + } else if (needosfopt && has_osf) { if (!os.str().empty()) os << ','; os << to_ascii(osfoption_); - } else if (sc && providesSC()) { + } else if (sc && has_sc) { if (!os.str().empty()) os << ','; os << to_ascii(scoption_); } - if (scale != 100 && !scaleoption_.empty()) { + + if (scale != 100 && !scaleoption_.empty() + && providesScale(ot1, complete, nomath)) { if (!os.str().empty()) os << ','; os << subst(to_ascii(scaleoption_), "$$val", @@ -168,36 +268,43 @@ string const LaTeXFont::getPackageOptions(bool ot1, bool sc, bool osf, int scale string const LaTeXFont::getLaTeXCode(bool dryrun, bool ot1, bool complete, bool sc, - bool osf, int const & scale) + bool osf, bool nomath, int const & scale) { ostringstream os; + docstring const usedfont = getUsedFont(ot1, complete, nomath); + if (usedfont.empty()) + return string(); + else if (usedfont != name_) + return altFont(usedfont).getLaTeXCode(dryrun, ot1, complete, sc, osf, nomath, scale); + if (switchdefault_) { if (family_.empty()) { LYXERR0("Error: Font `" << name_ << "' has no family defined!"); return string(); } - if (available(ot1) || dryrun) + if (available(ot1, nomath) || dryrun) os << "\\renewcommand{\\" << to_ascii(family_) << "default}{" - << to_ascii(name_) << "}\n"; + << to_ascii(name_) << "}\n"; else frontend::Alert::warning(_("Font not available"), bformat(_("The LaTeX package `%1$s' needed for the font `%2$s'\n" "is not available on your system. LyX will fall back to the default font."), requires_, guiname_), true); } else { - bool alt = false; string const package = - getAvailablePackage(dryrun, ot1, complete, alt); - // Package options are not for alternative packages - string const packageopts = alt ? string() : getPackageOptions(ot1, sc, osf, scale); + getAvailablePackage(dryrun); + string const packageopts = getPackageOptions(ot1, complete, sc, osf, scale, 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) && !osfpackage_.empty()) - os << "\\usepackage{" << to_ascii(osfpackage_) << "}\n"; + if (osf && providesOSF(ot1, complete, nomath) && !osffont_.empty()) + os << altFont(osffont_).getLaTeXCode(dryrun, ot1, complete, sc, osf, nomath, scale); + + if (!preamble_.empty()) + os << to_utf8(preamble_); return os.str(); } @@ -206,17 +313,20 @@ string const LaTeXFont::getLaTeXCode(bool dryrun, bool ot1, bool complete, bool bool LaTeXFont::readFont(Lexer & lex) { enum LaTeXFontTags { - LF_ALT_PACKAGES = 1, - LF_COMPLETE_PACKAGE, + LF_ALT_FONTS = 1, + LF_COMPLETE_FONT, LF_END, LF_FAMILY, LF_GUINAME, + LF_NOMATHFONT, + LF_OSFDEFAULT, + LF_OSFFONT, LF_OSFOPTION, - LF_OSFPACKAGE, LF_OSFSCOPTION, - LF_OT1_PACKAGE, + LF_OT1_FONT, LF_PACKAGE, LF_PACKAGEOPTION, + LF_PREAMBLE, LF_PROVIDES, LF_REQUIRES, LF_SCALEOPTION, @@ -226,17 +336,20 @@ bool LaTeXFont::readFont(Lexer & lex) // Keep these sorted alphabetically! LexerKeyword latexFontTags[] = { - { "altpackages", LF_ALT_PACKAGES }, - { "completepackage", LF_COMPLETE_PACKAGE }, + { "altfonts", LF_ALT_FONTS }, + { "completefont", LF_COMPLETE_FONT }, { "endfont", LF_END }, { "family", LF_FAMILY }, { "guiname", LF_GUINAME }, + { "nomathfont", LF_NOMATHFONT }, + { "osfdefault", LF_OSFDEFAULT }, + { "osffont", LF_OSFFONT }, { "osfoption", LF_OSFOPTION }, - { "osfpackage", LF_OSFPACKAGE }, { "osfscoption", LF_OSFSCOPTION }, - { "ot1package", LF_OT1_PACKAGE }, + { "ot1font", LF_OT1_FONT }, { "package", LF_PACKAGE }, { "packageoption", LF_PACKAGEOPTION }, + { "preamble", LF_PREAMBLE }, { "provides", LF_PROVIDES }, { "requires", LF_REQUIRES }, { "scaleoption", LF_SCALEOPTION }, @@ -267,14 +380,14 @@ bool LaTeXFont::readFont(Lexer & lex) case LF_END: // end of structure finished = true; break; - case LF_ALT_PACKAGES: { + case LF_ALT_FONTS: { lex.eatLine(); docstring altp = lex.getDocString(); - altpackages_ = getVectorFromString(altp); + altfonts_ = getVectorFromString(altp); break; } - case LF_COMPLETE_PACKAGE: - lex >> completepackage_; + case LF_COMPLETE_FONT: + lex >> completefont_; break; case LF_FAMILY: lex >> family_; @@ -282,17 +395,23 @@ bool LaTeXFont::readFont(Lexer & lex) case LF_GUINAME: lex >> guiname_; break; + case LF_NOMATHFONT: + lex >> nomathfont_; + break; case LF_OSFOPTION: lex >> osfoption_; break; - case LF_OSFPACKAGE: - lex >> osfpackage_; + case LF_OSFFONT: + lex >> osffont_; + break; + case LF_OSFDEFAULT: + lex >> osfdefault_; break; case LF_OSFSCOPTION: lex >> osfscoption_; break; - case LF_OT1_PACKAGE: - lex >> ot1package_; + case LF_OT1_FONT: + lex >> ot1font_; break; case LF_PACKAGE: lex >> package_; @@ -300,6 +419,9 @@ bool LaTeXFont::readFont(Lexer & lex) case LF_PACKAGEOPTION: lex >> packageoption_; break; + case LF_PREAMBLE: + preamble_ = lex.getLongString(from_ascii("EndPreamble")); + break; case LF_PROVIDES: { lex.eatLine(); string features = lex.getString(); @@ -332,6 +454,7 @@ bool LaTeXFont::readFont(Lexer & lex) bool LaTeXFont::read(Lexer & lex) { switchdefault_ = 0; + osfdefault_ = 0; if (!lex.next()) { lex.printError("No name given for LaTeX font: `$$Token'."); @@ -345,26 +468,6 @@ bool LaTeXFont::read(Lexer & lex) return false; } - bool available = true; - if (!requires_.empty()) - available = LaTeXFeatures::isAvailable(to_ascii(requires_)); - else if (!package_.empty()) { - available = LaTeXFeatures::isAvailable(to_ascii(package_)); - if (!available && !altpackages_.empty()) { - for (size_t i = 0; i < altpackages_.size(); ++i) { - available = LaTeXFeatures::isAvailable(to_ascii(altpackages_[i])); - if (available) - break; - } - } - } - available_ = available; - - if (!ot1package_.empty() && ot1package_ != "none") - available_ot1_ = LaTeXFeatures::isAvailable(to_ascii(ot1package_)); - else - available_ot1_ = available; - return true; } @@ -389,7 +492,8 @@ void LaTeXFonts::readLaTeXFonts() default: break; } - if (lex.getString() != "Font") { + string const type = lex.getString(); + if (type != "Font" && type != "AltFont") { lex.printError("Unknown LaTeXFont tag `$$Token'"); continue; } @@ -398,7 +502,10 @@ void LaTeXFonts::readLaTeXFonts() if (!lex) break; - texfontmap_[f.name()] = f; + if (type == "AltFont") + texaltfontmap_[f.name()] = f; + else + texfontmap_[f.name()] = f; } } @@ -413,7 +520,7 @@ LaTeXFonts::TexFontMap LaTeXFonts::getLaTeXFonts() LaTeXFont LaTeXFonts::getLaTeXFont(docstring const & name) { - if (name == "default") + if (name == "default" || name == "auto") return LaTeXFont(); if (texfontmap_.empty()) readLaTeXFonts(); @@ -425,4 +532,18 @@ LaTeXFont LaTeXFonts::getLaTeXFont(docstring const & name) } +LaTeXFont LaTeXFonts::getAltFont(docstring const & name) +{ + if (name == "default" || name == "auto") + return LaTeXFont(); + if (texaltfontmap_.empty()) + readLaTeXFonts(); + if (texaltfontmap_.find(name) == texaltfontmap_.end()) { + LYXERR0("LaTeXFonts::getAltFont: alternative font '" << name << "' not found!"); + return LaTeXFont(); + } + return texaltfontmap_[name]; +} + + } // namespace lyx