rg2c+@andrew.cmu.edu (Robert Nelson Gasch) (04/18/91)
I've been trying to get CopyBits to work properly, but so far I have managed to generate nothing but junk. This has gone on for quite a while by now and it's getting annoying. So if anybody out there has the source code for some program they would be willing to donate, I'd appreciate hearing from them. Alternativeley, if some samples exist on some FTP server, I'd be equally happy. I just want something I can look at and figure out what I'm doing wrong. Anything will do. Thanx in advance --> Rob
vrm@babcock.cerc.wvu.wvnet.edu (Vasile R. Montan) (04/19/91)
From article <4c3JO2600WBLE0ZlJU@andrew.cmu.edu>, by rg2c+@andrew.cmu.edu (Robert Nelson Gasch): > I've been trying to get CopyBits to work properly, but so far I have > managed to generate nothing but junk. This has gone on for quite > a while by now and it's getting annoying. So if anybody out > there has the source code for some program they would be willing > to donate, I'd appreciate hearing from them. Alternativeley, > if some samples exist on some FTP server, I'd be equally happy. > I just want something I can look at and figure out what I'm > doing wrong. Anything will do. Below I've pasted Tech Note #41. It should do just what you want. (I know, it's available all over the place, but not all of us have easy access to it anyway, so here it is.) --Kurisuto un020070@vaxa.wvnet.edu The following is a short example of drawing to, then copying from, an offscreen bitmap. The only major concern when setting this up is that the number of rowBytes in the bitmap is even. Given these constants and variables CONST myString = 'The EYE'; VAR oldPort : GrafPtr; {saved port} offScreen : GrafPort; {our offscreen bitmap} ovalRect : Rect; {used for example drawing} the offscreen port and bitmap can be allocated with the following statements: GetPort(oldPort); OpenPort(@offScreen); SetPort(oldPort); WITH offScreen, portBits, bounds DO BEGIN {make bitmap exactly the size of the port} portRect := thePort^.portRect; bounds := portRect; {rowBytes is size of row, rounded up to an even number of bytes} rowBytes := (((right - left) + 15) DIV 16) * 2; {number of bytes in BitMap is rowBytes * number of rows} {this calculation must be done with longs} baseAddr:= NewPtr(rowBytes * LongInt(bottom - top)); {check MemError here to see if we had enough room for the bitmap} END; We are now ready to draw into our offscreen port: SetPort(@offScreen); {since it's just an area of memory, we'd better clear it before we start} EraseRect(thePort^.portRect); {Example drawing} ovalRect := thePort^.portRect; FillOval(ovalRect, black); InsetRect(ovalRect, 1, 20); FillOval(ovalRect, white); InsetRect(ovalRect, 40, 1); FillOval(ovalRect, black); WITH ovalRect DO MoveTo((left+right-StringWidth(myString)) DIV 2, (top+bottom-12) DIV 2); TextMode(srcXOr); DrawString(myString); Now we're ready to do the CopyBits, copying the image that we've drawn in the offscreen bitmap to thePort^.portBits, from the rectangle offScreen.bounds to the rectangle thePort^.portRect: SetPort(oldPort); CopyBits(offScreen.portBits, thePort^.portBits, offScreen.portRect, thePort^.portRect, srcCopy, NIL); Notice here that if thePort^.portRect and offScreen.bounds are not the same size, CopyBits will scale the bit image that is being copied. From MPW C, given these variables char* myString = "\pThe EYE"; /* string to display */ GrafPtr oldPort; /* saved port */ GrafPort offScreen; /* our offscreen bitmap */ Rect ovalRect; /* used for example drawing */ the offscreen port and bitmap can be allocated with the following statements: GetPort(&oldPort); OpenPort(&offScreen); SetPort(oldPort); /* make bitmap exactly the size of the port */ offScreen.portRect = qd.thePort->portRect; offScreen.portBits.bounds = offScreen.portRect; /* rowBytes is size of row, rounded up to an even number of bytes */ offScreen.portBits.rowBytes = (((offScreen.portBits.bounds.right - offScreen.portBits.bounds.left) + 15) >> 4) << 1; /* number of bytes in BitMap is rowBytes * number of rows */ /* this calculation must be done with longs */ offScreen.portBits.baseAddr = NewPtr(offScreen.portBits.rowBytes * (long) (offScreen.portBits.bounds.bottom - offScreen.portBits.bounds.top)); /* check MemError here to see if we had enough room for the bitmap */ We are now ready to draw into our offscreen port: SetPort(&offScreen); /* since it's just memory, we'd better clear it before we start */ EraseRect(&qd.thePort->portRect); /* Example drawing */ ovalRect = qd.thePort->portRect; FillOval(&ovalRect, qd.black); InsetRect(&ovalRect, 1, 20); FillOval(&ovalRect, qd.white); InsetRect(&ovalRect, 40, 1); FillOval(&ovalRect, qd.black); MoveTo((ovalRect.left+ovalRect.right-StringWidth(myString)) >> 1, (ovalRect.top+ovalRect.bottom-12) >> 1); TextMode(srcXor); DrawString(myString); SetPort(oldPort); CopyBits(&offScreen.portBits, &qd.thePort->portBits, &offScreen.portRect, &qd.thePort->portRect, srcCopy, NULL); Please note that this way of doing things is NOT faster than simply defining a picture and then drawing it to your window. There are cases, however, such as text rotation, where it will be advantageous to do the drawing off the screen, manipulate the bit image and then copy the result to the visible window. In addition, this technique will reduce flicker, because all of the drawing done offscreen will appear on the screen at once.
stevec@Apple.COM (Steve Christensen) (04/19/91)
rg2c+@andrew.cmu.edu (Robert Nelson Gasch) writes: >I've been trying to get CopyBits to work properly, but so far I have >managed to generate nothing but junk. This has gone on for quite >a while by now and it's getting annoying. So if anybody out >there has the source code for some program they would be willing >to donate, I'd appreciate hearing from them. Alternativeley, >if some samples exist on some FTP server, I'd be equally happy. >I just want something I can look at and figure out what I'm >doing wrong. Anything will do. Well, here's a sample snippet that uses CopyBits. Let's assume we have already created a window and we want to draw an icon in it (yes, I know we could just call PlotIcon, but this is an example). WindowPtr theWindow; BitMap theBits; Rect destRect; Handle theIcon; theIcon = GetResource('ICON', 128); // get the icon HLock(theIcon); // and lock it while we use it theBits.baseAddr = *theIcon; // point to the icon's data theBits.rowBytes = 4; // 32 pixels == 4 bytes SetRect(&theBits.bounds,0,0,16,16); // icon's bounding rectangle SetRect(destRect,20,10,36,26); // where the icon goes CopyBits(&theBits,&theWindow->portBits,&theBits.bounds,&destRect,srcCopy,nil); That's all there is to it. You could also specify theBits.bounds in the window's local coordinates and use it as both the srcRect and dstRect in this case. You could also specify a portion of the icon by setting up another rectangle in theBits.bounds' coordinate system and use it for the srcRect... steve -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Steve Christensen Never hit a man with glasses. stevec@apple.com Hit him with a baseball bat.
mxmora@unix.SRI.COM (Matt Mora) (04/19/91)
In article <1608@babcock.cerc.wvu.wvnet.edu> un020070@vaxa.wvnet.edu writes: > VAR > oldPort : GrafPtr; {saved port} > offScreen : GrafPort; {our offscreen bitmap} > ovalRect : Rect; {used for example drawing} > >the offscreen port and bitmap can be allocated with the following statements: > > GetPort(oldPort); > OpenPort(@offScreen); ^ IS THAT RIGHT? I don't think you need the @ sign here. Or at the other SetPort(@Offscreen); -- ___________________________________________________________ Matthew Mora | my Mac Matt_Mora@sri.com SRI International | my unix mxmora@unix.sri.com ___________________________________________________________
jcav@quads.uchicago.edu (john cavallino) (04/20/91)
In article <23407@unix.SRI.COM> mxmora@unix.sri.com (Matt Mora) writes: >In article <1608@babcock.cerc.wvu.wvnet.edu> un020070@vaxa.wvnet.edu writes: >> VAR >> oldPort : GrafPtr; {saved port} >> offScreen : GrafPort; {our offscreen bitmap} >> ovalRect : Rect; {used for example drawing} >> >>the offscreen port and bitmap can be allocated with the following statements: >> >> GetPort(oldPort); >> OpenPort(@offScreen); > ^ > IS THAT RIGHT? > >I don't think you need the @ sign here. >Or at the other SetPort(@Offscreen); Actually, it is correct, but the style is somewhat yecchy. OpenPort takes a GrafPtr, the variable "offscreen" is a GrafPort, the "@" operator takes the address of something, so @offscreen give you a GrafPtr. It would be easier to read if there were an explicit variable of type GrafPtr. -- John Cavallino | EMail: jcav@midway.uchicago.edu University of Chicago Hospitals | USMail: 5841 S. Maryland Ave, Box 145 Office of Facilities Management | Chicago, IL 60637 B0 f++ w c+ g+ k s(+) e+ h- pv | Telephone: 312-702-6900