On Wed, Dec 06, 2006 at 04:30:09PM +0100, Jean-Marc Lasgouttes wrote: > >>>>> "Enrico" == Enrico Forestieri <[EMAIL PROTECTED]> writes: > >> I would be very interested, but I will need a windows user to do > >> that for me, since I cannot really test. Anyway caching ascent and > >> descent looks like a good idea. > > Enrico> Jean-Marc are you looking at this? I had a quick look but I > Enrico> fear that backporting the patch is not as trivial as I would > Enrico> have hoped. > > I would if I had time. Currently, my free time is ridiculously low. So > I won't look at this these next weeks :(
Of course, after I got my coffee it occurred to me that I should had not tried to backport the patch but rather its philosopy... Please, find attached a patch that caches ascent and descent values on Windows and Mac. I don't activate the cache on *nix because I cannot see a noticeable improvement (I could have sworn I would have seen it), but this is a 'feeling' as I don't performed any measurement. LyX 1.4 is now usable at least as 1.3.7 was on Windows ;-) Jean-Marc, can I apply the patch? BTW, I noticed that LyX crashes if you press page down right after loading this document: http://bugzilla.lyx.org/attachment.cgi?id=1296&action=view The crash occurs with or without this patch, though. I also attach the backtrace I get on linux. -- Enrico
Index: src/frontends/qt2/qfont_loader.C =================================================================== --- src/frontends/qt2/qfont_loader.C (revision 16192) +++ src/frontends/qt2/qfont_loader.C (working copy) @@ -402,3 +402,47 @@ bool FontLoader::available(LyXFont const cache[family] = true; return true; } + + +#if defined(USE_LYX_FONTMETRICSCACHE) +int FontLoader::ascent(LyXFont const & f, char c) +{ + QLFontInfo::MetricsCache & ascentcache = fontinfo(f).ascentcache; + QLFontInfo::MetricsCache::const_iterator cit = ascentcache.find(c); + if (cit != ascentcache.end()) + return cit->second; + + QRect const & r = metrics(f).boundingRect(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) + int const v = -r.top() - r.height(); +#else + int const v = -r.top(); +#endif + ascentcache[c] = v; + return v; +} + + +int FontLoader::descent(LyXFont const & f, char c) +{ + QLFontInfo::MetricsCache & descentcache = fontinfo(f).descentcache; + QLFontInfo::MetricsCache::const_iterator cit = descentcache.find(c); + if (cit != descentcache.end()) + return cit->second; + + QRect const & r = metrics(f).boundingRect(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) + int const v = r.bottom() + r.height() + 1; +#else + int const v = r.bottom() + 1; +#endif + descentcache[c] = v; + return v; +} +#endif Index: src/frontends/qt2/qfont_loader.h =================================================================== --- src/frontends/qt2/qfont_loader.h (revision 16192) +++ src/frontends/qt2/qfont_loader.h (working copy) @@ -22,7 +22,11 @@ #define USE_LYX_FONTCACHE #endif -#if defined(USE_LYX_FONTCACHE) +#if defined(Q_WS_MACX) || defined(Q_WS_WIN) +#define USE_LYX_FONTMETRICSCACHE +#endif + +#if defined(USE_LYX_FONTCACHE) || defined(USE_LYX_FONTMETRICSCACHE) #include <map> #endif @@ -47,6 +51,14 @@ public: /// Cache of char widths WidthCache widthcache; #endif + +#if defined(USE_LYX_FONTMETRICSCACHE) + typedef std::map<char, int> MetricsCache; + /// Cache of char ascents + MetricsCache ascentcache; + /// Cache of char descents + MetricsCache descentcache; +#endif }; @@ -75,6 +87,14 @@ public: return fontinfo(f).metrics; } +#if defined(USE_LYX_FONTMETRICSCACHE) + /// Get the ascent QFont metric for this LyXFont + int ascent(LyXFont const & f, char c); + + /// Get the descent QFont metric for this LyXFont + int descent(LyXFont const & f, char c); +#endif + /// Called before QApplication is initialized static void initFontPath(); Index: src/frontends/qt2/qfont_metrics.C =================================================================== --- src/frontends/qt2/qfont_metrics.C (revision 16192) +++ src/frontends/qt2/qfont_metrics.C (working copy) @@ -46,6 +46,9 @@ int ascent(char c, LyXFont const & f) { if (!lyx_gui::use_gui) return 1; +#if defined(USE_LYX_FONTMETRICSCACHE) + return fontloader.ascent(f, c); +#else QRect const & r = fontloader.metrics(f).boundingRect(c); // Qt/Win 3.2.1nc (at least) corrects the GetGlyphOutlineA|W y // value by the height: (x, -y-height, width, height). @@ -55,6 +58,7 @@ int ascent(char c, LyXFont const & f) #else return -r.top(); #endif +#endif } @@ -62,6 +66,9 @@ int descent(char c, LyXFont const & f) { if (!lyx_gui::use_gui) return 1; +#if defined(USE_LYX_FONTMETRICSCACHE) + return fontloader.descent(f, c); +#else QRect const & r = fontloader.metrics(f).boundingRect(c); // Qt/Win 3.2.1nc (at least) corrects the GetGlyphOutlineA|W y // value by the height: (x, -y-height, width, height). @@ -71,6 +78,7 @@ int descent(char c, LyXFont const & f) #else return r.bottom() + 1; #endif +#endif }
Program received signal SIGSEGV, Segmentation fault. [Switching to Thread -1491155264 (LWP 32374)] 0x080e7141 in CursorSlice::paragraph () (gdb) bt #0 0x080e7141 in CursorSlice::paragraph () #1 0x0819ca87 in LyXText::cursorDown () #2 0x0819d2f4 in LyXText::cursorNext () #3 0x0819f1aa in LyXText::dispatch () #4 0x080e64e4 in LCursor::dispatch () #5 0x081266e9 in LyXFunc::dispatch () #6 0x0812f5db in LyXFunc::processKeySym () #7 0x080659fc in BufferView::Pimpl::workAreaKeyPress () #8 0x08072b84 in boost::detail::function::void_function_obj_invoker2<boost::_bi::bind_t<void, boost::_mfi::mf2<void, BufferView::Pimpl, boost::shared_ptr<LyXKeySym>, key_modifier::state>, boost::_bi::list3<boost::_bi::value<BufferView::Pimpl*>, boost::arg<1> (*)(), boost::arg<2> (*)()> >, void, boost::shared_ptr<LyXKeySym>, key_modifier::state>::invoke () #9 0x0838709d in boost::function2<void, boost::shared_ptr<LyXKeySym>, key_modifier::state, std::allocator<void> >::operator() () #10 0x083873c9 in boost::operator++<boost::signals::detail::slot_call_iterator<boost::signals::detail::call_bound2<void>::caller<boost::shared_ptr<LyXKeySym>, key_modifier::state, boost::function<void ()(boost::shared_ptr<LyXKeySym>, key_modifier::state), std::allocator<void> > >, boost::signals::detail::named_slot_map_iterator>, boost::signals::detail::unusable, boost::single_pass_traversal_tag, boost::signals::detail::unusable const&, int> () #11 0x08387b90 in boost::signal2<void, boost::shared_ptr<LyXKeySym>, key_modifier::state, boost::last_value<void>, int, std::less<int>, boost::function<void ()(---Type <return> to continue, or q <return> to quit--- boost::shared_ptr<LyXKeySym>, key_modifier::state), std::allocator<void> > >::operator() () #12 0x08386434 in QContentPane::keyeventTimeout () #13 0x0838f098 in QContentPane::qt_invoke () #14 0xa7addcb3 in QObject::activate_signal () from /usr/lib/libqt-mt.so.3 #15 0xa7ade744 in QObject::activate_signal () from /usr/lib/libqt-mt.so.3 #16 0xa7e68db6 in QTimer::timeout () from /usr/lib/libqt-mt.so.3 #17 0xa7b05567 in QTimer::event () from /usr/lib/libqt-mt.so.3 #18 0xa7a75bd6 in QApplication::internalNotify () from /usr/lib/libqt-mt.so.3 #19 0xa7a779f3 in QApplication::notify () from /usr/lib/libqt-mt.so.3 #20 0xa7a093d1 in QApplication::sendEvent () from /usr/lib/libqt-mt.so.3 #21 0xa7a685d3 in QEventLoop::activateTimers () from /usr/lib/libqt-mt.so.3 #22 0xa7a1d71f in QEventLoop::processEvents () from /usr/lib/libqt-mt.so.3 #23 0xa7a90129 in QEventLoop::enterLoop () from /usr/lib/libqt-mt.so.3 #24 0xa7a8ff4a in QEventLoop::exec () from /usr/lib/libqt-mt.so.3 #25 0xa7a7776f in QApplication::exec () from /usr/lib/libqt-mt.so.3 #26 0x082c651b in lyx_gui::start () #27 0x081165f9 in LyX::exec2 () #28 0x082c6075 in lyx_gui::exec () #29 0x08116c88 in LyX::priv_exec () #30 0x08116dcc in LyX::exec () #31 0x0806262a in main ()