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 ()