|
@@ -297,40 +297,14 @@ class CPDFAnnotationMarkupExtraIvars: NSObject {
|
|
|
@objc extension CPDFMarkupAnnotation {
|
|
|
/*
|
|
|
NSString *SKPDFAnnotationSelectionSpecifierKey = @"selectionSpecifier";
|
|
|
-
|
|
|
@interface SKPDFAnnotationMarkupExtraIvars : NSObject {
|
|
|
- NSPointerArray *lineRects;
|
|
|
- NSString *textString;
|
|
|
SKNoteText *noteText;
|
|
|
}
|
|
|
- @property (nonatomic, retain) NSPointerArray *lineRects;
|
|
|
- @property (nonatomic, retain) NSString *textString;
|
|
|
@property (nonatomic, retain) SKNoteText *noteText;
|
|
|
@end
|
|
|
|
|
|
- @implementation SKPDFAnnotationMarkupExtraIvars
|
|
|
- @synthesize lineRects, textString, noteText;
|
|
|
- - (void)dealloc {
|
|
|
- SKDESTROY(lineRects);
|
|
|
- SKDESTROY(textString);
|
|
|
- SKDESTROY(noteText);
|
|
|
- [super dealloc];
|
|
|
- }
|
|
|
- @end
|
|
|
-
|
|
|
- #pragma mark -
|
|
|
-
|
|
|
@implementation PDFAnnotationMarkup (SKExtensions)
|
|
|
|
|
|
- /*
|
|
|
- http://www.cocoabuilder.com/archive/message/cocoa/2007/2/16/178891
|
|
|
- The docs are wrong (as is Adobe's spec). The ordering on the rotated page is:
|
|
|
- --------
|
|
|
- | 0 1 |
|
|
|
- | 2 3 |
|
|
|
- --------
|
|
|
- */
|
|
|
-
|
|
|
static void addQuadPointsWithBounds(NSMutableArray *quadPoints, const NSRect bounds, const NSPoint origin, NSInteger rotation)
|
|
|
{
|
|
|
rotation = rotation%360;
|
|
@@ -457,20 +431,6 @@ class CPDFAnnotationMarkupExtraIvars: NSObject {
|
|
|
return self;
|
|
|
}
|
|
|
|
|
|
- - (NSString *)fdfString {
|
|
|
- NSMutableString *fdfString = [[[super fdfString] mutableCopy] autorelease];
|
|
|
- NSPoint point;
|
|
|
- NSRect bounds = [self bounds];
|
|
|
- [fdfString appendFDFName:SKFDFAnnotationQuadrilateralPointsKey];
|
|
|
- [fdfString appendString:@"["];
|
|
|
- for (NSValue *value in [self quadrilateralPoints]) {
|
|
|
- point = [value pointValue];
|
|
|
- [fdfString appendFormat:@"%f %f ", point.x + NSMinX(bounds), point.y + NSMinY(bounds)];
|
|
|
- }
|
|
|
- [fdfString appendString:@"]"];
|
|
|
- return fdfString;
|
|
|
- }
|
|
|
-
|
|
|
- (NSPointerArray *)lineRects {
|
|
|
SKPDFAnnotationMarkupExtraIvars *extraIvars = [self extraIvars];
|
|
|
NSPointerArray *lineRects = [extraIvars lineRects];
|
|
@@ -516,21 +476,6 @@ class CPDFAnnotationMarkupExtraIvars: NSObject {
|
|
|
return lineRects;
|
|
|
}
|
|
|
|
|
|
- - (PDFSelection *)selection {
|
|
|
- NSMutableArray *selections = [NSMutableArray array];
|
|
|
- NSPointerArray *lines = [self lineRects];
|
|
|
- NSUInteger i, iMax = [lines count];
|
|
|
- CGFloat outset = RUNNING_AFTER(10_6) ? -1.0 : 0.0;
|
|
|
-
|
|
|
- for (i = 0; i < iMax; i++) {
|
|
|
- // slightly outset the rect to avoid rounding errors, as selectionForRect is pretty strict in some OS versions, but unfortunately not in others
|
|
|
- PDFSelection *selection = [[self page] selectionForRect:NSInsetRect([lines rectAtIndex:i], outset, outset)];
|
|
|
- if ([selection hasCharacters])
|
|
|
- [selections addObject:selection];
|
|
|
- }
|
|
|
- return [PDFSelection selectionByAddingSelections:selections];
|
|
|
- }
|
|
|
-
|
|
|
- (BOOL)hitTest:(NSPoint)point {
|
|
|
if ([super hitTest:point] == NO)
|
|
|
return NO;
|
|
@@ -551,15 +496,6 @@ class CPDFAnnotationMarkupExtraIvars: NSObject {
|
|
|
return [[self page] sortOrderForBounds:bounds];
|
|
|
}
|
|
|
|
|
|
- - (NSRect)displayRectForBounds:(NSRect)bounds lineWidth:(CGFloat)lineWidth {
|
|
|
- bounds = [super displayRectForBounds:bounds lineWidth:lineWidth];
|
|
|
- if ([self markupType] == kPDFMarkupTypeHighlight) {
|
|
|
- CGFloat delta = -0.03 * NSHeight(bounds);
|
|
|
- bounds = ([[self page] intrinsicRotation] % 180) == 0 ? NSInsetRect(bounds, 0.0, delta) : NSInsetRect(bounds, delta, 0.0);
|
|
|
- }
|
|
|
- return bounds;
|
|
|
- }
|
|
|
-
|
|
|
- (void)drawSelectionHighlightForView:(PDFView *)pdfView inContext:(CGContextRef)context {
|
|
|
if (NSIsEmptyRect([self bounds]))
|
|
|
return;
|
|
@@ -581,14 +517,6 @@ class CPDFAnnotationMarkupExtraIvars: NSObject {
|
|
|
CGContextRestoreGState(context);
|
|
|
}
|
|
|
|
|
|
- - (BOOL)isMarkup { return YES; }
|
|
|
-
|
|
|
- - (BOOL)hasBorder { return NO; }
|
|
|
-
|
|
|
- - (BOOL)isConvertibleAnnotation { return YES; }
|
|
|
-
|
|
|
- - (BOOL)hasNoteText { return [self isEditable]; }
|
|
|
-
|
|
|
- (SKNoteText *)noteText {
|
|
|
if ([self isEditable] == NO)
|
|
|
return nil;
|
|
@@ -602,35 +530,6 @@ class CPDFAnnotationMarkupExtraIvars: NSObject {
|
|
|
return noteText;
|
|
|
}
|
|
|
|
|
|
- - (NSString *)textString {
|
|
|
- if ([[self page] pageRef] == NULL)
|
|
|
- return nil;
|
|
|
- SKPDFAnnotationMarkupExtraIvars *extraIvars = [self extraIvars];
|
|
|
- NSString *textString = [extraIvars textString];
|
|
|
- if (textString == nil) {
|
|
|
- textString = [[self selection] cleanedString] ?: @"";
|
|
|
- [extraIvars setTextString:textString];
|
|
|
- }
|
|
|
- return textString;
|
|
|
- }
|
|
|
-
|
|
|
- - (NSString *)colorDefaultKey {
|
|
|
- switch ([self markupType]) {
|
|
|
- case kPDFMarkupTypeUnderline: return SKUnderlineNoteColorKey;
|
|
|
- case kPDFMarkupTypeStrikeOut: return SKStrikeOutNoteColorKey;
|
|
|
- case kPDFMarkupTypeHighlight: return SKHighlightNoteColorKey;
|
|
|
- }
|
|
|
- return nil;
|
|
|
- }
|
|
|
-
|
|
|
- - (void)autoUpdateString {
|
|
|
- if ([[NSUserDefaults standardUserDefaults] boolForKey:SKDisableUpdateContentsFromEnclosedTextKey])
|
|
|
- return;
|
|
|
- NSString *selString = [self textString];
|
|
|
- if ([selString length])
|
|
|
- [self setString:selString];
|
|
|
- }
|
|
|
-
|
|
|
- (NSSet *)keysForValuesToObserveForUndo {
|
|
|
static NSSet *markupKeys = nil;
|
|
|
if (markupKeys == nil) {
|
|
@@ -681,5 +580,118 @@ class CPDFAnnotationMarkupExtraIvars: NSObject {
|
|
|
}
|
|
|
return pointLists;
|
|
|
}
|
|
|
+
|
|
|
*/
|
|
|
+
|
|
|
+ override func displayRectForBounds(_ bounds: NSRect, lineWidth: CGFloat) -> NSRect {
|
|
|
+ var rect = super.displayRectForBounds(bounds, lineWidth: lineWidth)
|
|
|
+ if self.markupType() == .highlight {
|
|
|
+ let delta = -0.03 * NSHeight(rect)
|
|
|
+// bounds = ([[self page] intrinsicRotation] % 180) == 0 ? NSInsetRect(bounds, 0.0, delta) : NSInsetRect(bounds, delta, 0.0);
|
|
|
+ if let page = self.page {
|
|
|
+ if page.rotation % 180 == 0 {
|
|
|
+ rect = NSInsetRect(rect, 0.0, delta)
|
|
|
+ } else {
|
|
|
+ rect = NSInsetRect(rect, delta, 0.0)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ rect = NSInsetRect(rect, 0.0, delta)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return rect
|
|
|
+ }
|
|
|
+
|
|
|
+ override func fdfString() -> String {
|
|
|
+ var fdfString = super.fdfString()
|
|
|
+ var point: NSPoint = .zero
|
|
|
+ let bounds = self.bounds
|
|
|
+ fdfString = fdfString.appendFDFName(SKFDFAnnotationQuadrilateralPointsKey)
|
|
|
+ fdfString.append("[")
|
|
|
+
|
|
|
+ let points = self.quadrilateralPoints ?? []
|
|
|
+ for value in points {
|
|
|
+// for (NSValue *value in [self quadrilateralPoints]) {
|
|
|
+ if let data = value as? NSValue {
|
|
|
+ point = data.pointValue
|
|
|
+ fdfString = fdfString.appendingFormat("%f %f ", point.x + NSMinX(bounds), point.y + NSMinY(bounds))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ fdfString.append("]")
|
|
|
+ return fdfString
|
|
|
+ }
|
|
|
+
|
|
|
+ func selection() -> CPDFSelection? {
|
|
|
+ var selections = NSMutableArray()
|
|
|
+ let lines = self.lineRects()
|
|
|
+ var iMax = lines?.count ?? 0
|
|
|
+// CGFloat outset = RUNNING_AFTER(10_6) ? -1.0 : 0.0;
|
|
|
+ let outset = -1.0
|
|
|
+
|
|
|
+ for i in 0 ..< iMax {
|
|
|
+ // slightly outset the rect to avoid rounding errors, as selectionForRect is pretty strict in some OS versions, but unfortunately not in others
|
|
|
+ let rect = lines!.rect(at: UInt(i))
|
|
|
+ let page = self.page
|
|
|
+ guard let selection = page?.selection(for: NSInsetRect(rect, outset, outset)) else {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if selection.hasCharacters() {
|
|
|
+ selections.add(selection)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return CPDFSelection.selectionByAddingSelections(selections)
|
|
|
+ }
|
|
|
+
|
|
|
+ override func textString() -> String? {
|
|
|
+ let page = self.page
|
|
|
+ if page == nil {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+// if ([[self page] pageRef] == NULL)
|
|
|
+// return nil;
|
|
|
+
|
|
|
+ let extraIvars = self.extraIvars()
|
|
|
+ var textString = extraIvars?.textString
|
|
|
+ if textString == nil {
|
|
|
+ textString = self.selection()?.PDFListViewCleanedString()
|
|
|
+ extraIvars?.textString = textString ?? ""
|
|
|
+ }
|
|
|
+ return textString
|
|
|
+ }
|
|
|
+ override func colorDefaultKey() -> String? {
|
|
|
+ let type = self.markupType()
|
|
|
+ if type == .highlight {
|
|
|
+ return SKHighlightNoteColorKey
|
|
|
+ } else if type == .strikeOut {
|
|
|
+ return SKStrikeOutNoteColorKey
|
|
|
+ } else if type == .underline {
|
|
|
+ return SKUnderlineNoteColorKey
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ override func autoUpdateString() {
|
|
|
+ if UserDefaults.standard.bool(forKey: SKDisableUpdateContentsFromEnclosedTextKey) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if let selString = self.textString(), selString.isEmpty == false {
|
|
|
+ self.setString(selString)
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ override func isMarkup() -> Bool {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+
|
|
|
+ override func hasBorder() -> Bool {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+
|
|
|
+ override func isConvertibleAnnotation() -> Bool {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+
|
|
|
+ override func hasNoteText() -> Bool {
|
|
|
+ return self.isEditable()
|
|
|
+ }
|
|
|
}
|