Skip to content

Instantly share code, notes, and snippets.

@nilium
Created March 6, 2011 20:20
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save nilium/857614 to your computer and use it in GitHub Desktop.
Save nilium/857614 to your computer and use it in GitHub Desktop.
/*
* NSImage+NinePartDrawing.h
*
* Copyright (c) 2011 Noel R. Cower
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*
*/
#import <Cocoa/Cocoa.h>
extern const CGFloat NNoCap;
@interface NSImage (NinePartDrawing)
- (void)drawInRect:(NSRect)dstSpacePortionRect
operation:(NSCompositingOperation)op
fraction:(CGFloat)requestedAlpha
respectFlipped:(BOOL)respectContextIsFlipped
hints:(NSDictionary *)hints
topCap:(CGFloat)top
bottomCap:(CGFloat)bottom
leftCap:(CGFloat)left
rightCap:(CGFloat)right;
- (void)drawInRect:(NSRect)dstSpacePortionRect
topCap:(CGFloat)top
bottomCap:(CGFloat)bottom
leftCap:(CGFloat)left
rightCap:(CGFloat)right;
- (void)drawInRect:(NSRect)dstSpacePortionRect
heightCap:(CGFloat)heightCap
widthCap:(CGFloat)widthCap;
- (void)drawInRect:(NSRect)dstSpacePortionRect
withCap:(CGFloat)cap;
@end
/*
* NSImage+NinePartDrawing.m
*
* Copyright (c) 2011 Noel R. Cower
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*
*/
#import "NSImage+NinePartDrawing.h"
const CGFloat NNoCap = -1;
@implementation NSImage (NinePartDrawing)
- (void)drawInRect:(NSRect)dstSpacePortionRect
topCap:(CGFloat)top
bottomCap:(CGFloat)bottom
leftCap:(CGFloat)left
rightCap:(CGFloat)right {
[self drawInRect:dstSpacePortionRect
operation:NSCompositeSourceOver
fraction:1.0
respectFlipped:YES
hints:nil
topCap:top
bottomCap:left
leftCap:bottom
rightCap:right];
}
- (void)drawInRect:(NSRect)dstSpacePortionRect
heightCap:(CGFloat)heightCap
widthCap:(CGFloat)widthCap {
[self drawInRect:dstSpacePortionRect
operation:NSCompositeSourceOver
fraction:1.0
respectFlipped:YES
hints:nil
topCap:heightCap
bottomCap:heightCap
leftCap:widthCap
rightCap:widthCap];
}
- (void)drawInRect:(NSRect)dstSpacePortionRect
withCap:(CGFloat)cap {
[self drawInRect:dstSpacePortionRect
operation:NSCompositeSourceOver
fraction:1.0
respectFlipped:YES
hints:nil
topCap:cap
bottomCap:cap
leftCap:cap
rightCap:cap];
}
- (void)drawInRect:(NSRect)dstSpacePortionRect
operation:(NSCompositingOperation)op
fraction:(CGFloat)requestedAlpha
respectFlipped:(BOOL)respectContextIsFlipped
hints:(NSDictionary *)hints
topCap:(CGFloat)top
bottomCap:(CGFloat)bottom
leftCap:(CGFloat)left
rightCap:(CGFloat)right {
top = fmax(top, 0);
bottom = fmax(bottom, 0);
left = fmax(left, 0);
right = fmax(right, 0);
NSSize size = [self size];
NSRect srcRect = NSZeroRect;
NSRect dstRect = dstSpacePortionRect;
srcRect.size.width = left;
srcRect.size.height = bottom;
dstRect.size = srcRect.size;
if (bottom > 0) {
if (left > 0) {
[self drawInRect:dstRect
fromRect:srcRect
operation:op
fraction:requestedAlpha
respectFlipped:respectContextIsFlipped
hints:hints];
}
dstRect.origin.x += (srcRect.origin.x = left);
dstRect.size.width = dstSpacePortionRect.size.width - (left + right);
srcRect.size.width = size.width - left - right;
[self drawInRect:dstRect
fromRect:srcRect
operation:op
fraction:requestedAlpha
respectFlipped:respectContextIsFlipped
hints:hints];
dstRect.origin.x = (dstSpacePortionRect.origin.x + dstSpacePortionRect.size.width) - right;
srcRect.origin.x = size.width - right;
dstRect.size.width = srcRect.size.width = right;
if (right > 0) {
[self drawInRect:dstRect
fromRect:srcRect
operation:op
fraction:requestedAlpha
respectFlipped:respectContextIsFlipped
hints:hints];
}
}
srcRect.size.height = size.height - (bottom + top);
dstRect.size.height = dstSpacePortionRect.size.height - (bottom + top);
dstRect.origin.y = dstSpacePortionRect.origin.y + (srcRect.origin.y = bottom);
if (right > 0) {
[self drawInRect:dstRect
fromRect:srcRect
operation:op
fraction:requestedAlpha
respectFlipped:respectContextIsFlipped
hints:hints];
}
if (left > 0) {
srcRect.origin.x = 0;
dstRect.origin.x = dstSpacePortionRect.origin.x;
dstRect.size.width = srcRect.size.width = left;
[self drawInRect:dstRect
fromRect:srcRect
operation:op
fraction:requestedAlpha
respectFlipped:respectContextIsFlipped
hints:hints];
}
dstRect.origin.x = dstSpacePortionRect.origin.x + (srcRect.origin.x = left);
dstRect.size.width = dstSpacePortionRect.size.width - (left + right);
srcRect.size.width = size.width - left - right;
[self drawInRect:dstRect
fromRect:srcRect
operation:op
fraction:requestedAlpha
respectFlipped:respectContextIsFlipped
hints:hints];
if (top > 0) {
srcRect.origin.y = size.height - top;
dstRect.origin.y = (dstSpacePortionRect.origin.y + dstSpacePortionRect.size.height) - top;
dstRect.size.height = srcRect.size.height = top;
[self drawInRect:dstRect
fromRect:srcRect
operation:op
fraction:requestedAlpha
respectFlipped:respectContextIsFlipped
hints:hints];
if (right > 0) {
srcRect.origin.x = size.width - right;
dstRect.origin.x = (dstSpacePortionRect.origin.x + dstSpacePortionRect.size.width) - right;
srcRect.size.width = dstRect.size.width = right;
[self drawInRect:dstRect
fromRect:srcRect
operation:op
fraction:requestedAlpha
respectFlipped:respectContextIsFlipped
hints:hints];
}
if (left > 0) {
srcRect.origin.x = 0;
dstRect.origin.x = dstSpacePortionRect.origin.x;
srcRect.size.width = dstRect.size.width = left;
[self drawInRect:dstRect
fromRect:srcRect
operation:op
fraction:requestedAlpha
respectFlipped:respectContextIsFlipped
hints:hints];
}
}
}
@end
@mrjjwright
Copy link

Props to you good sir; works well!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment