Here it is. OK ? This is a little faster; sub-second times on userguide are now common, so it's pretty much on a par with xforms (glacial) speed
regards john -- "Saying that taste is just personal preference is a good way to prevent disputes. The trouble is, it's not true." - Paul Graham
Index: qfont_loader.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/qt2/qfont_loader.h,v retrieving revision 1.8 diff -u -r1.8 qfont_loader.h --- qfont_loader.h 17 Nov 2002 10:34:17 -0000 1.8 +++ qfont_loader.h 10 Dec 2002 19:03:13 -0000 @@ -16,6 +16,9 @@ #pragma interface #endif +#include <map> + +#include "encoding.h" #include "lyxfont.h" #include <qfont.h> @@ -44,6 +47,10 @@ QFontMetrics const & metrics(LyXFont const & f) { return getfontinfo(f)->metrics; } + + /// return pixel width for the given unicode char + short charwidth(LyXFont const & f, Uchar val); + private: /// hold info about a particular font struct font_info { @@ -53,13 +60,17 @@ QFont font; /// metrics on the font QFontMetrics metrics; + + typedef std::map<Uchar, short> WidthCache; + /// cache of char widths + WidthCache widthcache; }; /// get font info (font + metrics) for the given LyX font. Does not fail. - font_info const * getfontinfo(LyXFont const & f); + font_info * getfontinfo(LyXFont const & f); /// BUTT ugly ! - font_info const * fontinfo_[LyXFont::NUM_FAMILIES][2][4][10]; + font_info * fontinfo_[LyXFont::NUM_FAMILIES][2][4][10]; }; extern qfont_loader fontloader; Index: qfont_loader.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/qt2/qfont_loader.C,v retrieving revision 1.21 diff -u -r1.21 qfont_loader.C --- qfont_loader.C 1 Dec 2002 22:59:19 -0000 1.21 +++ qfont_loader.C 10 Dec 2002 19:03:13 -0000 @@ -23,6 +23,7 @@ #include "qt_helpers.h" #include <qglobal.h> +#include <qfontmetrics.h> #if QT_VERSION < 300 #include "support/lstrings.h" #endif @@ -225,13 +226,13 @@ } -qfont_loader::font_info const * qfont_loader::getfontinfo(LyXFont const & f) +qfont_loader::font_info * qfont_loader::getfontinfo(LyXFont const & f) { if (!lyxrc.use_gui) { // FIXME } - font_info const * fi = fontinfo_[f.family()][f.series()][f.realShape()][f.size()]; + font_info * fi = fontinfo_[f.family()][f.series()][f.realShape()][f.size()]; if (!fi) { fi = new font_info(f); fontinfo_[f.family()][f.series()][f.realShape()][f.size()] = fi; @@ -241,6 +242,20 @@ } +short qfont_loader::charwidth(LyXFont const & f, Uchar val) +{ + font_info * fi = getfontinfo(f); + + font_info::WidthCache::const_iterator cit = fi->widthcache.find(val); + if (cit != fi->widthcache.end()) + return cit->second; + + short const w = fi->metrics.width(QChar(val)); + fi->widthcache[val] = w; + return w; +} + + bool qfont_loader::available(LyXFont const & f) { if (!lyxrc.use_gui) Index: qfont_metrics.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/qt2/qfont_metrics.C,v retrieving revision 1.17 diff -u -r1.17 qfont_metrics.C --- qfont_metrics.C 21 Oct 2002 15:51:06 -0000 1.17 +++ qfont_metrics.C 10 Dec 2002 19:03:14 -0000 @@ -24,8 +24,7 @@ #include <qfontmetrics.h> #include <qfont.h> - - + namespace { QFontMetrics const & metrics(LyXFont const & f) @@ -33,6 +32,12 @@ return fontloader.metrics(f); } + +int charwidth(Uchar val, LyXFont const & f) +{ + return fontloader.charwidth(f, val); +} + } // namespace anon @@ -46,22 +51,22 @@ int maxDescent(LyXFont const & f) { - return metrics(f).descent()+1; // We add 1 as the value returned by QT is different than X // See http://doc.trolltech.com/2.3/qfontmetrics.html#200b74 + return metrics(f).descent() + 1; } int ascent(char c, LyXFont const & f) { - QRect r = metrics(f).boundingRect(c); + QRect const & r = metrics(f).boundingRect(c); return -r.top(); } int descent(char c, LyXFont const & f) { - QRect r = metrics(f).boundingRect(c); + QRect const & r = metrics(f).boundingRect(c); return r.bottom()+1; } @@ -81,43 +86,59 @@ } -int width(char const * s, size_t ls, LyXFont const & f) +Encoding const * fontencoding(LyXFont const & f) { Encoding const * encoding = f.language()->encoding(); if (f.isSymbolFont()) encoding = encodings.symbol_encoding(); + return encoding; +} + - QString str; -#if QT_VERSION >= 300 - str.setLength(ls); - for (size_t i = 0; i < ls; ++i) - str[i] = QChar(encoding->ucs(s[i])); -#else - for (size_t i = 0; i < ls; ++i) - str += QChar(encoding->ucs(s[i])); -#endif - - if (f.realShape() != LyXFont::SMALLCAPS_SHAPE) { - return metrics(f).width(str); - } - +int smallcapswidth(char const * s, size_t ls, LyXFont const & f) +{ // handle small caps ourselves ... LyXFont smallfont(f); smallfont.decSize().decSize().setShape(LyXFont::UP_SHAPE); - QFontMetrics qm = fontloader.metrics(f); - QFontMetrics qsmallm = fontloader.metrics(smallfont); + QFontMetrics const & qm = fontloader.metrics(f); + QFontMetrics const & qsmallm = fontloader.metrics(smallfont); + Encoding const * encoding(fontencoding(f)); + int w = 0; for (size_t i = 0; i < ls; ++i) { - QChar const c = str[i].upper(); - if (c != str[i]) - w += qsmallm.width(c); + QChar const c = QChar(encoding->ucs(s[i])); + QChar const uc = c.upper(); + if (c != uc) + w += qsmallm.width(uc); else w += qm.width(c); } + return w; +} + + +int width(char const * s, size_t ls, LyXFont const & f) +{ + if (f.realShape() == LyXFont::SMALLCAPS_SHAPE) { + return smallcapswidth(s, ls, f); + } + + Encoding const * encoding(fontencoding(f)); + + if (ls == 1) { + return charwidth(encoding->ucs(s[0]), f); + } + + int w = 0; + + for (size_t i = 0; i < ls; ++i) { + w += charwidth(encoding->ucs(s[i]), f); + } + return w; }