mirror of
https://github.com/gnustep/libs-back.git
synced 2025-02-23 20:01:22 +00:00
Fixed many drawing issues (many ones being related to the flipping).
See bug report #27782 In particular, fixed -[NSImage drawXXX] and -[NSImage composite/dissolveXXX] methods to work exactly as Cocoa when the Cairo backend is used. Added a new draw operator (in addition to composite) to the backend. Cairo is the only backend that implements it for now. Eliminated as many flipping checks as possible. Warning: Untested with the winlib backend. You must update, recompile and install both Back and Gui. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@30523 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
1d0aa595c9
commit
b53fe57e7c
5 changed files with 242 additions and 95 deletions
23
ChangeLog
23
ChangeLog
|
@ -1,3 +1,26 @@
|
||||||
|
2010-06-01 Quentin Mathe <quentin.mathe@gmail.com>
|
||||||
|
|
||||||
|
Fixed composite operator to behave correctly and added a new draw
|
||||||
|
operator to get -[NSImage drawXXX] methods work exactly as Cocoa and
|
||||||
|
improve the drawing performance in some cases.
|
||||||
|
Eliminated all flipping checks in the backend to ensure the flipping
|
||||||
|
remains an high-level AppKit concept.
|
||||||
|
* Source/gsc/GSContext.m:
|
||||||
|
(-GSdraw:toPoint:fromRect:operation:fraction:): Added.
|
||||||
|
This method calls -drawGState:fromRect:toPoint:op:fraction:.
|
||||||
|
* Headers/gsc/GSGState.h (-drawGState:fromRect:toPoint:op:): Added
|
||||||
|
as an informal protocol which can be implemented by subclasses
|
||||||
|
* Source/cairo/CairoContext.m (-supportsDrawGState): Added overriden
|
||||||
|
implementation that enables -drawGState:fromRect:toPoint:op:fraction:.
|
||||||
|
* Source/cairo/CairoGState.m:
|
||||||
|
(-drawOrientationMarkersIn:): Added.
|
||||||
|
(-DPSimage::::::): Removed flipping check.
|
||||||
|
(-compositeGState:fromRect:toPoint:op:fraction:): Fixed to precisely
|
||||||
|
implement the PostScript behavior which is to ignore rotation and
|
||||||
|
scaling effect for the content but not for the destination point.
|
||||||
|
Also documented in details since this code is complex.
|
||||||
|
(-drawGState:fromRect:toPoint:op:fraction:): Added.
|
||||||
|
|
||||||
2010-05-25 Riccardo Mottola <rmottola@users.sf.net>
|
2010-05-25 Riccardo Mottola <rmottola@users.sf.net>
|
||||||
|
|
||||||
* Source/x11/XGDragView.m
|
* Source/x11/XGDragView.m
|
||||||
|
|
|
@ -105,6 +105,16 @@ typedef enum {
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
/** Informal protocol to which backends can conform to when they support drawing a
|
||||||
|
graphics state with arbitrary transforms on the current graphics context. */
|
||||||
|
@interface NSObject (GSDrawGState)
|
||||||
|
- (void) drawGState: (GSGState *)source
|
||||||
|
fromRect: (NSRect)aRect
|
||||||
|
toPoint: (NSPoint)aPoint
|
||||||
|
op: (NSCompositingOperation)op
|
||||||
|
fraction: (float)delta;
|
||||||
|
@end
|
||||||
|
|
||||||
#include "GSGStateOps.h"
|
#include "GSGStateOps.h"
|
||||||
|
|
||||||
#endif /* _GSGState_h_INCLUDE */
|
#endif /* _GSGState_h_INCLUDE */
|
||||||
|
|
|
@ -96,6 +96,11 @@
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (BOOL) supportsDrawGState
|
||||||
|
{
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
- (void) flushGraphics
|
- (void) flushGraphics
|
||||||
{
|
{
|
||||||
#if BUILD_SERVER == SERVER_x11
|
#if BUILD_SERVER == SERVER_x11
|
||||||
|
|
|
@ -1038,6 +1038,17 @@ _set_op(cairo_t *ct, NSCompositingOperation op)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For debugging */
|
||||||
|
- (void) drawOrientationMarkersIn: (cairo_t *)ct
|
||||||
|
{
|
||||||
|
cairo_rectangle(_ct, 0, 0, 20, 10);
|
||||||
|
cairo_set_source_rgba(_ct, 0, 1, 0, 1);
|
||||||
|
cairo_fill(_ct);
|
||||||
|
cairo_rectangle(_ct, 0, 30, 20, 10);
|
||||||
|
cairo_set_source_rgba(_ct, 0, 0, 1, 1);
|
||||||
|
cairo_fill(_ct);
|
||||||
|
}
|
||||||
|
|
||||||
- (void) DPSimage: (NSAffineTransform *)matrix : (int)pixelsWide
|
- (void) DPSimage: (NSAffineTransform *)matrix : (int)pixelsWide
|
||||||
: (int)pixelsHigh : (int)bitsPerSample
|
: (int)pixelsHigh : (int)bitsPerSample
|
||||||
: (int)samplesPerPixel : (int)bitsPerPixel
|
: (int)samplesPerPixel : (int)bitsPerPixel
|
||||||
|
@ -1197,45 +1208,26 @@ _set_op(cairo_t *ct, NSCompositingOperation op)
|
||||||
tstruct.tX, tstruct.tY);
|
tstruct.tX, tstruct.tY);
|
||||||
cairo_transform(_ct, &local_matrix);
|
cairo_transform(_ct, &local_matrix);
|
||||||
|
|
||||||
// Make up for flip done in GUI
|
{
|
||||||
if (viewIsFlipped)
|
cairo_pattern_t *cpattern;
|
||||||
{
|
cairo_matrix_t source_matrix;
|
||||||
cairo_pattern_t *cpattern;
|
|
||||||
cairo_matrix_t local_matrix;
|
cpattern = cairo_pattern_create_for_surface(surface);
|
||||||
|
cairo_matrix_init_scale(&source_matrix, 1, -1);
|
||||||
cpattern = cairo_pattern_create_for_surface(surface);
|
cairo_matrix_translate(&source_matrix, 0, -pixelsHigh);
|
||||||
cairo_matrix_init_scale(&local_matrix, 1, -1);
|
cairo_pattern_set_matrix(cpattern, &source_matrix);
|
||||||
cairo_matrix_translate(&local_matrix, 0, -2*pixelsHigh);
|
if (cairo_version() >= CAIRO_VERSION_ENCODE(1, 6, 0))
|
||||||
cairo_pattern_set_matrix(cpattern, &local_matrix);
|
{
|
||||||
if (cairo_version() >= CAIRO_VERSION_ENCODE(1, 6, 0))
|
cairo_pattern_set_extend(cpattern, CAIRO_EXTEND_PAD);
|
||||||
{
|
}
|
||||||
cairo_pattern_set_extend(cpattern, CAIRO_EXTEND_PAD);
|
cairo_set_source(_ct, cpattern);
|
||||||
}
|
cairo_pattern_destroy(cpattern);
|
||||||
cairo_set_source(_ct, cpattern);
|
cairo_rectangle(_ct, 0, 0, pixelsWide, pixelsHigh);
|
||||||
cairo_pattern_destroy(cpattern);
|
}
|
||||||
|
|
||||||
cairo_rectangle(_ct, 0, pixelsHigh, pixelsWide, pixelsHigh);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cairo_pattern_t *cpattern;
|
|
||||||
cairo_matrix_t local_matrix;
|
|
||||||
|
|
||||||
cpattern = cairo_pattern_create_for_surface(surface);
|
|
||||||
cairo_matrix_init_scale(&local_matrix, 1, -1);
|
|
||||||
cairo_matrix_translate(&local_matrix, 0, -pixelsHigh);
|
|
||||||
cairo_pattern_set_matrix(cpattern, &local_matrix);
|
|
||||||
if (cairo_version() >= CAIRO_VERSION_ENCODE(1, 6, 0))
|
|
||||||
{
|
|
||||||
cairo_pattern_set_extend(cpattern, CAIRO_EXTEND_PAD);
|
|
||||||
}
|
|
||||||
cairo_set_source(_ct, cpattern);
|
|
||||||
cairo_pattern_destroy(cpattern);
|
|
||||||
|
|
||||||
cairo_rectangle(_ct, 0, 0, pixelsWide, pixelsHigh);
|
|
||||||
}
|
|
||||||
cairo_clip(_ct);
|
cairo_clip(_ct);
|
||||||
cairo_paint(_ct);
|
cairo_paint(_ct);
|
||||||
|
//[self drawOrientationMarkersIn: _ct];
|
||||||
cairo_surface_destroy(surface);
|
cairo_surface_destroy(surface);
|
||||||
cairo_restore(_ct);
|
cairo_restore(_ct);
|
||||||
|
|
||||||
|
@ -1271,94 +1263,114 @@ _set_op(cairo_t *ct, NSCompositingOperation op)
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) compositeGState: (CairoGState *)source
|
- (void) compositeGState: (CairoGState *)source
|
||||||
fromRect: (NSRect)aRect
|
fromRect: (NSRect)srcRect
|
||||||
toPoint: (NSPoint)aPoint
|
toPoint: (NSPoint)destPoint
|
||||||
op: (NSCompositingOperation)op
|
op: (NSCompositingOperation)op
|
||||||
fraction: (float)delta
|
fraction: (float)delta
|
||||||
{
|
{
|
||||||
cairo_surface_t *src;
|
cairo_surface_t *src = cairo_get_target(source->_ct);
|
||||||
|
NSSize ssize = NSZeroSize;
|
||||||
|
BOOL copyOnSelf = (src == cairo_get_target(_ct));
|
||||||
|
/* The source rect in the source base coordinate space.
|
||||||
|
This rect is the minimum bounding rect of srcRect. */
|
||||||
|
NSRect srcRectInBase = NSZeroRect;
|
||||||
|
/* The destination point in the target base coordinate space */
|
||||||
|
NSPoint destPointInBase = NSZeroPoint;
|
||||||
|
/* The origin of srcRectInBase */
|
||||||
double minx, miny;
|
double minx, miny;
|
||||||
|
/* The composited content size */
|
||||||
double width, height;
|
double width, height;
|
||||||
|
/* The adjusted destination point in the target base coordinate space */
|
||||||
double x, y;
|
double x, y;
|
||||||
NSSize ssize;
|
/* Alternative source rect origin in the source current CTM */
|
||||||
|
NSPoint srcRectAltOrigin = NSMakePoint(srcRect.origin.x, srcRect.origin.y + srcRect.size.height);
|
||||||
|
/* Alternative source rect origin in the source base coordinate space */
|
||||||
|
NSPoint srcRectAltOriginInBase = [source->ctm transformPoint: srcRectAltOrigin];
|
||||||
|
/* The source rect origin in the source base coordinate space */
|
||||||
|
NSPoint srcRectOriginInBase = [source->ctm transformPoint: srcRect.origin];
|
||||||
|
BOOL originFlippedBetweenBaseAndSource = NO;
|
||||||
|
/* The delta between the origins of srcRect and srcRectInBase */
|
||||||
|
double dx, dy;
|
||||||
cairo_pattern_t *cpattern;
|
cairo_pattern_t *cpattern;
|
||||||
cairo_matrix_t local_matrix;
|
cairo_matrix_t source_matrix;
|
||||||
BOOL copyOnSelf = NO;
|
|
||||||
|
|
||||||
if (!_ct || !source->_ct)
|
if (!_ct || !source->_ct)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//NSLog(@"Composite surface %p source size %@ target size %@", self->_surface, NSStringFromSize([self->_surface size]), NSStringFromSize([source->_surface size]));
|
||||||
* we check if we copy on ourself, if that's the case
|
|
||||||
* we'll use the groups trick...
|
|
||||||
*/
|
|
||||||
|
|
||||||
src = cairo_get_target(source->_ct);
|
|
||||||
if (src == cairo_get_target(_ct))
|
|
||||||
{
|
|
||||||
NSRect targetRect;
|
|
||||||
|
|
||||||
targetRect.origin = aPoint;
|
|
||||||
targetRect.size = aRect.size;
|
|
||||||
|
|
||||||
if (!NSIsEmptyRect(NSIntersectionRect(aRect, targetRect)))
|
|
||||||
{
|
|
||||||
copyOnSelf = YES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cairo_save(_ct);
|
cairo_save(_ct);
|
||||||
|
|
||||||
|
/* When the target and source are the same surface, we use the group tricks */
|
||||||
if (copyOnSelf) cairo_push_group(_ct);
|
if (copyOnSelf) cairo_push_group(_ct);
|
||||||
|
|
||||||
cairo_new_path(_ct);
|
cairo_new_path(_ct);
|
||||||
_set_op(_ct, op);
|
_set_op(_ct, op);
|
||||||
|
|
||||||
if (viewIsFlipped && !copyOnSelf)
|
//NSLog(@"Point %@", NSStringFromPoint(destPoint));
|
||||||
|
|
||||||
|
/* Scales and/or rotates the local destination point with the current AppKit CTM */
|
||||||
|
destPointInBase = [ctm transformPoint: destPoint];
|
||||||
|
//NSLog(@"Point in base %@", NSStringFromPoint(destPointInBase));
|
||||||
|
|
||||||
|
/* Scales and/or rotates the source rect and retrieves the minimum bounding
|
||||||
|
rectangle that encloses it and makes it our source area */
|
||||||
|
[source->ctm boundingRectFor: srcRect result: &srcRectInBase];
|
||||||
|
//NSLog(@"Bounding rect %@ from %@", NSStringFromRect(srcRectInBase), NSStringFromRect(srcRect));
|
||||||
|
|
||||||
|
/* Find whether the source rect origin in the base is the same than in the
|
||||||
|
source current CTM.
|
||||||
|
We need to know the origin in the base to compute how much the source
|
||||||
|
bounding rect origin is shifted relatively to the closest source rect corner.
|
||||||
|
We use this delta (dx, dy) to correctly composite from a rotated source. */
|
||||||
|
originFlippedBetweenBaseAndSource =
|
||||||
|
((srcRect.origin.y < srcRectAltOrigin.y && srcRectOriginInBase.y > srcRectAltOriginInBase.y)
|
||||||
|
|| (srcRect.origin.y > srcRectAltOrigin.y && srcRectOriginInBase.y < srcRectAltOriginInBase.y));
|
||||||
|
if (originFlippedBetweenBaseAndSource)
|
||||||
{
|
{
|
||||||
aPoint.y -= aRect.size.height;
|
srcRectOriginInBase = srcRectAltOriginInBase;
|
||||||
}
|
}
|
||||||
|
dx = srcRectOriginInBase.x - srcRectInBase.origin.x;
|
||||||
|
dy = srcRectOriginInBase.y - srcRectInBase.origin.y;
|
||||||
|
|
||||||
{
|
//NSLog(@"Point in base adjusted %@", NSStringFromPoint(NSMakePoint(destPointInBase.x - dx, destPointInBase.y - dy)));
|
||||||
NSRect newRect;
|
|
||||||
|
|
||||||
newRect.origin = aPoint;
|
|
||||||
newRect.size = aRect.size;
|
|
||||||
[ctm boundingRectFor: newRect result: &newRect];
|
|
||||||
aPoint = newRect.origin;
|
|
||||||
}
|
|
||||||
|
|
||||||
[source->ctm boundingRectFor: aRect result: &aRect];
|
|
||||||
if (cairo_version() >= CAIRO_VERSION_ENCODE(1, 8, 0))
|
|
||||||
{
|
|
||||||
NSSize size = [source->_surface size];
|
|
||||||
|
|
||||||
// For cairo > 1.8 we seem to need this adjustment
|
|
||||||
aRect.origin.y -= 2*(source->offset.y - size.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
x = floorf(aPoint.x);
|
|
||||||
y = floorf(aPoint.y + 0.5);
|
|
||||||
minx = NSMinX(aRect);
|
|
||||||
miny = NSMinY(aRect);
|
|
||||||
width = NSWidth(aRect);
|
|
||||||
height = NSHeight(aRect);
|
|
||||||
|
|
||||||
if (source->_surface != nil)
|
if (source->_surface != nil)
|
||||||
{
|
{
|
||||||
ssize = [source->_surface size];
|
ssize = [source->_surface size];
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
if (cairo_version() >= CAIRO_VERSION_ENCODE(1, 8, 0))
|
||||||
ssize = NSMakeSize(0, 0);
|
{
|
||||||
|
// For cairo > 1.8 we seem to need this adjustment
|
||||||
|
srcRectInBase.origin.y -= 2 * (source->offset.y - ssize.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
x = floorf(destPointInBase.x);
|
||||||
|
y = floorf(destPointInBase.y + 0.5);
|
||||||
|
minx = NSMinX(srcRectInBase);
|
||||||
|
miny = NSMinY(srcRectInBase);
|
||||||
|
width = NSWidth(srcRectInBase);
|
||||||
|
height = NSHeight(srcRectInBase);
|
||||||
|
|
||||||
|
/* We respect the AppKit CTM effect on the origin 'aPoint' (see
|
||||||
|
-[ctm transformPoint:]), but we ignore the scaling and rotation effect on
|
||||||
|
the composited content and size. Which means we never rotate or scale the
|
||||||
|
content we composite.
|
||||||
|
We use a pattern as a trick to simulate a target CTM change, this way we
|
||||||
|
don't touch the source CTM even when both source and target are identical
|
||||||
|
(e.g. scrolling case).
|
||||||
|
We must use a pattern matrix that matches the AppKit base CTM set up in
|
||||||
|
-DPSinitgraphics to ensure no transform is applied to the source content,
|
||||||
|
translation adjustements related to destination point and source rect put
|
||||||
|
aside. */
|
||||||
cpattern = cairo_pattern_create_for_surface(src);
|
cpattern = cairo_pattern_create_for_surface(src);
|
||||||
cairo_matrix_init_scale(&local_matrix, 1, -1);
|
cairo_matrix_init_scale(&source_matrix, 1, -1);
|
||||||
cairo_matrix_translate(&local_matrix, -x + minx, - ssize.height - y + miny);
|
//cairo_matrix_translate(&source_matrix, 0, -[_surface size].height);
|
||||||
cairo_pattern_set_matrix(cpattern, &local_matrix);
|
cairo_matrix_translate(&source_matrix, minx - x + dx, miny - y + dy - ssize.height);
|
||||||
|
cairo_pattern_set_matrix(cpattern, &source_matrix);
|
||||||
cairo_set_source(_ct, cpattern);
|
cairo_set_source(_ct, cpattern);
|
||||||
cairo_pattern_destroy(cpattern);
|
cairo_pattern_destroy(cpattern);
|
||||||
cairo_rectangle(_ct, x, y, width, height);
|
cairo_rectangle(_ct, x, y, width, height);
|
||||||
|
@ -1382,6 +1394,82 @@ _set_op(cairo_t *ct, NSCompositingOperation op)
|
||||||
cairo_restore(_ct);
|
cairo_restore(_ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Unlike -compositeGState, -drawGSstate fully respects the AppKit CTM but
|
||||||
|
doesn't support to use the receiver cairo target as the source. */
|
||||||
|
- (void) drawGState: (CairoGState *)source
|
||||||
|
fromRect: (NSRect)aRect
|
||||||
|
toPoint: (NSPoint)aPoint
|
||||||
|
op: (NSCompositingOperation)op
|
||||||
|
fraction: (float)delta
|
||||||
|
{
|
||||||
|
NSAffineTransformStruct tstruct = [ctm transformStruct];
|
||||||
|
cairo_surface_t *src = cairo_get_target(source->_ct);
|
||||||
|
double width, height;
|
||||||
|
double x, y;
|
||||||
|
cairo_pattern_t *cpattern;
|
||||||
|
cairo_matrix_t local_matrix;
|
||||||
|
cairo_matrix_t source_matrix;
|
||||||
|
|
||||||
|
if (!_ct || !source->_ct)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_save(_ct);
|
||||||
|
|
||||||
|
cairo_new_path(_ct);
|
||||||
|
_set_op(_ct, op);
|
||||||
|
|
||||||
|
if (cairo_version() >= CAIRO_VERSION_ENCODE(1, 8, 0))
|
||||||
|
{
|
||||||
|
NSSize size = [source->_surface size];
|
||||||
|
|
||||||
|
// For cairo > 1.8 we seem to need this adjustment
|
||||||
|
aRect.origin.y -= 2*(source->offset.y - size.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
x = floorf(aPoint.x);
|
||||||
|
y = floorf(aPoint.y + 0.5);
|
||||||
|
width = NSWidth(aRect);
|
||||||
|
height = NSHeight(aRect);
|
||||||
|
|
||||||
|
// NOTE: We don't keep the Cairo matrix in sync with the AppKit matrix (aka
|
||||||
|
// -[NSGraphicsContext GSCurrentCTM])
|
||||||
|
|
||||||
|
/* Prepare a Cairo matrix with the current AppKit CTM */
|
||||||
|
cairo_matrix_init(&local_matrix,
|
||||||
|
tstruct.m11, tstruct.m12,
|
||||||
|
tstruct.m21, tstruct.m22,
|
||||||
|
tstruct.tX, tstruct.tY);
|
||||||
|
/* Append the local point transformation */
|
||||||
|
cairo_matrix_translate(&local_matrix, x - aRect.origin.x, y - aRect.origin.y);
|
||||||
|
/* Concat to the Cairo matrix created in -DPSinitgraphics, which adjusts the
|
||||||
|
mismatch between the Cairo top left vs AppKit bottom left origin. */
|
||||||
|
cairo_transform(_ct, &local_matrix);
|
||||||
|
|
||||||
|
//[self drawOrientationMarkersIn: _ct];
|
||||||
|
|
||||||
|
cpattern = cairo_pattern_create_for_surface(src);
|
||||||
|
cairo_matrix_init_scale(&source_matrix, 1, -1);
|
||||||
|
cairo_matrix_translate(&source_matrix, 0, -[source->_surface size].height);
|
||||||
|
cairo_pattern_set_matrix(cpattern, &source_matrix);
|
||||||
|
cairo_set_source(_ct, cpattern);
|
||||||
|
cairo_pattern_destroy(cpattern);
|
||||||
|
cairo_rectangle(_ct, aRect.origin.x, aRect.origin.y, width, height);
|
||||||
|
cairo_clip(_ct);
|
||||||
|
|
||||||
|
if (delta < 1.0)
|
||||||
|
{
|
||||||
|
cairo_paint_with_alpha(_ct, delta);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cairo_paint(_ct);
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_restore(_ct);
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation CairoGState (PatternColor)
|
@implementation CairoGState (PatternColor)
|
||||||
|
|
|
@ -821,6 +821,27 @@ static NSMapTable *gtable;
|
||||||
fraction: delta];
|
fraction: delta];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) GSdraw: (int)gstateNum
|
||||||
|
toPoint: (NSPoint)aPoint
|
||||||
|
fromRect: (NSRect)srcRect
|
||||||
|
operation: (NSCompositingOperation)op
|
||||||
|
fraction: (float)delta
|
||||||
|
{
|
||||||
|
GSGState *g = gstate;
|
||||||
|
|
||||||
|
if (gstateNum)
|
||||||
|
{
|
||||||
|
[self DPSexecuserobject: gstateNum];
|
||||||
|
ctxt_pop(g, opstack, GSGState);
|
||||||
|
}
|
||||||
|
|
||||||
|
[gstate drawGState: g
|
||||||
|
fromRect: srcRect
|
||||||
|
toPoint: aPoint
|
||||||
|
op: op
|
||||||
|
fraction: delta];
|
||||||
|
}
|
||||||
|
|
||||||
- (void) GSDrawImage: (NSRect) rect: (void *) imageref
|
- (void) GSDrawImage: (NSRect) rect: (void *) imageref
|
||||||
{
|
{
|
||||||
NSBitmapImageRep *bitmap;
|
NSBitmapImageRep *bitmap;
|
||||||
|
|
Loading…
Reference in a new issue