[Aptitude-devel] r3094 - in branches/aptitude-0.3/aptitude: . src/cmdline src/vscreen

Daniel Burrows dburrows@costa.debian.org
Tue, 26 Apr 2005 14:58:10 +0000


Author: dburrows
Date: Tue Apr 26 14:58:06 2005
New Revision: 3094

Modified:
   branches/aptitude-0.3/aptitude/ChangeLog
   branches/aptitude-0.3/aptitude/src/cmdline/cmdline_show.cc
   branches/aptitude-0.3/aptitude/src/vscreen/fragment.cc
   branches/aptitude-0.3/aptitude/src/vscreen/fragment.h
   branches/aptitude-0.3/aptitude/src/vscreen/vs_layout_item.cc
   branches/aptitude-0.3/aptitude/src/vscreen/vs_text_layout.cc
Log:
Make the text layout algorithm also take indentation into account.

Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog	(original)
+++ branches/aptitude-0.3/aptitude/ChangeLog	Tue Apr 26 14:58:06 2005
@@ -1,5 +1,10 @@
 2005-04-26  Daniel Burrows  <dburrows@debian.org>
 
+	* src/cmdline/cmdline_show.cc, src/vscreen/fragment.cc, src/vscreen/fragment.h, src/vscreen/vs_layout_item.cc, src/vscreen/vs_text_layout.cc:
+
+	  Make the text layout algorithm also take indentation into
+	  account.
+
 	* src/vscreen/fragment.cc, src/vscreen/fragment.h, src/vscreen/vs_text_layout.cc:
 
 	  Adjust the fragment width calculation to properly take

Modified: branches/aptitude-0.3/aptitude/src/cmdline/cmdline_show.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/cmdline/cmdline_show.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/cmdline/cmdline_show.cc	Tue Apr 26 14:58:06 2005
@@ -238,7 +238,7 @@
 
   fragment *f=sequence_fragment(fragments);
 
-  cout << f->layout(screen_width);
+  cout << f->layout(screen_width, screen_width);
 
   delete f;
 }
@@ -330,7 +330,7 @@
     {
       fragment *f=version_file_fragment(ver, ver.FileList(), verbose);
 
-      cout << f->layout(screen_width);
+      cout << f->layout(screen_width, screen_width);
 
       delete f;
     }
