mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-23 03:11:18 +00:00
Merge Source/NSGradient.m Source/NSImage.m Source/NSImageRep.m
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/branches/gnustep_testplant_branch@38729 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
1a6aa35155
commit
d867a44374
3 changed files with 192 additions and 141 deletions
|
@ -42,6 +42,12 @@
|
|||
#define PI 3.1415926535897932384626434
|
||||
#endif
|
||||
|
||||
@interface NSGradient (Private)
|
||||
- (void) _drawInRect: (NSRect)rect angle: (CGFloat)angle;
|
||||
- (void) _drawInRect: (NSRect)rect
|
||||
relativeCenterPosition: (NSPoint)relativeCenterPoint;
|
||||
@end
|
||||
|
||||
@implementation NSGradient
|
||||
|
||||
- (NSColorSpace *) colorSpace;
|
||||
|
@ -79,7 +85,7 @@
|
|||
|
||||
[currentContext saveGraphicsState];
|
||||
[path addClip];
|
||||
[self drawInRect: [path bounds] angle: angle];
|
||||
[self _drawInRect: [path bounds] angle: angle];
|
||||
[currentContext restoreGraphicsState];
|
||||
}
|
||||
|
||||
|
@ -90,102 +96,28 @@
|
|||
|
||||
[currentContext saveGraphicsState];
|
||||
[path addClip];
|
||||
[self drawInRect: [path bounds] relativeCenterPosition: relativeCenterPoint];
|
||||
[self _drawInRect: [path bounds] relativeCenterPosition: relativeCenterPoint];
|
||||
[currentContext restoreGraphicsState];
|
||||
}
|
||||
|
||||
- (void) drawInRect: (NSRect)rect angle: (CGFloat)angle
|
||||
{
|
||||
NSGraphicsContext *currentContext = [NSGraphicsContext currentContext];
|
||||
NSPoint startPoint;
|
||||
NSPoint endPoint;
|
||||
float rad;
|
||||
float length;
|
||||
|
||||
// Normalize to 0.0 <= angle <= 360.0
|
||||
while (angle < 0.0)
|
||||
{
|
||||
angle += 360.0;
|
||||
}
|
||||
while (angle > 360.0)
|
||||
{
|
||||
angle -= 360.0;
|
||||
}
|
||||
|
||||
if (angle < 90.0)
|
||||
{
|
||||
startPoint = NSMakePoint(NSMinX(rect), NSMinY(rect));
|
||||
}
|
||||
else if (angle < 180.0)
|
||||
{
|
||||
startPoint = NSMakePoint(NSMaxX(rect), NSMinY(rect));
|
||||
}
|
||||
else if (angle < 270.0)
|
||||
{
|
||||
startPoint = NSMakePoint(NSMaxX(rect), NSMaxY(rect));
|
||||
}
|
||||
else
|
||||
{
|
||||
startPoint = NSMakePoint(NSMinX(rect), NSMaxY(rect));
|
||||
}
|
||||
rad = PI * angle / 180;
|
||||
length = abs(NSWidth(rect) * cos(rad) + NSHeight(rect) * sin(rad));
|
||||
endPoint = NSMakePoint(startPoint.x + length * cos(rad),
|
||||
startPoint.y + length * sin(rad));
|
||||
|
||||
[currentContext saveGraphicsState];
|
||||
[NSBezierPath clipRect: rect];
|
||||
[self drawFromPoint: startPoint
|
||||
toPoint: endPoint
|
||||
options: 0];
|
||||
[self _drawInRect: rect angle: angle];
|
||||
[currentContext restoreGraphicsState];
|
||||
}
|
||||
|
||||
static inline float sqr(float a)
|
||||
{
|
||||
return a * a;
|
||||
}
|
||||
|
||||
static inline float euclidian_distance(NSPoint start, NSPoint end)
|
||||
{
|
||||
return sqrt(sqr(end.x - start.x) + sqr(end.y - start.y));
|
||||
}
|
||||
|
||||
- (void) drawInRect: (NSRect)rect
|
||||
relativeCenterPosition: (NSPoint)relativeCenterPoint
|
||||
{
|
||||
NSGraphicsContext *currentContext = [NSGraphicsContext currentContext];
|
||||
NSPoint startCenter;
|
||||
NSPoint endCenter;
|
||||
CGFloat endRadius;
|
||||
CGFloat distance;
|
||||
|
||||
NSAssert(relativeCenterPoint.x >= 0.0 && relativeCenterPoint.x <= 1.0, @"NSGradient invalid relative center point");
|
||||
NSAssert(relativeCenterPoint.y >= 0.0 && relativeCenterPoint.y <= 1.0, @"NSGradient invalid relative center point");
|
||||
startCenter = NSMakePoint(NSMidX(rect), NSMidY(rect));
|
||||
endCenter = NSMakePoint(startCenter.x + rect.size.width * relativeCenterPoint.x,
|
||||
startCenter.y + rect.size.height * relativeCenterPoint.y);
|
||||
endRadius = 0.0;
|
||||
distance = euclidian_distance(endCenter, NSMakePoint(NSMinX(rect), NSMinY(rect)));
|
||||
if (endRadius < distance)
|
||||
endRadius = distance;
|
||||
distance = euclidian_distance(endCenter, NSMakePoint(NSMaxX(rect), NSMinY(rect)));
|
||||
if (endRadius < distance)
|
||||
endRadius = distance;
|
||||
distance = euclidian_distance(endCenter, NSMakePoint(NSMinX(rect), NSMaxY(rect)));
|
||||
if (endRadius < distance)
|
||||
endRadius = distance;
|
||||
distance = euclidian_distance(endCenter, NSMakePoint(NSMaxX(rect), NSMaxY(rect)));
|
||||
if (endRadius < distance)
|
||||
endRadius = distance;
|
||||
|
||||
[currentContext saveGraphicsState];
|
||||
[NSBezierPath clipRect: rect];
|
||||
[self drawFromCenter: startCenter
|
||||
radius: 0.0
|
||||
toCenter: endCenter
|
||||
radius: endRadius
|
||||
options: 0];
|
||||
[self _drawInRect: rect relativeCenterPosition: relativeCenterPoint];
|
||||
[currentContext restoreGraphicsState];
|
||||
}
|
||||
|
||||
|
@ -365,3 +297,93 @@ relativeCenterPosition: (NSPoint)relativeCenterPoint
|
|||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSGradient (Private)
|
||||
|
||||
- (void) _drawInRect: (NSRect)rect angle: (CGFloat)angle
|
||||
{
|
||||
NSPoint startPoint;
|
||||
NSPoint endPoint;
|
||||
float rad;
|
||||
float length;
|
||||
|
||||
// Normalize to 0.0 <= angle <= 360.0
|
||||
while (angle < 0.0)
|
||||
{
|
||||
angle += 360.0;
|
||||
}
|
||||
while (angle > 360.0)
|
||||
{
|
||||
angle -= 360.0;
|
||||
}
|
||||
|
||||
if (angle < 90.0)
|
||||
{
|
||||
startPoint = NSMakePoint(NSMinX(rect), NSMinY(rect));
|
||||
}
|
||||
else if (angle < 180.0)
|
||||
{
|
||||
startPoint = NSMakePoint(NSMaxX(rect), NSMinY(rect));
|
||||
}
|
||||
else if (angle < 270.0)
|
||||
{
|
||||
startPoint = NSMakePoint(NSMaxX(rect), NSMaxY(rect));
|
||||
}
|
||||
else
|
||||
{
|
||||
startPoint = NSMakePoint(NSMinX(rect), NSMaxY(rect));
|
||||
}
|
||||
rad = PI * angle / 180;
|
||||
length = fabs(NSWidth(rect) * cos(rad) + NSHeight(rect) * sin(rad));
|
||||
endPoint = NSMakePoint(startPoint.x + length * cos(rad),
|
||||
startPoint.y + length * sin(rad));
|
||||
|
||||
[self drawFromPoint: startPoint
|
||||
toPoint: endPoint
|
||||
options: 0];
|
||||
}
|
||||
|
||||
static inline float sqr(float a)
|
||||
{
|
||||
return a * a;
|
||||
}
|
||||
|
||||
static inline float euclidian_distance(NSPoint start, NSPoint end)
|
||||
{
|
||||
return sqrt(sqr(end.x - start.x) + sqr(end.y - start.y));
|
||||
}
|
||||
|
||||
- (void) _drawInRect: (NSRect)rect
|
||||
relativeCenterPosition: (NSPoint)relativeCenterPoint
|
||||
{
|
||||
NSPoint startCenter;
|
||||
NSPoint endCenter;
|
||||
CGFloat endRadius;
|
||||
CGFloat distance;
|
||||
|
||||
NSAssert(relativeCenterPoint.x >= 0.0 && relativeCenterPoint.x <= 1.0, @"NSGradient invalid relative center point");
|
||||
NSAssert(relativeCenterPoint.y >= 0.0 && relativeCenterPoint.y <= 1.0, @"NSGradient invalid relative center point");
|
||||
startCenter = NSMakePoint(NSMidX(rect), NSMidY(rect));
|
||||
endCenter = NSMakePoint(startCenter.x + rect.size.width * relativeCenterPoint.x,
|
||||
startCenter.y + rect.size.height * relativeCenterPoint.y);
|
||||
endRadius = 0.0;
|
||||
distance = euclidian_distance(endCenter, NSMakePoint(NSMinX(rect), NSMinY(rect)));
|
||||
if (endRadius < distance)
|
||||
endRadius = distance;
|
||||
distance = euclidian_distance(endCenter, NSMakePoint(NSMaxX(rect), NSMinY(rect)));
|
||||
if (endRadius < distance)
|
||||
endRadius = distance;
|
||||
distance = euclidian_distance(endCenter, NSMakePoint(NSMinX(rect), NSMaxY(rect)));
|
||||
if (endRadius < distance)
|
||||
endRadius = distance;
|
||||
distance = euclidian_distance(endCenter, NSMakePoint(NSMaxX(rect), NSMaxY(rect)));
|
||||
if (endRadius < distance)
|
||||
endRadius = distance;
|
||||
|
||||
[self drawFromCenter: startCenter
|
||||
radius: 0.0
|
||||
toCenter: endCenter
|
||||
radius: endRadius
|
||||
options: 0];
|
||||
}
|
||||
@end
|
||||
|
|
152
Source/NSImage.m
152
Source/NSImage.m
|
@ -96,6 +96,10 @@ NSString *const NSImageNameNetwork = @"NSNetwork";
|
|||
// OS_API_VERSION(MAC_OS_X_VERSION_10_6, GS_API_LATEST)
|
||||
NSString *const NSImageNameFolder = @"NSFolder";
|
||||
|
||||
@interface NSView (Private)
|
||||
- (void) _lockFocusInContext: (NSGraphicsContext *)ctxt inRect: (NSRect)rect;
|
||||
@end
|
||||
|
||||
@implementation NSBundle (NSImageAdditions)
|
||||
|
||||
- (NSString*) pathForImageResource: (NSString*)name
|
||||
|
@ -499,6 +503,16 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
|
|||
return NO;
|
||||
}
|
||||
|
||||
- (NSString*) description
|
||||
{
|
||||
return [NSString stringWithFormat: @"<%@ %p Name=%@ Size=%@ Reps=%@>",
|
||||
[self class],
|
||||
self,
|
||||
[self name],
|
||||
NSStringFromSize([self size]),
|
||||
[self representations]];
|
||||
}
|
||||
|
||||
/* This methd sets the name of an image, updating the global name dictionary
|
||||
* to point to the image (or removing an image from the dictionary if the
|
||||
* new name is nil).
|
||||
|
@ -788,7 +802,7 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
|
|||
// Set the CTM to the identity matrix with the current translation
|
||||
// and the user space scale factor
|
||||
{
|
||||
NSAffineTransform *backup = [ctxt GSCurrentCTM];
|
||||
NSAffineTransform *backup = [[ctxt GSCurrentCTM] retain];
|
||||
NSAffineTransform *newTransform = [NSAffineTransform transform];
|
||||
NSPoint translation = [backup transformPoint: aPoint];
|
||||
[newTransform translateXBy: translation.x
|
||||
|
@ -803,6 +817,8 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
|
|||
fraction: delta];
|
||||
|
||||
[ctxt GSSetCTM: backup];
|
||||
|
||||
[backup release];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -963,10 +979,13 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
|
|||
{
|
||||
GSRepData *repd;
|
||||
|
||||
repd = [GSRepData new];
|
||||
repd->rep = RETAIN(imageRep);
|
||||
[_reps addObject: repd];
|
||||
RELEASE(repd);
|
||||
if (imageRep != nil)
|
||||
{
|
||||
repd = [GSRepData new];
|
||||
repd->rep = RETAIN(imageRep);
|
||||
[_reps addObject: repd];
|
||||
RELEASE(repd);
|
||||
}
|
||||
}
|
||||
|
||||
- (void) addRepresentations: (NSArray *)imageRepArray
|
||||
|
@ -1035,9 +1054,14 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
|
|||
window = [(NSCachedImageRep *)imageRep window];
|
||||
_lockedView = [window contentView];
|
||||
if (_lockedView == nil)
|
||||
[NSException raise: NSImageCacheException
|
||||
format: @"Cannot lock focus on nil rep"];
|
||||
[_lockedView lockFocus];
|
||||
{
|
||||
[NSException raise: NSImageCacheException
|
||||
format: @"Cannot lock focus on nil rep"];
|
||||
}
|
||||
|
||||
// FIXME: This is needed to get image caching working while printing. A better solution
|
||||
// needs to remove the viewIsPrinting variable from NSView.
|
||||
[_lockedView _lockFocusInContext: [window graphicsContext] inRect: [_lockedView bounds]];
|
||||
if (repd->bg == nil)
|
||||
{
|
||||
NSRect fillrect = NSMakeRect(0, 0, _size.width, _size.height);
|
||||
|
@ -2394,61 +2418,65 @@ iterate_reps_for_types(NSArray* imageReps, SEL method)
|
|||
}
|
||||
|
||||
// We end here, when no representation are there or no match is found.
|
||||
{
|
||||
NSImageRep *cacheRep = nil;
|
||||
GSRepData *repd;
|
||||
NSSize imageSize = [self size];
|
||||
NSSize repSize;
|
||||
NSInteger pixelsWide, pixelsHigh;
|
||||
|
||||
if (rep != nil)
|
||||
{
|
||||
repSize = [rep size];
|
||||
|
||||
if (repSize.width <= 0 || repSize.height <= 0)
|
||||
repSize = imageSize;
|
||||
|
||||
pixelsWide = [rep pixelsWide];
|
||||
pixelsHigh = [rep pixelsHigh];
|
||||
|
||||
if (pixelsWide == NSImageRepMatchesDevice ||
|
||||
pixelsHigh == NSImageRepMatchesDevice)
|
||||
{
|
||||
// FIXME: Since the cached rep must be a bitmap,
|
||||
// we must rasterize vector reps at a particular DPI.
|
||||
// Here we hardcode 72, but we should choose the DPI more intelligently.
|
||||
pixelsWide = repSize.width;
|
||||
pixelsHigh = repSize.height;
|
||||
}
|
||||
}
|
||||
else // e.g. when there are no representations at all
|
||||
{
|
||||
repSize = imageSize;
|
||||
// FIXME: assumes 72 DPI. Also truncates, not sure if that is a problem.
|
||||
pixelsWide = imageSize.width;
|
||||
pixelsHigh = imageSize.height;
|
||||
}
|
||||
|
||||
if (repSize.width <= 0 || repSize.height <= 0 ||
|
||||
pixelsWide <= 0 || pixelsHigh <= 0)
|
||||
{
|
||||
NSImageRep *cacheRep = nil;
|
||||
GSRepData *repd;
|
||||
NSSize imageSize = [self size];
|
||||
NSSize repSize;
|
||||
NSInteger pixelsWide, pixelsHigh;
|
||||
|
||||
if (rep != nil)
|
||||
{
|
||||
repSize = [rep size];
|
||||
|
||||
if (repSize.width <= 0 || repSize.height <= 0)
|
||||
repSize = imageSize;
|
||||
|
||||
pixelsWide = [rep pixelsWide];
|
||||
pixelsHigh = [rep pixelsHigh];
|
||||
|
||||
if (pixelsWide == NSImageRepMatchesDevice ||
|
||||
pixelsHigh == NSImageRepMatchesDevice)
|
||||
{
|
||||
// FIXME: Since the cached rep must be a bitmap,
|
||||
// we must rasterize vector reps at a particular DPI.
|
||||
// Here we hardcode 72, but we should choose the DPI more intelligently.
|
||||
pixelsWide = repSize.width;
|
||||
pixelsHigh = repSize.height;
|
||||
}
|
||||
}
|
||||
else // e.g. when there are no representations at all
|
||||
{
|
||||
repSize = imageSize;
|
||||
// FIXME: assumes 72 DPI. Also truncates, not sure if that is a problem.
|
||||
pixelsWide = imageSize.width;
|
||||
pixelsHigh = imageSize.height;
|
||||
}
|
||||
|
||||
if (repSize.width <= 0 || repSize.height <= 0 ||
|
||||
pixelsWide <= 0 || pixelsHigh <= 0)
|
||||
return nil;
|
||||
|
||||
// Create a new cached image rep without any contents.
|
||||
cacheRep = [[cachedClass alloc] initWithSize: repSize
|
||||
pixelsWide: pixelsWide
|
||||
pixelsHigh: pixelsHigh
|
||||
depth: [[NSScreen mainScreen] depth]
|
||||
separate: _flags.cacheSeparately
|
||||
alpha: [rep hasAlpha]];
|
||||
if (cacheRep == nil)
|
||||
{
|
||||
return nil;
|
||||
|
||||
// Create a new cached image rep without any contents.
|
||||
cacheRep = [[cachedClass alloc]
|
||||
initWithSize: repSize
|
||||
pixelsWide: pixelsWide
|
||||
pixelsHigh: pixelsHigh
|
||||
depth: [[NSScreen mainScreen] depth]
|
||||
separate: _flags.cacheSeparately
|
||||
alpha: [rep hasAlpha]];
|
||||
repd = [GSRepData new];
|
||||
repd->rep = cacheRep;
|
||||
repd->original = rep; // may be nil!
|
||||
[_reps addObject: repd];
|
||||
RELEASE(repd); /* Retained in _reps array. */
|
||||
|
||||
return repd;
|
||||
}
|
||||
}
|
||||
|
||||
repd = [GSRepData new];
|
||||
repd->rep = cacheRep;
|
||||
repd->original = rep; // may be nil!
|
||||
[_reps addObject: repd];
|
||||
RELEASE(repd); /* Retained in _reps array. */
|
||||
|
||||
return repd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -849,7 +849,7 @@ Fallback for backends other than Cairo. */
|
|||
{
|
||||
NSAffineTransform *newXform;
|
||||
|
||||
backup = [ctx GSCurrentCTM];
|
||||
backup = [[ctx GSCurrentCTM] retain];
|
||||
|
||||
newXform = [backup copy];
|
||||
[newXform translateXBy: dstRect.origin.x yBy: dstRect.origin.y + dstRect.size.height];
|
||||
|
@ -876,6 +876,7 @@ Fallback for backends other than Cairo. */
|
|||
if (compensateForFlip)
|
||||
{
|
||||
[ctx GSSetCTM: backup];
|
||||
[backup release];
|
||||
}
|
||||
|
||||
return YES;
|
||||
|
|
Loading…
Reference in a new issue