Archived
1

Internal Redesign:

- Combined MPExpression and MPMutableExpression
- Abstracted children of MPExpression into MPExpressionElement protocol
- Abstracted most of MPExpressionLayout and MPFunctionLayout into common superclass MPLayout
This commit is contained in:
Kim Wittenburg
2014-08-11 13:57:48 +02:00
parent 740c3fd80a
commit 60760b8b3d
31 changed files with 1222 additions and 1343 deletions

159
MathPad/MPLayout.m Normal file
View File

@@ -0,0 +1,159 @@
//
// MPLayout.m
// MathPad
//
// Created by Kim Wittenburg on 11.08.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import "MPLayout.h"
@interface MPLayout ()
// Querying Caches
- (BOOL)hasCacheForElementAtIndex:(NSUInteger)index;
// Storing Caches
- (void)cacheObject:(id)anObject
forElementAtIndex:(NSUInteger)index;
- (void)ensureCacheSizeForIndex:(NSUInteger)index;
@end
@implementation MPLayout {
NSMutableArray *_cache;
NSBezierPath *_cachedPath;
}
#pragma mark Creation Methods
- (id)init
{
self = [super init];
if (self) {
_cache = [[NSMutableArray alloc] init];
_cachedPath = nil;
_path = [[NSIndexPath alloc] init];
}
return self;
}
- (id)initWithPath:(NSIndexPath *)path
parent:(MPLayout *)parent
{
self = [self init];
if (self) {
_path = path;
_parent = parent;
}
return self;
}
#pragma Text System Objects
- (MPExpressionStorage *)expressionStorage
{
return self.parent.expressionStorage;
}
- (NSLayoutManager *)layoutManager
{
return self.expressionStorage.layoutManager;
}
- (NSTextContainer *)textContainer
{
return self.expressionStorage.textContainer;
}
- (NSTextStorage *)textStorage
{
return self.expressionStorage.textStorage;
}
#pragma mark Cache Tree
// Querying Caches
- (BOOL)hasCacheForElementAtIndex:(NSUInteger)index
{
if (index >= _cache.count) {
return NO;
}
return _cache[index] != MPNull;
}
- (id)cachableObjectForIndex:(NSUInteger)index
generator:(id (^)())generator
{
if ([self hasCacheForElementAtIndex:index]) {
return _cache[index];
}
id object = generator();
[self cacheObject:object
forElementAtIndex:index];
return object;
}
// Storing Caches
- (void)cacheObject:(id)anObject
forElementAtIndex:(NSUInteger)index
{
[self ensureCacheSizeForIndex:index];
_cache[index] = anObject;
}
- (void)ensureCacheSizeForIndex:(NSUInteger)index
{
while (index >= _cache.count) {
[_cache addObject:MPNull];
}
}
// Clearing Caches
- (void)clearCacheInRange:(NSRange)range
replacementLength:(NSUInteger)replacementLength
{
NSMutableArray *placeholders = [[NSMutableArray alloc] initWithCapacity:replacementLength];
while (placeholders.count < replacementLength) {
[placeholders addObject:MPNull];
}
[_cache replaceObjectsInRange:range
withObjectsFromArray:placeholders];
[self invalidate];
}
- (void)invalidate
{
_cachedPath = nil;
[self.parent invalidate];
}
#pragma mark Calculation Methods
- (NSSize)size
{
return self.bezierPath.bounds.size;
}
- (NSBezierPath *)bezierPath
{
if (!_cachedPath) {
_cachedPath = [self generateBezierPath];
}
return _cachedPath;
}
- (NSBezierPath *)bezierPathAtOrigin:(NSPoint)point
{
NSAffineTransform *transform = [NSAffineTransform transform];
[transform translateXBy:point.x
yBy:point.y];
NSBezierPath *path = [NSBezierPath bezierPath];
[path appendBezierPath:self.bezierPath];
[path transformUsingAffineTransform:transform];
return path;
}
- (void)drawAtPoint:(NSPoint)point
{
NSBezierPath *path = [self bezierPathAtOrigin:point];
[path fill];
}
@end