[comp.sys.mac.programmer] Text Drawing at speeds greater than 1200baud

srpenndo@uokmax.UUCP (Sean Richard Penndorf) (01/18/89)

Thanks to everyone that answered my question of text drawing at speeds greater
than 1200baud.  I will check these routes out and see how well they work.


What I would really like to know now is how many of you have tried to write to
the screen  in local mode (not connected to a modem or other serial device)
at speeds faster than 2400baud?

What we are doing at Ultimatum Software is writing a BBS program (in addition
to the terminal program I mentioned in my last post)...and personally I would
like the Mac to print to my screen faster than 2400 baud.  I think some where
around 9600 baud would be nice.

Do you use the same tricks, or is there something else you would do for the
special local mode case?   I am sure that this seems trivial to most of you,
but any help you can give me will cut down on our development time.  Our
Ultimate objective is go beyond simple text on the screen, BUT first we would
like to get the text working at high speeds.  Thanks for all the comments.


Sean
----

-- 
Sean 'Longstride' Penndorf
!texsun!uokmax!srpenndo                    .  .        .-----------
GEnie:  S.PENNDORF                         |  |        `---.
srpenndo@uokmax.UUCP                       `--'LTIMATUM----'OFTWARE

oster@dewey.soe.berkeley.edu (David Phillip Oster) (01/18/89)

The ultimate in text drawing speed can be achieved by:
(o) using a custom font, where each character is 7 pixels high, and, say,
9 pixels tall. f there is one pixel of white space between characters,
then each pixel fits in an 8-bit wide cell.

(o) constrain motion and growing of the window, (a la hypercard) so that
the portRect is always on a byte boundary.

(o) if and only if the destination is a 1-bit deep pixmap, completely
visible, the front window, and un-obscured by other windows, than do the
following ultra-fast code. Otherwise, use the DrawText solution you've
already been told about.

(o) use hand-tuned assembly language to move one of our 9x7 characters to
the screen using 9 move.b instructions.
If you are careful with you registers, you can wrap this up into a custom
SuperDrawText

(o) use hand-tuned assembly instructions to scroll the screen using 
loops unrolled into lots of move.l instructions.

tim@hoptoad.uucp (Tim Maroney) (01/19/89)

In article <27572@ucbvax.BERKELEY.EDU> oster@dewey.soe.berkeley.edu.UUCP
(David Phillip Oster) writes:
>The ultimate in text drawing speed can be achieved by:
>(o) using a custom font, where each character is 7 pixels high, and, say,
>9 pixels tall. f there is one pixel of white space between characters,
>then each pixel fits in an 8-bit wide cell.

Sounds good, but when you do the math, the characters are too wide.
512 bits on the screen; 16 for a scroll bar; 8 for margins and borders;
512 - (16 + 8) = 488; 488 / 8 = 61 characters.  You need 80.
-- 
Tim Maroney, Consultant, Eclectic Software, sun!hoptoad!tim
"The negro slaves of the South are the happiest, and, in some sense, the
 freest people in the world.  The children and the aged and infirm work not
 at all, and yet have all the comforts and neccessaries of life provided for
 them." -- George Fitzhugh, CANNIBALS ALL! OR, SLAVES WITHOUT MASTERS, 1857

oster@dewey.soe.berkeley.edu (David Phillip Oster) (01/19/89)

In article <6336@hoptoad.uucp> tim@hoptoad.UUCP (Tim Maroney) writes:
>Sounds good, but when you do the math, the characters are too wide.
Thanks Tim, you are absolutely right.  The idea can still be salvaged by
keeping eight copies of your font around, each one preshifted by a
different numbr of bits, with enough leading white bits that you can
always draw the character in at most two OR instructions.  Than use three
versions of your hand-tuned bit slammer code:
(o) version 1, uses OR.Bs, as the MOVE.Bs before, for when the character fits
in a single byte.
(o) version 2, uses OR.W for characters that span two bytes, but the
destination is on a word boundary.
(o) version 3, uses two OR.Bs for characters that span two bytes, but the
destination is odd.

Note: the third case can be eliminated by using 16 copies of the font
and always using OR.W instructions to slam those black bits to the screen.

