/** * \file xfont_metrics.C * This file is part of LyX, the document processor. * Licence details can be found in the file COPYING. * * \author Huang Ying * * Full author contact details are available in file CREDITS. */ #include // Too hard to make concept checks work with this file #ifdef _GLIBCXX_CONCEPT_CHECKS #undef _GLIBCXX_CONCEPT_CHECKS #endif #ifdef _GLIBCPP_CONCEPT_CHECKS #undef _GLIBCPP_CONCEPT_CHECKS #endif #include "GtkmmX.h" #include "xftFontLoader.h" #include "font_metrics.h" #include "lyxrc.h" #include "encoding.h" #include "language.h" #include "support/lstrings.h" #include "debug.h" #include #include #include using std::string; namespace { inline XftFont * getXftFont(LyXFont const & f) { return fontLoader.load(f.family(), f.series(), f.realShape(), f.size()); } inline int XGlyphAscent(XGlyphInfo const & info) { return info.y; } inline int XGlyphDescent(XGlyphInfo const & info) { return info.height - info.y; } inline int XGlyphLbearing(XGlyphInfo const & info) { return -info.x; } inline int XGlyphRbearing(XGlyphInfo const & info) { return -info.x + info.width; } inline int XGlyphLogWidth(XGlyphInfo const & info) { return info.xOff; } } // namespace anon namespace font_metrics { int maxAscent(LyXFont const & f) { XftFont * font = getXftFont(f); return font->ascent; } int maxDescent(LyXFont const & f) { XftFont * font = getXftFont(f); return font->descent; } int ascent(char c,LyXFont const & f) { XftFont * font = getXftFont(f); XGlyphInfo glyph; XftTextExtents8(getDisplay(), font, reinterpret_cast(&c), 1, &glyph); return XGlyphAscent(glyph); } int descent(char c,LyXFont const & f) { XftFont * font = getXftFont(f); XGlyphInfo glyph; XftTextExtents8(getDisplay(), font, reinterpret_cast(&c), 1, &glyph); return XGlyphDescent(glyph); } int lbearing(char c,LyXFont const & f) { XftFont * font = getXftFont(f); XGlyphInfo glyph; XftTextExtents8(getDisplay(), font, reinterpret_cast(&c), 1, &glyph); return XGlyphLbearing(glyph); } int rbearing(char c,LyXFont const & f) { XftFont * font = getXftFont(f); XGlyphInfo glyph; XftTextExtents8(getDisplay(), font, reinterpret_cast(&c), 1, &glyph); return XGlyphRbearing(glyph); } int width(char const * s, size_t n, LyXFont const & f) { XftFont * font = getXftFont(f); XGlyphInfo glyph; if (f.realShape() != LyXFont::SMALLCAPS_SHAPE){ XftTextExtents8(getDisplay(), font, reinterpret_cast(const_cast(s)), n, &glyph); return XGlyphLogWidth(glyph); } else { int result = 0; LyXFont smallfont(f); smallfont.decSize().decSize().setShape(LyXFont::UP_SHAPE); XftFont * fontS = getXftFont(smallfont); for (size_t i = 0; i < n; ++i) { char c = lyx::support::uppercase(s[i]); if (c != s[i]) { XftTextExtents8(getDisplay(), fontS, reinterpret_cast(&c), 1, &glyph); result += XGlyphLogWidth(glyph); } else { XftTextExtents8(getDisplay(), font, reinterpret_cast(&c), 1, &glyph); result += XGlyphLogWidth(glyph); } } return result; } } int signedWidth(string const & s, LyXFont const & f) { if (s.empty()) return 0; if (s[0] == '-') return width(s.c_str() + 1, s.size() - 1, f); else return width(s.c_str(), s.size(), f); } void rectText(string const & str, LyXFont const & font, int & width, int & ascent, int & descent) { static int const d = 2; width = font_metrics::width(str, font) + d * 2 + 2; ascent = font_metrics::maxAscent(font) + d; descent = font_metrics::maxDescent(font) + d; } void buttonText(string const & str, LyXFont const & font, int & width, int & ascent, int & descent) { static int const d = 3; width = font_metrics::width(str, font) + d * 2 + 2; ascent = font_metrics::maxAscent(font) + d; descent = font_metrics::maxDescent(font) + d; } } // namespace font_metrics