From: pottier@clipper.ens.fr (Francois Pottier) Subject: csmp-digest-v3-042 Date: Tue, 5 Jul 1994 14:50:36 +0200 (MET DST) C.S.M.P. Digest Tue, 05 Jul 94 Volume 3 : Issue 42 Today's Topics: **Novice Question on saving files** CODE Resources Code Resources with CodeWarrior MacTCP DNR for PowerPC? Major bug with Symantec CDK *Please Read* Perspective in GX (was Re: can toolbox draw text at an angle?) Still trouble finding floating windows code. _vSyncWait infinite loop? can toolbox draw text at an angle? The Comp.Sys.Mac.Programmer Digest is moderated by Francois Pottier (pottier@clipper.ens.fr). The digest is a collection of article threads from the internet newsgroup comp.sys.mac.programmer. It is designed for people who read c.s.m.p. semi- regularly and want an archive of the discussions. If you don't know what a newsgroup is, you probably don't have access to it. Ask your systems administrator(s) for details. If you don't have access to news, you may still be able to post messages to the group by using a mail server like anon.penet.fi (mail help@anon.penet.fi for more information). Each issue of the digest contains one or more sets of articles (called threads), with each set corresponding to a 'discussion' of a particular subject. The articles are not edited; all articles included in this digest are in their original posted form (as received by our news server at nef.ens.fr). Article threads are not added to the digest until the last article added to the thread is at least two weeks old (this is to ensure that the thread is dead before adding it to the digest). Article threads that consist of only one message are generally not included in the digest. The digest is officially distributed by two means, by email and ftp. If you want to receive the digest by mail, send email to listserv@ens.fr with no subject and one of the following commands as body: help Sends you a summary of commands subscribe csmp-digest Your Name Adds you to the mailing list signoff csmp-digest Removes you from the list Once you have subscribed, you will automatically receive each new issue as it is created. The official ftp info is //ftp.dartmouth.edu/pub/csmp-digest. Questions related to the ftp site should be directed to scott.silver@dartmouth.edu. Currently no previous volumes of the CSMP digest are available there. Also, the digests are available to WAIS users. To search back issues with WAIS, use comp.sys.mac.programmer.src. With Mosaic, use http://www.wais.com/wais-dbs/comp.sys.mac.programmer.html. ------------------------------------------------------- >From ftrogers@eos.ncsu.edu (FRANKLIN TAREK ROGERS) Subject: **Novice Question on saving files** Date: 21 Jun 1994 13:21:32 GMT Organization: North Carolina State University, Project Eos I'm trying to save data into a file, and am having trouble understanding the underlying concepts. Inside Macintosh "Files" gives a verty detailed discussion on the subject, but all example deal only with TextEdit. The FSWrite command takes a pointer to a data buffer: What is a data buffer? Just any allocated block of memory? The data I wish to save is all contained within one data structure, (memory allocated with NewPointer). Basically what I've got is: typedef struct myStruct { StringPtr aString1, aString2... } Is a data struct of strings considered a data buffer my the OS or do I need to cram my info into some particular form. Also, how would I find the size of the data buffer when not TextEdit? Thanks, F. Tarek Rogers ftrogers@eos.ncsu.edu +++++++++++++++++++++++++++ >From Rick_Holzgrafe@taligent.com (Rick Holzgrafe) Date: Tue, 21 Jun 1994 18:38:58 GMT Organization: Semicolon Software In article <2u6pgs$k9c@taco.cc.ncsu.edu>, ftrogers@eos.ncsu.edu (FRANKLIN TAREK ROGERS) wrote: > I'm trying to save data into a file, and am having trouble understanding > the underlying concepts. Inside Macintosh "Files" gives a verty detailed > discussion on the subject, but all example deal only with TextEdit. > The FSWrite command takes a pointer to a data buffer: > What is a data buffer? Just any allocated block of memory? Right. The pointer can in fact point to any memory you please, even to a local variable if that's what you want to write out. > The data I wish to save is all contained within one data structure, > (memory allocated with NewPointer). Basically what I've got is: > typedef struct myStruct > { > StringPtr aString1, aString2... > } You could write out the entire struct by passing a pointer to it to FSWrite, getting its size from 'sizeof myStruct'. However, that's not what you want to do, because your structure contains only the pointers to the strings, and not the strings' contents. To write out the strings, call FSWrite once for each string, like this: long dataLength = (((long)myStruct.aString1[0]) & 0xff) + 1; FSWrite (refNum, &dataLength, (ptr)myStruct.aString1); The example assumes that your strings are in Pascal format, so that the first byte of the string gives the string's length. The part about '&0xff' ensures that you don't get a negative length for strings that have the high bit set in their length byte; it isn't always necessary but better safe than sorry. The example also writes each string out with its proper length: no disk space is wasted. This means that when you read the strings back in, you'll have to read the length byte first to see how long the string actually is. An alternative is to always write out 256 bytes for each string (or perhaps some shorter length guaranteed to be long enough for your purposes). This wastes some space but ensures a simpler and easier-to-read file format. Normally I wouldn't recommend wantonly wasting space but if it's just a few strings the wastage may not be significant. > how would I find the > size of the data buffer when not TextEdit? That entirely depends on the nature and source of the data. The solution for Pascal strings is shown above. > F. Tarek Rogers > ftrogers@eos.ncsu.edu -- Rick Holzgrafe, a member of the Taligentsia Rick_Holzgrafe@taligent.com rmh@taligent.com --------------------------- >From Bill McCloskey Subject: CODE Resources Date: 19 Jun 1994 01:14:55 GMT Organization: ??? If I was going to write a 'CODE' resource in Think C, how could I execute it in my program? Also, are there any examples for this anywhere? Thanks for any help, -Bill +++++++++++++++++++++++++++ >From Mark Hanrek Date: Sun, 19 Jun 1994 05:08:25 GMT Organization: The Information Workshop In article <2u066f$avl@mailhost.interaccess.com> Bill McCloskey, billm@interaccess.com writes: > If I was going to write a 'CODE' resource in Think C, how could I > execute it in my program? Also, are there any examples for this > anywhere? You would certainly want to copy the way it is done in some example source code. I prepared an ansewr to a question like yours before, so I've attached it below. It is ready to be pasted in and compiled. Also, in your questions, you could have meant >> 'CODE' << literally or figuratively. Just in case, I wanted to mention that resources of type 'CODE' should remain reserved for the traditional way applications are constructed, so I figure you are asking how you wuld create a custom code resource with a resource type of, say, 'CoDe', or XCMD, or 'bill' or whatever. :) There are examples around. Be sure to look in the source code folder under "dev" in sumex and elsewhere. Hope this helps. Mark Hanrek =================================================================== Calling a Code Resource from an Application // // First, determine and define the interface you would like. // For instance... // typedef pascal OSErr (*CodeResourceProcPtr)( long param1, short param2 ); // // Here's a function in your application that will load and call that // kind of code resource, which you've compiled separately. // OSErr CallCodeResource( long param1, short param2 ) { Handle theCodeResource; CodeResourceProcPtr theEntryPoint; OSErr err; // Get it theCodeResource = GetResource( 'bill', 128 ); if ( err = ResError()) return( err ); // Position it DetachResource( theCodeResource ); MoveHHi( theCodeResource ); HLock( theCodeResource ); // Locate it and Strip it theEntryPoint = (CodeResourceProcPtr) StripAddress( *theCodeResource ); // Jump into it err = (*theEntryPoint)( param1, param2 ); // Dispose of it HUnlock( theCodeResource ); DisposeHandle( theCodeResource ); return( err ); } - ---------------------------------------------------------- The Code Resource Itself // Your code resource, compiled separately, would start // life like this... #include pascal OSErr main( long param1, short param2 ); pascal OSErr main( long param1, short param2 ) { RememberA0(); SetUpA4(); // bla bla bla RestoreA4(); return( err ); } - ---------------------------------------------------------- Setup for Separately Compiled Code Resources In the "Set Project Type..." dialog, type "bill" into the code resource type, do NOT check custom header, make sure "purgeable" is checked, and give it any name or id you like. The ID can be important. If you check "multi-segment" code resource, you have to be sure your code resource's id is less that 64, and it does the numbering so that the resource manager can determine at runtime which segments belong to this code resource. There is no other "contect" to worry about or set up to worry about. There are other resource numbering rules, but it I think the important thing is to not every use 'CODE'. - ---------------------------------------------------------- Other Notes Think C provides a nice way of dealing with the interface to code resources. All you'll have to do to the above is change 'bill' to whatever you want, change the data type and number of parameters you'll be needing, and the data type of the return value, ( or void ). That's it! Intead of using DetachResource / DisposeHandle, you could also just ReleaseResource it when you are done with it, which will save on disk thrashing if you will be accessing it a number of times. And don't forget the keyword 'pascal' in the typedef! You could look at your code all day long and not catch that one! :) :) Have fun. Mark Hanrek The Information Workshop +++++++++++++++++++++++++++ >From oster@netcom.com (David Phillip Oster) Date: Mon, 20 Jun 1994 15:52:59 GMT Organization: Netcom Online Communications Services (408-241-9760 login: guest) Mark Hanrek posted a code example of calling a code resource. It contained some errors: 1.) it called DetachResource at the beginning and DisposHandle at the end. It is often better to omit these two steps, and just do a HGetState() at the beginning and an HSetState() at the end. 2.) It assumes that both the calling C program and the code resource are either both 680x0 code or both PowerPC code. If there is a chance that they might be mixed, you need to call the code resource slightly differently. This is fully documented in the PowerPC volume of InsideMac. You also might want to consider creating a "fat" code resource, chich contains both 680x0 and PowerPC instructions so it it will run at top speed no matter who calls +++++++++++++++++++++++++++ >From Kevin.R.Boyce@gsfc.nasa.gov (Kevin R. Boyce) Date: Mon, 20 Jun 1994 12:38:47 -0400 Organization: NASA/GSFC Mark Hanrek wrote: > In article <2u066f$avl@mailhost.interaccess.com> Bill McCloskey, > billm@interaccess.com writes: > > > If I was going to write a 'CODE' resource in Think C, how could I > > execute it in my program? Also, are there any examples for this > > anywhere? > > You would certainly want to copy the way it is done in some example > source code. I prepared an ansewr to a question like yours before, so > I've attached it below. It is ready to be pasted in and compiled. [Sample code that is almost identical to my own stock answer deleted.] There is one other thing you need to be aware of, if you are using any system callbacks in your code resource. (System callbacks are things like dialog filters, that get called from within an OS/Toolbox routine that you call.) The problem is that the system may have messed with A4 before calling your callback routine, so you have to set it up within the callback. Here is the second half of my stock answer, where I discuss this in detail: And one final (very important) point is that the A4 routines are static (they only apply to the file in which they appear). So if you need to use SetUpA4() in a file other than the one which called RememberA0(), you need to call RememberA4() (NOT RememberA0()) from within that file, sometime before the call to SetUpA4(). Uh, maybe an example would help (this also demonstrates how to return the value of a global)... - - file MainCode.c --- #include char aGlobal; char main(long foo) /* Wants to return value of aGlobal */ { char retVal; RememberA0(); SetUpA4(); ... DoSomeDialog(); ... retVal = aGlobal; /* Have to do this while A4 is still valid! */ RestoreA4(); /* A4 no longer points to our global area */ return retVal; /* But local (automatic) variables are still ok */ } - - file MyDialogs.c --- #include extern short aGlobal; void DoSomeDialog() { DialogPtr theDialog; short itemHit; RememberA4(); /* Save A4 for functions in this file. */ theDialog = GetNewDialog( dlgRsrcID, nil, (WindowPtr)-1 ); ModalDialog( myFilter, &itemHit ); ... return; } pascal Boolean MyFilter(DialogPtr theDlg, EventRecord *theEvent, short *itemHit ) { Boolean status; SetUpA4(); if ( theEvent->what == keyDown ) { aGlobal = (theEvent->message) & charCodeMask; *itemHit = ok; status = TRUE; } else { status = FALSE; } RestoreA4(); return status; } -- Kevin Kevin.R.Boyce@gsfc.nasa.gov I then suspended the assembly by the edges of the CD, and began filling the box with Inside Macintosh volumes. --Kevin Bell +++++++++++++++++++++++++++ >From Mark Hanrek Date: Tue, 21 Jun 1994 08:45:55 GMT Organization: The Information Workshop In article David Phillip Oster, oster@netcom.com writes: >It contained some errors: >1.) it called DetachResource at the beginning and DisposHandle at the end. >It is often better to omit these two steps, and just do a HGetState() at >the beginning and an HSetState() at the end. > >2.) It assumes that both the calling C program and the code resource are >either both 680x0 code or both PowerPC code. If there is a chance that they >might be mixed, you need to call the code resource slightly differently. >This is fully documented in the PowerPC volume of InsideMac. You also might >want to consider creating a "fat" code resource, chich contains both 680x0 >and PowerPC instructions so it it will run at top speed no matter who calls David, Neither are errors. Errors are where you do something wrong. The first is a situational kind of thing. As for the PowerPC concerns, that is not appropriate here, because the Bill asked how to call a code resource, and he was given just what he needs to be successful. The objective in answering questions is to hopefully make it so the answer makes whatever it is seem like a piece of cake. My DetachResource approach isolates him from Resource Manager concerns so this does not foul up his first experiences. Moving the handle high also eliminates memory fragmentation concerns. By and by, he will know as much about it as you or I and be answering questions himself. :) Not only that, if he wanted to take advantage of what you mentioned, how would he do that? All you did was mention that there was a concern, and a reference to HGetState. Kevin on the other hand, rather than simply mentioning that there are concerns with dialog callbacks, laid it all out in black and white, and very clearly. A piece of cake. :) Mark Hanrek P.S. There were, though, tons of editing errors in my post. Something must have gone wrong with the editor. ( yeah, right :) --------------------------- >From will@cs.su.oz.au (William Uther) Subject: Code Resources with CodeWarrior Date: 20 Jun 1994 16:16:24 +1000 Organization: Basser Dept of Computer Sciece, Uni of Sydney, Australia Hi, I've just been trying to covert a THINK C 6.0 Code Resource to CodeWarrior. I'm using the 68k DR3. I've set the prefs up to produce a code resource and included all the files. When I test the code resource it doesn't work. The A4 world is set up by the program calling the code resource. And seems to be correct. One of the first things the code resource does is call TextBox to display a debug string. The call is in the assembler - but it doesn't come up. I have no idea wot's wrong. There are NO compile or link errors. Are there any bugs in DR3 with code resources, or is there some strange thing I have to set - I've RTFM'd but there really isn't much there. \x/ill :-} +++++++++++++++++++++++++++ >From rang@winternet.com (Anton Rang) Date: 20 Jun 1994 12:27:49 GMT Organization: Minnesota Angsters In article <2u3c7o$6sh@staff.cs.su.oz.au> will@cs.su.oz.au (William Uther) writes: >When I test the code resource it doesn't work. The A4 world is set >up by the program calling the code resource. And seems to be >correct. You say the A4 world is set up by the *caller*? Are you following the CodeWarrior rules on this? (They're different from THINK.) In THINK C, the A4 register needs to point to the beginning of the code resource. I don't recall the CW rules for sure, but it's definitely different, more along the lines of 'A4 = the end plus $8000'. (Run one of the examples that uses A4, or write a quick one, and pop into the debugger to check for sure.) -- Anton Rang (rang@winternet.com) +++++++++++++++++++++++++++ >From will@cs.su.oz.au (William Uther) Date: 20 Jun 1994 22:43:21 +1000 Organization: Basser Dept of Computer Sciece, Uni of Sydney, Australia Hello again, Fixed the problem - I was assuming that CW used a similar A4 world to THINK and MPW - A4 was being set wrong and yet it wasn't crashing. It would be nice if this were mentioned in the manuals (I eventaully found it, well documented, in a code example). \x/ill :-} P.S. Aside from the odd conversion problem from THINK C, CW is very good - I am in the process of converting everything. --------------------------- >From Frank Price Subject: MacTCP DNR for PowerPC? Date: Tue, 21 Jun 1994 03:16:28 GMT Organization: Netcom I noticed that the DNR.c file on the CodeWarrior DR3 CD and the MacOnRISC release CD is basically bogus when it actually gets compiled. It is far from a complete conversion to native code...at least as far as CodeWarrior is concerned. After making many small changes that were obvious, the functions still "don't match prototypes." Anyway, I'd rather not muck with this file if there is an official or correctly updated version out there. Anyone know what the story is or want to send me an updated file? Thanks! Frank +++++++++++++++++++++++++++ >From scouten@maroon.tc.umn.edu (Eric Scouten) Date: Tue, 21 Jun 1994 14:29:56 GMT Organization: University of Minnesota, Student Affairs In article , Frank Price wrote: > I noticed that the DNR.c file on the CodeWarrior DR3 CD and the MacOnRISC > release CD is basically bogus when it actually gets compiled. It is far > from a complete conversion to native code...at least as far as > CodeWarrior is concerned. After making many small changes that were > obvious, the functions still "don't match prototypes." Anyway, I'd > rather not muck with this file if there is an official or correctly > updated version out there. Anyone know what the story is or want to send > me an updated file? Sorry. You'll have to rewrite DNR.c. Apple did a pretty poor job of creating a universal header for this file. You will have to change all of the typedefs and the ProcInfo definitions. The following is an excerpt from some of my own TCP code that shows the corrected values. - ------- // NOTE: The dnr.c file created for universal headers contained an error. All // of the selectors are treated by the DNR as long values, not short. This has // been corrected in TurboTCP. extern "C" { typedef OSErr (*OpenResolverProcPtr)(long selector, char* fileName); // ^^^^ this was "short" in dnr.c typedef OSErr (*CloseResolverProcPtr)(long selector); typedef OSErr (*StrToAddrProcPtr)(long selector, char* hostName, struct hostInfo* rtnStruct, long resultProc, char* userData); typedef OSErr (*AddrToStrProcPtr)(long selector, long address, char* hostName); typedef OSErr (*AddrToNameProcPtr)(long selector, unsigned long addr, struct hostInfo* rtnStruct, long resultProc, char* userData); typedef OSErr (*HInfoProcPtr)(long selector, char* hostName, struct returnRec* returnRecPtr, long resultProc, char* userData); typedef OSErr (*MXInfoProcPtr)(long selector, char* hostName, struct returnRec* returnRecPtr, long resultProc, char* userData); }; #if USESROUTINEDESCRIPTORS enum { uppOpenResolverProcInfo = kCStackBased | RESULT_SIZE(SIZE_CODE(sizeof(short))) | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long))) | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(char*))) }; // etc. // // change parameter 1 of all ProcInfos to (sizeof(long)) // - ------- Hope this was helpful. -Eric -- Eric Scouten * U of MN * scouten@maroon.tc.umn.edu * +1 612 626 0746 ** MS Computer Science student, Univ of Illinois, starting Aug '94 ** Maps tell the truth, the whole truth, and anything but the truth. --------------------------- >From kerr@math.ohio-state.edu (Kerr Gibson) Subject: Major bug with Symantec CDK *Please Read* Date: 21 Jun 1994 19:13:36 -0400 Organization: Department of Mathematics, The Ohio State University Thought I would write this to spare you some of the headaches I went through in linking a Symantec PPC project. My original problem was that I had ported an old project to a new Virtual Architect PPC project. The project linked via the ToolServer and produced an application which inexplicably would not run. All it would do was produce an error and quit. The actual bug has to do with Quicktime and the makefile for the ToolServer. My original project uses Quicktime and the QuickTime xcoff library is not included in the VA PPC starter project. "Uh Oh.", I think, "I had better make sure the Quicktime lib is included in the linker script for the ToolServer. So I open the PPCBuild.ts file and find the following: ... MakePEF {XCOFFname} -o {AppName} 6 -l "AppleScriptLib.xcoff.o=AppleScriptLib" 6 -l "InterfaceLib.xcoff.o=InterfaceLib" 6 -l "MathLib.xcoff.o=MathLib" 6 -l "ObjectSupportLib.xcoff.o=ObjectSupportLib" 6 -l "QuickTimeLib.xcoff.o=InterfaceLib" 6 -l "StdCLib.xcoff.o=StdCLib" 6 -ft 'APPL' -fc "{Creator}" Lo and behold, it is already there. "Ok Cool", I say to myself, "I just won't change the file." So I leave it alone and then I spend the next week trying to figure out why my program links but wont run. The astute observer of course will see what I failed to notice: -l "QuickTimeLib.xcoff.o=InterfaceLib" 6 ^^^^^^^^^^^^ Its the wrong d*mn library name! This explains the issue. The linker did not report an error because the library really was loaded. Unfortunately it was loaded right over top of the previous InterfaceLib PEF file! The reason this bug was never found is because if there is no Quicktime lib in the project, it is ignored by this script. I imagine that this little diddy wreaked hell with the code fragment, hence, it was unable to run. I had been duped by a simple copy/paste error (see 3 lines above it). Now I don't have a problem with copy/paste errors, God knows I make them all the time. But I'm a little miffed that certain libraries were never tested with the final out-the-door product. Anyway, if you want to use QuickTime with the CDK, this is your warning. --Kerr Gibson P.S. I'm also pissed that the Finder did not give me an error code- all it said was "The Application xxx could not be launched because an error ocurred." What gives? --------------------------- >From ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) Subject: Perspective in GX (was Re: can toolbox draw text at an angle?) Date: 21 Jun 94 14:06:37 +1200 Organization: University of Waikato, Hamilton, New Zealand In article <3624861694.8241498@tempest.tempest.net.hk>, johnb@tempest.net.hk (John W. Blackburne) writes: > Jens Alfke (jens_alfke@powertalk.apple.com) wrote: > >> Why yes -- QuickDraw GX supports arbitrary transformations of text, > including >> skew and perspective in addition to rotation. Anything you can describe in > a >> 3x3 matrix. Not only that, but you can allow the user to edit the > transformed >> text (typing into perspective text is pretty trippy.) You can also fit text >> to a curve, but it's not directly editable after that. > > Can someone please explain to me how this works. If you are using a 3 x 3 > matrix (on an anything x anything matrix) for transformations you get > linear transformations, which include scaling, rotating, reflecting and > skewing but NOT transforming the perspective of a shape, at least not when > operating on the real two-dimensional space QD GX works in. Yes, you can. Remember, these are 3 x 3 matrices, not 2 x 2. Also, perspective is very much a linear transformation, since it maps straight lines to straight lines, after all. Here's how it works: for transformations other than perspective, you work in homogeneous coordinates, which normally look like this: [x y 1] [a b 0] = [x' y' 1] [c d 0] [e f 1] Perspective transforms work like this: [x y 1] [1 0 u] = [x y (xu + yv + 1)] [0 1 v] [0 0 1] The matrix doesn't quite fit into the usual normalized form, but QuickDraw GX supports it just fine. And when you normalize the result vector, you end up with x' = x / (xu + yv + 1) y' = y / (xu + yv + 1) et voila! A perspective transformation. Of course, you can combine these with other linear transformations in the usual way. Now the big mystery: with all the other convenience routines that they bothered to put into the QuickDraw GX API, why didn't they include one to build perpective transformations? Lawrence D'Oliveiro fone: +64-7-856-2889 Info & Tech Services Division fax: +64-7-838-4066 University of Waikato electric mail: ldo@waikato.ac.nz Hamilton, New Zealand 37^ 47' 26" S, 175^ 19' 7" E, GMT+12:00 "If you want competence, you must read everything. But, if you want originality, you must not." -- Edward de Bono +++++++++++++++++++++++++++ >From turk@apple.com (Ken Turkowski) Date: Tue, 21 Jun 1994 21:56:40 GMT Organization: Apple Computer, Inc. In article <1994Jun21.140637.29986@waikato.ac.nz>, ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) wrote: > Now the big mystery: with all the other convenience routines that they bothered > to put into the QuickDraw GX API, why didn't they include one to build > perpective transformations? Try Quad2D2Quad2D(), given below. This works if you know the projective transformations of 4 points. Are there any other specifications you'd be interested in? /* Original code due to Paul Heckbert. * Recoded by Ken Turkowski. * AS IS. No guarantees. */ #define MAXDIM 32 #define kFudge 1e-16 #define kBadMap 0 #define kProjectiveMap 1 #define kAffineMap 2 #include #define ConcatMap(map1Type, map2Type) ((map1Type < map2Type) ? map1Type : map2Type) typedef struct TPoint2D { float x, y; } TPoint2D; typedef struct TPoint3D { float x, y, z; } TPoint3D; typedef struct TVector4D { float x, y, z, w; } TVector4D; typedef FLOAT vec3[3]; void MLAdjointMatrix3x3(float *M) { float t[3][3]; struct MX { float m[3][3]; }; register vec3* m = (vec3*)M; t[0][0] = m[1][1] * m[2][2] - m[1][2] * m[2][1]; /* t(0,0) */ t[0][1] = - m[0][1] * m[2][2] + m[0][2] * m[2][1]; /* t(0,1) */ t[0][2] = m[0][1] * m[1][2] - m[0][2] * m[1][1]; /* t(0,2) */ t[1][0] = - m[1][0] * m[2][2] + m[1][2] * m[2][0]; /* t(1,0) */ t[1][1] = m[0][0] * m[2][2] - m[0][2] * m[2][0]; /* t(1,1) */ t[1][2] = - m[0][0] * m[1][2] + m[0][2] * m[1][0]; /* t(1,2) */ t[2][0] = m[1][0] * m[2][1] - m[1][1] * m[2][0]; /* t(2,0) */ t[2][1] = - m[0][0] * m[2][1] + m[0][1] * m[2][0]; /* t(2,1) */ t[2][2] = m[0][0] * m[1][1] - m[0][1] * m[1][0]; /* t(2,2) */ *((struct MX*)(&m[0][0])) = *((struct MX*)(&t[0][0])); } /**************************************************************** * Linear transformations, for transforming vectors and matrices. * This works for row vectors and column vectors alike. * L[nRows][lCol] - input (left) matrix * rg[lCol][rCol] - transformation (right) matrix * P[nRows][rCol] - output (product) matrix * * Examples: * v[3] * M[3][3] -> w[3] : LinearTransform(&v[0], &M[0][0], &w[0], 1, 3, 3); * M[3][3] * v[3] -> w[3] : LinearTransform(&M[0][0], &v[0], &w[0], 3, 3, 1); * M[4][4] * N[4][4] -> P[4][4]: LinearTransform(&M[0][0], &N[0][0], &P[0][0], 4, 4, 4); * v[4] * M[4][3] -> w[3]: LinearTransform(&v[0], &M[0][0], &w[0], 1, 4, 3); * v[3] tensor w[3] -> T[3][3]: LinearTransform(&v[0], &w[0], T[3][3], 3, 1, 3); ****************************************************************/ void LinearTransform( const float *L, /* The left matrix */ const float *R, /* The right matrix */ register float *P, /* The resultant matrix */ long nRows, /* The number of rows of the left and resultant matrices */ long lCol, /* The number of columns in the left matrix */ long rCol /* The number of columns in the resultant matrix */ ) { register const float *lp; /* Left matrix pointer for dot product */ register const char *rp; /* Right matrix pointer for dot product */ register long k; /* Loop counter */ register long double sum; /* Extended precision for intermediate results */ register long rRowBytes = rCol * sizeof(float); register long j, i; /* Loop counters */ register long lRowBytes = lCol * sizeof(float); const char *lb = (const char*)L; for (i = nRows; i--; lb += lRowBytes) { /* Each row in L */ for (j = 0; j < rCol; j++) { /* Each column in R */ lp = (const float *)lb; /* Left of ith row of L */ rp = (const char *)(R + j); /* Top of jth column of R */ sum = 0; for (k = lCol; k--; rp += rRowBytes) sum += *lp++ * (*((const float*)rp)); /* *P += L[i'][k'] * R[k'][j] */ *P++ = sum; } } } /**************************************************************** **************************************************************** **************************************************************** *** 2D Projective Mappings **************************************************************** **************************************************************** ****************************************************************/ #define DET2(a,b, c,d) ((a)*(d) - (b)*(c)) /**************************************************************** * UnitSquare2Quad2D() * * compute the TDMatrix3x3 M such that * [x y w] = [u v 1] M * where the points * (0,0), (0,1), (1,1), (1,0) * map into the points * p[0], p[1], p[2], p[3]. ****************************************************************/ int UnitSquare2Quad2D(register const TPoint2D *p, float M[3][3]) { double px, py; double dx12, dx32, dy12, dy32; double d, g, h; px = p[0].x - p[1].x + p[2].x - p[3].x; py = p[0].y - p[1].y + p[2].y - p[3].y; if ((fabs(px) < kFudge) && (fabs(py) < kFudge)) { /* Affine */ M[0][0] = p[1].x-p[0].x; M[0][1] = p[1].y-p[0].y; M[0][2] = 0; /* New x-axis */ M[1][0] = p[3].x-p[0].x; M[1][1] = p[3].y-p[0].y; M[1][2] = 0; /* New y-axis */ M[2][0] = p[0].x; M[2][1] = p[0].y; M[2][2] = 1; /* New origin */ return(kAffineMap); } /* Projective mapping */ dx12 = p[1].x - p[2].x; dx32 = p[3].x - p[2].x; dy12 = p[1].y - p[2].y; dy32 = p[3].y - p[2].y; d = DET2(dx12,dx32, dy12,dy32); /* Discriminant */ g = DET2(px,dx32, py,dy32); /* X-keystoning */ h = DET2(dx12,px, dy12,py); /* Y-Keystoning */ if (d != 0) { g /= d; /* Normalize these to get a matrix in standard form */ h /= d; M[0][0] = p[1].x-p[0].x+g*p[1].x; M[0][1] = p[1].y-p[0].y+g*p[1].y; M[0][2] = g; M[1][0] = p[3].x-p[0].x+h*p[3].x; M[1][1] = p[3].y-p[0].y+h*p[3].y; M[1][2] = h; M[2][0] = p[0].x; M[2][1] = p[0].y; M[2][2] = 1; return(kProjectiveMap); } else { return(kBadMap); } } /**************************************************************** * Rect2Projective() * * compute the matrix M[3][3] such that * [x y w] = [u v 1] M * where the points * q[0], q[1], q[2], q[3] * map into the points * p[0], p[1], p[2], p[3]. * If the inverse flag is set, it map xy->uv instead of ux->xy ****************************************************************/ int Rect2Quad2D(double u0, double v0, double u1, double v1, const TPoint2D* p, float M[3][3], int inverse) { double du = u1 - u0; double dv = v1 - v0; int mapType; if (du == 0 || dv == 0) return(0); /* Degenerate rectangle */ if ((mapType = UnitSquare2Quad2D(p, M)) == kBadMap) return(kBadMap); /* Bad perspectivity */ /* Apply rectangular stretching and translation */ M[0][0] /= du; M[0][1] /= du; M[0][2] /= du; M[1][0] /= dv; M[1][1] /= dv; M[1][2] /= dv; M[2][0] -= M[0][0]*u0+M[1][0]*v0; M[2][1] -= M[0][1]*u0+M[1][1]*v0; M[2][2] -= M[0][2]*u0+M[1][2]*v0; if (inverse) /* Do we want uv->xy or xy->uv? */ AdjointMatrix3x3(M[0]); /* xy->uv! */ return(mapType); } /**************************************************************** * Quad2D2Quad2D() * * compute the matrix M[3][3] such that * [x y w] = [u v 1] M * where the points * q[0], q[1], q[2], q[3] * map into the points * p[0], p[1], p[2], p[3]. ****************************************************************/ int Quad2D2Quad2D(register const TPoint2D* q, const TPoint2D* p, float M[3][3]) { if (q[0].x==q[3].x && q[1].x==q[2].x && /* vertical edges 3-0 and 1-2 */ q[0].y==q[1].y && q[2].y==q[3].y /* horizontal edges 0-1 and 2-3 */ ) { return(Rect2Quad2D(q[0].x, q[0].y, q[2].x, q[2].y, p, M, 0)); } else if (q[0].x==q[1].x && q[2].x==q[3].x && q[1].y==q[2].y && q[3].y==q[0].y ) { TPoint2D prot[4]; prot[0]=p[1]; prot[1]=p[2]; prot[2]=p[3]; prot[3]=p[0]; /* cycle points */ return(Rect2Quad2D(q[1].x, q[1].y, q[3].x, q[3].y, prot, M, 0)); } else { float L[3][3], R[3][3]; int map1Type, map2Type; /* Calculate mapping from quad q to unit square */ if ((map1Type = UnitSquare2Quad2D(q, L)) == kBadMap) /* unit square to quad q */ return(kBadMap); AdjointMatrix3x3(L[0]); /* Calculate mapping from unit square to quad p */ if ((map2Type = UnitSquare2Quad2D(p, R)) == kBadMap) /* unit square to quad p */ return(kBadMap); /* Concatenate the two transformations */ LinearTransform(L[0], R[0], M[0], 3, 3, 3); return(ConcatMap(map1Type, map2Type)); } } //Ken Turkowski; Apple Computer, Inc.; 1 Infinite Loop; Cupertino, CA 95014 //turk@apple.com --------------------------- >From gilem@litecdev.eng.rpi.edu (Michael R. Gile) Subject: Still trouble finding floating windows code. Date: 14 Jun 1994 18:36:13 GMT Organization: Rensselaer Polytechnic Institute, Troy NY I am still looking for some code which implements floating windows on the mac, which will compile using either think C or metrowerks C. I have tried compiling yu's code from d e v e l o p issue 15 using both of these compilers, with absolutely no success. The code compiles, but then crashes hard as soon as any events are sent to the handlers. Does anyone have any suggestions? I don't have MPW, so that doesn't help. thanks Mike -- Michael Gile | Graduate Assistant gilem@rpi.edu | Computer & Systems Engineering "Don't Blame Me, I voted for Perot!"| Rensselaer Polytechnic Institute +++++++++++++++++++++++++++ >From egurney@vcd.hp.com (Eddy J. Gurney) Date: Wed, 15 Jun 1994 01:01:35 GMT Organization: Hewlett-Packard VCD Michael R. Gile (gilem@litecdev.eng.rpi.edu) wrote: >I am still looking for some code which implements floating windows on >the mac, which will compile using either think C or metrowerks C. I >have tried compiling yu's code from d e v e l o p issue 15 using both >of these compilers, with absolutely no success. The code compiles, but >then crashes hard as soon as any events are sent to the handlers. Does >anyone have any suggestions? I don't have MPW, so that doesn't help. Well, there are some bugs in the code, even with the latest version on the Bookmark 18 CD. But it may work for your application. (I sent mail to Dean Yu on them and did not get a response.) Your problem most likely has to do with the fact that the code is written for MPW and *not* THINK C, which use different methods to access low-memory globals (unless you have compiled MacHeaders to use SysEqu.h instead of LoMem.h, not likely for the average joe.) Anyway, the solution is to look at the two functions GetWindowList() and SetWindowList() and change them to return (WindowRef)WindowList; and WindowList = (WindowPeek)windowReference; respectively. A more robust solution would be to #ifdef THINKC (or whatever the compiler-set define is) around these changes, but I digress... -- Eddy J. Gurney N8FPW Hewlett-Packard Company, Vancouver (USA!) Division egurney@vcd.hp.com #include "Failures are divided into two classes-- those who thought and never did, and those who did and never thought." John Charles Salak +++++++++++++++++++++++++++ >From kenlong@netcom.com (Ken Long) Date: Wed, 15 Jun 1994 05:43:20 GMT Organization: NETCOM On-line Communication Services (408 261-4700 guest) There are floating window sources available on the net. Some even have the word "float" or "floating" in the filename. What I'd recommend is connecting to the major Mac source sites and getting all sources with window, WDEF and floating in the filename. Better yet, connect and get any description indexes for the site, and target your files you want to get before you connect for the files. "Nifty" has floaters, Infinity Windoid (an excellent one), an old file called "floating" does, too. As I recall, buried down in the TCL folder, in a subfolder, that came with Think C there is a windoid source. These sources may or may not have routines which result in the window staying in front no matter what (maybe bar dialogs), but there was a lengthy thread on this not to long ago. Maybe someone saved the thread and would send it to you, as well. -Ken- +++++++++++++++++++++++++++ >From Mark Hanrek Date: Wed, 15 Jun 1994 08:10:29 GMT Organization: The Information Workshop In article <2tktau$asu@usenet.rpi.edu> Michael R. Gile, gilem@litecdev.eng.rpi.edu writes: > I am still looking for some code which implements floating windows on the mac, > which will compile using either think C or metrowerks C. Besides what was just mentioned, I know there is an example called "Floating Windows 1.3" floating around. ( Sorry :) But, the best floating windows C example source code, integrated with the best windowing I have ever seen, is available as part of DTS.Lib, written by Eric Soldan. This is THE reference for any kind of windowing on the Mac, and it is excellent. You can find it at ftp.apple.com. Hope this helps. Mark Hanrek +++++++++++++++++++++++++++ >From jc@vivitech.com (John Cooper) Date: Fri, 17 Jun 1994 20:13:42 GMT Organization: Vivid Technologies Inc. I see a lot of people ask for code that implements floating windows. One common suggestion is to use Yu's code from _develop_, but everyone knows that that code is buggy. The follow-up suggestion is usually of the form: "The code in _develop_ still has bugs. Just go to an archive site and grab Infinity Windoid or ... " But is this all they really have to do? Just go get someone's WDEF, make a NewWindow with it and, voila!, instant floating windows? Now please forgive my ignorance; I've never written a WDEF before. Could someone explain to me how a WDEF alone achieves "floating" behavior in the Macintosh environment? How can a WDEF itself control the BringToFront behavior of all the other windows in an application (including doing the right thing with dialog boxes)? Doesn't an application have to manage all the layering itself even if a "windoid" WDEF is available? Doesn't the Infinity Windoid-- to use one example--only determine the windoid's appearance, and not it's "floating" properties? Telling someone who is trying to get floating palettes working to go get the Infinity Windoid is not enough, is it? Sure, that person will have pretty windoids, but they won't float all by themselves, will they? -John +--------------------------+------------------------------------------+ | John R. Cooper | Internet: jc@vivitech.com, | | Vivid Technologies, Inc. | jcooper@world.std.com | | Waltham, MA 02154 | AOL: JRCooper (jrcooper@aol.com) | +--------------------------+------------------------------------------+ | "God split himself into a myriad parts that he might have friends." | | This may not be true, but it sounds good and is no sillier than any | | other theology. | | -- Long's Notes -- | +---------------------------------------------------------------------+ +++++++++++++++++++++++++++ >From tbrown@dorsai.org (Tommy Brown) Date: Tue, 21 Jun 1994 20:46:07 GMT Organization: The Dorsai Embassy, New York, NY John Cooper (jc@vivitech.com) wrote: : I see a lot of people ask for code that implements floating windows. One : common suggestion is to use Yu's code from _develop_, but everyone knows : that that code is buggy. The follow-up suggestion is usually of the form: : "The code in _develop_ still has bugs. Just go to an archive site and : grab Infinity Windoid or ... " : But is this all they really have to do? Just go get someone's WDEF, make : a NewWindow with it and, voila!, instant floating windows? No. Although the code in develop has some bugs, as far as I know it is pretty much adequate. You will need to use the Infinity Windoid AND the code in develop to properly implement floating windows. The Infinity Windoid merely creates a window that looks like it should be floating. To make it actually float, you need to use modified code; the most recent code that I know of that will do the trick is what was found in develop. -- Tommy Brown | Je suis tombe par terre, c'est la faute a tbrown@dorsai.dorsai.org | Voltaire. Le nez dans le ruisseau, c'est la tommy6@aol.com | faute a Rousseau. zipit@softlock.com | - Gavroche --------------------------- >From damon@CS.ColoState.EDU (Yimmit) Subject: _vSyncWait infinite loop? Date: Thu, 16 Jun 1994 03:24:29 GMT Organization: Imladris Occupants Inc. OK. So, I'm doing some communications with the serial ports, but every so often I get stuck in _vSyncWait forever. My question is: Why? What are the reasons for an infinite loop to occur in _vSyncWait? This happens just after I do an FSWrite to the serial port. Has anyone had this problem? ANY help would be appreciated since I can find no documentation on this - anywhere. Tim Damon +++++++++++++++++++++++++++ >From resnick@uiuc.edu (Pete Resnick) Date: Wed, 15 Jun 1994 23:05:25 -0500 Organization: University of Illinois at Urbana-Champaign In article , damon@CS.ColoState.EDU (Yimmit) wrote: >OK. So, I'm doing some communications with the serial ports, but every >so often I get stuck in _vSyncWait forever. My question is: Why? What >are the reasons for an infinite loop to occur in _vSyncWait? This happens >just after I do an FSWrite to the serial port. The _vSyncWait loop is where synchronous calls wait for the interrupt telling them that the I/O routine has completed. Since FSWrite is simply a synchronous PBWrite, that's what's going on. Two causes are either (a) you called a synchronous routine like FSWrite at interrupt time and the interrupt for completion is never coming through or (b) the routine is never completing, which means that the data is never getting to the serial port (which would be very wierd). I vote for (a). :-) pr -- Pete Resnick (...so what is a mojo, and why would one be rising?) Doctoral Student - Philosophy Department, Gregory Hall, UIUC System manager - Cognitive Science Group, Beckman Institute, UIUC Internet: resnick@uiuc.edu +++++++++++++++++++++++++++ >From absurd@apple.com (Tim Dierks) Date: Thu, 16 Jun 1994 07:24:30 GMT Organization: Apple Computer, Inc. In article , damon@CS.ColoState.EDU (Yimmit) wrote: > OK. So, I'm doing some communications with the serial ports, but every so often > I get stuck in _vSyncWait forever. My question is: Why? What are the reasons > for an infinite loop to occur in _vSyncWait? This happens just after I do an > FSWrite to the serial port. Has anyone had this problem? ANY help would be > appreciated since I can find no documentation on this - anywhere. > > Tim Damon It basically means your write isn't completing; you made a synchronous write, so it won't return until all the bytes have been shoved through the serial port. When it can't shove all the characters through the serial port, it waits until it can finish. Possibilities include: - Handshaking is on (hardware or software) and it's been told not to send. This is in particular a problem when writing code that runs on PowerBooks; apparently, a desktop machine without its hardware handshaking line hooked up will usually think it's OK to send, while a portable will usually think that it's not OK to send; since hardware handshaking is on by default, this can be a surprise the first time you run your program on a PowerBook with a cable which doesn't have that pin hooked up. - You made a synchronous serial call from an interrupt level which doesn't allow the serial port's interrupts to get through; in general, only make asynchronous calls at interrupt time. - Something else is screwed up; however, the first two are most likely. Best, - Tim -- Tim Dierks absurd@apple.com +++++++++++++++++++++++++++ >From jvp@tools1.ee.iastate.edu (Jim Van Peursem) Date: 16 Jun 94 16:26:56 GMT Organization: Iowa State University, Ames, Iowa In resnick@uiuc.edu (Pete Resnick) writes: >In article , damon@CS.ColoState.EDU >(Yimmit) wrote: >>OK. So, I'm doing some communications with the serial ports, but every >>so often I get stuck in _vSyncWait forever. My question is: Why? What >>are the reasons for an infinite loop to occur in _vSyncWait? This happens >>just after I do an FSWrite to the serial port. >The _vSyncWait loop is where synchronous calls wait for the interrupt >telling them that the I/O routine has completed. Since FSWrite is simply a >synchronous PBWrite, that's what's going on. Two causes are either (a) you >called a synchronous routine like FSWrite at interrupt time and the >interrupt for completion is never coming through or (b) the routine is >never completing, which means that the data is never getting to the serial >port (which would be very wierd). I vote for (a). :-) Not wierd at all actually. The problem is most likely due to improper initialization of serial handshaking options. Some machines default to hardware handshaking, and their port defaults to the "wait" state when no hardware handshaking lines are present. The fix is to call SerHShake() or the preferred, Control(14?) to initialize the handshaking options. +---------------------------------------------------------------+ | Jim Van Peursem - Ph.D. Candidate (Ham Radio -> KE0PH) | | Department of Electrical Engineering and Computer Engineering | | Iowa State University - Ames, IA 50011 : (515) 294-8339 | | internet - jvp@iastate.edu -or- jvp@cpre1.ee.iastate.edu | +---------------------------------------------------------------+ +++++++++++++++++++++++++++ >From d88-jwa@mumrik.nada.kth.se (Jon Wätte) Date: 17 Jun 1994 20:55:20 GMT Organization: The Royal Institute of Technology In damon@CS.ColoState.EDU (Yimmit) writes: >OK. So, I'm doing some communications with the serial ports, but every so often >I get stuck in _vSyncWait forever. My question is: Why? What are the reasons _vSyncWait is where your Mac spends most of its time. It takes a parameter block as parameter, and waits until ioResult isn't 1 anymore. I/O is usually done through spawning off an interrupt task which sets ioResult to the result code. There's probably something keeping your Mac from sending the data, like an XOFF or no CTS or something. You can avoid such hangs by always writing in async mode (but that brings about other problems) with PBWriteAsync. Cheers, / h+ -- -- Jon W{tte, h+@nada.kth.se, Mac Software Engineer Deluxe -- "My boss made me say it. He dares you to sue!" +++++++++++++++++++++++++++ >From damon@CS.ColoState.EDU (Yimmit) Date: Sat, 18 Jun 1994 01:28:09 GMT Organization: Imladris Occupants Inc. Thanks to all who replied to this problem. Silly me, I forgot to prototype my send function for a separate source file. Therefore, my command parameter was being trashed in the send function and I was accidentally sending some huge amount of data!! Oh well. Thanks again! -->Tim Damon +++++++++++++++++++++++++++ >From Bruce@hoult.actrix.gen.nz (Bruce Hoult) Date: Sun, 19 Jun 1994 12:41:39 +1200 (NZST) Organization: (none) damon@CS.ColoState.EDU (Yimmit) writes: > OK. So, I'm doing some communications with the serial ports, but every so often > I get stuck in _vSyncWait forever. My question is: Why? What are the reasons > for an infinite loop to occur in _vSyncWait? This happens just after I do an > FSWrite to the serial port. Has anyone had this problem? ANY help would be > appreciated since I can find no documentation on this - anywhere. Bet you're not calling SerHShake. -- Bruce --------------------------- >From kelley@cs.dal.ca (Dan Kelley) Subject: can toolbox draw text at an angle? Date: Thu, 16 Jun 1994 13:04:12 GMT Organization: Oceanography, Dalhousie University, Halifax, NS, Canada Some years ago I did some Mac programming, and was disappointed to realize that it could not easily draw text at an angle. Is this still the case, or has system7/truefont/... made it possible to draw text at an angle to the horizontal? If you have information, I'd appreciate an email (since I presume, scanning the group for the last few days, that others might not be interested). Thanks. Dan. -- Dan Kelley | dan.kelley@dal.ca (902)494-1694 Oceanography Department | ``We rise again, Dalhousie University | in the faces of our children'' Halifax, NS, CANADA, B3H 4J1 | The Rankin Family +++++++++++++++++++++++++++ >From andrewt@fluffy.cs.wisc.edu (Andrew Thomas-Cramer) Date: 16 Jun 1994 16:39:46 GMT Organization: University of WI, Madison -- Computer Sciences Dept. kelley@cs.dal.ca (Dan Kelley) writes: >Some years ago I did some Mac programming, and was disappointed to realize that >it could not easily draw text at an angle. >Is this still the case, or has system7/truefont/... made it possible to draw text >at an angle to the horizontal? >If you have information, I'd appreciate an email (since I presume, scanning the >group for the last few days, that others might not be interested). Thanks. Dan. I'd be interested. Please post any responses. Clearly, it's possible -- composition and illustration software do it routinely. But how is it fastest done? A transformation of the bits generated from Toolbox routines to a new rotation, or direct use of the font description? Or has a Toolbox routine been added lately? andy thomas-cramer +++++++++++++++++++++++++++ >From jwbaxter@olympus.net (John W. Baxter) Date: Thu, 16 Jun 1994 15:00:05 -0700 Organization: Internet for the Olympic Peninsula In article , kelley@cs.dal.ca (Dan Kelley) wrote: > Some years ago I did some Mac programming, and was disappointed to realize that > it could not easily draw text at an angle. > > Is this still the case, or has system7/truefont/... made it possible to draw text > at an angle to the horizontal? QuickDraw GX makes rotated text (or rotated anything, almost) trivial. Summer. -- John Baxter Port Ludlow, WA, USA [West shore, Puget Sound] No hablo Intel. jwbaxter@pt.olympus.net +++++++++++++++++++++++++++ >From gabe@shiva.com (Gabriel Lawrence) Date: Thu, 16 Jun 94 21:59:02 GMT Organization: Shiva Corporation In Article <2tpv8i$4rn@spool.cs.wisc.edu>, andrewt@fluffy.cs.wisc.edu (Andrew Thomas-Cramer) wrote: >kelley@cs.dal.ca (Dan Kelley) writes: > >>Some years ago I did some Mac programming, and was disappointed to realize >>that it could not easily draw text at an angle. >> >>Is this still the case, or has system7/truefont/... made it possible to draw >>text at an angle to the horizontal? Regular old QuickDraw never supported it but Adobe Type Manager did. I asked Apple a few years ago how to do it without ATM and was told that if I used the same approach that ATM offered, they would produce a compatible method. They've finally offered a solution (though not really compatible) in the form of QuickDraw GX. The following is excerpted from "IM-QuickDraw GX Typography" "GXRotateShape: Rotates the typographic shape. This function can affect the mapping of the typographic shape's transform if the gxMapTransformShape attribute is set. Otherwise, it converts a text shape to a glyph shape, and it changes the values in the glyph shape's tangents array. You use the GXRotateShape function to create vertical text. See the chapter "Typographic Styles" for more information on vertical text." You can also directly alter the glyph tangent array if you want to do something like draw text along an arbitrary line. In short, now you can easily do amazing things to text including rotation, skews, and generic transforms. =Gabe= > I'd be interested. Please post any responses. > Clearly, it's possible -- composition and illustration software do it >routinely. But how is it fastest done? A transformation of the bits generated >from Toolbox routines to a new rotation, or direct use of the font description? >Or has a Toolbox routine been added lately? > > andy thomas-cramer > - ---------------------- Gabriel Lawrence Shiva Corporation Software Tool "All Disclaimers Apply" gabe@shiva.com +++++++++++++++++++++++++++ >From Jens Alfke Date: Thu, 16 Jun 1994 23:05:05 GMT Organization: Apple Computer In article <2tpv8i$4rn@spool.cs.wisc.edu> Andrew Thomas-Cramer, andrewt@fluffy.cs.wisc.edu writes: > Clearly, it's possible -- composition and illustration software do it > routinely. But how is it fastest done? A transformation of the bits generated > from Toolbox routines to a new rotation, or direct use of the font description? I'd guess that most programs currently draw offscreen and transform the bitmap. For details on bitmap transmogrification, see "Graphics Gems 3" from Academic Press. > Or has a Toolbox routine been added lately? Why yes -- QuickDraw GX supports arbitrary transformations of text, including skew and perspective in addition to rotation. Anything you can describe in a 3x3 matrix. Not only that, but you can allow the user to edit the transformed text (typing into perspective text is pretty trippy.) You can also fit text to a curve, but it's not directly editable after that. --Jens Alfke jens_alfke@powertalk Rebel girl, rebel girl, .apple.com Rebel girl you are the queen of my world +++++++++++++++++++++++++++ >From Mark Hanrek Date: Fri, 17 Jun 1994 05:02:28 GMT Organization: The Information Workshop In article John W. Baxter, jwbaxter@olympus.net writes: > QuickDraw GX makes rotated text (or rotated anything, almost) trivial. I heard a rumor that QuickTime 2.0 was going to have the stuff that allows still pictures to be quickly rotated. Then again, it does make sense for this kinda stuff to be in QuickDraw/GX. Anyone know the skinny on this? In particular, I am interested in rotating pixmaps an arbitrary number of degrees, kinda thing. Thanks. Mark Hanrek +++++++++++++++++++++++++++ >From jwbaxter@olympus.net (John W. Baxter) Date: Fri, 17 Jun 1994 09:10:47 -0700 Organization: Internet for the Olympic Peninsula In article , Mark Hanrek wrote: > In article John W. Baxter, > jwbaxter@olympus.net writes: > > > QuickDraw GX makes rotated text (or rotated anything, almost) trivial. > ... > In particular, I am interested in rotating pixmaps an arbitrary number of > degrees, kinda thing. QD GX does that, in two fundamentally different ways: (a) by shuffling the pixels around in the actual bitmap geometry, or (b) by applying a rotation transform during drawing. (a) is often very bad, particularly if you are going to rotate several times. There's an example of the result of that in the color plates at the front of Inside Mac: QD GX Graphics. [It starts as a nice color ramp...it finishes as a Rorschach inkblot.] -- John Baxter Port Ludlow, WA, USA [West shore, Puget Sound] No hablo Intel. jwbaxter@pt.olympus.net +++++++++++++++++++++++++++ >From johnb@tempest.net.hk (John W. Blackburne) Date: 18 Jun 1994 03:50:03 GMT Organization: Tempest, Hong Kong Jens Alfke (jens_alfke@powertalk.apple.com) wrote: > Why yes -- QuickDraw GX supports arbitrary transformations of text, including > skew and perspective in addition to rotation. Anything you can describe in a > 3x3 matrix. Not only that, but you can allow the user to edit the transformed > text (typing into perspective text is pretty trippy.) You can also fit text > to a curve, but it's not directly editable after that. Can someone please explain to me how this works. If you are using a 3 x 3 matrix (on an anything x anything matrix) for transformations you get linear transformations, which include scaling, rotating, reflecting and skewing but NOT transforming the perspective of a shape, at least not when operating on the real two-dimensional space QD GX works in. John Tempest, a FirstClass BBS, Hong Kong 802-7395 John W. Blackburne, administrator - - When You're cruisin' in overdrive, Don' have to listen to no, run o' the mill talk jive --- +++++++++++++++++++++++++++ >From Cary Clark Date: Sun, 19 Jun 1994 22:04:31 GMT Organization: Apple Computer, Inc. In article <3624861694.8241498@tempest.tempest.net.hk> John W. Blackburne, >>Jens Alfke (jens_alfke@powertalk.apple.com) wrote: >> Why yes -- QuickDraw GX supports arbitrary transformations of text, >> including skew and perspective in addition to rotation. Anything you >> can describe in a 3x3 matrix. Not only that, but you can allow the user >> to edit the transformed text (typing into perspective text is pretty >> trippy.) johnb@tempest.net.hk writes: >Can someone please explain to me how this works. If you are using a 3 x 3 >matrix (on an anything x anything matrix) for transformations you get >linear transformations, which include scaling, rotating, reflecting and >skewing but NOT transforming the perspective of a shape, at least not >when operating on the real two-dimensional space QD GX works in. QuickDraw GX expresses all of its coordinates by the vector (x, y, 1). Multiplying this by the 3x3 results in (x', y', z'). Viewing this back in the destination space requires that z = 1, so this vector is normalized as (x'/z', y'/z', 1). The extra divisions required by perspective calculations are performed only when necessary, so that non-perspective drawing isn't penalized. Cary Clark Apple Computer, Inc. +++++++++++++++++++++++++++ >From kelley@cs.dal.ca (Dan Kelley) Date: Mon, 20 Jun 1994 12:40:28 GMT Organization: Oceanography, Dalhousie University, Halifax, NS, Canada The answers to my question about rotated text have all mentioned GX. I'm new to the mac, and have 2 questions: 1) is quickdraw gx available on all shipping platforms, or is it something new? 2) is there a downloadable document on gx, or a book title I can look up? Thanks very much to everyone who has been so helpful. -- Dan Kelley | dan.kelley@dal.ca (902)494-1694 Oceanography Department | ``We rise again, Dalhousie University | in the faces of our children'' Halifax, NS, CANADA, B3H 4J1 | The Rankin Family +++++++++++++++++++++++++++ >From jwbaxter@olympus.net (John W. Baxter) Date: Mon, 20 Jun 1994 07:50:02 -0700 Organization: Internet for the Olympic Peninsula In article , kelley@cs.dal.ca (Dan Kelley) wrote: > The answers to my question about rotated text have all mentioned GX. I'm new > to the mac, and have 2 questions: > > 1) is quickdraw gx available on all shipping platforms, or is it something new? QuickDraw GX is just emerging into the post-beta world. It is available for license to distribute with applications which use it, and will be shipped with System 7.5 (real soon now). > 2) is there a downloadable document on gx, or a book title I can look up? There is more than "a book". There are 7 new volumes of Inside Macintosh, 3 of which (at least) have hit the stores in paper form. They are available (except for the Overview document so far) on various Apple CD ROMs. Issue 18 of "develop" ($10 as a back issue...double check that the back issue includes the same-numbered CD) is one source. "develop" is worth subscribing too regardless of the CD, IMHO. It's been more years than it should have been since I have been in Halifax (via cruise ship). -- John Baxter Port Ludlow, WA, USA [West shore, Puget Sound] No hablo Intel. jwbaxter@pt.olympus.net +++++++++++++++++++++++++++ >From bhorling@mail.trincoll.edu (Bryan Horling) Date: Sun, 19 Jun 1994 20:55:49 -0500 Organization: Trinity College In article <1994Jun19.220431.20334@gallant.apple.com>, Cary Clark wrote: > In article <3624861694.8241498@tempest.tempest.net.hk> John W. > Blackburne, >>Jens Alfke (jens_alfke@powertalk.apple.com) wrote: > >> Why yes -- QuickDraw GX supports arbitrary transformations of text, > >> including skew and perspective in addition to rotation. Anything you > >> can describe in a 3x3 matrix. Not only that, but you can allow the user > >> to edit the transformed text (typing into perspective text is pretty > >> trippy.) > > johnb@tempest.net.hk writes: > >Can someone please explain to me how this works. If you are using a 3 x 3 > >matrix (on an anything x anything matrix) for transformations you get > >linear transformations, which include scaling, rotating, reflecting and > >skewing but NOT transforming the perspective of a shape, at least not > >when operating on the real two-dimensional space QD GX works in. > > QuickDraw GX expresses all of its coordinates by the vector (x, y, 1). > Multiplying this by the 3x3 results in (x', y', z'). Viewing this back in > the destination space requires that z = 1, so this vector is normalized > as (x'/z', y'/z', 1). The extra divisions required by perspective > calculations are performed only when necessary, so that non-perspective > drawing isn't penalized. > > Cary Clark > Apple Computer, Inc. Is there any easy way to do rotations without QuickDraw GX? Say you wanted to write in the y axis label on a graph or somthing like that (so that the the bottom of the text was parallel with the axis), how could you go about doing it? -- Bryan C.Horling |||| Trinity College @@ bhorling@mail.cc.trincoll.edu Hartford, CT == +++++++++++++++++++++++++++ >From Jens Alfke Date: Mon, 20 Jun 1994 20:58:11 GMT Organization: Apple Computer John W. Blackburne, johnb@tempest.net.hk writes: > Can someone please explain to me how this works. If you are using a 3 x 3 > matrix (on an anything x anything matrix) for transformations you get > linear transformations, which include scaling, rotating, reflecting and > skewing but NOT transforming the perspective of a shape, at least not when > operating on the real two-dimensional space QD GX works in. 3x3 matrices, if you set the top-right and middle-right elements to be nonzero, WILL produce perspective transforms that make it appear as though the two-dimensional drawing plane has been rotated in 3space and projected back onto the screen. You obviously can't draw stuff in real 3d this way, since your input is only 2d points, but for mapping your drawing onto an arbitrarily oriented surface in 3space it's ideal. Check out some of the demos at the end of the SlideMaster GX demo -- there's one that does a flyby of some 3d text, and another with a 3d rotating die. (I think for the die they had to use a different transformation for each face.) --Jens Alfke jens_alfke@powertalk Rebel girl, rebel girl, .apple.com Rebel girl you are the queen of my world --------------------------- End of C.S.M.P. Digest **********************