[comp.sys.next] Caching Images for Views ....

songer@orchestra.ecn.purdue.edu (Christopher M Songer) (05/15/91)

Hi,

     I'm looking to put a Postscript image in a view smaller than the
total image -- ie, I would like to be able to scroll around in it. I
looked through the concepts manual and it seemed to indicate that the
best way to do fast updates is to draw to a bitmap and then copy the
bit map into the view (no suprise there.) The on-line manual describes
a "Bitmap" object. It does not seem to be present in 2.0.

     I looked through the Yap source code, to find the creation of the
cache it uses. Somehow, it seemed to be using a "Window" object as the cache.
The overall effect is that I am pretty in the dark as to how to first
get a bit map and then draw to it. If some kind soul has a simple piece
of sample code or can explain what is going on to me, I'd really apprecaite
it. I'm sure it is not hard, but my hard copy docs are still (still
still still still ...) on order and I am having a tough time pulling what
I need out of the on-line stuff. 

Thanks!
-Chris
songer@ecn.purdue.edu

izumi@mindseye.berkeley.edu (Izumi Ohzawa) (05/16/91)

In article <1991May15.161837.27550@noose.ecn.purdue.edu> songer@orchestra.ecn.purdue.edu (Christopher M Songer) writes:
>Hi,
>
>     I'm looking to put a Postscript image in a view smaller than the
>total image -- ie, I would like to be able to scroll around in it. I
>looked through the concepts manual and it seemed to indicate that the
>best way to do fast updates is to draw to a bitmap and then copy the
>bit map into the view (no suprise there.) The on-line manual describes
>a "Bitmap" object. It does not seem to be present in 2.0.
>

Bitmap object is obsolete.  Its functionality has been
expanded by NXImage object.

This is what I do with NXImage and compositing,
it may not be exactly what you need, but should contain
most of the steps needed.

 ....
NXRect myRect;
id myImage;

.... where you prepare cached bitmaps...
//	initialize myRect to size and location of bitmap.

	myImage = [[NXImage alloc] initSize:&myRect.size];
//	You can do Zone allocation above if necessary.

	[myImage useCacheWithDepth: NX_TwoBitGrayDepth];
	[myImage lockFocus];	/* focus on NXImage to work on */

.... standard drawing code into myImage

	[myImage unlockFocus];


.... In your compositing section, in another method...

	[myImage composite: NX_COPY toPoint: &myRect.origin ];


Izumi Ohzawa             [ $@Bg_78^=;(J ]
USMail: University of California, 360 Minor Hall, Berkeley, CA 94720
Telephone: (415) 642-6440             Fax:  (415) 642-3323
Internet: izumi@violet.berkeley.edu   NeXTmail: izumi@pinoko.berkeley.edu 

aozer@next.com (Ali Ozer) (05/17/91)

In article <1991May15.183632.22391@agate.berkeley.edu> Izumi Ohzawa writes:
>Bitmap object is obsolete.  Its functionality has been
>expanded by NXImage object.
>
>	myImage = [[NXImage alloc] initSize:&myRect.size];
>	[myImage useCacheWithDepth: NX_TwoBitGrayDepth];
>	[myImage lockFocus];	/* focus on NXImage to work on */

Nice description! However, one point: Caling "useCacheWithDepth:" with
the NX_TwoBitGrayDepth argument forces the cache to be 2 bits; you
really want a cache which can hold the cached image in its full glory.
Thus you should use NX_DefaultDepth as the argument, which causes the
cache to be depth limited to the depth limit of the system. And,
because of the lazy depth promotion, the cache will remain at 2 bits
(even on a deep machine) as long as you happen to draw 2-bits worth of
gray into it (which is what most views do). But if the view happens to
draw color, and you are on a color machine, you'd really like your
cache to hold color as well. (You might want to refer to the recent
discussions on window depths and depth limits.)

It turns out that if your image has no representations, simply calling
lockFocus creates a cache with the default depth. Thus calling
useCacheWithDepth: becomes unnecessary. (This is a feature which allows
Bitmap based apps to be converted more easily.)

A final point is that the lockFocus method for NXImage returns a BOOL to 
indicate errors.  Thus the correct way to use the lockFocus/unlockFocus pair is
to

	if ([myImage lockFocus]) {
	    // ... draw ...
	    [myImage unlockFocus];
	}

You probably won't get any errors trying to focus on a simple cache;
however, you might get errors if the image was built from an EPS or
TIFF file, which are interpreted lazily, at time of composite: or lockFocus.

Ali, Ali_Ozer@NeXT.com

king (Peter King) (05/17/91)

In article <1991May15.183632.22391@agate.berkeley.edu>  
izumi@mindseye.berkeley.edu (Izumi Ohzawa) writes:
>
> ...
>
> Bitmap object is obsolete.  Its functionality has been
> expanded by NXImage object.
> 
> This is what I do with NXImage and compositing,
> it may not be exactly what you need, but should contain
> most of the steps needed.
> 
> ....

If you want to display Encapsulated PostScript (EPS) files, the code is  
simpler:

    NXStream	*myStream;
    id myImage;

    /* Open the NXStream so that it contains the EPS (file, memory, whatever)
				myStream = NXMapFile(someFileName, NX_READONLY);

    /* Create the NXImage */
    myImage = [[NXImage alloc] initFromStream:myStream];

    /* Close the stream */
    NXClose(myStream);

NXImage can spot whether the data in an NXStream is EPS or TIFF and will do the  
right thing.  Also, you don't need to hassle with specifying the size of the  
image.  NXImage gets that from the NXStream as well.

> 
> ..... In your compositing section, in another method...
> 
> 	[myImage composite: NX_COPY toPoint: &myRect.origin ];
>

A small performance nit:  it is better to use NX_SOVER than NX_COPY.  If there  
is an alpha channel in your NXImage, you don't want the compositing to create  
on alpha channel in your on-screen window.  This causes some performance  
degradation, and the window's backing store might double in size.  NX_COPY will  
copy all bits (alpha included).  NX_SOVER does not copy the alpha bits, it only  
uses them during the compositing.

Peter

----------Disclaimers?  No such thing.  Everything's the truth----------
Peter F. King	Developer Trainer	NeXT Computer, Inc.
USPS:		900 Chesapeake Dr.	Redwood City, CA  94063
Internet:	Peter_King@NeXT.COM