Added OPGStateRef tracking and switching at appropriate times. Added OpalGState's -copyWithZone:.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@37119 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
ivucica 2013-09-19 22:39:11 +00:00
parent 8da244ce06
commit d751693eb4
4 changed files with 95 additions and 2 deletions

View file

@ -1,3 +1,26 @@
2013-09-19 Ivan Vucica <ivan@vucica.net>
* Source/opal/OpalContext.m:
Added GState switcher -DPSsetgstate:. See description of
_opGState in OpalGState.h.
* Headers/opal/OpalGState.h:
Added _opGState i-var and relevant accessors.
* Source/opal/OpalGState.m:
Instead of yellow rectangle, -compositeGState:... method *should*
now be painting doublebuffered content from the 'other' GState,
but sadly does not. This needs debugging.
Implemented -copyWithZone:. See description of _opGState in
OpalGState.h to see how and why is _opGState used in this class,
how it is being copied and why it's alright to keep it nil during
-init and even after -DPSinitgraphics, but needs to be set in
-copyWithZone:.
Added -setOPGState: and -OPGState accessors for the _opGState
field.
2013-09-18 Ivan Vucica <ivan@vucica.net>
* Source/opal/OpalSurface.m:

View file

@ -25,6 +25,7 @@
Boston, MA 02110-1301, USA.
*/
#import <CoreGraphics/CoreGraphics.h>
#import "gsc/GSGState.h"
@class OpalSurface;
@ -32,6 +33,30 @@
@interface OpalGState : GSGState
{
OpalSurface * _opalSurface;
/** When a surface's gstate is being switched away from,
we store the current gstate in _opGState.
When a surface's gstate is being switched back to,
if _opGState is not nil, we apply the stored gstate.
To facilitate OpalGState class instance copying, we
also store a copy of the gstate inside _opGState when
gstate's -copyWithZone: is being run. This is because
the same _opalSurface should be used in both new and
old OpalGState.
The same is done in Cairo backend, with one key
difference: since all graphics state operations in
Cairo are done directly on cairo_t and are unrelated
to the surface, Opal mixes the concepts of a gstate
and a surface into a context. Hence, when gstate is
switched, it's OpalContext's duty to apply the stored
copy of a gstate from _opGState. No such trickery
is needed with Cairo, as Cairo backend can simply
have a different cairo_t with the same surface.
**/
OPGStateRef _opGState;
}
- (void) DPSinitclip;
@ -63,4 +88,6 @@
@interface OpalGState (Accessors)
- (CGContextRef) cgContext;
- (OPGStateRef) OPGState;
- (void) setOPGState: (OPGStateRef) opGState;
@end

View file

@ -84,6 +84,25 @@
[OGSTATE DPSgrestore];
}
/** For information about this method, please see description of
i-var '_opGState' in OpalGState.h.
**/
- (void) DPSsetgstate: (int)gstateID
{
OPGStateRef previousGState = OPContextCopyGState([OGSTATE cgContext]);
[OGSTATE setOPGState: previousGState];
[previousGState release]; // FIXME
[super DPSsetgstate: gstateID];
OPGStateRef newGState = [OGSTATE OPGState];
if (newGState)
{
OPContextSetGState([OGSTATE cgContext], newGState);
[OGSTATE setOPGState: nil];
}
}
/*
// FIXME: we should add this as soon as we implement -drawGState:...
- (BOOL) supportsDrawGState

View file

@ -153,7 +153,7 @@ NSLog(@" : samplesperpixel = %d", samplesPerPixel);
fraction: (CGFloat)delta
{
NSDebugLLog(@"OpalGState", @"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
#if 1
#if 0
CGContextSaveGState(CGCTX);
CGContextSetRGBFillColor(CGCTX, 1, 1, 0, 1);
CGContextFillRect(CGCTX, CGRectMake(destPoint.x, destPoint.y, srcRect.size.width, srcRect.size.height));
@ -225,6 +225,16 @@ NSLog(@" : samplesperpixel = %d", samplesPerPixel);
@implementation OpalGState (InitializationMethods)
- (id)copyWithZone: (NSZone *)zone
{
OpalGState * theCopy = (OpalGState *) [super copyWithZone: zone];
[_opalSurface retain];
theCopy->_opGState = OPContextCopyGState(CGCTX);
return theCopy;
}
/* SOME NOTES:
- GState approximates a cairo context: a drawing state.
- Surface approximates a cairo surface: a place to draw things.
@ -303,6 +313,20 @@ NSLog(@" : samplesperpixel = %d", samplesPerPixel);
return [_opalSurface cgContext];
}
- (OPGStateRef) OPGState
{
return _opGState;
}
- (void) setOPGState: (OPGStateRef)opGState
{
if (opGState == _opGState)
return;
[opGState retain];
[_opGState release];
_opGState = opGState;
}
@end
// MARK: Non-required methods
@ -468,7 +492,7 @@ static CGFloat theAlpha = 1.; // TODO: removeme
{
NSDebugLLog(@"OpalGState", @"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
CGContextFlush(CGCTX);
[_opalSurface handleExpose:CGRectMake(0, 0, 1024, 1024)];
[_opalSurface handleExpose:CGRectMake(0, 0, 1024, 1024)]; // FIXME
}
- (void) DPSgsave
{