mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-05-31 21:50:46 +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/gui/trunk@30523 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
128a121bc8
commit
9be1f4da8e
9 changed files with 274 additions and 28 deletions
41
ChangeLog
41
ChangeLog
|
@ -1,3 +1,44 @@
|
||||||
|
2010-06-01 Quentin Mathe <quentin.mathe@gmail.com>
|
||||||
|
|
||||||
|
Fixed many drawing issues (many ones being related to the flipping).
|
||||||
|
In particular, fixed -[NSImage drawXXX] methods to work exactly as
|
||||||
|
Cocoa and improve the drawing performance in some cases (the last two
|
||||||
|
points only holds with Cairo backend).
|
||||||
|
Eliminated as many flipping checks as possible.
|
||||||
|
Warning: Untested with the winlib backend.
|
||||||
|
* Headers/AppKit/NSGraphicsContext.h:
|
||||||
|
* Source/NSGraphicsContext.m:
|
||||||
|
(-supportsDrawGState, -GSdraw:toPoint:fromRect:operation:fraction:):
|
||||||
|
Added (see also the Backend Changelog).
|
||||||
|
* Source/NSImage.m
|
||||||
|
(-drawInRect:fromRect:operation:fraction:): Moved the previous
|
||||||
|
implementation to -guiDrawInRect:fromRect:operation:fraction: and
|
||||||
|
rewritten as a switch that checks -supportsDrawState.
|
||||||
|
(-guiDrawInRect:fromRect:operation:fraction:): New method identical to
|
||||||
|
the old -drawInRect:fromRect:operation:fraction:.
|
||||||
|
(-nativeDrawInRect:fromRect:operation:fraction:): Added.
|
||||||
|
New method that leverages the backend as much possible and implement
|
||||||
|
semantic that exactly matches Cocoa.
|
||||||
|
(-drawRepresentation:inRect:): Removed flipping
|
||||||
|
check.
|
||||||
|
* Source/NSImageRep.m (-drawInPoint:, -drawInRect:): Removed the
|
||||||
|
flipping checks.
|
||||||
|
* Source/NSImageCell.m (-drawInteriorWithFrame:inView:): Fixed
|
||||||
|
-drawInRect:fromRect:operation:fraction use as Apple doc suggests it
|
||||||
|
rather than using a negative height trick which doesn't work anymore
|
||||||
|
(at least with Cairo) and has never worked on Mac OS X.
|
||||||
|
* Source/NSView.m (-scrollRect:by:): Ajusted to do the copy bits on
|
||||||
|
the window gstate rather than the view gstate.
|
||||||
|
Required now that Cairo NSCopyBits/compositeGState won't compensate the
|
||||||
|
flipping when copyOnSelf is YES. Moreover -scrollRect:by: was broken
|
||||||
|
previously when the view wass not flipped (at least for Cairo).
|
||||||
|
Finally NSCopyBits() behaves in another way on Mac OS X when the view
|
||||||
|
gstate is used instead of the window gstate. By using the window gstate,
|
||||||
|
we can more easily change how NSCopyBits() handles the view gstate to
|
||||||
|
match Cocoa.
|
||||||
|
* Source/NSClipView.m (-setBoundsOrigin:): Turned off dubious code that
|
||||||
|
should probably be removed.
|
||||||
|
|
||||||
2010-06-01 Wolfgang Lux <wolfgang.lux@gmail.com>
|
2010-06-01 Wolfgang Lux <wolfgang.lux@gmail.com>
|
||||||
|
|
||||||
* Source/NSDocumentController.m (-_setupOpenPanel): Disable
|
* Source/NSDocumentController.m (-_setupOpenPanel): Disable
|
||||||
|
|
|
@ -410,6 +410,12 @@ APPKIT_EXPORT NSGraphicsContext *GSCurrentContext(void);
|
||||||
fromRect: (NSRect)srcRect
|
fromRect: (NSRect)srcRect
|
||||||
operation: (NSCompositingOperation)op
|
operation: (NSCompositingOperation)op
|
||||||
fraction: (float)delta;
|
fraction: (float)delta;
|
||||||
|
- (BOOL) supportsDrawGState;
|
||||||
|
- (void) GSdraw: (int)gstateNum
|
||||||
|
toPoint: (NSPoint)aPoint
|
||||||
|
fromRect: (NSRect)srcRect
|
||||||
|
operation: (NSCompositingOperation)op
|
||||||
|
fraction: (float)delta;
|
||||||
- (void) GSDrawImage: (NSRect)rect : (void *)imageref;
|
- (void) GSDrawImage: (NSRect)rect : (void *)imageref;
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
|
@ -118,6 +118,7 @@ PACKAGE_SCOPE
|
||||||
int _gstate;
|
int _gstate;
|
||||||
void *_nextKeyView;
|
void *_nextKeyView;
|
||||||
void *_previousKeyView;
|
void *_previousKeyView;
|
||||||
|
NSRect *_dirtyRects;
|
||||||
|
|
||||||
@public
|
@public
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -372,11 +372,11 @@ static inline NSRect integralRect (NSRect rect, NSView *view)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ?? TODO: Understand the following code - and add explanatory comment */
|
/* ?? TODO: Understand the following code - and add explanatory comment */
|
||||||
if ([NSView focusView] == _documentView)
|
/*if ([NSView focusView] == _documentView)
|
||||||
{
|
{
|
||||||
PStranslate (NSMinX (originalBounds) - aPoint.x,
|
PStranslate (NSMinX (originalBounds) - aPoint.x,
|
||||||
NSMinY (originalBounds) - aPoint.y);
|
NSMinY (originalBounds) - aPoint.y);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
[_super_view reflectScrolledClipView: self];
|
[_super_view reflectScrolledClipView: self];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1540,6 +1540,44 @@ NSGraphicsContext *GSCurrentContext(void)
|
||||||
[self subclassResponsibility: _cmd];
|
[self subclassResponsibility: _cmd];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** <override-dummy />
|
||||||
|
Returns whether the backend supports a GSDraw operator.
|
||||||
|
|
||||||
|
By default, returns NO.<br />
|
||||||
|
When a GSContext backend subclass overrides this method to return YES, the
|
||||||
|
backend must also implement -drawGState:fromRect:toPoint:op:fraction: in its
|
||||||
|
GSState subclass.
|
||||||
|
|
||||||
|
When YES is returned, -[NSImage drawXXX] methods that involves rotation,
|
||||||
|
scaling etc. will delegate as much as possible the image drawing to the backend,
|
||||||
|
rather than trying to emulate the resulting image in Gui by using intermediate
|
||||||
|
images to rotate and scale the content, and then composite the result with
|
||||||
|
-GScomposite:toPoint:fromRect:operation:fraction:.
|
||||||
|
|
||||||
|
Backends which doesn't implement -compositeGState:fromRect:toPoint:op:fraction:
|
||||||
|
can draw rotated or scaled images, but the semantic won't exactly match the
|
||||||
|
NSImage documentation in non-trivial cases. */
|
||||||
|
- (BOOL) supportsDrawGState
|
||||||
|
{
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** <override-dummy />
|
||||||
|
Draws a gstate in a way that fully respects the destination transform,
|
||||||
|
unlike the GSComposite operator which ignores the rotation and the scaling
|
||||||
|
effect on the content.
|
||||||
|
|
||||||
|
Note: For the GScomposite operator, the scaling and rotation affects the
|
||||||
|
destination point but not the content. */
|
||||||
|
- (void) GSdraw: (int)gstateNum
|
||||||
|
toPoint: (NSPoint)aPoint
|
||||||
|
fromRect: (NSRect)srcRect
|
||||||
|
operation: (NSCompositingOperation)op
|
||||||
|
fraction: (float)delta
|
||||||
|
{
|
||||||
|
[self subclassResponsibility: _cmd];
|
||||||
|
}
|
||||||
|
|
||||||
/** Generic method to draw an image into a rect. The image is defined
|
/** Generic method to draw an image into a rect. The image is defined
|
||||||
by imageref, an opaque structure. Support for this method hasn't
|
by imageref, an opaque structure. Support for this method hasn't
|
||||||
been implemented yet, so it should not be used anywhere. */
|
been implemented yet, so it should not be used anywhere. */
|
||||||
|
|
182
Source/NSImage.m
182
Source/NSImage.m
|
@ -797,7 +797,6 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
|
||||||
return _color;
|
return _color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Using the Image
|
// Using the Image
|
||||||
- (void) compositeToPoint: (NSPoint)aPoint
|
- (void) compositeToPoint: (NSPoint)aPoint
|
||||||
operation: (NSCompositingOperation)op
|
operation: (NSCompositingOperation)op
|
||||||
|
@ -813,8 +812,8 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
|
||||||
fromRect: (NSRect)aRect
|
fromRect: (NSRect)aRect
|
||||||
operation: (NSCompositingOperation)op
|
operation: (NSCompositingOperation)op
|
||||||
{
|
{
|
||||||
[self compositeToPoint: aPoint
|
[self compositeToPoint: aPoint
|
||||||
fromRect: aRect
|
fromRect: aRect
|
||||||
operation: op
|
operation: op
|
||||||
fraction: 1.0];
|
fraction: 1.0];
|
||||||
}
|
}
|
||||||
|
@ -850,27 +849,27 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
|
||||||
|
|
||||||
if (cache != nil)
|
if (cache != nil)
|
||||||
{
|
{
|
||||||
|
NSGraphicsContext *ctxt = GSCurrentContext();
|
||||||
NSRect rect = [cache rect];
|
NSRect rect = [cache rect];
|
||||||
|
|
||||||
NSDebugLLog(@"NSImage", @"composite rect %@ in %@",
|
NSDebugLLog(@"NSImage", @"composite rect %@ in %@",
|
||||||
NSStringFromRect(rect), NSStringFromRect(srcRect));
|
NSStringFromRect(rect), NSStringFromRect(srcRect));
|
||||||
|
|
||||||
// Move the drawing rectangle to the origin of the image rep
|
// Move the drawing rectangle to the origin of the image rep
|
||||||
// and intersect the two rects.
|
// and intersect the two rects.
|
||||||
srcRect.origin.x += rect.origin.x;
|
srcRect.origin.x += rect.origin.x;
|
||||||
srcRect.origin.y += rect.origin.y;
|
srcRect.origin.y += rect.origin.y;
|
||||||
rect = NSIntersectionRect(srcRect, rect);
|
rect = NSIntersectionRect(srcRect, rect);
|
||||||
|
|
||||||
[GSCurrentContext() GScomposite: [[cache window] gState]
|
[ctxt GScomposite: [[cache window] gState]
|
||||||
toPoint: aPoint
|
toPoint: aPoint
|
||||||
fromRect: rect
|
fromRect: rect
|
||||||
operation: op
|
operation: op
|
||||||
fraction: delta];
|
fraction: delta];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NSRect rect;
|
NSRect rect = NSMakeRect(aPoint.x, aPoint.y, _size.width, _size.height);
|
||||||
|
|
||||||
rect = NSMakeRect(aPoint.x, aPoint.y, _size.width, _size.height);
|
|
||||||
[self drawRepresentation: rep inRect: rect];
|
[self drawRepresentation: rep inRect: rect];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -922,9 +921,6 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
|
||||||
{
|
{
|
||||||
NSRect fillrect = aRect;
|
NSRect fillrect = aRect;
|
||||||
|
|
||||||
if ([[NSView focusView] isFlipped])
|
|
||||||
fillrect.origin.y -= _size.height;
|
|
||||||
|
|
||||||
[_color set];
|
[_color set];
|
||||||
NSRectFill(fillrect);
|
NSRectFill(fillrect);
|
||||||
|
|
||||||
|
@ -957,10 +953,145 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
|
||||||
fraction: delta];
|
fraction: delta];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) drawInRect: (NSRect)dstRect
|
/* New code path that delegates as much as possible to the backend and whose
|
||||||
fromRect: (NSRect)srcRect
|
behavior precisely matches Cocoa. */
|
||||||
operation: (NSCompositingOperation)op
|
- (void) nativeDrawInRect: (NSRect)dstRect
|
||||||
fraction: (float)delta
|
fromRect: (NSRect)srcRect
|
||||||
|
operation: (NSCompositingOperation)op
|
||||||
|
fraction: (float)delta
|
||||||
|
{
|
||||||
|
NSGraphicsContext *ctxt = GSCurrentContext();
|
||||||
|
NSSize imgSize = [self size];
|
||||||
|
float widthScaleFactor;
|
||||||
|
float heightScaleFactor;
|
||||||
|
|
||||||
|
if (NSEqualRects(srcRect, NSZeroRect))
|
||||||
|
{
|
||||||
|
srcRect.size = imgSize;
|
||||||
|
/* For -drawAtPoint:fromRect:operation:fraction: used with a zero rect */
|
||||||
|
if (NSEqualSizes(dstRect.size, NSZeroSize))
|
||||||
|
{
|
||||||
|
dstRect.size = imgSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dstRect.size.width || !dstRect.size.height
|
||||||
|
|| !srcRect.size.width || !srcRect.size.height)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Clip to image bounds
|
||||||
|
if (srcRect.origin.x < 0)
|
||||||
|
srcRect.origin.x = 0;
|
||||||
|
if (srcRect.origin.y < 0)
|
||||||
|
srcRect.origin.y = 0;
|
||||||
|
if (NSMaxX(srcRect) > imgSize.width)
|
||||||
|
srcRect.size.width = imgSize.width - srcRect.origin.x;
|
||||||
|
if (NSMaxY(srcRect) > imgSize.height)
|
||||||
|
srcRect.size.height = imgSize.height - srcRect.origin.y;
|
||||||
|
|
||||||
|
widthScaleFactor = dstRect.size.width / srcRect.size.width;
|
||||||
|
heightScaleFactor = dstRect.size.height / srcRect.size.height;
|
||||||
|
|
||||||
|
if (![ctxt isDrawingToScreen])
|
||||||
|
{
|
||||||
|
/* We can't composite or dissolve if we aren't drawing to a screen,
|
||||||
|
so we'll just draw the right part of the image in the right
|
||||||
|
place. */
|
||||||
|
NSPoint p;
|
||||||
|
|
||||||
|
p.x = dstRect.origin.x / widthScaleFactor - srcRect.origin.x;
|
||||||
|
p.y = dstRect.origin.y / heightScaleFactor - srcRect.origin.y;
|
||||||
|
|
||||||
|
DPSgsave(ctxt);
|
||||||
|
DPSrectclip(ctxt, dstRect.origin.x, dstRect.origin.y,
|
||||||
|
dstRect.size.width, dstRect.size.height);
|
||||||
|
DPSscale(ctxt, widthScaleFactor, heightScaleFactor);
|
||||||
|
[self drawRepresentation: [self bestRepresentationForDevice: nil]
|
||||||
|
inRect: NSMakeRect(p.x, p.y, imgSize.width, imgSize.height)];
|
||||||
|
DPSgrestore(ctxt);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We cannot ask the backend to draw the image directly when the source rect
|
||||||
|
doesn't cover the whole image.
|
||||||
|
Cairo doesn't support to specify a source rect for a surface used as a
|
||||||
|
source, see cairo_set_source_surface()).
|
||||||
|
CoreGraphics is similarly limited, see CGContextDrawImage().
|
||||||
|
For now, we always use a two step process:
|
||||||
|
- draw the image data in a cache to apply the srcRect to inRect scaling
|
||||||
|
- draw the cache into the destination context
|
||||||
|
It might be worth to move the first step to the backend, so we don't have
|
||||||
|
to create a cache window but just an intermediate surface.
|
||||||
|
We create a cache every time but otherwise we are more efficient than the
|
||||||
|
old code path since the cache size is limited to what we actually draw
|
||||||
|
and doesn't involve drawing the whole image. */
|
||||||
|
{
|
||||||
|
/* An intermediate image used to scale the image to be drawn as needed */
|
||||||
|
NSCachedImageRep *cache;
|
||||||
|
/* The scaled image graphics state we used as the source from which we
|
||||||
|
draw into the destination (the current graphics context)*/
|
||||||
|
int gState;
|
||||||
|
/* The context of the cache window */
|
||||||
|
NSGraphicsContext *cacheCtxt;
|
||||||
|
/* The size of the cache window that will hold the scaled image */
|
||||||
|
NSSize cacheSize = NSMakeSize(imgSize.width * widthScaleFactor,
|
||||||
|
imgSize.height * heightScaleFactor);
|
||||||
|
NSRect srcRectInCache = NSMakeRect(srcRect.origin.x * widthScaleFactor,
|
||||||
|
srcRect.origin.y * heightScaleFactor,
|
||||||
|
srcRect.size.width * widthScaleFactor,
|
||||||
|
srcRect.size.height * heightScaleFactor);
|
||||||
|
|
||||||
|
cache = [[NSCachedImageRep alloc]
|
||||||
|
initWithSize: cacheSize
|
||||||
|
depth: [[NSScreen mainScreen] depth]
|
||||||
|
separate: YES
|
||||||
|
alpha: YES];
|
||||||
|
|
||||||
|
[[[cache window] contentView] lockFocus];
|
||||||
|
cacheCtxt = GSCurrentContext();
|
||||||
|
|
||||||
|
/* Clear the cache window surface */
|
||||||
|
DPScompositerect(cacheCtxt, 0, 0, cacheSize.width, cacheSize.height, NSCompositeClear);
|
||||||
|
gState = [cacheCtxt GSDefineGState];
|
||||||
|
|
||||||
|
//NSLog(@"Draw in cache size %@", NSStringFromSize(cacheSize));
|
||||||
|
|
||||||
|
/* We must not use -drawRepresentation:inRect: because the image must drawn
|
||||||
|
scaled even when -scalesWhenResized is NO */
|
||||||
|
[[self bestRepresentationForDevice: nil]
|
||||||
|
drawInRect: NSMakeRect(0, 0, cacheSize.width, cacheSize.height)];
|
||||||
|
/* If we're doing a dissolve, use a DestinationIn composite to lower
|
||||||
|
the alpha of the pixels. */
|
||||||
|
if (delta != 1.0)
|
||||||
|
{
|
||||||
|
DPSsetalpha(cacheCtxt, delta);
|
||||||
|
DPScompositerect(cacheCtxt, 0, 0, cacheSize.width, cacheSize.height,
|
||||||
|
NSCompositeDestinationIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[[cache window] contentView] unlockFocus];
|
||||||
|
|
||||||
|
//NSLog(@"Draw in %@ from %@ from cache rect %@", NSStringFromRect(dstRect),
|
||||||
|
// NSStringFromRect(srcRect), NSStringFromRect(srcRectInCache));
|
||||||
|
|
||||||
|
[ctxt GSdraw: gState
|
||||||
|
toPoint: dstRect.origin
|
||||||
|
fromRect: srcRectInCache
|
||||||
|
operation: op
|
||||||
|
fraction: delta];
|
||||||
|
|
||||||
|
[ctxt GSUndefineGState: gState];
|
||||||
|
DESTROY(cache);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Old code path that can probably partially be merged with the new native implementation.
|
||||||
|
Fallback for backends other than Cairo. */
|
||||||
|
- (void) guiDrawInRect: (NSRect)dstRect
|
||||||
|
fromRect: (NSRect)srcRect
|
||||||
|
operation: (NSCompositingOperation)op
|
||||||
|
fraction: (float)delta
|
||||||
{
|
{
|
||||||
NSGraphicsContext *ctxt = GSCurrentContext();
|
NSGraphicsContext *ctxt = GSCurrentContext();
|
||||||
NSAffineTransform *transform;
|
NSAffineTransform *transform;
|
||||||
|
@ -1143,6 +1274,21 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) drawInRect: (NSRect)dstRect
|
||||||
|
fromRect: (NSRect)srcRect
|
||||||
|
operation: (NSCompositingOperation)op
|
||||||
|
fraction: (float)delta
|
||||||
|
{
|
||||||
|
if ([GSCurrentContext() supportsDrawGState])
|
||||||
|
{
|
||||||
|
[self nativeDrawInRect: dstRect fromRect: srcRect operation: op fraction: delta];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
[self guiDrawInRect: dstRect fromRect: srcRect operation: op fraction: delta];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void) addRepresentation: (NSImageRep *)imageRep
|
- (void) addRepresentation: (NSImageRep *)imageRep
|
||||||
{
|
{
|
||||||
GSRepData *repd;
|
GSRepData *repd;
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <Foundation/NSDebug.h>
|
#include <Foundation/NSDebug.h>
|
||||||
|
#include "AppKit/NSAffineTransform.h"
|
||||||
#include "AppKit/NSCell.h"
|
#include "AppKit/NSCell.h"
|
||||||
#include "AppKit/NSGraphics.h"
|
#include "AppKit/NSGraphics.h"
|
||||||
#include "AppKit/NSImageCell.h"
|
#include "AppKit/NSImageCell.h"
|
||||||
|
@ -197,6 +198,7 @@ scaleProportionally(NSSize imageSize, NSRect canvasRect)
|
||||||
NSPoint position;
|
NSPoint position;
|
||||||
BOOL is_flipped = [controlView isFlipped];
|
BOOL is_flipped = [controlView isFlipped];
|
||||||
NSSize imageSize, realImageSize;
|
NSSize imageSize, realImageSize;
|
||||||
|
NSAffineTransform *xform = nil;
|
||||||
|
|
||||||
NSDebugLLog(@"NSImageCell", @"NSImageCell drawInteriorWithFrame called");
|
NSDebugLLog(@"NSImageCell", @"NSImageCell drawInteriorWithFrame called");
|
||||||
|
|
||||||
|
@ -273,10 +275,13 @@ scaleProportionally(NSSize imageSize, NSRect canvasRect)
|
||||||
}
|
}
|
||||||
|
|
||||||
// account for flipped views
|
// account for flipped views
|
||||||
if (is_flipped)
|
if (is_flipped && controlView != nil)
|
||||||
{
|
{
|
||||||
position.y += imageSize.height;
|
xform = [NSAffineTransform transform];
|
||||||
imageSize.height = -imageSize.height;
|
[xform translateXBy: 0 yBy: [controlView bounds].size.height];
|
||||||
|
[xform scaleXBy: 1 yBy: -1];
|
||||||
|
[xform concat];
|
||||||
|
position.y = [controlView bounds].size.height - position.y - imageSize.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw!
|
// draw!
|
||||||
|
@ -286,6 +291,12 @@ scaleProportionally(NSSize imageSize, NSRect canvasRect)
|
||||||
realImageSize.height)
|
realImageSize.height)
|
||||||
operation: NSCompositeSourceOver
|
operation: NSCompositeSourceOver
|
||||||
fraction: 1.0];
|
fraction: 1.0];
|
||||||
|
|
||||||
|
if (is_flipped && controlView != nil)
|
||||||
|
{
|
||||||
|
[xform invert];
|
||||||
|
[xform concat];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSSize) cellSize
|
- (NSSize) cellSize
|
||||||
|
|
|
@ -453,8 +453,6 @@ implement, so we can't do that. */
|
||||||
ctxt = GSCurrentContext();
|
ctxt = GSCurrentContext();
|
||||||
if (aPoint.x != 0 || aPoint.y != 0)
|
if (aPoint.x != 0 || aPoint.y != 0)
|
||||||
{
|
{
|
||||||
if ([[ctxt focusView] isFlipped])
|
|
||||||
aPoint.y -= _size.height;
|
|
||||||
ctm = GSCurrentCTM(ctxt);
|
ctm = GSCurrentCTM(ctxt);
|
||||||
DPStranslate(ctxt, aPoint.x, aPoint.y);
|
DPStranslate(ctxt, aPoint.x, aPoint.y);
|
||||||
reset = 1;
|
reset = 1;
|
||||||
|
@ -480,8 +478,6 @@ implement, so we can't do that. */
|
||||||
ctxt = GSCurrentContext();
|
ctxt = GSCurrentContext();
|
||||||
scale = NSMakeSize(NSWidth(aRect) / _size.width,
|
scale = NSMakeSize(NSWidth(aRect) / _size.width,
|
||||||
NSHeight(aRect) / _size.height);
|
NSHeight(aRect) / _size.height);
|
||||||
if ([[ctxt focusView] isFlipped])
|
|
||||||
aRect.origin.y -= NSHeight(aRect);
|
|
||||||
ctm = GSCurrentCTM(ctxt);
|
ctm = GSCurrentCTM(ctxt);
|
||||||
DPStranslate(ctxt, NSMinX(aRect), NSMinY(aRect));
|
DPStranslate(ctxt, NSMinX(aRect), NSMinY(aRect));
|
||||||
DPSscale(ctxt, scale.width, scale.height);
|
DPSscale(ctxt, scale.width, scale.height);
|
||||||
|
|
|
@ -3002,9 +3002,16 @@ in the main thread.
|
||||||
destPoint = aRect.origin;
|
destPoint = aRect.origin;
|
||||||
destPoint.x += delta.width;
|
destPoint.x += delta.width;
|
||||||
destPoint.y += delta.height;
|
destPoint.y += delta.height;
|
||||||
|
if ([self isFlipped])
|
||||||
|
{
|
||||||
|
destPoint.y += aRect.size.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
//NSLog(@"destPoint %@ in %@", NSStringFromPoint(destPoint), NSStringFromRect(_bounds));
|
||||||
|
|
||||||
[self lockFocus];
|
[self lockFocus];
|
||||||
NSCopyBits(0, aRect, destPoint);
|
//NSCopyBits(0, aRect, destPoint);
|
||||||
|
NSCopyBits([[self window] gState], [self convertRect: aRect toView: nil], destPoint);
|
||||||
[self unlockFocus];
|
[self unlockFocus];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue