docstring const stateText(FontInfo const & f) { odocstringstream os; if (f.family() != INHERIT_FAMILY) os << _(GUIFamilyNames[f.family()]) << ", "; if (f.series() != INHERIT_SERIES) os << _(GUISeriesNames[f.series()]) << ", "; if (f.shape() != INHERIT_SHAPE) os << _(GUIShapeNames[f.shape()]) << ", "; if (f.size() != FONT_SIZE_INHERIT) os << _(GUISizeNames[f.size()]) << ", "; if (f.color() != Color_inherit) os << lcolor.getGUIName(f.color()) << ", "; // FIXME: uncomment this when we support background. //if (f.background() != Color_inherit) // os << lcolor.getGUIName(f.background()) << ", "; if (f.emph() != FONT_INHERIT) os << bformat(_("Emphasis %1$s, "), _(GUIMiscNames[f.emph()])); if (f.underbar() != FONT_INHERIT) os << bformat(_("Underline %1$s, "), _(GUIMiscNames[f.underbar()])); if (f.strikeout() != FONT_INHERIT) os << bformat(_("Strikeout %1$s, "), _(GUIMiscNames[f.strikeout()])); if (f.uuline() != FONT_INHERIT) os << bformat(_("Double underline %1$s, "), _(GUIMiscNames[f.uuline()])); if (f.uwave() != FONT_INHERIT) os << bformat(_("Wavy underline %1$s, "), _(GUIMiscNames[f.uwave()])); if (f.noun() != FONT_INHERIT) os << bformat(_("Noun %1$s, "), _(GUIMiscNames[f.noun()])); if (f == inherit_font) os << _("Default") << ", "; return os.str(); }
bool FontLoader::available(FontInfo const & f) { static vector<int> cache_set(NUM_FAMILIES, false); static vector<int> cache(NUM_FAMILIES, false); FontFamily family = f.family(); if (cache_set[family]) return cache[family]; cache_set[family] = true; QString const pat = symbolFamily(family); if (pat.isEmpty()) // We don't care about non-symbol fonts return false; bool ok; symbolFont(pat, &ok); if (!ok) return false; cache[family] = true; return true; }
/// Writes ending block of LaTeX needed to close use of this font // Returns number of chars written // This one corresponds to latexWriteStartChanges(). (Asger) int Font::latexWriteEndChanges(otexstream & os, BufferParams const & bparams, OutputParams const & runparams, Font const & base, Font const & next, bool const & closeLanguage) 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 FontInfo f = bits_; f.reduce(base.bits_); 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() != Color_inherit && f.color() != Color_ignore) { os << '}'; ++count; env = true; // Size change need not bother about closing env. } if (f.emph() == FONT_ON) { os << '}'; ++count; env = true; // Size change need not bother about closing env. } if (f.noun() == FONT_ON) { os << '}'; ++count; env = true; // Size change need not bother about closing env. } if (f.size() != FONT_SIZE_INHERIT) { // We only have to close if only size changed if (!env) { os << '}'; ++count; } } if (f.underbar() == FONT_ON) { os << '}'; ++count; runparams.inulemcmd = false; } if (f.strikeout() == FONT_ON) { os << '}'; ++count; runparams.inulemcmd = false; } if (f.uuline() == FONT_ON) { os << '}'; ++count; runparams.inulemcmd = false; } if (f.uwave() == FONT_ON) { os << '}'; ++count; runparams.inulemcmd = false; } // If the current language is Hebrew, Arabic, or Farsi // the numbers are written Left-to-Right. ArabTeX package // reorders the number automatically but the packages used // for Hebrew and Farsi (Arabi) do not. if (bits_.number() == FONT_ON && next.fontInfo().number() != FONT_ON && (language()->lang() == "hebrew" || language()->lang() == "farsi" || language()->lang() == "arabic_arabi")) { os << "\\endL}"; count += 6; } if (open_encoding_) { // We need to close the encoding even if it does not change // to do correct environment nesting Encoding const * const ascii = encodings.fromLyXName("ascii"); pair<bool, int> const c = switchEncoding(os.os(), bparams, runparams, *ascii); LATTEST(c.first); count += c.second; runparams.encoding = ascii; open_encoding_ = false; } if (closeLanguage && language() != base.language() && language() != next.language() && language()->encoding()->package() != Encoding::CJK) { os << '}'; ++count; } return count; }
/// Writes the head of the LaTeX needed to impose this font // Returns number of chars written. int Font::latexWriteStartChanges(odocstream & os, BufferParams const & bparams, OutputParams const & runparams, Font const & base, Font const & prev) const { bool env = false; int count = 0; // polyglossia or babel? if (runparams.use_polyglossia && language()->lang() != base.language()->lang() && language() != prev.language()) { if (!language()->polyglossia().empty()) { string tmp = "\\text" + language()->polyglossia(); if (!language()->polyglossiaOpts().empty()) tmp += "[" + language()->polyglossiaOpts() + "]"; tmp += "{"; os << from_ascii(tmp); count += tmp.length(); } else { os << '{'; count += 1; } } else if (language()->babel() != base.language()->babel() && language() != prev.language()) { if (language()->lang() == "farsi") { os << "\\textFR{"; count += 8; } else if (!isRightToLeft() && base.language()->lang() == "farsi") { os << "\\textLR{"; count += 8; } else if (language()->lang() == "arabic_arabi") { os << "\\textAR{"; count += 8; } else if (!isRightToLeft() && base.language()->lang() == "arabic_arabi") { os << "\\textLR{"; count += 8; // currently the remaining RTL languages are arabic_arabtex and hebrew } else if (isRightToLeft() != prev.isRightToLeft()) { if (isRightToLeft()) { os << "\\R{"; count += 3; } else { os << "\\L{"; count += 3; } } else if (!language()->babel().empty()) { string const tmp = subst(lyxrc.language_command_local, "$$lang", language()->babel()); os << from_ascii(tmp); count += tmp.length(); } else { os << '{'; count += 1; } } if (language()->encoding()->package() == Encoding::CJK) { pair<bool, int> const c = switchEncoding(os, bparams, runparams, *(language()->encoding())); if (c.first) { open_encoding_ = true; count += c.second; runparams.encoding = language()->encoding(); } } // If the current language is Hebrew, Arabic, or Farsi // the numbers are written Left-to-Right. ArabTeX package // reorders the number automatically but the packages used // for Hebrew and Farsi (Arabi) do not. if (bits_.number() == FONT_ON && prev.fontInfo().number() != FONT_ON && (language()->lang() == "hebrew" || language()->lang() == "farsi" || language()->lang() == "arabic_arabi")) { os << "{\\beginL "; count += 9; } FontInfo f = bits_; f.reduce(base.bits_); 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() != Color_inherit && f.color() != Color_ignore) { os << "\\textcolor{" << from_ascii(lcolor.getLaTeXName(f.color())) << "}{"; count += lcolor.getLaTeXName(f.color()).length() + 13; env = true; //We have opened a new environment } // FIXME: uncomment this when we support background. /* if (f.background() != Color_inherit && f.background() != Color_ignore) { os << "\\textcolor{" << from_ascii(lcolor.getLaTeXName(f.background())) << "}{"; count += lcolor.getLaTeXName(f.background()).length() + 13; env = true; //We have opened a new environment } */ if (f.emph() == FONT_ON) { os << "\\emph{"; count += 6; env = true; //We have opened a new environment } // \noun{} is a LyX special macro if (f.noun() == FONT_ON) { os << "\\noun{"; count += 6; env = true; //We have opened a new environment } if (f.size() != FONT_SIZE_INHERIT) { // 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()]) + 3; } // The ulem commands need to be on the deepest nesting level // because ulem puts every nested group or macro in a box, // which prevents linebreaks (#8424, #8733) if (f.underbar() == FONT_ON) { os << "\\uline{"; count += 10; runparams.inulemcmd = true; } if (f.strikeout() == FONT_ON) { os << "\\sout{"; count += 9; runparams.inulemcmd = true; } if (f.uuline() == FONT_ON) { os << "\\uuline{"; count += 11; runparams.inulemcmd = true; } if (f.uwave() == FONT_ON) { os << "\\uwave{"; count += 10; runparams.inulemcmd = true; } return count; }
GuiFontInfo::GuiFontInfo(FontInfo const & f) : metrics(QFont()) { font.setKerning(false); QString const pat = symbolFamily(f.family()); if (!pat.isEmpty()) { bool ok; font = symbolFont(pat, &ok); } else { switch (f.family()) { case ROMAN_FAMILY: { QString family = makeFontName(toqstr(lyxrc.roman_font_name), toqstr(lyxrc.roman_font_foundry)); font.setFamily(family); #ifdef Q_WS_MACX #if QT_VERSION >= 0x040300 //&& QT_VERSION < 0x040800 // Workaround for a Qt bug, see http://www.lyx.org/trac/ticket/3684 // and http://bugreports.qt.nokia.com/browse/QTBUG-11145. // FIXME: Check whether this is really fixed in Qt 4.8 if (family == "Times" && !font.exactMatch()) font.setFamily("Times New Roman"); #endif #endif break; } case SANS_FAMILY: font.setFamily(makeFontName(toqstr(lyxrc.sans_font_name), toqstr(lyxrc.sans_font_foundry))); break; case TYPEWRITER_FAMILY: font.setFamily(makeFontName(toqstr(lyxrc.typewriter_font_name), toqstr(lyxrc.typewriter_font_foundry))); break; default: break; } } switch (f.series()) { case MEDIUM_SERIES: font.setWeight(QFont::Normal); break; case BOLD_SERIES: font.setWeight(QFont::Bold); break; default: break; } switch (f.realShape()) { case ITALIC_SHAPE: case SLANTED_SHAPE: font.setItalic(true); break; default: break; } LYXERR(Debug::FONT, "Font '" << stateText(f) << "' matched by\n" << font.family()); // Is this an exact match? if (font.exactMatch()) LYXERR(Debug::FONT, "This font is an exact match"); else LYXERR(Debug::FONT, "This font is NOT an exact match"); LYXERR(Debug::FONT, "XFLD: " << font.rawName()); font.setPointSizeF(convert<double>(lyxrc.font_sizes[f.size()]) * lyxrc.zoom / 100.0); LYXERR(Debug::FONT, "The font has size: " << font.pointSizeF()); if (f.realShape() != SMALLCAPS_SHAPE) { metrics = GuiFontMetrics(font); } else { // handle small caps ourselves ... FontInfo smallfont = f; smallfont.decSize().decSize().setShape(UP_SHAPE); QFont font2(font); font2.setKerning(false); font2.setPointSizeF(convert<double>(lyxrc.font_sizes[smallfont.size()]) * lyxrc.zoom / 100.0); metrics = GuiFontMetrics(font, font2); } }