|
@@ -41,13 +41,20 @@ import Foundation
|
|
|
|
|
|
point = self.endPoint
|
|
|
CPDFListViewDrawResizeHandle(context, point, delta, true)
|
|
|
+ if self.isMeasure {
|
|
|
+ let translationDistance = measureInfo!.leadLength
|
|
|
+ let normalVector = calculateNormalVector(startPoint: startPoint, endPoint: endPoint)
|
|
|
+ let startPoint = translate(point: startPoint, withNormalVector: normalVector, distance: translationDistance)
|
|
|
+ let endPoint = translate(point: endPoint, withNormalVector: normalVector, distance: translationDistance)
|
|
|
+ point = NSMakePoint((startPoint.x+endPoint.x)/2, (startPoint.y+endPoint.y)/2)
|
|
|
+ CPDFListViewDrawResizeHandle(context, point, delta, true)
|
|
|
+ }
|
|
|
} else {
|
|
|
let rect = self.bounds
|
|
|
let lineWidth = pdfView.unitWidth(on: self.page)
|
|
|
context.saveGState()
|
|
|
let color = CPDFListViewConfig.defaultManager.annotationBorderColor.cgColor
|
|
|
context.setStrokeColor(color)
|
|
|
-
|
|
|
if(isHover) {
|
|
|
var length: [CGFloat] = [5.0, 5.0]
|
|
|
context.setLineDash(phase: 0, lengths: length)
|
|
@@ -75,7 +82,21 @@ import Foundation
|
|
|
|
|
|
override func hitTest(_ point: NSPoint) -> Bool {
|
|
|
let delta = fmax(4.0, 0.5 * self.lineWidth())
|
|
|
- return self.shouldDisplay() && CPDFListViewPointNearLineFromPointToPoint(CPDFListViewSubstractPoints(point, self.bounds.origin), CPDFListViewSubstractPoints(self.observedStartPoint(),self.bounds.origin), CPDFListViewSubstractPoints(self.observedEndPoint(),self.bounds.origin), delta)
|
|
|
+ if (self.isMeasure) {
|
|
|
+ let translationDistance = measureInfo!.leadLength
|
|
|
+ let normalVector = calculateNormalVector(startPoint: startPoint, endPoint: endPoint)
|
|
|
+ let translateStartPoint = translate(point: startPoint, withNormalVector: normalVector, distance: translationDistance)
|
|
|
+ if CPDFListViewPointNearLineFromPointToPoint(CPDFListViewSubstractPoints(point, bounds.origin), CPDFListViewSubstractPoints(observedStartPoint(), bounds.origin), CPDFListViewSubstractPoints(translateStartPoint, bounds.origin), delta) {
|
|
|
+ return shouldDisplay() && true
|
|
|
+ } else if CPDFListViewPointNearLineFromPointToPoint(CPDFListViewSubstractPoints(point, bounds.origin), CPDFListViewSubstractPoints(translateStartPoint, bounds.origin), CPDFListViewSubstractPoints(translateStartPoint, bounds.origin), delta) {
|
|
|
+ return shouldDisplay() && true
|
|
|
+ } else if CPDFListViewPointNearLineFromPointToPoint(CPDFListViewSubstractPoints(point, bounds.origin), CPDFListViewSubstractPoints(translateStartPoint, bounds.origin), CPDFListViewSubstractPoints(observedEndPoint(), bounds.origin), delta) {
|
|
|
+ return shouldDisplay() && true
|
|
|
+ }
|
|
|
+ return shouldDisplay() && false
|
|
|
+ } else {
|
|
|
+ return self.shouldDisplay() && CPDFListViewPointNearLineFromPointToPoint(CPDFListViewSubstractPoints(point, self.bounds.origin), CPDFListViewSubstractPoints(self.observedStartPoint(),self.bounds.origin), CPDFListViewSubstractPoints(self.observedEndPoint(),self.bounds.origin), delta)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
func observedStartPoint() -> NSPoint {
|
|
@@ -103,15 +124,36 @@ import Foundation
|
|
|
return CRectEdges(rawValue: 0)
|
|
|
}
|
|
|
let size = CPDFListViewMakeSquareSize(8 / scaleFactor)
|
|
|
- if (NSPointInRect(point, CPDFListViewRectFromCenterAndSize(self.endPoint, size))) {
|
|
|
- return .maxXEdgeMask
|
|
|
- } else if (NSPointInRect(point, CPDFListViewRectFromCenterAndSize(self.startPoint, size))) {
|
|
|
- return .minXEdgeMask
|
|
|
- } else if (self.hitTest(point)) {
|
|
|
- return .editInEdgeMask
|
|
|
- }
|
|
|
|
|
|
- return CRectEdges(rawValue: 0)
|
|
|
+ if (isMeasure) {
|
|
|
+ let translationDistance = measureInfo!.leadLength;
|
|
|
+ let normalVector = calculateNormalVector(startPoint: startPoint, endPoint: endPoint)
|
|
|
+ let startPoint = translate(point: startPoint, withNormalVector: normalVector, distance: translationDistance)
|
|
|
+ let endPoint = translate(point: endPoint, withNormalVector: normalVector, distance: translationDistance)
|
|
|
+ let midPoint = NSMakePoint((startPoint.x+endPoint.x)/2, (startPoint.y+endPoint.y)/2)
|
|
|
+
|
|
|
+ if (NSPointInRect(point, CPDFListViewRectFromCenterAndSize(endPoint, size))) {
|
|
|
+ return .maxXEdgeMask
|
|
|
+ } else if (NSPointInRect(point, CPDFListViewRectFromCenterAndSize(startPoint, size))) {
|
|
|
+ return .minXEdgeMask
|
|
|
+ } else if (NSPointInRect(point, CPDFListViewRectFromCenterAndSize(midPoint, size))) {
|
|
|
+ return .midEdgeMask
|
|
|
+ } else if (hitTest(point)) {
|
|
|
+ return .editInEdgeMask
|
|
|
+ } else {
|
|
|
+ return CRectEdges(rawValue: 0);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (NSPointInRect(point, CPDFListViewRectFromCenterAndSize(self.endPoint, size))) {
|
|
|
+ return .maxXEdgeMask;
|
|
|
+ } else if (NSPointInRect(point, CPDFListViewRectFromCenterAndSize(self.startPoint, size))) {
|
|
|
+ return .minXEdgeMask;
|
|
|
+ } else if (hitTest(point)) {
|
|
|
+ return .editInEdgeMask
|
|
|
+ } else {
|
|
|
+ return CRectEdges(rawValue: 0);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private static var _l_keys: Set<AnyHashable>?
|
|
@@ -449,266 +491,6 @@ extension CPDFLineAnnotation {
|
|
|
return rect
|
|
|
}
|
|
|
|
|
|
- /*
|
|
|
-
|
|
|
- static void (*original_drawWithBox_inContext)(id, SEL, PDFDisplayBox, CGContextRef) = NULL;
|
|
|
- static void (*original_setBounds)(id, SEL, NSRect) = NULL;
|
|
|
-
|
|
|
- static inline void addLineTipToPath(CGMutablePathRef path, NSPoint point, CGFloat angle, PDFLineStyle lineStyle, CGFloat lineWidth) {
|
|
|
- CGAffineTransform transform = CGAffineTransformRotate(CGAffineTransformMakeTranslation(point.x, point.y), angle);
|
|
|
- switch (lineStyle) {
|
|
|
- case kPDFLineStyleNone:
|
|
|
- return;
|
|
|
- case kPDFLineStyleSquare:
|
|
|
- CGPathAddRect(path, &transform, CGRectMake(-1.5 * lineWidth, -1.5 * lineWidth, 3.0 * lineWidth, 3.0 * lineWidth));
|
|
|
- break;
|
|
|
- case kPDFLineStyleCircle:
|
|
|
- CGPathAddEllipseInRect(path, &transform, CGRectMake(-1.5 * lineWidth, -1.5 * lineWidth, 3.0 * lineWidth, 3.0 * lineWidth));
|
|
|
- break;
|
|
|
- case kPDFLineStyleDiamond:
|
|
|
- CGPathMoveToPoint(path, &transform, 1.5 * lineWidth, 0.0);
|
|
|
- CGPathAddLineToPoint(path, &transform, 0.0, 1.5 * lineWidth);
|
|
|
- CGPathAddLineToPoint(path, &transform, -1.5 * lineWidth, 0.0);
|
|
|
- CGPathAddLineToPoint(path, &transform, 0.0, -1.5 * lineWidth);
|
|
|
- CGPathCloseSubpath(path);
|
|
|
- break;
|
|
|
- case kPDFLineStyleOpenArrow:
|
|
|
- CGPathMoveToPoint(path, &transform, -3.0 * lineWidth, 1.5 * lineWidth);
|
|
|
- CGPathAddLineToPoint(path, &transform, 0.0, 0.0);
|
|
|
- CGPathAddLineToPoint(path, &transform, -3.0 * lineWidth, -1.5 * lineWidth);
|
|
|
- break;
|
|
|
- case kPDFLineStyleClosedArrow:
|
|
|
- CGPathMoveToPoint(path, &transform, -3.0 * lineWidth, 1.5 * lineWidth);
|
|
|
- CGPathAddLineToPoint(path, &transform, 0.0, 0.0);
|
|
|
- CGPathAddLineToPoint(path, &transform, -3.0 * lineWidth, -1.5 * lineWidth);
|
|
|
- CGPathCloseSubpath(path);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- - (void)replacement_drawWithBox:(PDFDisplayBox)box inContext:(CGContextRef)context {
|
|
|
- if ([self hasAppearanceStream]) {
|
|
|
- original_drawWithBox_inContext(self, _cmd, box, context);
|
|
|
- } else {
|
|
|
- NSPoint origin = [self bounds].origin;
|
|
|
- NSPoint startPoint = SKAddPoints(origin, [self startPoint]);
|
|
|
- NSPoint endPoint = SKAddPoints(origin, [self endPoint]);
|
|
|
- CGFloat angle = atan2(endPoint.y - startPoint.y, endPoint.x - startPoint.x);
|
|
|
- CGFloat lineWidth = [self lineWidth];
|
|
|
- CGMutablePathRef path = CGPathCreateMutable();
|
|
|
- CGContextSaveGState(context);
|
|
|
- [[self page] transformContext:context forBox:box];
|
|
|
- CGContextSetStrokeColorWithColor(context, [[self color] CGColor]);
|
|
|
- CGContextSetLineWidth(context, lineWidth);
|
|
|
- CGContextSetLineJoin(context, kCGLineJoinRound);
|
|
|
- if ([self borderStyle] == kPDFBorderStyleDashed) {
|
|
|
- NSArray *dashPattern = [self dashPattern];
|
|
|
- NSInteger i, count = [dashPattern count];
|
|
|
- CGFloat dash[count];
|
|
|
- for (i = 0; i < count; i++)
|
|
|
- dash[i] = [[dashPattern objectAtIndex:i] doubleValue];
|
|
|
- CGContextSetLineDash(context, 0.0, dash, count);
|
|
|
- CGContextSetLineCap(context, kCGLineCapButt);
|
|
|
- } else {
|
|
|
- CGContextSetLineCap(context, kCGLineCapRound);
|
|
|
- }
|
|
|
- CGPathMoveToPoint(path, NULL, startPoint.x, startPoint.y);
|
|
|
- CGPathAddLineToPoint(path, NULL, endPoint.x, endPoint.y);
|
|
|
- if ([self startLineStyle] != kPDFLineStyleNone)
|
|
|
- addLineTipToPath(path, startPoint, angle + M_PI, [self startLineStyle], lineWidth);
|
|
|
- if ([self endLineStyle] != kPDFLineStyleNone)
|
|
|
- addLineTipToPath(path, endPoint, angle, [self endLineStyle], lineWidth);
|
|
|
- CGContextBeginPath(context);
|
|
|
- CGContextAddPath(context, path);
|
|
|
- CGPathRelease(path);
|
|
|
- CGContextStrokePath(context);
|
|
|
- CGContextRestoreGState(context);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- - (void)replacement_setBounds:(NSRect)newBounds {
|
|
|
- NSPoint startPoint = [self startPoint];
|
|
|
- NSPoint endPoint = [self endPoint];
|
|
|
- original_setBounds(self, _cmd, newBounds);
|
|
|
- [self setStartPoint:startPoint];
|
|
|
- [self setEndPoint:endPoint];
|
|
|
- }
|
|
|
-
|
|
|
- + (void)load {
|
|
|
- if (RUNNING(10_11))
|
|
|
- original_drawWithBox_inContext = (void (*)(id, SEL, PDFDisplayBox, CGContextRef))SKReplaceInstanceMethodImplementationFromSelector(self, @selector(drawWithBox:inContext:), @selector(replacement_drawWithBox:inContext:));
|
|
|
- if (RUNNING(10_13))
|
|
|
- original_setBounds = (void (*)(id, SEL, NSRect))SKReplaceInstanceMethodImplementationFromSelector(self, @selector(setBounds:), @selector(replacement_setBounds:));
|
|
|
- }
|
|
|
-
|
|
|
- - (id)initSkimNoteWithBounds:(NSRect)bounds {
|
|
|
- self = [super initSkimNoteWithBounds:bounds];
|
|
|
- if (self) {
|
|
|
- [self setColor:[[NSUserDefaults standardUserDefaults] colorForKey:SKLineNoteColorKey]];
|
|
|
- NSColor *color = [[NSUserDefaults standardUserDefaults] colorForKey:SKLineNoteInteriorColorKey];
|
|
|
- if ([color alphaComponent] > 0.0)
|
|
|
- [self setInteriorColor:color];
|
|
|
- [self setStartLineStyle:[[NSUserDefaults standardUserDefaults] integerForKey:SKLineNoteStartLineStyleKey]];
|
|
|
- [self setEndLineStyle:[[NSUserDefaults standardUserDefaults] integerForKey:SKLineNoteEndLineStyleKey]];
|
|
|
- [self setStartPoint:NSMakePoint(0.0, 0.0)];
|
|
|
- [self setEndPoint:NSMakePoint(NSWidth(bounds), NSHeight(bounds))];
|
|
|
- PDFBorder *border = [[PDFBorder allocWithZone:[self zone]] init];
|
|
|
- [border setLineWidth:[[NSUserDefaults standardUserDefaults] floatForKey:SKLineNoteLineWidthKey]];
|
|
|
- [border setDashPattern:[[NSUserDefaults standardUserDefaults] arrayForKey:SKLineNoteDashPatternKey]];
|
|
|
- [border setStyle:[[NSUserDefaults standardUserDefaults] floatForKey:SKLineNoteLineStyleKey]];
|
|
|
- [self setBorder:[border lineWidth] > 0.0 ? border : nil];
|
|
|
- [border release];
|
|
|
- }
|
|
|
- return self;
|
|
|
- }
|
|
|
-
|
|
|
- - (BOOL)isResizable { return [self isSkimNote]; }
|
|
|
- - (BOOL)isMovable { return [self isSkimNote]; }
|
|
|
-
|
|
|
- - (BOOL)hitTest:(NSPoint)point {
|
|
|
- CGFloat delta = fmax(4.0, 0.5 * [self lineWidth]);
|
|
|
- return [self shouldDisplay] && SKPointNearLineFromPointToPoint(SKSubstractPoints(point, [self bounds].origin), [self startPoint], [self endPoint], delta);
|
|
|
- }
|
|
|
-
|
|
|
- - (CGFloat)boundsOrder {
|
|
|
- CGFloat delta = ceil(fmax(4.0 * [self lineWidth], 4.0));
|
|
|
- NSPoint origin = [self bounds].origin;
|
|
|
- NSRect startBounds = SKRectFromCenterAndSquareSize(SKAddPoints(origin, [self startPoint]), delta);
|
|
|
- NSRect endBounds = SKRectFromCenterAndSquareSize(SKAddPoints(origin, [self endPoint]), delta);
|
|
|
- PDFPage *page = [self page];
|
|
|
- return fmin([page sortOrderForBounds:startBounds], [page sortOrderForBounds:endBounds]);
|
|
|
- }
|
|
|
-
|
|
|
- - (SKRectEdges)resizeHandleForPoint:(NSPoint)point scaleFactor:(CGFloat)scaleFactor {
|
|
|
- if ([self isResizable] == NO)
|
|
|
- return 0;
|
|
|
- NSSize size = SKMakeSquareSize(8.0 / scaleFactor);
|
|
|
- point = SKSubstractPoints(point, [self bounds].origin);
|
|
|
- if (NSPointInRect(point, SKRectFromCenterAndSize([self endPoint], size)))
|
|
|
- return SKMaxXEdgeMask;
|
|
|
- else if (NSPointInRect(point, SKRectFromCenterAndSize([self startPoint], size)))
|
|
|
- return SKMinXEdgeMask;
|
|
|
- else
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- - (void)drawSelectionHighlightForView:(PDFView *)pdfView inContext:(CGContextRef)context {
|
|
|
- if (NSIsEmptyRect([self bounds]))
|
|
|
- return;
|
|
|
- BOOL active = RUNNING_AFTER(10_12) ? YES : [[pdfView window] isKeyWindow] && [[[pdfView window] firstResponder] isDescendantOf:pdfView];
|
|
|
- NSPoint origin = [self bounds].origin;
|
|
|
- NSPoint point = SKAddPoints(origin, [self startPoint]);
|
|
|
- CGFloat delta = 4.0 * [pdfView unitWidthOnPage:[self page]];
|
|
|
- SKDrawResizeHandle(context, point, delta, active);
|
|
|
- point = SKAddPoints(origin, [self endPoint]);
|
|
|
- SKDrawResizeHandle(context, point, delta, active);
|
|
|
- }
|
|
|
-
|
|
|
- - (NSSet *)keysForValuesToObserveForUndo {
|
|
|
- static NSSet *lineKeys = nil;
|
|
|
- if (lineKeys == nil) {
|
|
|
- NSMutableSet *mutableKeys = [[super keysForValuesToObserveForUndo] mutableCopy];
|
|
|
- [mutableKeys addObject:SKNPDFAnnotationStartLineStyleKey];
|
|
|
- [mutableKeys addObject:SKNPDFAnnotationEndLineStyleKey];
|
|
|
- [mutableKeys addObject:SKPDFAnnotationObservedStartPointKey];
|
|
|
- [mutableKeys addObject:SKPDFAnnotationObservedEndPointKey];
|
|
|
- [mutableKeys addObject:SKNPDFAnnotationInteriorColorKey];
|
|
|
- lineKeys = [mutableKeys copy];
|
|
|
- [mutableKeys release];
|
|
|
- }
|
|
|
- return lineKeys;
|
|
|
- }
|
|
|
-
|
|
|
- #pragma mark Scripting support
|
|
|
-
|
|
|
- + (NSSet *)customScriptingKeys {
|
|
|
- static NSSet *customLineScriptingKeys = nil;
|
|
|
- if (customLineScriptingKeys == nil) {
|
|
|
- NSMutableSet *customKeys = [[super customScriptingKeys] mutableCopy];
|
|
|
- [customKeys addObject:SKPDFAnnotationStartPointAsQDPointKey];
|
|
|
- [customKeys addObject:SKPDFAnnotationEndPointAsQDPointKey];
|
|
|
- [customKeys addObject:SKPDFAnnotationScriptingStartLineStyleKey];
|
|
|
- [customKeys addObject:SKPDFAnnotationScriptingEndLineStyleKey];
|
|
|
- [customKeys addObject:SKPDFAnnotationScriptingInteriorColorKey];
|
|
|
- customLineScriptingKeys = [customKeys copy];
|
|
|
- [customKeys release];
|
|
|
- }
|
|
|
- return customLineScriptingKeys;
|
|
|
- }
|
|
|
-
|
|
|
- - (void)setStartPointAsQDPoint:(NSData *)inQDPointAsData {
|
|
|
- if ([self isEditable] && inQDPointAsData && [inQDPointAsData isEqual:[NSNull null]] == NO) {
|
|
|
- NSPoint startPoint = [inQDPointAsData pointValueAsQDPoint];
|
|
|
-
|
|
|
- NSRect bounds = [self bounds];
|
|
|
- NSPoint endPoint = SKIntegralPoint(SKAddPoints([self endPoint], bounds.origin));
|
|
|
-
|
|
|
- bounds = SKIntegralRectFromPoints(startPoint, endPoint);
|
|
|
-
|
|
|
- if (NSWidth(bounds) < 8.0) {
|
|
|
- bounds.size.width = 8.0;
|
|
|
- bounds.origin.x = floor(0.5 * (startPoint.x + endPoint.x) - 4.0);
|
|
|
- }
|
|
|
- if (NSHeight(bounds) < 8.0) {
|
|
|
- bounds.size.height = 8.0;
|
|
|
- bounds.origin.y = floor(0.5 * (startPoint.y + endPoint.y) - 4.0);
|
|
|
- }
|
|
|
-
|
|
|
- startPoint = SKSubstractPoints(startPoint, bounds.origin);
|
|
|
- endPoint = SKSubstractPoints(endPoint, bounds.origin);
|
|
|
-
|
|
|
- [self setBounds:bounds];
|
|
|
- [self setObservedStartPoint:startPoint];
|
|
|
- [self setObservedEndPoint:endPoint];
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- - (NSData *)startPointAsQDPoint {
|
|
|
- NSRect bounds = [self bounds];
|
|
|
- NSPoint startPoint = SKAddPoints([self startPoint], bounds.origin);
|
|
|
- startPoint.x = floor(startPoint.x);
|
|
|
- startPoint.y = floor(startPoint.y);
|
|
|
- return [NSData dataWithPointAsQDPoint:startPoint];
|
|
|
- }
|
|
|
-
|
|
|
- - (void)setEndPointAsQDPoint:(NSData *)inQDPointAsData {
|
|
|
- if ([self isEditable] && inQDPointAsData && [inQDPointAsData isEqual:[NSNull null]] == NO) {
|
|
|
- NSPoint endPoint = [inQDPointAsData pointValueAsQDPoint];
|
|
|
-
|
|
|
- NSRect bounds = [self bounds];
|
|
|
- NSPoint startPoint = SKIntegralPoint(SKAddPoints([self startPoint], bounds.origin));
|
|
|
-
|
|
|
- bounds = SKIntegralRectFromPoints(startPoint, endPoint);
|
|
|
-
|
|
|
- if (NSWidth(bounds) < 8.0) {
|
|
|
- bounds.size.width = 8.0;
|
|
|
- bounds.origin.x = floor(0.5 * (startPoint.x + endPoint.x) - 4.0);
|
|
|
- }
|
|
|
- if (NSHeight(bounds) < 8.0) {
|
|
|
- bounds.size.height = 8.0;
|
|
|
- bounds.origin.y = floor(0.5 * (startPoint.y + endPoint.y) - 4.0);
|
|
|
- }
|
|
|
-
|
|
|
- startPoint = SKSubstractPoints(startPoint, bounds.origin);
|
|
|
- endPoint = SKSubstractPoints(endPoint, bounds.origin);
|
|
|
-
|
|
|
- [self setBounds:bounds];
|
|
|
- [self setObservedStartPoint:startPoint];
|
|
|
- [self setObservedEndPoint:endPoint];
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- - (NSData *)endPointAsQDPoint {
|
|
|
- NSRect bounds = [self bounds];
|
|
|
- NSPoint endPoint = SKAddPoints([self endPoint], bounds.origin);
|
|
|
- endPoint.x = floor(endPoint.x);
|
|
|
- endPoint.y = floor(endPoint.y);
|
|
|
- return [NSData dataWithPointAsQDPoint:endPoint];
|
|
|
- }
|
|
|
- */
|
|
|
-
|
|
|
override func colorDefaultKey() -> String? {
|
|
|
return KMLineNoteColorKey
|
|
|
}
|