190 lines
5.3 KiB
Objective-C
190 lines
5.3 KiB
Objective-C
//
|
|
// MPParenthesisFunctionLayout.m
|
|
// MathPad
|
|
//
|
|
// Created by Kim Wittenburg on 17.09.14.
|
|
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
|
|
//
|
|
|
|
#import "MPParenthesisFunctionLayout.h"
|
|
|
|
#define MPParenthesisFunctionOpeningParensOffset 2
|
|
#define MPParenthesisFunctionClosingParensOffset 0
|
|
|
|
@interface MPParenthesisFunctionLayout ()
|
|
|
|
- (NSBezierPath *)openingParens;
|
|
- (NSBezierPath *)closingParens;
|
|
|
|
- (NSBezierPath *)transformedOpeningParens;
|
|
- (NSBezierPath *)transformedClosingParens;
|
|
|
|
- (NSAffineTransform *)parenthesisTransform;
|
|
|
|
@end
|
|
|
|
@implementation MPParenthesisFunctionLayout
|
|
|
|
- (MPParenthesisFunction *)parenthesisFunction
|
|
{
|
|
return (MPParenthesisFunction *)self.function;
|
|
}
|
|
|
|
- (NSBezierPath *)openingParens
|
|
{
|
|
NSBezierPath *parens = [self objectForPrivateCacheIndex:0 generator:^id{
|
|
CTLineRef line = [self createLineForString:@"("];
|
|
CFArrayRef glyphRuns = CTLineGetGlyphRuns(line);
|
|
CFRetain(glyphRuns);
|
|
CTRunRef glyphRun = CFArrayGetValueAtIndex(glyphRuns, 0);
|
|
CFRetain(glyphRun);
|
|
|
|
CGGlyph *glyphs = malloc(1 * sizeof(CGGlyph));
|
|
CTRunGetGlyphs(glyphRun, CFRangeMake(0, 1), glyphs);
|
|
NSGlyph glyph = glyphs[0];
|
|
|
|
NSBezierPath *path = [[NSBezierPath alloc] init];
|
|
[path moveToPoint:NSZeroPoint];
|
|
[path appendBezierPathWithGlyph:glyph
|
|
inFont:self.font];
|
|
|
|
CFRelease(line);
|
|
CFRelease(glyphRuns);
|
|
CFRelease(glyphRun);
|
|
free(glyphs);
|
|
|
|
return path;
|
|
}];
|
|
return parens;
|
|
}
|
|
|
|
- (NSBezierPath *)closingParens
|
|
{
|
|
NSBezierPath *parens = [self objectForPrivateCacheIndex:1 generator:^id{
|
|
CTLineRef line = [self createLineForString:@")"];
|
|
CFArrayRef glyphRuns = CTLineGetGlyphRuns(line);
|
|
CFRetain(glyphRuns);
|
|
CTRunRef glyphRun = CFArrayGetValueAtIndex(glyphRuns, 0);
|
|
CFRetain(glyphRun);
|
|
|
|
CGGlyph *glyphs = malloc(1 * sizeof(CGGlyph));
|
|
CTRunGetGlyphs(glyphRun, CFRangeMake(0, 1), glyphs);
|
|
NSGlyph glyph = glyphs[0];
|
|
|
|
NSBezierPath *path = [[NSBezierPath alloc] init];
|
|
[path moveToPoint:NSZeroPoint];
|
|
[path appendBezierPathWithGlyph:glyph
|
|
inFont:self.font];
|
|
|
|
CFRelease(line);
|
|
CFRelease(glyphRuns);
|
|
CFRelease(glyphRun);
|
|
free(glyphs);
|
|
|
|
return path;
|
|
}];
|
|
return parens;
|
|
}
|
|
|
|
- (NSBezierPath *)transformedOpeningParens
|
|
{
|
|
NSBezierPath *parens = self.openingParens.copy;
|
|
[parens transformUsingAffineTransform:self.parenthesisTransform];
|
|
return parens;
|
|
}
|
|
|
|
- (NSBezierPath *)transformedClosingParens
|
|
{
|
|
NSBezierPath *parens = self.closingParens.copy;
|
|
[parens transformUsingAffineTransform:self.parenthesisTransform];
|
|
return parens;
|
|
}
|
|
|
|
- (NSAffineTransform *)parenthesisTransform
|
|
{
|
|
NSRect parensBounds = self.openingParens.bounds;
|
|
NSRect expressionBounds = [self childLayoutAtIndex:0].bounds;
|
|
NSAffineTransform *transform = [NSAffineTransform transform];
|
|
if (expressionBounds.size.height >= parensBounds.size.height) {
|
|
return transform;
|
|
}
|
|
CGFloat scaleFactor = expressionBounds.size.height / parensBounds.size.height;
|
|
[transform scaleXBy:1
|
|
yBy:scaleFactor];
|
|
return transform;
|
|
}
|
|
|
|
- (NSPoint)offsetOfChildLayoutAtIndex:(NSUInteger)index
|
|
{
|
|
if (index == 0) {
|
|
return NSMakePoint(self.openingParens.bounds.size.width + MPParenthesisFunctionOpeningParensOffset, 0);
|
|
}
|
|
return NSZeroPoint;
|
|
}
|
|
|
|
- (NSIndexPath *)indexPathForLocalMousePoint:(NSPoint)point
|
|
{
|
|
#warning Missing Implementation
|
|
return [NSIndexPath indexPathWithIndex:0];
|
|
}
|
|
|
|
- (NSUInteger)indexOfLeadingChild
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
- (NSUInteger)indexOfTrailingChild
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
- (NSIndexSet *)indexesOfRemainingChildren
|
|
{
|
|
return [NSIndexSet indexSetWithIndex:0];
|
|
}
|
|
|
|
- (NSRect)generateBounds
|
|
{
|
|
NSRect openingParensBounds = self.transformedOpeningParens.bounds;
|
|
NSRect closingParensBounds = self.transformedClosingParens.bounds;
|
|
NSRect bounds = [self childLayoutAtIndex:0].bounds;
|
|
|
|
if (openingParensBounds.size.height > bounds.size.height) {
|
|
bounds.size.height = openingParensBounds.size.height;
|
|
}
|
|
if (closingParensBounds.size.height > bounds.size.height) {
|
|
bounds.size.height = closingParensBounds.size.height;
|
|
}
|
|
|
|
bounds.size.width += MPParenthesisFunctionOpeningParensOffset;
|
|
bounds.size.width += openingParensBounds.size.width;
|
|
bounds.size.width += MPParenthesisFunctionClosingParensOffset;
|
|
bounds.size.width += closingParensBounds.size.width;
|
|
|
|
return bounds;
|
|
}
|
|
|
|
- (void)draw
|
|
{
|
|
NSBezierPath *openingParens = self.transformedOpeningParens;
|
|
MPLayout *expressionLayout = [self childLayoutAtIndex:0];
|
|
NSBezierPath *closingParens = self.transformedClosingParens;
|
|
|
|
CGFloat x = 0;
|
|
|
|
[openingParens fill];
|
|
x += openingParens.bounds.size.width;
|
|
x += MPParenthesisFunctionOpeningParensOffset;
|
|
[expressionLayout drawAtPoint:NSMakePoint(x, 0)];
|
|
x += expressionLayout.bounds.size.width;
|
|
x += MPParenthesisFunctionClosingParensOffset;
|
|
|
|
NSAffineTransform *transform = [NSAffineTransform transform];
|
|
[transform translateXBy:x
|
|
yBy:0];
|
|
[closingParens transformUsingAffineTransform:transform];
|
|
[closingParens fill];
|
|
}
|
|
|
|
@end
|