Implement real string width computation

Important features:
* widths are cached in a map
* old behavior is still used when lyxrc.force_paint_single_char is true.
This commit is contained in:
Jean-Marc Lasgouttes 2013-06-25 08:18:25 +02:00
parent b044696d59
commit 8539f756ed
3 changed files with 36 additions and 21 deletions

View File

@ -5,20 +5,29 @@ for now we intend to keep unchanged behavior for testing purposes.
What is done:
* Make TextMetrics methods operate on Row objects: breakRow and
setRowHeight instead of rowBreakPoint and rowHeight.
setRowHeight instead of rowBreakPoint and rowHeight.
* change breakRow operation to operate on text strings on which
metrics are computed. Note that for now FontMetrics::width(docstring)
still computes the sum of character widths, so that behavior is
unchanged.
metrics are computed. Note that for now
FontMetrics::width(docstring) still computes the sum of character
widths, so that behavior is unchanged.
* Implement proper string metrics computation (with cache), when
lyxrc.force_paint_single_char is false.
Next steps:
* Make breakRow build a list of elements (string, inset,
separator,...) in the row. This will be reused by other methods
separator,...) in the row. This will be reused by other methods
* get rid of rowWidth (breakRow does compute this)
* re-implement getColumnNearX using row elements
* re-implement x2pos using row elements
* re-implement row painting using row elements
* Finally, implement proper string metrics computation (with cache)
* re-implement cursorX using row elements
* re-implement row painting using row elements (can it be done?)
* profile and see how performance can be improved.
Difference in behavior

View File

@ -15,8 +15,9 @@
#include "qt_helpers.h"
#include "Language.h"
#include "Dimension.h"
#include "Language.h"
#include "LyXRC.h"
#include "insets/Inset.h"
@ -110,21 +111,20 @@ int GuiFontMetrics::rbearing(char_type c) const
int GuiFontMetrics::width(docstring const & s) const
{
size_t ls = s.size();
int w = 0;
for (unsigned int i = 0; i < ls; ++i) {
//FIXME: we need to detect surrogate pairs and act accordingly
/**
if isSurrogateBase(s[i]) {
docstring c = s[i];
w += metrics_.width(toqstr(c + s[i + 1]));
++i;
}
else
*/
if (lyxrc.force_paint_single_char) {
size_t const ls = s.size();
for (size_t i = 0; i < ls; ++i)
w += width(s[i]);
} else {
map<docstring, int>::const_iterator it = strwidth_cache_.find(s);
if (it != strwidth_cache_.end()) {
w = it->second;
} else {
w = metrics_.width(toqstr(s));
strwidth_cache_[s] = w;
}
}
return w;
}

View File

@ -16,6 +16,8 @@
#include "support/docstring.h"
#include <map>
#include <QFontMetrics>
#include <QHash>
@ -59,6 +61,10 @@ private:
/// Cache of char widths
mutable QHash<char_type, int> width_cache_;
/// Cache of string widths
/// FIXME Try to use a QHash (this requires to define qHash(docstring))
mutable std::map<docstring, int> strwidth_cache_;
struct AscendDescend {
int ascent;
int descent;