Archived
1
This repository has been archived on 2022-08-08. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
mathpad/MathPad/MPParenthesisFunctionLayout.m
2014-11-07 19:50:28 +01:00

186 lines
5.4 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
{
NSAffineTransform *transform = [NSAffineTransform transform];
[transform scaleXBy:1
yBy:self.scaleFactor];
return transform;
}
- (CGFloat)scaleFactor
{
NSRect parensBounds = self.openingParens.bounds;
NSRect expressionBounds = [self childLayoutAtIndex:0].bounds;
CGFloat parensHeight = parensBounds.size.height;
CGFloat expressionHeight = expressionBounds.size.height;
if (expressionHeight <= parensHeight) {
return 1.0;
}
return expressionHeight / parensHeight;
}
- (NSPoint)offsetOfChildLayoutAtIndex:(NSUInteger)index
{
return NSMakePoint(self.openingParens.bounds.size.width + MPParenthesisFunctionOpeningParensOffset, 0);
}
- (NSIndexPath *)indexPathForLocalMousePoint:(NSPoint)point
{
#warning Missing Implementation
return [NSIndexPath indexPathWithIndex: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;
CGFloat y = -openingParens.bounds.origin.y + expressionLayout.bounds.origin.y;
NSAffineTransform *transform = [NSAffineTransform transform];
[transform translateXBy:0
yBy:y];
[openingParens transformUsingAffineTransform:transform];
[openingParens fill];
x += openingParens.bounds.size.width;
x += MPParenthesisFunctionOpeningParensOffset;
x += expressionLayout.bounds.size.width;
x += MPParenthesisFunctionClosingParensOffset;
[transform translateXBy:x
yBy:0];
[closingParens transformUsingAffineTransform:transform];
[closingParens fill];
}
@end