X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ffrontends%2Fqt4%2FGuiFontMetrics.C;h=ecfe48722e07ae3c5bf8d75683f58db5147b9d11;hb=591d47a64b8ba894be5c793472397374d0496984;hp=080a3f45c09561025e61f2588d9eeb02f5da6c0b;hpb=7f94f08bbe9d380c4d51145d795dc8c760a78be7;p=lyx.git diff --git a/src/frontends/qt4/GuiFontMetrics.C b/src/frontends/qt4/GuiFontMetrics.C index 080a3f45c0..ecfe48722e 100644 --- a/src/frontends/qt4/GuiFontMetrics.C +++ b/src/frontends/qt4/GuiFontMetrics.C @@ -19,15 +19,11 @@ #include "support/unicode.h" -using lyx::char_type; -using lyx::docstring; - using std::string; namespace lyx { namespace frontend { - GuiFontMetrics::GuiFontMetrics(QFont const & font) : metrics_(font), smallcaps_metrics_(font), smallcaps_shape_(false) { @@ -54,34 +50,6 @@ int GuiFontMetrics::maxDescent() const } -int GuiFontMetrics::ascent(char_type c) const -{ - QRect const & r = metrics_.boundingRect(ucs4_to_qchar(c)); - // Qt/Win 3.2.1nc (at least) corrects the GetGlyphOutlineA|W y - // value by the height: (x, -y-height, width, height). - // Other versions return: (x, -y, width, height) -#if defined(Q_WS_WIN) && (QT_VERSION == 0x030201) - return -r.top() - r.height(); -#else - return -r.top(); -#endif -} - - -int GuiFontMetrics::descent(char_type c) const -{ - QRect const & r = metrics_.boundingRect(ucs4_to_qchar(c)); - // Qt/Win 3.2.1nc (at least) corrects the GetGlyphOutlineA|W y - // value by the height: (x, -y-height, width, height). - // Other versions return: (x, -y, width, height) -#if defined(Q_WS_WIN) && (QT_VERSION == 0x030201) - return r.bottom() + r.height() + 1; -#else - return r.bottom() + 1; -#endif -} - - int GuiFontMetrics::lbearing(char_type c) const { return metrics_.leftBearing(ucs4_to_qchar(c)); @@ -115,20 +83,23 @@ int GuiFontMetrics::smallcapsWidth(QString const & s) const int GuiFontMetrics::width(char_type const * s, size_t ls) const { + // Caution: The following ucs4_to_something conversions work for + // symbol fonts only because they are no real conversions but simple + // casts in reality. + if (ls == 1 && !smallcaps_shape_) { - QChar const c = ucs4_to_qchar(s[0]); - return width(c.unicode()); + return width(s[0]); } - QString ucs2; - ucs4_to_qstring(s, ls, ucs2); - - if (smallcaps_shape_) + if (smallcaps_shape_) { + QString ucs2; + ucs4_to_qstring(s, ls, ucs2); return smallcapsWidth(ucs2); + } int w = 0; for (unsigned int i = 0; i < ls; ++i) - w += width(ucs2[i].unicode()); + w += width(s[i]); return w; } @@ -154,8 +125,11 @@ int GuiFontMetrics::width(QString const & ucs2) const int GuiFontMetrics::signedWidth(docstring const & s) const { + if (s.empty()) + return 0; + if (s[0] == '-') - return -FontMetrics::width(s.substr(1, s.length() - 1)); + return -width(&(s[1]), s.length() - 1); else return FontMetrics::width(s); } @@ -181,18 +155,61 @@ void GuiFontMetrics::buttonText(docstring const & str, descent = metrics_.descent() + d; } -#ifdef USE_LYX_FONTCACHE -int GuiFontMetrics::width(unsigned short val) const +#ifndef USE_LYX_FONTCACHE + +int GuiFontMetrics::ascent(char_type c) const +{ + QRect const & r = metrics_.boundingRect(ucs4_to_qchar(c)); + return -r.top(); +} + + +int GuiFontMetrics::descent(char_type c) const { - GuiFontMetrics::WidthCache::const_iterator cit = widthcache.find(val); - if (cit != widthcache.end()) - return cit->second; + QRect const & r = metrics_.boundingRect(ucs4_to_qchar(c)); + return r.bottom() + 1; +} - int const w = metrics_.width(QChar(val)); - widthcache[val] = w; - return w; +#else + +void GuiFontMetrics::fillMetricsCache(char_type c) const +{ + QRect const & r = metrics_.boundingRect(ucs4_to_qchar(c)); + AscendDescend ad = { -r.top(), r.bottom() + 1}; + // We could as well compute the width but this is not really + // needed for now as it is done directly in width() below. + metrics_cache_.insert(c, ad); } -#endif + +int GuiFontMetrics::width(char_type c) const +{ + if (!width_cache_.contains(c)) { + width_cache_.insert(c, metrics_.width(ucs4_to_qchar(c))); + } + + return width_cache_.value(c); } + + +int GuiFontMetrics::ascent(char_type c) const +{ + if (!metrics_cache_.contains(c)) + fillMetricsCache(c); + + return metrics_cache_.value(c).ascent; } + + +int GuiFontMetrics::descent(char_type c) const +{ + if (!metrics_cache_.contains(c)) + fillMetricsCache(c); + + return metrics_cache_.value(c).descent; +} + +#endif + +} // frontend +} // lyx