@@ -340,7 +340,7 @@
 	{
 	  fragment *f=version_file_fragment(ver, vf, verbose);
 
-	  cout << f->layout(screen_width) << endl;
+	  cout << f->layout(screen_width, screen_width) << endl;
 
 	  delete f;
 

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	Tue Apr 26 14:58:06 2005
@@ -24,7 +24,7 @@
 public:
   _text_fragment(const chstring &_s):s(_s) {}
 
-  fragment_contents layout(size_t w)
+  fragment_contents layout(size_t firstw, size_t restw)
   {
     fragment_contents rval;
     rval.push_back(s);
@@ -69,7 +69,7 @@
 public:
   _newline_fragment() {}
 
-  fragment_contents layout(size_t w)
+  fragment_contents layout(size_t firstw, size_t restw)
   {
     fragment_contents rval;
     rval.set_final_nl(true);
@@ -181,7 +181,7 @@
   {
   }
 
-  fragment_contents layout(size_t w)
+  fragment_contents layout(size_t firstw, const size_t restw)
   {
     fragment_contents rval;
 
@@ -190,7 +190,25 @@
     for(vector<fragment*>::const_iterator i=contents.begin();
 	i!=contents.end(); ++i)
       {
-	fragment_contents lines=(*i)->layout(w);
+	fragment_contents lines=(*i)->layout(firstw, restw);
+
+	// Update firstw appropriately.
+	if(lines.get_final_nl())
+	  firstw=restw;
+	else if(lines.size()>0)
+	  {
+	    size_t 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();
+	    else
+	      firstw=0;
+	  }
 
 	// Make sure that implicit newlines are handled correctly.
 	if(lines.size()==0)
@@ -331,12 +349,12 @@
 public:
   _flowbox(fragment *_contents):contents(_contents) {}
 
-  fragment_contents layout(size_t w)
+  fragment_contents layout(size_t firstw, const size_t restw)
   {
-    if(w==0)
+    if(restw==0)
       return fragment_contents();
 
-    fragment_contents rval,lines=contents->layout(w);
+    fragment_contents rval,lines=contents->layout(firstw, restw);
 
     for(fragment_contents::const_iterator i=lines.begin();
 	i!=lines.end(); ++i)
@@ -362,15 +380,16 @@
 
 	    // If there are few enough characters to fit on a single
 	    // line, do that.
-	    if(s.size()-first<=w)
+	    if(s.size()-first<=firstw)
 	      {
 		rval.push_back(chstring(s, first, s.size()-first));
+		firstw=restw;
 		first=s.size();
 		output_something=true;
 	      }
 	    else
 	      {
-		size_t amt=w;
+		size_t amt=firstw;
 
 		while(amt>0 && !isspace(s[first+amt]&A_CHARTEXT))
 		  --amt;
@@ -378,9 +397,10 @@
 		// Oops, there's a word that's longer than the current line.
 		if(amt==0)
 		  {
-		    rval.push_back(chstring(s, first, w));
+		    rval.push_back(chstring(s, first, firstw));
+		    first+=firstw;
+		    firstw=restw;
 		    output_something=true;
-		    first+=w;
 		  }
 		else
 		  {
@@ -391,6 +411,7 @@
 		      --amt;
 
 		    rval.push_back(chstring(s, first, amt));
+		    firstw=restw;
 		    first+=amt;
 		    output_something=true;
 		  }
@@ -398,7 +419,10 @@
 	  }
 
 	if(!output_something)
-	  rval.push_back(chstring(""));
+	  {
+	    rval.push_back(chstring(""));
+	    firstw=restw;
+	  }
 
 	// Ok, go to the next line now.
       }
@@ -441,12 +465,12 @@
 public:
   _fillbox(fragment *_contents):contents(_contents) {}
 
-  fragment_contents layout(size_t w)
+  fragment_contents layout(size_t firstw, size_t restw)
   {
-    if(w==0)
+    if(restw==0)
       return fragment_contents();
 
-    fragment_contents rval,lines=contents->layout(w);
+    fragment_contents rval,lines=contents->layout(firstw, restw);
 
     for(fragment_contents::const_iterator i=lines.begin();
 	i!=lines.end(); ++i)
@@ -488,7 +512,7 @@
 	    // As long as adding the *next* word doesn't put us
 	    // past the right edge, add it.
 	    while(word_start+nwords < words.size() &&
-		  curwidth+words[word_start+nwords].size()+nwords <= w)
+		  curwidth+words[word_start+nwords].size()+nwords <= firstw)
 	      {
 		curwidth=curwidth+words[word_start+nwords].size();
 		++nwords;
@@ -497,8 +521,9 @@
 	    if(nwords==0)
 	      {
 		// Split a single word: just chop the beginning off.
-		rval.push_back(chstring(words[word_start], 0, w));
-		words[word_start]=chstring(words[word_start], w);
+		rval.push_back(chstring(words[word_start], 0, firstw));
+		words[word_start]=chstring(words[word_start], firstw);
+		firstw=restw;
 		output_something=true;
 	      }
 	    else
@@ -506,7 +531,7 @@
 		size_t diff;
 
 		if(word_start+nwords<words.size())
-		  diff=w-(curwidth+nwords-1);
+		  diff=firstw-(curwidth+nwords-1);
 		else
 		  // Cheat to disable fililng on the last line of the
 		  // paragraph.
@@ -542,13 +567,17 @@
 
 		output_something=true;
 		rval.push_back(final);
+		firstw=restw;
 
 		word_start+=nwords;
 	      }
 	  }
 
 	if(!output_something)
-	  rval.push_back(chstring(""));
+	  {
+	    rval.push_back(chstring(""));
+	    firstw=restw;
+	  }
       }
 
     // fillboxes always have a final newline.
@@ -591,31 +620,38 @@
 
   ~_hardwrapbox() {delete contents;}
 
-  fragment_contents layout(size_t w)
+  fragment_contents layout(size_t firstw, const size_t restw)
   {
-    if(w==0)
+    if(restw==0)
       return fragment_contents();
 
-    fragment_contents rval, lines=contents->layout(w);
+    fragment_contents rval, lines=contents->layout(firstw, restw);
 
     for(fragment_contents::const_iterator i=lines.begin();
 	i!=lines.end(); ++i)
       {
 	if(i->empty())
-	  rval.push_back(chstring(""));
+	  {
+	    rval.push_back(chstring(""));
+	    firstw=restw;
+	  }
 	else
 	  {
 	    chstring s=*i;
 	    chstring::size_type start=0;
 
-	    while(s.size()-start>w)
+	    while(s.size()-start>firstw)
 	      {
-		rval.push_back(chstring(s, start, w));
-		start+=w;
+		rval.push_back(chstring(s, start, firstw));
+		start+=firstw;
+		firstw=restw;
 	      }
 
 	    if(start<s.size())
-	      rval.push_back(chstring(s, start));
+	      {
+		rval.push_back(chstring(s, start));
+		firstw=restw;
+	      }
 	  }
       }
 
@@ -655,16 +691,18 @@
 public:
   _clipbox(fragment *_contents):contents(_contents) {}
 
-  fragment_contents layout(size_t w)
+  fragment_contents layout(size_t firstw, const size_t restw)
   {
-    fragment_contents rval, lines=contents->layout(w);
+    fragment_contents rval, lines=contents->layout(firstw, restw);
 
     for(fragment_contents::const_iterator i=lines.begin(); i!=lines.end(); ++i)
       {
-	if(i->size()<=w)
+	if(i->size()<=firstw)
 	  rval.push_back(*i);
 	else
-	  rval.push_back(chstring(*i, 0, w));
+	  rval.push_back(chstring(*i, 0, firstw));
+
+	firstw=restw;
       }
 
     // Clipboxes are always followed by a final newline.
@@ -707,15 +745,19 @@
     :contents(_contents), indentattr(0),
      firstindent(_firstindent), restindent(_restindent) {}
 
-  fragment_contents layout(size_t w)
+  fragment_contents layout(size_t firstw, size_t restw)
   {
-    if(w<=firstindent || w<=restindent)
+    if(restw<=restindent)
       return fragment_contents();
 
     fragment_line firstprepend(firstindent, ' '|indentattr);
     fragment_line restprepend(restindent, ' '|indentattr);
 
-    fragment_contents rval, lines=contents->layout(w-restindent);
+    size_t child_firstw=firstw>=firstindent?firstw-firstindent:0;
+    size_t child_restw=restw>=restindent?restw-restindent:0;
+
+    fragment_contents rval, lines=contents->layout(child_firstw,
+						   child_restw);
 
     for(fragment_contents::const_iterator i=lines.begin(); i!=lines.end(); ++i)
       {

Modified: branches/aptitude-0.3/aptitude/src/vscreen/fragment.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/fragment.h	(original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/fragment.h	Tue Apr 26 14:58:06 2005
@@ -18,17 +18,23 @@
 class fragment
 {
 public:
-  /** Return all the lines of this fragment, given a particular
-   *  formatting width.
+  /** Return all the lines of this fragment, given the "shape" of the
+   *  fragment.  Note that some fragments ignore the given widths, so
+   *  the caller is expected to either put everything in a formatting
+   *  box (one that forces its contents to stay "in bounds") or
+   *  manually clip the return value.
    *
-   *  \param w the width to which this should be formatted, if
-   *  applicable (an advisory value only; some fragments will ignore
-   *  the width).
+   *  \param firstw the width to which the first line of the fragment
+   *  should be formatted.
+   *
+   *  \param w the width to which subsequent lines of the fragment
+   *  should be formatted.
    *
    *  \return the lines of this fragment; the caller is responsible
    *  for deleting it.
    */
-  virtual fragment_contents layout(size_t w)=0;
+  virtual fragment_contents layout(size_t firstw,
+				   size_t w)=0;
 
   /** Set the attributes of this fragment.
    *

Modified: branches/aptitude-0.3/aptitude/src/vscreen/vs_layout_item.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/vs_layout_item.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/vs_layout_item.cc	Tue Apr 26 14:58:06 2005
@@ -82,7 +82,8 @@
   if(win->getmaxx()!=lastw)
     {
       // Indent it MANUALLY for now.
-      lines=f->layout(win->getmaxx()-basex);
+      lines=f->layout(win->getmaxx()-basex,
+		      win->getmaxx()-basex);
       for(child_list::iterator i=children.begin(); i!=children.end(); ++i)
 	delete *i;
       children.clear();

Modified: branches/aptitude-0.3/aptitude/src/vscreen/vs_text_layout.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/vs_text_layout.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/vs_text_layout.cc	Tue Apr 26 14:58:06 2005
@@ -65,7 +65,7 @@
 {
   // Wasteful: calculate the contents and throw them away.
   if(f!=NULL)
-    return f->layout(w).size();
+    return f->layout(w, w).size();
   else
     return 0;
 }
@@ -151,7 +151,7 @@
 {
   if(stale)
     {
-      contents=f->layout(getmaxx());
+      contents=f->layout(getmaxx(), getmaxx());
 
       do_signal();