[Aptitude-svn-commit] r3433 - in branches/aptitude-0.3/aptitude: . src/vscreen
Daniel Burrows
dburrows@costa.debian.org
Sat, 25 Jun 2005 20:29:22 +0000
Author: dburrows
Date: Sat Jun 25 20:29:20 2005
New Revision: 3433
Modified:
branches/aptitude-0.3/aptitude/ChangeLog
branches/aptitude-0.3/aptitude/src/vscreen/fragment.cc
Log:
Rewrite the main flow algorithm to handle wide characters.
Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog (original)
+++ branches/aptitude-0.3/aptitude/ChangeLog Sat Jun 25 20:29:20 2005
@@ -1,5 +1,10 @@
2005-06-25 Daniel Burrows <dburrows@debian.org>
+ * src/vscreen/fragment.cc:
+
+ Rewrite the main flow algorithm to handle wide characters (i.e.,
+ separate the concepts of "visible width" and "character count").
+
* src/vscreen/columnify.cc, src/vscren/columnify.h, src/vscreen/config/column_definition.cc, src/vscreen/config/column_definition.h:
Rewrite the columnification code to handle wide characters
Modified: branches/aptitude-0.3/aptitude/src/vscreen/fragment.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/fragment.cc (original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/fragment.cc Sat Jun 25 20:29:20 2005
@@ -38,13 +38,13 @@
size_t max_width(size_t first_indent,
size_t rest_indent) const
{
- return first_indent+s.size();
+ return first_indent+wcswidth(s.c_str(), s.size());
}
size_t trailing_width(size_t first_indent,
size_t rest_indent) const
{
- return first_indent+s.size();
+ return first_indent+wcswidth(s.c_str(), s.size());
}
bool final_newline() const
@@ -258,15 +258,15 @@
firstw=restw;
else if(lines.size()>0)
{
- size_t deduct_from;
+ int deduct_from;
if(lines.size()==1)
deduct_from=firstw;
else
deduct_from=restw;
- if(deduct_from>=lines.back().size())
- firstw=deduct_from-lines.back().size();
+ if(deduct_from>=lines.back().width())
+ firstw=deduct_from-lines.back().width();
else
firstw=0;
}
@@ -433,39 +433,83 @@
// If there are few enough characters to fit on a single
// line, do that.
- if(s.size()-first<=firstw)
+ fragment_line maybe_curr(s, first, s.size()-first);
+ if(maybe_curr.width()<=(signed) firstw)
{
- rval.push_back(fragment_line(s, first, s.size()-first));
+ rval.push_back(maybe_curr);
firstw=restw;
first=s.size();
output_something=true;
}
else
{
- size_t amt=firstw;
+ int chunkw=0;
+ size_t chars=0;
+ while(chunkw<(signed) firstw && chars+first<s.size())
+ {
+ chunkw+=wcwidth(s[first+chars].ch);
+ ++chars;
+ }
- while(amt>0 && !iswspace(s[first+amt].ch))
- --amt;
+ // Save this for later (see below). Note that if we
+ // actually overshot the width goal, we need to
+ // possibly strip the last character off (it's
+ // guaranteed to be only one since otherwise we'd have
+ // stopped sooner...)
+ const size_t high_water_mark=chars;
+ const int high_water_width=chunkw;
+
+ // We pushed the line as far as possible; back up
+ // until we are no longer in the middle of a word AND
+ // the string is short enough. (we know it's not at
+ // the end of the whole string because of the earlier
+ // test)
+ while(chars>0 && (chunkw>(signed) firstw ||
+ !iswspace(s[first+chars].ch)))
+ {
+ --chars;
+ chunkw-=wcwidth(s[first+chars].ch);
+ }
- // Oops, there's a word that's longer than the current line.
- if(amt==0)
+ if(chars==0)
{
- rval.push_back(fragment_line(s, first, firstw));
- first+=firstw;
+ // Oops, there's a word that's longer than the
+ // current line. Push as much as fits onto the
+ // current line.
+
+ // First, try to exclude any characters that
+ // overlap the right margin.
+ chars=high_water_mark;
+ chunkw=high_water_width;
+ while(chars>0 && chunkw>(signed) firstw)
+ {
+ --chars;
+ chunkw-=wcwidth(s[first+chars].ch);
+ }
+
+ // If even that's impossible, go ahead and push a
+ // single character onto the end. Note that this
+ // means we're probably in such a tiny space that
+ // the result will suck no matter what..
+ if(chars==0)
+ chars=1;
+
+ rval.push_back(fragment_line(s, first, chars));
+ first+=chars;
firstw=restw;
output_something=true;
}
else
{
- // Eh, strip trailing whitespace.
- while(amt>0 &&
- isspace(s[first+amt].ch) &&
- isspace(s[first+amt-1].ch))
- --amt;
+ // Strip trailing whitespace, then `output' the
+ // line.
+ while(chars>0 &&
+ iswspace(s[first+chars-1].ch))
+ --chars;
- rval.push_back(fragment_line(s, first, amt));
+ rval.push_back(fragment_line(s, first, chars));
firstw=restw;
- first+=amt;
+ first+=chars;
output_something=true;
}
}