mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-27 03:36:39 +00:00
* qt_helpers.h:
- ucs4_to_qchar(): add a FIXME and an assertion * GuiFontMetrics: replace the table based cache with two QHash based cache. With this change, the speed overhead is not negligible (exact same score with the UserGuide test) and the required additional memory is minimal (maybe one or two megabytes). git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@16132 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
b2e5732971
commit
591d47a64b
@ -24,22 +24,9 @@ using std::string;
|
|||||||
namespace lyx {
|
namespace lyx {
|
||||||
namespace frontend {
|
namespace frontend {
|
||||||
|
|
||||||
namespace {
|
|
||||||
// Used for checking initialisation state of the C-ish metrics table.
|
|
||||||
const short int BadMetrics = -1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
GuiFontMetrics::GuiFontMetrics(QFont const & font)
|
GuiFontMetrics::GuiFontMetrics(QFont const & font)
|
||||||
: metrics_(font), smallcaps_metrics_(font), smallcaps_shape_(false)
|
: 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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -185,61 +172,41 @@ int GuiFontMetrics::descent(char_type c) const
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
void GuiFontMetrics::fillCache(unsigned short val) const
|
void GuiFontMetrics::fillMetricsCache(char_type c) const
|
||||||
{
|
{
|
||||||
QRect const & r = metrics_.boundingRect(QChar(val));
|
QRect const & r = metrics_.boundingRect(ucs4_to_qchar(c));
|
||||||
metrics_cache_[val].descent = static_cast<short>(r.bottom() + 1);
|
AscendDescend ad = { -r.top(), r.bottom() + 1};
|
||||||
metrics_cache_[val].ascent = static_cast<short>(-r.top());
|
|
||||||
// We could as well compute the width but this is not really
|
// We could as well compute the width but this is not really
|
||||||
// needed for now as it is done directly in width() below.
|
// 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
|
int GuiFontMetrics::width(char_type c) const
|
||||||
{
|
{
|
||||||
// FIXME: The following cast is not a real conversion but it work
|
if (!width_cache_.contains(c)) {
|
||||||
// for the ucs2 subrange of unicode. Instead of an assertion we should
|
width_cache_.insert(c, metrics_.width(ucs4_to_qchar(c)));
|
||||||
// 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)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return metrics_cache_[val].width;
|
return width_cache_.value(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int GuiFontMetrics::ascent(char_type c) const
|
int GuiFontMetrics::ascent(char_type c) const
|
||||||
{
|
{
|
||||||
// FIXME: The following cast is not a real conversion but it work
|
if (!metrics_cache_.contains(c))
|
||||||
// for the ucs2 subrange of unicode. Instead of an assertion we should
|
fillMetricsCache(c);
|
||||||
// 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);
|
|
||||||
|
|
||||||
return metrics_cache_[val].ascent;
|
return metrics_cache_.value(c).ascent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int GuiFontMetrics::descent(char_type c) const
|
int GuiFontMetrics::descent(char_type c) const
|
||||||
{
|
{
|
||||||
// FIXME: The following cast is not a real conversion but it work
|
if (!metrics_cache_.contains(c))
|
||||||
// for the ucs2 subrange of unicode. Instead of an assertion we should
|
fillMetricsCache(c);
|
||||||
// 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);
|
|
||||||
|
|
||||||
return metrics_cache_[val].descent;
|
return metrics_cache_.value(c).descent;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "support/docstring.h"
|
#include "support/docstring.h"
|
||||||
|
|
||||||
#include <QFontMetrics>
|
#include <QFontMetrics>
|
||||||
|
#include <QHash>
|
||||||
|
|
||||||
// Starting with version 3.1.0, Qt/X11 does its own caching of
|
// Starting with version 3.1.0, Qt/X11 does its own caching of
|
||||||
// character width, so it is not necessary to provide ours.
|
// character width, so it is not necessary to provide ours.
|
||||||
@ -27,16 +28,6 @@
|
|||||||
namespace lyx {
|
namespace lyx {
|
||||||
namespace frontend {
|
namespace frontend {
|
||||||
|
|
||||||
size_t const MaxCharType = 65536;
|
|
||||||
|
|
||||||
struct CharMetrics
|
|
||||||
{
|
|
||||||
short int width;
|
|
||||||
short int ascent;
|
|
||||||
short int descent;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class GuiFontMetrics: public FontMetrics
|
class GuiFontMetrics: public FontMetrics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -82,15 +73,23 @@ private:
|
|||||||
bool smallcaps_shape_;
|
bool smallcaps_shape_;
|
||||||
|
|
||||||
#ifdef USE_LYX_FONTCACHE
|
#ifdef USE_LYX_FONTCACHE
|
||||||
/// fill in \c metrics_cache_ at specified value.
|
|
||||||
void fillCache(unsigned short val) const;
|
|
||||||
/// Cache of char widths
|
/// Cache of char widths
|
||||||
/** This cache adds 20Mo of memory to the LyX executable when
|
/** This cache adds 20Mo of memory to the LyX executable when
|
||||||
* loading UserGuide.lyx which contains a good number of fonts. If
|
* 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
|
* this turns out to be too much, we can switch to a \c QHash based
|
||||||
* solution.
|
* 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
|
#endif // USE_LYX_FONTCACHE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -78,6 +78,11 @@ inline char_type const qchar_to_ucs4(QChar const & qchar) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline QChar const ucs4_to_qchar(char_type const ucs4) {
|
inline QChar const ucs4_to_qchar(char_type const ucs4) {
|
||||||
|
// FIXME: The following cast is not a real conversion but it work
|
||||||
|
// for the ucs2 subrange of unicode. Instead of an assertion we should
|
||||||
|
// return some special characters that indicates that its display is
|
||||||
|
// not supported.
|
||||||
|
BOOST_ASSERT(ucs4 < 65536);
|
||||||
return QChar(static_cast<unsigned short>(ucs4));
|
return QChar(static_cast<unsigned short>(ucs4));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user