Joined: May 25, 2003 Posts: 4752 Location: Santa Barbara, CA
Posted: Sun Jun 08, 2003 12:45 pm Post subject: CG clipping region fix
OK, I fixed up some of the basic clipping issues in Neo. The issue was the old "mbClipRgnChanged" flag. Here's the problem...with the NSQDView, quickdraw ports were roughly permanent, that is, if you set the clip region on the port it would be maintained across calls to lockFocus/unlockFocus. With the CGContexts, we're obtaining a fresh CG context each time we lockFocus...so we need to not only do the coordinate flip at all times but also set the appropriate clip region each time in BeginGraphics().
I also changed the semantics of empty clip regions...if the vector of clip rectangles is empty, it is assumed that the drawing in the CGContext should be unclipped. I didn't examine things carefully, but think this might be safer for construction of SalGraphicsData objects and simplifies the ResetClipRgn() function which was potentially trying to obtain view boundaries without having a valid CGContext.
Checking in aqua/source/gdi/salgdi.cxx;
/cvs/vcl/aqua/source/gdi/salgdi.cxx,v <-- salgdi.cxx
new revision: 1.39; previous revision: 1.38
done
Checking in aqua/source/gdi/salgdiutils.cxx;
/cvs/vcl/aqua/source/gdi/salgdiutils.cxx,v <-- salgdiutils.cxx
new revision: 1.20; previous revision: 1.19
done
Looking SWEET. One of these days I'm going to kill the SalBitmap transparency problem dead. There are some NSImage caching semantics that I just don't understand right now. Will have to experiment.
Also, I noticed that there is some text coloration issues. For example, if you drop down the font color menu in writer or draw, next time the menu button text is redrawn (not in th menu, but on the button) it is white like the selected item's text color, not black like it should be.
I'll look at the code more later and try to nail down the VirDev flipping issues.
Joined: May 25, 2003 Posts: 4752 Location: Santa Barbara, CA
Posted: Mon Jun 09, 2003 10:50 am Post subject:
FWIW I was playing with this last night (along with some beer...) and found the following did begin to solve the flipping, but couldn't find out how to properly translate the origin from the translated to untranslated coordinate systems. It seems to be off by about 1/4 of the height, judging from the ruler.
Code inserted into SalGraphics::CopyBits() in the mbVirDev branch (line 571 in my build). I was playing with the y coordinate of the origin. This results in the virdev being blitted in the correct orientation, just the position is slightly off.
Code:
// [ed] 6/8/03 Normally, our CGContexts have their coordinate systems flipped
// with the origin translated to the upper left corner and vertical axis inverted.
// This gives us a QD coordinate system. Unfortunately, copying images under these
// settings for virtual devices introduces a double-flip operation as their bitmaps
// were already flipped in their own drawing graphics contexts. Therefore, we will
// do explicit translation of the destination rect into unflipped coordinates,
// remove our inversion transform, and execute the copy.
Note I also added a CGContextSaveGState() right before the transformations were applied to the context in BeginGraphics() so I could restore it to original with CGContextRestoreGState().
The CG current translation matrix (CTM) functions that flip the CG context are cumulative. I figured this out by getting the CTM and displaying its members. There are: a, b, c, d, tx, and ty. Now when you have no CTM, you get:
a: 0.0, b: 0.0, c: 0.0, d: 0.0, tx: 0.0, ty: 0.0
When you initiate the flip in BeginGraphics, it changes to:
(where 400.00 is the y amount to flip it as set in CGContextTranslateCTM).
So when you "unflip" the matrix, as before anything ATSUI, you have to first undo the 400 translation before undoing the -1 scale factor, or else it simply makes the 400 and 800 because you are re-scaling.
So to flip, you must:
Translate( height )
Scale( -1 )
To unflip, you must
Translate( height ) <moves ty to 0.0>
Scale( -1 ) <reverses the b scale of -1.0>
All in all, a pain. And once its unflipped, you have to translate the y coordinates of stuff like ATSUI calls yourself by subtracting its top coordinate from the height of the viewport to get the actual coordinate in CG/cocoa coordinate space.
Joined: May 25, 2003 Posts: 4752 Location: Santa Barbara, CA
Posted: Mon Jun 09, 2003 7:57 pm Post subject:
That's actually quite helpful information on the silly matrix stuff. Watching the WWDC 02 session left me wanting more details It does appear that I need to do a little extra with the y position.
Question though...the calls are cumulative, yes, but I thought the CGContextSaveGState() saved the entire matrix...so issuing it before both the translation and inversion should cache the unflipped, untranslated state, no? Or am I smoking crack?
(has to leave Neo for a bit and dive the world of French accents in X11...silly foreign languages and non-OS X input methods... )
Yes, the CGContextSaveGState()/RestoreGState() calls should push the CTM onto the GState stack and pop it off. However, they of course must be balanced So we can't use them to save the GState in BeginGraphics() and then pop it off to get a pristine state anywhere else than EndGraphics(). Because, if you pop it off in the drawing code somewhere, it _could_ be that two different drawing routines get called (I'm thinking sub-routines in gdiutils.cxx or something, not actual SalGraphics:: calls) that want to pop off the structure, hence you're popping off 2 gstates where you only pushed one onto the stack. I think the safest bet is to not do _too_ much with SaveGState()/Restore. We shouldn't assume that the GState is in _any_ state when we are in a function, but should only push it onto the stack, make changes, and pop it off at the end.
Joined: May 25, 2003 Posts: 4752 Location: Santa Barbara, CA
Posted: Sun Jun 22, 2003 12:51 am Post subject:
Bingo It's fixed. Problem was that I needed to translate the bottom edge of the destination and not the top (makes sense due to flipped coords). Committed fix, but am using the SaveGState hack in BeginGraphics().
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum