[comp.sys.mac.programmer] Rubberbanding

lippin@maypo.berkeley.edu (The Apathist) (08/12/88)

Recently aib@j.cc.purdue.edu (coleman) said:
>Does any one know how to get the Rubberbanding effect as in MacDraw?

One of the best ways to get flicker-free drawing is to translate the
things you want to draw to regions, and combine a set of changes off
screen, then apply it to the screen.

For lines, you can try something like this:

void LineRgn(dest,start,finish)
  RgnHandle dest;
  Point start,finish;
  {
   OpenRgn();
   MoveTo(start.h,start.v);
   Line(finish.h-start.h,finish.v-start.v);
   Line(thePort->penSize.h,thePort->penSize.v);
   Line(start.h-finish.h,start.v-finish.v);
   Line(-thePort->penSize.h,-thePort->penSize.v);
   CloseRgn(dest);
  }

void PaintTwoLines(start1,finish1,start2,finish2)
  Point start1,finish1,start2,finish2;
  {
   RgnHandle line1,both;
   line1=NewRgn();
   LineRgn(line1,start1,finish1);
   both=NewRgn();
   LineRgn(both,start2,finish2);
   XorRgn(both,line1,both);
   PaintRgn(both);
  }

Set the pen mode to srcXor, draw your starting line in the usual
fashion, then use PaintTwoLines to move the line around.  When you're
done, you can erase the final line by drawing it again in srcXor.
This should give you rubberbanding as in MacDraw.  Or at least I
suspect so; I haven't tried this, but I have been using a similar
algorithm for rubber band rectangles.  (With minor variations, it
should work for any shape, although ovals will likely be slow.)

MacPaint, on the other hand, has a more clever way of doing its
rubberbanding -- the net effect being that the lines are drawn in
or-mode instead of xor.  One way to do this is to keep a second copy
of the drawing area in a bitmap off screen.  Draw the initial line in
srcOr on the screen and srcXor in the bitmap.  To move the line, draw
the new position in srcXor in the bitmap, and use CopyBits in srcXor
mode to copy the bitmap to the screen, clipping to the xor of the
regions of the old and new lines.  After the CopyBits, remove the old
line from the bitmap by drawing it in srcXor.  When the line is done
moving, you can erase it from the bitmap by drawing it in srcXor, then
CopyBits the area back to the screen, and everything will be as it was
when you started.  I don't know how fast this would run, but I'd guess
it's fast enough for rubberbanding.

					--Tom Lippincott
					..ucbvax!math!lippin
					  lippin@math.berkeley.edu

"Ask a fish head anything you want to.  It won't answer you; they can't talk."

aberno@questor.wimsey.bc.ca (Anthony Berno) (01/08/91)

Thank you to everyone that replied to my query about rubberbanding.

For all of you in doubt on this topic, a code sample was given a
few messages back. It's not hard. Should have thought of it myself.
= )