namespace lyx {
namespace frontend {
-namespace {
-// Used for checking initialisation state of the C-ish metrics table.
-const short int BadMetrics = -1000;
-}
-
-
GuiFontMetrics::GuiFontMetrics(QFont const & font)
: metrics_(font), smallcaps_metrics_(font), smallcaps_shape_(false)
{
-#ifdef USE_LYX_FONTCACHE
- for (size_t i = 0; i != MaxCharType; ++i) {
- metrics_cache_[i].width = BadMetrics;
- metrics_cache_[i].ascent = BadMetrics;
- metrics_cache_[i].descent = BadMetrics;
- }
-#endif
}
#else
-void GuiFontMetrics::fillCache(unsigned short val) const
+void GuiFontMetrics::fillMetricsCache(char_type c) const
{
- QRect const & r = metrics_.boundingRect(QChar(val));
- metrics_cache_[val].descent = static_cast<short>(r.bottom() + 1);
- metrics_cache_[val].ascent = static_cast<short>(-r.top());
+ 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_[val].width = metrics_.width(QChar(val));
+ metrics_cache_.insert(c, ad);
}
int GuiFontMetrics::width(char_type c) const
{
- // FIXME: The following cast is not a real conversion but it work
- // for the ucs2 subrange of unicode. Instead of an assertion we should
- // give the metrics of some special characters that indicates that
- // its display is not supported.
- BOOST_ASSERT(c < MaxCharType);
- unsigned short val = static_cast<unsigned short>(c);
- if (metrics_cache_[val].width == BadMetrics) {
- metrics_cache_[val].width
- = static_cast<short>(metrics_.width(QChar(val)));
+ if (!width_cache_.contains(c)) {
+ width_cache_.insert(c, metrics_.width(ucs4_to_qchar(c)));
}
- return metrics_cache_[val].width;
+ return width_cache_.value(c);
}
int GuiFontMetrics::ascent(char_type c) const
{
- // FIXME: The following cast is not a real conversion but it work
- // for the ucs2 subrange of unicode. Instead of an assertion we should
- // give the metrics of some special characters that indicates that
- // its display is not supported.
- BOOST_ASSERT(c < MaxCharType);
- unsigned short val = static_cast<unsigned short>(c);
- if (metrics_cache_[val].ascent == BadMetrics)
- fillCache(val);
+ if (!metrics_cache_.contains(c))
+ fillMetricsCache(c);
- return metrics_cache_[val].ascent;
+ return metrics_cache_.value(c).ascent;
}
int GuiFontMetrics::descent(char_type c) const
{
- // FIXME: The following cast is not a real conversion but it work
- // for the ucs2 subrange of unicode. Instead of an assertion we should
- // give the metrics of some special characters that indicates that
- // its display is not supported.
- BOOST_ASSERT(c < MaxCharType);
- unsigned short val = static_cast<unsigned short>(c);
- if (metrics_cache_[val].descent == BadMetrics)
- fillCache(val);
+ if (!metrics_cache_.contains(c))
+ fillMetricsCache(c);
- return metrics_cache_[val].descent;
+ return metrics_cache_.value(c).descent;
}
#endif
#include "support/docstring.h"
#include <QFontMetrics>
+#include <QHash>
// Starting with version 3.1.0, Qt/X11 does its own caching of
// character width, so it is not necessary to provide ours.
namespace lyx {
namespace frontend {
-size_t const MaxCharType = 65536;
-
-struct CharMetrics
-{
- short int width;
- short int ascent;
- short int descent;
-};
-
-
class GuiFontMetrics: public FontMetrics
{
public:
bool smallcaps_shape_;
#ifdef USE_LYX_FONTCACHE
- /// fill in \c metrics_cache_ at specified value.
- void fillCache(unsigned short val) const;
+
/// Cache of char widths
/** This cache adds 20Mo of memory to the LyX executable when
* loading UserGuide.lyx which contains a good number of fonts. If
* this turns out to be too much, we can switch to a \c QHash based
* solution.
**/
- mutable CharMetrics metrics_cache_[MaxCharType];
+ mutable QHash<char_type, int> width_cache_;
+
+ struct AscendDescend {
+ short int ascent;
+ short int descent;
+ };
+ mutable QHash<char_type, AscendDescend> metrics_cache_;
+ /// fill in \c metrics_cache_ at specified value.
+ void fillMetricsCache(char_type) const;
+
#endif // USE_LYX_FONTCACHE
};