Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // The only contents of an NSTextFieldCell subclass
- - (void)drawInteriorWithFrame:(NSRect)cellFrame
- inView:(NSView *)controlView
- {
- // Works but looks really bad
- NSBezierPath *stringPath = [self bezierPathWithString:self.stringValue
- inFont:self.font];
- NSAffineTransform *aTransform = [NSAffineTransform transform];
- [aTransform translateXBy:4
- yBy:5];
- [stringPath transformUsingAffineTransform:aTransform];
- if (!_innerShadow) {
- _innerShadow = [[NSShadow alloc] init];
- _innerShadow.shadowColor = [[NSColor blackColor] colorWithAlphaComponent:0.9];
- _innerShadow.shadowBlurRadius = 4.0;
- _innerShadow.shadowOffset = NSMakeSize(0, -1.0);
- }
- [NSGraphicsContext saveGraphicsState];
- NSShadow *raisedShaow = [[NSShadow alloc] init];
- raisedShaow.shadowColor = [[NSColor whiteColor] colorWithAlphaComponent:1.0];
- raisedShaow.shadowBlurRadius = 0.0;
- raisedShaow.shadowOffset = NSMakeSize(0, -1.0);
- [raisedShaow set];
- CGContextSetBlendMode([[NSGraphicsContext currentContext] graphicsPort], kCGBlendModeScreen);
- self.textColor = [NSColor blackColor];
- [super drawInteriorWithFrame:cellFrame
- inView:controlView];
- [NSGraphicsContext restoreGraphicsState];
- [NSGraphicsContext saveGraphicsState];
- NSBezierPath *framePath = [NSBezierPath bezierPathWithRect:cellFrame];
- [framePath setWindingRule:NSEvenOddWindingRule];
- [framePath appendBezierPath:stringPath];
- [stringPath setClip];
- [_innerShadow set];
- [framePath fill];
- [NSGraphicsContext restoreGraphicsState];
- // Doesn't really work, and I've no idea why
- /*CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceGray();
- CGContextRef maskContext = CGBitmapContextCreate(
- NULL,
- cellFrame.size.width,
- cellFrame.size.height,
- 8,
- cellFrame.size.width,
- colorspace,
- 0);
- CGColorSpaceRelease(colorspace);
- // Switch to the context for drawing
- [NSGraphicsContext saveGraphicsState];
- [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:maskContext
- flipped:YES]];
- // Draw a black background to exclude
- [[NSColor blackColor] set];
- CGContextFillRect(maskContext, cellFrame);
- // Draw the string in white to include
- [self.stringValue drawInRect:cellFrame
- withAttributes:@{
- NSFontAttributeName : self.font,
- NSForegroundColorAttributeName : [NSColor whiteColor]
- }];
- CGImageRef alphaMask = CGBitmapContextCreateImage(maskContext);
- [NSGraphicsContext restoreGraphicsState];
- // Draw a white background in the window
- CGContextRef windowContext = [[NSGraphicsContext currentContext] graphicsPort];
- // Draw the image, clipped by the mask
- CGContextSaveGState(windowContext);
- CGContextClipToMask(windowContext, NSRectToCGRect(cellFrame), alphaMask);
- [_innerShadow set];
- NSRectFill(cellFrame);
- CGContextRestoreGState(windowContext);
- CGImageRelease(alphaMask);*/
- }
- - (NSBezierPath *)bezierPathWithString:(NSString *)text
- inFont:(NSFont *)font
- {
- // This has some weird alphabet shifting problem
- // Don't use in production until fixed
- NSBezierPath *aPath = [NSBezierPath bezierPath];
- [aPath moveToPoint:NSZeroPoint];
- NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:text
- attributes:@{
- NSFontAttributeName : self.font
- }];
- CTLineRef line = CTLineCreateWithAttributedString((CFAttributedStringRef)CFBridgingRetain(attributedString));
- CFArrayRef glyphRuns = CTLineGetGlyphRuns(line);
- CFIndex count = CFArrayGetCount(glyphRuns);
- for (CFIndex index = 0; index < count; index++) {
- CTRunRef currentRun = CFArrayGetValueAtIndex(glyphRuns, index);
- CFIndex glyphCount = CTRunGetGlyphCount(currentRun);
- CGGlyph glyphs[glyphCount];
- CTRunGetGlyphs(currentRun, CTRunGetStringRange(currentRun), glyphs);
- NSGlyph bezierPathGlyphs[glyphCount];
- for (CFIndex glyphIndex = 0; glyphIndex < glyphCount; glyphIndex++) {
- bezierPathGlyphs[glyphIndex] = glyphs[glyphIndex];
- }
- [aPath appendBezierPathWithGlyphs:bezierPathGlyphs
- count:glyphCount
- inFont:font];
- }
- CFRelease(line);
- [aPath transformUsingAffineTransform:[self verticallyFlippedAffineTransformForRect:aPath.bounds]];
- return aPath;
- }
- - (NSAffineTransform *)verticallyFlippedAffineTransformForRect:(NSRect)rect
- {
- NSAffineTransform *affineTransform = [NSAffineTransform transform];
- NSAffineTransformStruct transformStruct;
- transformStruct.m11 = 1.0;
- transformStruct.m12 = 0.0;
- transformStruct.tX = 0;
- transformStruct.m21 = 0.0;
- transformStruct.m22 = -1.0;
- transformStruct.tY = rect.size.height;
- [affineTransform setTransformStruct:transformStruct];
- return affineTransform;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement