[comp.sys.mac.programmer] flicker-free drawing

jasmerb@orstcs.CS.ORST.EDU (Bryce Jasmer) (07/25/88)

I am writing a DA that needs to have flicker free drawing so I found
and decided to use Scott Knaster's trick of letting the Tickcount change
before drawing. Here is the code:
-----
aLong:=tickcount;
while aLong = tickcount do
	;
EraseRect( {about 50 x 10 pixels} );
DrawString( {about 10-12 characters (9 point)} );
-----
It works great while the small window is at the bottom of my screen but
flickers more and more the closer you move the window to the top of the
screen. Since it is a DA, I am requesting my DA get a slice of time 
every 1/60 of a second.

What should I do?

Bryce Jasmer
jasmerb@jacobs.cs.orst.edu

lippin@twinkies.berkeley.edu (The Apathist) (07/26/88)

Recently jasmerb@orstcs.CS.ORST.EDU (Bryce Jasmer) said:
>I am writing a DA that needs to have flicker free drawing so I found
>and decided to use Scott Knaster's trick of letting the Tickcount change
>before drawing. Here is the code:
>-----
>aLong:=tickcount;
>while aLong = tickcount do
>	;
>EraseRect( {about 50 x 10 pixels} );
>DrawString( {about 10-12 characters (9 point)} );
>-----
>It works great while the small window is at the bottom of my screen but
>flickers more and more the closer you move the window to the top of the
>screen.

A better way to avoid flicker is to skip the erasing that causes it,
like this:

TextMode(srcCopy);
DrawString(whatever);
EraseRgn(area outside the string);

If you're replacing old text, you can do an EraseRect, using a
procedure like this:

void clearto(endofline)
  int endofline;
  {
   FontInfo info;
   Rect r;
   Point pen;
   GetFontInfo(&info);
   GetPen(&pen);
   SetRect(&r,pen.h,pen.v-info.ascent,endofline,pen.v+info.descent);
   EraseRect(&r);
  }

The only hitch is that srcCopy for text doesn't exist for the most
ancient hardware/system software combinations.

					--Tom Lippincott
					..ucbvax!bosco!lippin

	"It's a multi-purpose shape: a box."
					--David Byrne

gandreas@umn-d-ub.D.UMN.EDU (Glenn Andreas) (07/26/88)

In article <12549@agate.BERKELEY.EDU> lippin@math.berkeley.edu writes:
>Recently jasmerb@orstcs.CS.ORST.EDU (Bryce Jasmer) said:
>>I am writing a DA that needs to have flicker free drawing...
[ stuff deleted ]
>A better way to avoid flicker is to skip the erasing that causes it,
>like this:

>TextMode(srcCopy);
>DrawString(whatever);
[more deleted ]

>The only hitch is that srcCopy for text doesn't exist for the most
>ancient hardware/system software combinations.

>					--Tom Lippincott
>					..ucbvax!bosco!lippin

There are more problems than that.  When you (or at least when I) use
srcCopy for text, it will often erase more than just to the end of the last
letter.  It seems that it erases up to the next byte/word boundary (?), and
so if you have your end of the text near say a line you've drawn, it may
erase a path through the line as well.  This may or may not be a problem,
depending on the situation (I wanted to draw text over a detailed, filled
map and by using srcCopy I got ugly results.  I ended up with EraseRect, but
I didn't need it flicker free).  You could always draw off screen and use
CopyBits :-).


=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
= "When I was young, all I wanted was to be  | - gandreas@ub.d.umn.edu -    =
=  ruler of the universe.  Now that isn't    |   Glenn Andreas              =
=  enough" - Alex P. Keaton                  |                              =
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

lippin@skippy.berkeley.edu (The Apathist) (07/27/88)

Recently gandreas@ub.d.umn.edu.UUCP (Glenn Andreas) wrote:
>  When you (or at least when I) use
>srcCopy for text, it will often erase more than just to the end of the last
>letter.  It seems that it erases up to the next byte/word boundary (?), and
>so if you have your end of the text near say a line you've drawn, it may
>erase a path through the line as well. 

You could be right -- in every case that I can remember trying, I've
been using a ClipRect around the area I'm drawing anyway.  This takes
care of the problem pretty well.

					--Tom Lippincott
					..ucbvax!math!lippin

"The train is the same; only the time is different.  Ecce homo, ergo elk."

darin@Apple.COM (Darin Adler) (07/27/88)

In article <424@umn-d-ub.D.UMN.EDU> gandreas@ub.d.umn.edu.UUCP writes:
> In article <12549@agate.BERKELEY.EDU> lippin@math.berkeley.edu writes:
> >Recently jasmerb@orstcs.CS.ORST.EDU (Bryce Jasmer) said:
> > >I am writing a DA that needs to have flicker free drawing...
> >A better way to avoid flicker is to skip the erasing that causes it,
> There are more problems than that.  When you (or at least when I) use
> srcCopy for text, it will often erase more than just to the end of the last
> letter.  It seems that it erases up to the next byte/word boundary (?), ...

This extra erasing is actually related to the italic and bold styles (believe
it or not). I do agree with the main point of this discussion, which is that
the way to avoid flicker is by avoiding erasing before drawing something in.
Off-screen bitmaps are often the best way.

Note that the TickCount method that was mentioned in the message that started
this chain is not valid on modern Macs (Mac IIs) that have screens with refresh
rates other than 60Hz. TickCount stays at 60Hz no matter what.
--
Darin Adler					       AppleLink: Adler4
UUCP: {sun,voder,nsc,mtxinu,dual}!apple!darin	  CSNET: darin@Apple.com

erik@hpsadla.HP (Erik Kilk) (07/29/88)

In your case, you should be able to change the pen mode and take out
the EraseRect call.  Use the pen mode which copies both your white and
black bits (I don't have InsideMac here, but maybe it was srcbit or something.)

In general, you can get flicker free graphics by not
erasing before you draw.  The flicker comes from the small amount of
time that you have nothing drawn.  

Using various techniques, you should draw the new image over
the old image and then erase the old image.  Sometimes you are lucky 
and drawing the new image will erase the entire old one.  Othertimes
you have to calculate offscreen the overlap and erase it yourself.

Erik

jmunkki@santra.HUT.FI (Juri Munkki) (07/30/88)

In article <14772@Apple.COM> darin@apple.apple.com.UUCP (Darin Adler) writes:
>Off-screen bitmaps are often the best way.

Just a note on off-screen bitmaps: I just wrote a program that uses a 320x320
offscreen bitmap. If I just blit it on the screen with a copybits, the cursor
flashes and is often invisible. The solution that I came to was to draw the
bitmap in 4 parts. The cursor flicker was reduced to a reasonable level.

Of course there are better ways to do this (like synchronizing with a screen),
but they a lot more code than breaking a copybits into four parts. The trap
dispatcher and QD overheads shouldn't be a problem unless your timing is really
critical.

Juri Munkki
jmunkki@santra.hut.fi
jmunkki@fingate.bitnet