Welcome to NeoOffice developer notes and announcements
NeoOffice
Developer notes and announcements
 
 

This website is an archive and is no longer active
NeoOffice announcements have moved to the NeoOffice News website


Support
· Forums
· NeoOffice Support
· NeoWiki


Announcements
· Twitter @NeoOffice


Downloads
· Download NeoOffice


  
NeoOffice :: View topic - CG clipping region fix
CG clipping region fix
 
   NeoOffice Forum Index -> NeoOffice/C Development
View previous topic :: View next topic  
Author Message
OPENSTEP
The One
The One


Joined: May 25, 2003
Posts: 4752
Location: Santa Barbara, CA

PostPosted: 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
Back to top
fa
The Architect
The Architect


Joined: May 27, 2003
Posts: 88

PostPosted: Sun Jun 08, 2003 9:49 pm    Post subject:

Ed,

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.

Dan
Back to top
OPENSTEP
The One
The One


Joined: May 25, 2003
Posts: 4752
Location: Santa Barbara, CA

PostPosted: 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.
                               
                                CGRect viewRect;
                                GetGraphicsBoundsCGRect( &maGraphicsData, &viewRect );
                               
                                NSRect translatedDestRect=NSMakeRect(dstRect.origin.x, dstRect.origin.y-viewRect.size.height, dstRect.size.width, dstRect.size.height);
                                CGContextRestoreGState(maGraphicsData.mpCGContext);
            [(pSrcGraphics->maGraphicsData.mhNSImage)   drawInRect:translatedDestRect
                                       fromRect:srcRect
                                       operation:NSCompositeSourceOver
                                       fraction:1.0];


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().

ed
Back to top
fa
The Architect
The Architect


Joined: May 27, 2003
Posts: 88

PostPosted: Mon Jun 09, 2003 7:26 pm    Post subject:

Ed,

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:

a: 0.0, b: -1.0, c: 0.0, d: 0.0, tx: 0.0, ty: 400.00

(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.

Dan
Back to top
OPENSTEP
The One
The One


Joined: May 25, 2003
Posts: 4752
Location: Santa Barbara, CA

PostPosted: 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 Smile 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... Evil or Very Mad )

ed
Back to top
fa
The Architect
The Architect


Joined: May 27, 2003
Posts: 88

PostPosted: Tue Jun 10, 2003 11:34 pm    Post subject:

Ed,

Yes, the CGContextSaveGState()/RestoreGState() calls should push the CTM onto the GState stack and pop it off. However, they of course must be balanced Smile 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.

Dan
Back to top
OPENSTEP
The One
The One


Joined: May 25, 2003
Posts: 4752
Location: Santa Barbara, CA

PostPosted: Sun Jun 22, 2003 12:51 am    Post subject:

Bingo Smile 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().
Back to top
Display posts from previous:   
   NeoOffice Forum Index -> NeoOffice/C Development All times are GMT - 7 Hours
Page 1 of 1

 
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

Powered by phpBB © 2001, 2005 phpBB Group

All logos and trademarks in this site are property of their respective owner. The comments are property of their posters, all the rest © Planamesa Inc.
NeoOffice is a registered trademark of Planamesa Inc. and may not be used without permission.
PHP-Nuke Copyright © 2005 by Francisco Burzi. This is free software, and you may redistribute it under the GPL. PHP-Nuke comes with absolutely no warranty, for details, see the license.