a "copy of a font" is 9 scan lines*256 characters*2bytes per scan line per
character = ~4.5k. 16 of them is ~72k.  Naturally, you build them at run
time rather than wasting disk space for this stuff.  Quite reasonable for
a 512k machine.

jmunkki@kampi.hut.fi (Juri Munkki) (01/19/89)

In article <27572@ucbvax.BERKELEY.EDU> oster@dewey.soe.berkeley.edu.UUCP (David Phillip Oster) writes:
>The ultimate in text drawing speed can be achieved by:
>(o) using a custom font, where each character is 7 pixels high, and, say,
>9 pixels tall. f there is one pixel of white space between characters,
>then each pixel fits in an 8-bit wide cell.

You mean 7 pixels wide. Looks awful and you can only get 64 characters per
line on a 512 pixel wide window. I wouldn't want to read a font like this.

>(o) constrain motion and growing of the window, (a la hypercard) so that
>the portRect is always on a byte boundary.

No objections here. I do not restrain my windows, but the effect on speed
is visible on a MacPlus. This is because I use an offscreen bitmap to
contain my text screens. If the bitmap and the window are not exactly
aligned, QD has to do a lot of bit-shifting.  Zooming the window positions
it intelligently to a word boundary (I plan to document this feature in the
manual).

>(o) use hand-tuned assembly instructions to scroll the screen using 
>loops unrolled into lots of move.l instructions.

Movem.l should be faster...at least apple is using them. QD Copybits
is almost as fast as BlockMove, and blockmove uses movem.l. I do not
see the need to write a custom bitmap scrolling routine.

I recommend giving the serial driver a reasonable large buffer to work
with. 8KB seems to be ok, but you might make it 16KB or more, if you're
really worried about missing characters & have enough RAM. Usually text
is received in bursts.

The original question was about achieving 2400 bps. You don't need
to optimize the scrolling at these speeds. Just remember that you
usually don't need to call your update routine after the screen scrolls
up. Most terminal programs do not do update their windows even when they
really should. Try ls -R and open a desk accessory. The lines that
scroll up from under the da are not updated. At least VersaTerm and
Microphone fail this test.

_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
|     Juri Munkki jmunkki@hut.fi  jmunkki@fingate.bitnet        I Want   Ne   |
|     Helsinki University of Technology Computing Centre        My Own   XT   |
~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~

parent@Apple.COM (Sean Parent) (01/20/89)

In article <27572@ucbvax.BERKELEY.EDU>, oster@dewey.soe.berkeley.edu (David Phillip Oster) writes:
> (o) if and only if the destination is a 1-bit deep pixmap, completely
> visible, the front window, and un-obscured by other windows, than do the
> following ultra-fast code. Otherwise, use the DrawText solution you've
> already been told about.

There is no way to tell for sure that there are not any windows in front of
your window. The system owns the screen.

> (o) use hand-tuned assembly language to move one of our 9x7 characters to
> the screen using 9 move.b instructions.

You cannot be garenteed access to the screen memory.

You could use a subset of this approach to build strikes off-screen and then
blast them up using copyBits. (copyBits is very fast and is tuned for each
processor)

Sean

beard@ux1.lbl.gov (Patrick C Beard) (01/21/89)

In article <24307@apple.Apple.COM> parent@Apple.COM (Sean Parent) writes:
>In article <27572@ucbvax.BERKELEY.EDU>, oster@dewey.soe.berkeley.edu (David Phillip Oster) writes:
>> (o) if and only if the destination is a 1-bit deep pixmap, completely
>> visible, the front window, and un-obscured by other windows, than do the
>> following ultra-fast code. Otherwise, use the DrawText solution you've
>> already been told about.
>
>There is no way to tell for sure that there are not any windows in front of
>your window. The system owns the screen.

Not true.  It is very easy.  Just look at the visRgn of the window in
question.  Clip your optimized drawing directly to the screen to this and
you won't get in trouble.  I know, I've done it.  It is dirty pool, but
it does work.

Patrick Beard
Berkeley Systems, Berkeley CA

ech@pegasus.ATT.COM (Edward C Horvath) (01/22/89)

In article <24307@apple.Apple.COM> parent@Apple.COM (Sean Parent) writes:
>There is no way to tell for sure that there are not any windows in front of
>your window. The system owns the screen.

From article <1728@helios.ee.lbl.gov>, by beard@ux1.lbl.gov (Patrick C Beard):
> Not true.  It is very easy.  Just look at the visRgn of the window in
> question.  Clip your optimized drawing directly to the screen to this and
> you won't get in trouble.  I know, I've done it.  It is dirty pool, but
> it does work.

There is NOTHING "dirty pool" about this technique: the visRgn is, quite
precisely, the visible region of your port, and IM-I (Quickdraw) makes it
very clear that your drawing will be clipped to the visRgn (among other
things).  Limiting drawing to the visRgn is a perfectly wonderful (and
safe, presumably forever) means of limiting the cost of updates.

Multifinder takes the responsibility of removing the visRgn of each layer
from that of the layers beneath.  Makes sense, ne?

You never HAVE to draw anything that doesn't intersect the visRgn, nor will
it ever do you any good to draw stuff that isn't in the visRgn.

Also, please note that BeginUpdate "saves" the visRgn, and sets the visRgn
to the intersection of the visRgn and the updateRgn.  EndUpdate restores the
visRgn.  So Beard's "trick" properly limits the work you have to do whenever
there's an update event.

No trick, no dirty pool: good programming practice!

=Ned Horvath=

kazim@Apple.COM (Alex Kazim) (01/22/89)

In article <18791@santra.UUCP> jmunkki@kampi.UUCP (Juri Munkki) writes:
>
>No objections here. I do not restrain my windows, but the effect on speed
>is visible on a MacPlus. This is because I use an offscreen bitmap to
>contain my text screens. If the bitmap and the window are not exactly
>aligned, QD has to do a lot of bit-shifting.  Zooming the window positions
>it intelligently to a word boundary (I plan to document this feature in the
>manual).

I can't say I like this approach -- window sizing is in the power of
the user, and the program shouldn't limit the the size to boundaries.
This would confuse a novice, because your windows will not work like
other applications...

>
>up. Most terminal programs do not do update their windows even when they
>really should. Try ls -R and open a desk accessory. The lines that
>scroll up from under the da are not updated. At least VersaTerm and
>Microphone fail this test.
>
>_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
>|     Juri Munkki jmunkki@hut.fi  jmunkki@fingate.bitnet        I Want   Ne   |
>|     Helsinki University of Technology Computing Centre        My Own   XT   |
>~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~

If they do a ScrollRect(), it returns an updateRgn that includes the
area scrolled out from under the DA.  Just check the rgnBBox of the returned
region to see what lines need to be refreshed.

==================================================================
Alex Kazim, Apple Computer
My ideas alone.
====================================================================

lsr@Apple.COM (Larry Rosenstein) (01/24/89)

In article <18791@santra.UUCP> jmunkki@kampi.UUCP (Juri Munkki) writes:
>
>No objections here. I do not restrain my windows, but the effect on speed
>is visible on a MacPlus. This is because I use an offscreen bitmap to
>contain my text screens. If the bitmap and the window are not exactly
>aligned, QD has to do a lot of bit-shifting.  Zooming the window positions
>it intelligently to a word boundary (I plan to document this feature in the
>manual).

One thing to try is to shift the offscreen bitmap so that it is always
aligned to the screen.  You can do this with a CopyBits call, or write some
custom code.

You only need to do this when the window moves or scrolls horizontally.  For
a full MacPaint-size page this takes .5 seconds on a Mac Plus.  For a
terminal screen, it should be faster.

-- 
		 Larry Rosenstein,  Object Specialist
 Apple Computer, Inc.  20525 Mariani Ave, MS 46-B  Cupertino, CA 95014
	    AppleLink:Rosenstein1    domain:lsr@Apple.COM
		UUCP:{sun,voder,nsc,decwrl}!apple!lsr

parent@Apple.COM (Sean Parent) (01/24/89)

In article <1728@helios.ee.lbl.gov>, beard@ux1.lbl.gov (Patrick C Beard) writes:
> In article <24307@apple.Apple.COM> parent@Apple.COM (Sean Parent) writes:
> >In article <27572@ucbvax.BERKELEY.EDU>, oster@dewey.soe.berkeley.edu (David Phillip Oster) writes:
> >> (o) if and only if the destination is a 1-bit deep pixmap, completely
> >> visible, the front window, and un-obscured by other windows, than do the
> >> following ultra-fast code. Otherwise, use the DrawText solution you've
> >> already been told about.
> >
> >There is no way to tell for sure that there are not any windows in front of
> >your window. The system owns the screen.
> 
> Not true.  It is very easy.  Just look at the visRgn of the window in
> question.  Clip your optimized drawing directly to the screen to this and
> you won't get in trouble.  I know, I've done it.  It is dirty pool, but
> it does work.

Good observation. Make sure that you are looking at the whole visRgn and not
just at the bounding rect (look out for holes in the rgn). This should work
for must stuff today but I still wouldn't recommend it. If you are doing all
this special casing why not use copybits. Then it will even work in the future
garenteed.

Sean

joachim@iraul1.ira.uka.de (Joachim Lindenberg) (01/24/89)

Hi folks,

I think you are on the wrong line. Back in 1986/87 I wrote Terminal DA
which works on a Mac+ at 9600 baud, while not scrolling. It uses
DrawText of as many characters as possible.

You must be doing something else wrong. Look at your source or do some
performance meassurements.

Somebody else already pointed out that you aren't granted that your GrafPort
is frontmost. Also, you had to test yourself if all of your Port is on screen
(or will your users not allowed to drag the window?).

Btw,  I tried very much the same you did back in 1986. I got a speed improvement
of only 40% (using a font 8 pixels wide and a byte aligned grafport). Look
elsewhere for big improvements...

Joachim Lindenberg

parent@Apple.COM (Sean Parent) (01/31/89)

In article <2534@pegasus.ATT.COM>, ech@pegasus.ATT.COM (Edward C Horvath) writes:
> In article <24307@apple.Apple.COM> parent@Apple.COM (Sean Parent) writes:
> >There is no way to tell for sure that there are not any windows in front of
> >your window. The system owns the screen.
> 
> From article <1728@helios.ee.lbl.gov>, by beard@ux1.lbl.gov (Patrick C Beard):
> > Not true.  It is very easy.  Just look at the visRgn of the window in
> > question.  Clip your optimized drawing directly to the screen to this and
> > you won't get in trouble.  I know, I've done it.  It is dirty pool, but
> > it does work.
> 
> There is NOTHING "dirty pool" about this technique: the visRgn is, quite
> precisely, the visible region of your port, and IM-I (Quickdraw) makes it
> very clear that your drawing will be clipped to the visRgn (among other
> things).  Limiting drawing to the visRgn is a perfectly wonderful (and
> safe, presumably forever) means of limiting the cost of updates.

The point that I was making has been lost. Of course you can use the VisRgn to
optimize your update code. Just don't update the screen with MOVEs to screen
memory. Use QD (CopyBits is very fast).

Also, to quote Inside Mac Vol 1. "The visRgn field is manipulated by the Window
Manager...The visRgn has no effect on images that aren't displayed on the
screen." So don't use it in your printing code and keep in mind that it is the
visable area of a port that is owned by a window.

Sean

kaufman@polya.Stanford.EDU (Marc T. Kaufman) (01/31/89)

In article <25017@apple.Apple.COM> parent@Apple.COM (Sean Parent) writes:

>Also, to quote Inside Mac Vol 1. "The visRgn field is manipulated by the Window
>Manager...The visRgn has no effect on images that aren't displayed on the
>screen." So don't use it in your printing code and keep in mind that it is the
>visable area of a port that is owned by a window.

I have experimental evidence that Quickdraw uses the visRgn  when drawing to
an off-screen GrafPort, if the visRgn is not nil.  There are also some
applications that expect the visRgn to be present, even on a printing
Grafport, so my print drivers set the visRgn == clipRgn == port rect.
What the heck... it can't hurt.

Marc Kaufman (kaufman@polya.stanford.edu)