comparison src/textabbrev.cpp @ 463:3d7070aa959e

Fix extremely slow Text::Abbrev:abbreviate for long texts (was making history scrolling very laggy with long changelogs)
author Chris Cannam
date Mon, 04 Jul 2011 13:31:39 +0100
parents b9c153e00e84
children 6fc4fafc5e6b
comparison
equal deleted inserted replaced
462:110d1fefa073 463:3d7070aa959e
14 License, or (at your option) any later version. See the file 14 License, or (at your option) any later version. See the file
15 COPYING included with this distribution for more information. 15 COPYING included with this distribution for more information.
16 */ 16 */
17 17
18 #include "textabbrev.h" 18 #include "textabbrev.h"
19 #include "debug.h"
19 20
20 #include <QFontMetrics> 21 #include <QFontMetrics>
21 #include <QApplication> 22 #include <QApplication>
22 23
23 #include <iostream> 24 #include <iostream>
90 const QFontMetrics &metrics, int &maxWidth, 91 const QFontMetrics &metrics, int &maxWidth,
91 Policy policy, QString ellipsis, int wrapLines) 92 Policy policy, QString ellipsis, int wrapLines)
92 { 93 {
93 if (ellipsis == "") ellipsis = getDefaultEllipsis(); 94 if (ellipsis == "") ellipsis = getDefaultEllipsis();
94 95
96 // std::cerr << "TextAbbrev::abbreviate: text = " << text << std::endl;
97
95 int tw = metrics.width(text); 98 int tw = metrics.width(text);
99 int tl = text.length();
100
101 // std::cerr << "\n*** TextAbbrev::abbreviate: tw = " << tw << "\n***\n" << std::endl;
96 102
97 if (tw <= maxWidth) { 103 if (tw <= maxWidth) {
98 maxWidth = tw; 104 maxWidth = tw;
99 return text; 105 return text;
100 } 106 }
101 107
102 int truncated = text.length();
103 QString original = text; 108 QString original = text;
104 109
110 int acw = metrics.averageCharWidth();
111
105 if (wrapLines < 2) { 112 if (wrapLines < 2) {
106 113
107 while (tw > maxWidth && truncated > 1) { 114 // std::cerr << "only " << wrapLines << " line(s) remaining, going by character..." << std::endl;
108 115
109 truncated--; 116 int truncateTo = tl;
117
118 while (tw > maxWidth && truncateTo > 1) {
119
120 if (tw > maxWidth + acw * 10) {
121 float ratio = float(maxWidth) / float(tw);
122 truncateTo = int(truncateTo * ratio * 1.2) + 10;
123 if (truncateTo >= tl) truncateTo = tl - 1;
124 } else {
125 truncateTo--;
126 }
110 127
111 if (truncated > ellipsis.length()) { 128 // std::cerr << "truncating from " << tl << " to " << truncateTo << std::endl;
112 text = abbreviateTo(original, truncated, policy, ellipsis); 129
130 if (truncateTo > ellipsis.length()) {
131 text = abbreviateTo(original, truncateTo, policy, ellipsis);
113 } else { 132 } else {
114 break; 133 break;
115 } 134 }
116 135
117 tw = metrics.width(text); 136 tw = metrics.width(text);
118 } 137 tl = text.length() - ellipsis.length();
138 }
139
140 // std::cerr << "done, final tw = " << tw << std::endl;
119 141
120 maxWidth = tw; 142 maxWidth = tw;
121 return text; 143 return text;
122 144
123 } else { 145 } else {
127 149
128 tw = 0; 150 tw = 0;
129 int i = 0; 151 int i = 0;
130 QString good = ""; 152 QString good = "";
131 int lastUsed = 0; 153 int lastUsed = 0;
154
155 // std::cerr << "have " << wrapLines << " lines remaining, going by word..." << std::endl;
156
132 while (tw < maxWidth && i < words.size()) { 157 while (tw < maxWidth && i < words.size()) {
133 if (text != "") text += " "; 158 if (text != "") text += " ";
134 text += words[i++]; 159 text += words[i++];
135 tw = metrics.width(text); 160 tw = metrics.width(text);
136 if (tw < maxWidth) { 161 if (tw < maxWidth) {
137 good = text; 162 good = text;
138 lastUsed = i; 163 lastUsed = i;
139 } 164 }
140 } 165 }
166
167 // std::cerr << "done" << std::endl;
141 168
142 if (tw < maxWidth) { 169 if (tw < maxWidth) {
143 maxWidth = tw; 170 maxWidth = tw;
144 return text; 171 return text;
145 } 172 }