Revision: 16538
http://sourceforge.net/p/skim-app/code/16538
Author: hofman
Date: 2026-09-26 21:41:10 +0000 (Sat, 26 Sep 2026)
Log Message:
-----------
implement custom support methods in PDFAnnotation class rather than in legacy
subclasses
Modified Paths:
--------------
trunk/PDFAnnotation_SKExtensions.h
trunk/PDFAnnotation_SKExtensions.m
trunk/SKMainDocument.m
trunk/SKNPDFAnnotationNote_SKExtensions.m
trunk/SKPDFView.m
trunk/Skim.xcodeproj/project.pbxproj
Modified: trunk/PDFAnnotation_SKExtensions.h
===================================================================
--- trunk/PDFAnnotation_SKExtensions.h 2026-09-24 08:24:03 UTC (rev 16537)
+++ trunk/PDFAnnotation_SKExtensions.h 2026-09-26 21:41:10 UTC (rev 16538)
@@ -43,11 +43,21 @@
NS_ASSUME_NONNULL_BEGIN
+extern NSString * const SKPDFAnnotationBezierPathsKey;
+
extern NSString * const SKPDFAnnotationScriptingColorKey;
extern NSString * const SKPDFAnnotationScriptingModificationDateKey;
extern NSString * const SKPDFAnnotationScriptingUserNameKey;
extern NSString * const SKPDFAnnotationScriptingTextContentsKey;
extern NSString * const SKPDFAnnotationScriptingInteriorColorKey;
+extern NSString * const SKPDFAnnotationScriptingFontColorKey;
+extern NSString * const SKPDFAnnotationScriptingAlignmentKey;
+extern NSString * const SKPDFAnnotationStartPointAsQDPointKey;
+extern NSString * const SKPDFAnnotationEndPointAsQDPointKey;
+extern NSString * const SKPDFAnnotationScriptingStartLineStyleKey;
+extern NSString * const SKPDFAnnotationScriptingEndLineStyleKey;
+extern NSString * const SKPDFAnnotationScriptingPointListsKey;
+extern NSString * const SKPDFAnnotationSelectionSpecifierKey;
extern NSString * const SKPDFAnnotationBoundsOrderKey;
@@ -127,7 +137,6 @@
@property (nonatomic, readonly) NSSet *keysForValuesToObserveForUndo;
-@property (class, nonatomic, readonly) NSSet *customScriptingKeys;
@property (nonatomic, readonly) NSScriptObjectSpecifier *objectSpecifier;
@property (nonatomic, nullable, copy) NSColor *scriptingColor;
@property (nonatomic, nullable, readonly) PDFPage *scriptingPage;
@@ -138,15 +147,15 @@
@property (nonatomic, nullable, copy) id textContents;
@property (nonatomic, nullable, readonly) id richText;
@property (nonatomic, copy) NSData *boundsAsQDRect;
-@property (nonatomic, readonly) NSInteger scriptingAlignment;
-@property (nonatomic, nullable, readonly) NSString *fontName;
-@property (nonatomic, readonly) CGFloat fontSize;
-@property (nonatomic, nullable, readonly) NSColor *scriptingFontColor;
-@property (nonatomic, nullable, readonly) NSColor *scriptingInteriorColor;
-@property (nonatomic, nullable, readonly) NSData *startPointAsQDPoint;
-@property (nonatomic, nullable, readonly) NSData *endPointAsQDPoint;
-@property (nonatomic, readonly) PDFLineStyle scriptingStartLineStyle;
-@property (nonatomic, readonly) PDFLineStyle scriptingEndLineStyle;
+@property (nonatomic) NSInteger scriptingAlignment;
+@property (nonatomic, nullable) NSString *fontName;
+@property (nonatomic) CGFloat fontSize;
+@property (nonatomic, nullable) NSColor *scriptingFontColor;
+@property (nonatomic, nullable) NSColor *scriptingInteriorColor;
+@property (nonatomic, nullable) NSData *startPointAsQDPoint;
+@property (nonatomic, nullable) NSData *endPointAsQDPoint;
+@property (nonatomic) PDFLineStyle scriptingStartLineStyle;
+@property (nonatomic) PDFLineStyle scriptingEndLineStyle;
@property (nonatomic, nullable, readonly) id selectionSpecifier;
@property (nonatomic, nullable, readonly) NSArray<NSArray<NSData *> *>
*scriptingPointLists;
Modified: trunk/PDFAnnotation_SKExtensions.m
===================================================================
--- trunk/PDFAnnotation_SKExtensions.m 2026-09-24 08:24:03 UTC (rev 16537)
+++ trunk/PDFAnnotation_SKExtensions.m 2026-09-26 21:41:10 UTC (rev 16538)
@@ -37,13 +37,6 @@
*/
#import "PDFAnnotation_SKExtensions.h"
-#import "PDFAnnotationCircle_SKExtensions.h"
-#import "PDFAnnotationSquare_SKExtensions.h"
-#import "PDFAnnotationLine_SKExtensions.h"
-#import "PDFAnnotationMarkup_SKExtensions.h"
-#import "PDFAnnotationFreeText_SKExtensions.h"
-#import "PDFAnnotationText_SKExtensions.h"
-#import "PDFAnnotationInk_SKExtensions.h"
#import "SKNPDFAnnotationNote_SKExtensions.h"
#import "SKStringConstants.h"
#import "SKFDFParser.h"
@@ -62,7 +55,13 @@
#import "SKNoteText.h"
#import "PDFView_SKExtensions.h"
#import "NSDate_SKExtensions.h"
+#import "NSPointerArray_SKExtensions.h"
+#import "NSShadow_SKExtensions.h"
+#import "NSCharacterSet_SKExtensions.h"
+#import "SKRuntime.h"
+#import <objc/objc-runtime.h>
+NSString * const SKPDFAnnotationBezierPathsKey = @"bezierPaths";
NSString * const SKPDFAnnotationScriptingColorKey = @"scriptingColor";
NSString * const SKPDFAnnotationScriptingModificationDateKey =
@"scriptingModificationDate";
@@ -69,14 +68,138 @@
NSString * const SKPDFAnnotationScriptingUserNameKey = @"scriptingUserName";
NSString * const SKPDFAnnotationScriptingTextContentsKey = @"textContents";
NSString * const SKPDFAnnotationScriptingInteriorColorKey =
@"scriptingInteriorColor";
+NSString * const SKPDFAnnotationScriptingFontColorKey = @"scriptingFontColor";
+NSString * const SKPDFAnnotationScriptingAlignmentKey = @"scriptingAlignment";
+NSString * const SKPDFAnnotationStartPointAsQDPointKey =
@"startPointAsQDPoint";
+NSString * const SKPDFAnnotationEndPointAsQDPointKey = @"endPointAsQDPoint";
+NSString * const SKPDFAnnotationScriptingStartLineStyleKey =
@"scriptingStartLineStyle";
+NSString * const SKPDFAnnotationScriptingEndLineStyleKey =
@"scriptingEndLineStyle";
+NSString * const SKPDFAnnotationScriptingPointListsKey =
@"scriptingPointLists";
+NSString * const SKPDFAnnotationSelectionSpecifierKey = @"selectionSpecifier";
NSString * const SKPDFAnnotationBoundsOrderKey = @"boundsOrder";
NSPasteboardType const SKPasteboardTypeSkimNote =
@"net.sourceforge.skim-app.pasteboard.skimnote";
+static char SKLineRectsKey;
+static char SKTextStringKey;
+static char SKNoteTextKey;
+/*
+ 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 NSArray *quadPointsForLineRects(NSPointerArray *lines, NSPoint origin,
NSInteger lineDirection) {
+ NSMutableArray *quadPoints = [[NSMutableArray alloc] init];
+ NSUInteger i, iMax = [lines count];
+ for (i = 0; i < iMax; i++) {
+ static NSInteger offset[4] = {0, 1, 3, 2};
+ NSRect r = NSOffsetRect([lines rectAtIndex:i], -origin.x, -origin.y);
+ NSInteger j = lineDirection;
+ NSPoint p[4];
+ memset(&p, 0, 4 * sizeof(NSPoint));
+ p[offset[j]] = SKBottomLeftPoint(r);
+ p[offset[++j%4]] = SKTopLeftPoint(r);
+ p[offset[++j%4]] = SKTopRightPoint(r);
+ p[offset[++j%4]] = SKBottomRightPoint(r);
+ for (j = 0; j < 4; j++)
+ [quadPoints addObject:[NSValue valueWithPoint:p[j]]];
+ }
+ return quadPoints;
+}
+
+static NSPointerArray *lineRectsForQuadPoints(NSArray *quadPoints, NSPoint
origin) {
+ NSPointerArray *lineRects = [[NSPointerArray alloc] initForRectPointers];
+ NSUInteger j, jMax = [quadPoints count] / 4;
+ NSRange range = NSMakeRange(0, 4);
+ for (j = 0; j < jMax; j++) {
+ range.location = 4 * j;
+ NSPoint point;
+ NSUInteger i;
+ CGFloat minX = CGFLOAT_MAX, maxX = -CGFLOAT_MAX, minY = CGFLOAT_MAX,
maxY = -CGFLOAT_MAX;
+ for (i = 0; i < 4; i++) {
+ point = [[quadPoints objectAtIndex:4 * j + i] pointValue];
+ minX = fmin(minX, point.x);
+ maxX = fmax(maxX, point.x);
+ minY = fmin(minY, point.y);
+ maxY = fmax(maxY, point.y);
+ }
+ NSRect lineRect = NSMakeRect(origin.x + minX, origin.y + minY, maxX -
minX, maxY - minY);
+ [lineRects addPointer:&lineRect];
+ }
+ return lineRects;
+}
+
+// NSTextAlignment enum values depend on the architecture, on arm64 right=2
and center=1
+static inline NSTextAlignment textAlignmentFromAlignment(NSInteger alignment) {
+ switch (alignment) {
+ case 0: return NSTextAlignmentLeft;
+ case 1: return NSTextAlignmentRight;
+ case 2: return NSTextAlignmentCenter;
+ default: return NSTextAlignmentLeft;
+ }
+}
+
+static inline NSInteger alignmentFromTextAlignment(NSTextAlignment alignment) {
+ switch (alignment) {
+ case NSTextAlignmentLeft: return 0;
+ case NSTextAlignmentRight: return 1;
+ case NSTextAlignmentCenter: return 2;
+ default: return 0;
+ }
+}
+
@implementation PDFAnnotation (SKExtensions)
+static CGAffineTransform (*CGContextGetBaseCTM_func)(CGContextRef) = NULL;
+
+static void (*original_setColor)(id, SEL, id) = NULL;
+static void (*original_setBounds)(id, SEL, NSRect) = NULL;
+
+// PDFView raises an exception when a highlight has a sRGB black color
+static void replacement_setColor(id self, SEL _cmd, NSColor *color) {
+ if ([[(PDFAnnotation *)self type] isEqualToString:SKNHighlightString]) {
+ static NSColor *blackColor = nil;
+ if (blackColor == nil)
+ blackColor = [NSColor colorWithSRGBRed:0.0 green:0.0 blue:0.0
alpha:1.0];
+ if ([color isEqual:blackColor])
+ color = [NSColor blackColor];
+ }
+ original_setColor(self, _cmd, color);
+}
+
+static void replacement_setBounds(id self, SEL _cmd , NSRect newBounds) {
+ if ([[(PDFAnnotation *)self type] isEqualToString:SKNLineString]) {
+ NSArray *points = [self
valueForAnnotationKey:PDFAnnotationKeyLinePoints];
+ if ([points isKindOfClass:[NSArray class]] && [points count] == 4) {
+ NSPoint d = SKSubstractPoints(newBounds.origin, [self
bounds].origin);
+ if (NSEqualPoints(d, NSZeroPoint))
+ points = nil;
+ else
+ points = @[@([points[0] doubleValue] + d.x), @([points[1]
doubleValue] + d.y), @([points[2] doubleValue] + d.x), @([points[3]
doubleValue] + d.y)];
+ } else if (points) {
+ points = nil;
+ }
+ original_setBounds(self, _cmd, newBounds);
+ if (points)
+ [self setValue:points forAnnotationKey:PDFAnnotationKeyLinePoints];
+ } else {
+ original_setBounds(self, _cmd, newBounds);
+ }
+}
+
++ (void)load {
+ CGContextGetBaseCTM_func =
(typeof(CGContextGetBaseCTM_func))CFBundleGetFunctionPointerForName(CFBundleGetBundleWithIdentifier(CFSTR("com.apple.CoreGraphics")),
CFSTR("CGContextGetBaseCTM"));
+ original_setColor = (void (*)(id, SEL,
id))SKReplaceInstanceMethodImplementation(self, @selector(setColor:),
(IMP)replacement_setColor);
+ if (@available(macOS 10.14, *)) {} else {
+ original_setBounds = (void (*)(id, SEL,
NSRect))SKReplaceInstanceMethodImplementation(self, @selector(setBounds:),
(IMP)replacement_setBounds);
+ }
+}
+
+ (NSArray *)readableTypesForPasteboard:(NSPasteboard *)pasteboard {
return @[SKPasteboardTypeSkimNote];
}
@@ -113,7 +236,7 @@
static inline Class SKAnnotationClassForType(NSString *type) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- if ([type isEqualToString:SKNNoteString] || [type
isEqualToString:SKNTextString])
+ if ([type isEqualToString:SKNNoteString] || [type
isEqualToString:SKNTextString] || [type isEqualToString:SKNStampString])
return [SKNPDFAnnotationNote class];
else if ([type isEqualToString:SKNFreeTextString])
return [PDFAnnotationFreeText class];
@@ -121,7 +244,7 @@
return [PDFAnnotationCircle class];
else if ([type isEqualToString:SKNSquareString])
return [PDFAnnotationSquare class];
- else if ([type isEqualToString:SKNHighlightString] || [type
isEqualToString:SKNMarkUpString] || [type isEqualToString:SKNUnderlineString]
|| [type isEqualToString:SKNStrikeOutString])
+ else if ([type isEqualToString:SKNHighlightString] || [type
isEqualToString:SKNUnderlineString] || [type
isEqualToString:SKNStrikeOutString] || [type isEqualToString:SKNMarkUpString])
return [PDFAnnotationMarkup class];
else if ([type isEqualToString:SKNLineString])
return [PDFAnnotationLine class];
@@ -138,17 +261,40 @@
+ (PDFAnnotation *)newSkimNoteWithProperties:(NSDictionary *)dict {
PDFAnnotation *annotation = [[SKAnnotationClassForType([dict
objectForKey:SKNPDFAnnotationTypeKey]) alloc] initSkimNoteWithProperties:dict];
- // this is only to make sure markup annotations generate the lineRects,
for thread safety
- if ([annotation isMarkup])
- [annotation boundsOrder];
+ if ([annotation isMarkup]) {
+ // generate the lineRects now, for thread safety
+ NSPointerArray *lines = lineRectsForQuadPoints([annotation
quadrilateralPoints], [annotation bounds].origin);
+ objc_setAssociatedObject(annotation, &SKLineRectsKey, lines,
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+ }
return annotation;
}
+ (PDFAnnotation *)newSkimNoteWithSelection:(PDFSelection *)selection
forPage:(PDFPage *)page forType:(NSString *)type {
+ NSRect bounds = NSZeroRect;
+ NSPointerArray *lines = nil;
+ if ([selection safeIndexOfFirstCharacterOnPage:page] != NSNotFound) {
+ for (PDFSelection *sel in [selection connectedSelectionsOnPage:page]) {
+ NSRect lineRect = [sel boundsForPage:page];
+ if (NSIsEmptyRect(lineRect) == NO && [[sel string]
rangeOfCharacterFromSet:[NSCharacterSet
nonWhitespaceAndNewlineCharacterSet]].length) {
+ if (lines == nil)
+ lines = [[NSPointerArray alloc] initForRectPointers];
+ [lines addPointer:&lineRect];
+ bounds = NSUnionRect(lineRect, bounds);
+ }
+ }
+ }
+ if (lines == nil)
+ return nil;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- return [[PDFAnnotationMarkup alloc] initSkimNoteWithSelection:selection
forPage:page forType:type];
+ PDFAnnotation *annotation = [[PDFAnnotationMarkup alloc]
initSkimNoteWithBounds:bounds forType:type];
#pragma clang diagnostic pop
+ if (annotation) {
+ NSArray *quadPoints = quadPointsForLineRects(lines, bounds.origin,
[page lineDirectionAngle] / 90);
+ [annotation setQuadrilateralPoints:quadPoints];
+ objc_setAssociatedObject(annotation, &SKLineRectsKey, lines,
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+ }
+ return annotation;
}
+ (PDFAnnotation *)newSkimNoteWithPaths:(NSArray *)paths {
@@ -204,6 +350,83 @@
return mutableProperties;
}
+- (void)setDefaultSkimNoteProperties {
+ NSUserDefaults *sud = [NSUserDefaults standardUserDefaults];
+ NSString *type = [self type];
+ if ([type isEqualToString:SKNFreeTextString]) {
+ NSFont *font = [sud fontForNameKey:SKFreeTextNoteFontNameKey
sizeKey:SKFreeTextNoteFontSizeKey];
+ if (font)
+ [self setFont:font];
+ [self setColor:[sud colorForKey:SKFreeTextNoteColorKey]];
+ [self setFontColor:[sud colorForKey:SKFreeTextNoteFontColorKey]];
+ [self setAlignment:textAlignmentFromAlignment([sud
integerForKey:SKFreeTextNoteAlignmentKey])];
+ PDFBorder *border = [[PDFBorder alloc] init];
+ [border setLineWidth:[sud floatForKey:SKFreeTextNoteLineWidthKey]];
+ [border setDashPattern:[sud arrayForKey:SKFreeTextNoteDashPatternKey]];
+ [border setStyle:[sud floatForKey:SKFreeTextNoteLineStyleKey]];
+ if ([border lineWidth] > 0.0) {
+ [self setBorder:border];
+ } else {
+ [self setBorder:nil];
+ // on 10.12 you can't set the border to nil, so set its lineWidth
to 0
+ [[self border] setLineWidth:0.0];
+ }
+ } else if ([type isEqualToString:SKNCircleString]) {
+ NSColor *color = [sud colorForKey:SKCircleNoteInteriorColorKey];
+ if ([color alphaComponent] > 0.0)
+ [self setInteriorColor:color];
+ [self setColor:[sud colorForKey:SKCircleNoteColorKey]];
+ [[self border] setLineWidth:[sud
floatForKey:SKCircleNoteLineWidthKey]];
+ [[self border] setDashPattern:[sud
arrayForKey:SKCircleNoteDashPatternKey]];
+ [[self border] setStyle:[sud floatForKey:SKCircleNoteLineStyleKey]];
+ } else if ([type isEqualToString:SKNSquareString]) {
+ NSColor *color = [sud colorForKey:SKSquareNoteInteriorColorKey];
+ if ([color alphaComponent] > 0.0)
+ [self setInteriorColor:color];
+ [self setColor:[sud colorForKey:SKSquareNoteColorKey]];
+ [[self border] setLineWidth:[sud
floatForKey:SKSquareNoteLineWidthKey]];
+ [[self border] setDashPattern:[sud
arrayForKey:SKSquareNoteDashPatternKey]];
+ [[self border] setStyle:[sud floatForKey:SKSquareNoteLineStyleKey]];
+ } else if ([type isEqualToString:SKNHighlightString]) {
+ [self setColor:[sud colorForKey:SKHighlightNoteColorKey]];
+ } else if ([type isEqualToString:SKNUnderlineString]) {
+ [self setColor:[sud colorForKey:SKUnderlineNoteColorKey]];
+ } else if ([type isEqualToString:SKNStrikeOutString]) {
+ [self setColor:[sud colorForKey:SKStrikeOutNoteColorKey]];
+ } else if ([type isEqualToString:SKNLineString]) {
+ NSRect bounds = [self bounds];
+ [self setColor:[sud colorForKey:SKLineNoteColorKey]];
+ NSColor *color = [sud colorForKey:SKLineNoteInteriorColorKey];
+ if ([color alphaComponent] > 0.0)
+ [self setInteriorColor:color];
+ [self setStartLineStyle:[sud
integerForKey:SKLineNoteStartLineStyleKey]];
+ [self setEndLineStyle:[sud integerForKey:SKLineNoteEndLineStyleKey]];
+ [self setStartPoint:NSMakePoint(0.0, 0.0)];
+ [self setEndPoint:NSMakePoint(NSWidth(bounds), NSHeight(bounds))];
+ PDFBorder *border = [[PDFBorder alloc] init];
+ [border setLineWidth:[sud floatForKey:SKLineNoteLineWidthKey]];
+ [border setDashPattern:[sud arrayForKey:SKLineNoteDashPatternKey]];
+ [border setStyle:[sud floatForKey:SKLineNoteLineStyleKey]];
+ [self setBorder:[border lineWidth] > 0.0 ? border : nil];
+ } else if ([type isEqualToString:SKNInkString]) {
+ [self setColor:[sud colorForKey:SKInkNoteColorKey]];
+ PDFBorder *border = [[PDFBorder alloc] init];
+ [border setLineWidth:[sud floatForKey:SKInkNoteLineWidthKey]];
+ [border setDashPattern:[sud arrayForKey:SKInkNoteDashPatternKey]];
+ [border setStyle:[sud floatForKey:SKInkNoteLineStyleKey]];
+ [self setBorder:[border lineWidth] > 0.0 ? border : nil];
+ }
+}
+
+static inline NSString *alignmentStyleKeyword(NSTextAlignment alignment) {
+ switch (alignment) {
+ case NSTextAlignmentLeft: return @"left";
+ case NSTextAlignmentRight: return @"right";
+ case NSTextAlignmentCenter: return @"center";
+ default: return @"left";
+ }
+}
+
- (NSString *)fdfString {
NSMutableString *fdfString = [NSMutableString string];
NSRect bounds = [self bounds];
@@ -212,6 +435,7 @@
NSString *contents = [self contents];
NSDate *modDate = [self modificationDate];
NSString *userName = [self userName];
+ NSString *type = [self type];
[[[self color] colorUsingColorSpaceName:NSDeviceRGBColorSpace] getRed:&r
green:&g blue:&b alpha:&a];
[fdfString appendFDFName:SKFDFTypeKey];
[fdfString appendFDFName:SKFDFAnnotation];
@@ -259,6 +483,85 @@
[fdfString appendFDFName:SKFDFAnnotationUserNameKey];
[fdfString appendFormat:@"(%@)", [[userName
lossyStringUsingEncoding:NSISOLatin1StringEncoding]
stringByEscapingParenthesis]];
}
+ if ([self hasInteriorColor]) {
+ a = 0.0;
+ [[[self interiorColor] colorUsingColorSpaceName:NSDeviceRGBColorSpace]
getRed:&r green:&g blue:&b alpha:&a];
+ if (a > 0.0) {
+ [fdfString appendFDFName:SKFDFAnnotationInteriorColorKey];
+ [fdfString appendFormat:@"[%f %f %f]", r, g, b];
+ }
+ }
+ if ([type isEqualToString:SKNFreeTextString]) {
+ [[[self fontColor] colorUsingColorSpaceName:NSDeviceRGBColorSpace]
getRed:&r green:&g blue:&b alpha:&a];
+ [fdfString appendFDFName:SKFDFDefaultAppearanceKey];
+ [fdfString appendFormat:@"(/%@ %f Tf %f %f %f rg)", [self fontName],
[self fontSize], r, g, b];
+ [fdfString appendFDFName:SKFDFDefaultStyleKey];
+ [[[self fontColor] colorUsingColorSpace:[NSColorSpace sRGBColorSpace]]
getRed:&r green:&g blue:&b alpha:&a];
+ [fdfString appendFormat:@"(font: %@ %fpt; text-align:%@;
color:#%.2x%.2x%.2x)", [self fontName], [self fontSize],
alignmentStyleKeyword([self alignment]), (unsigned int)(255*r), (unsigned
int)(255*g), (unsigned int)(255*b)];
+ [fdfString appendFDFName:SKFDFAnnotationAlignmentKey];
+ [fdfString appendFormat:@" %ld",
(long)SKFDFFreeTextAnnotationAlignmentFromPDFFreeTextAnnotationAlignment([self
alignment])];
+ } else if ([type isEqualToString:SKNHighlightString] || [type
isEqualToString:SKNUnderlineString] || [type
isEqualToString:SKNStrikeOutString]) {
+ [fdfString appendFDFName:SKFDFAnnotationQuadrilateralPointsKey];
+ [fdfString appendString:@"["];
+ for (NSValue *value in [self quadrilateralPoints]) {
+ NSPoint point = [value pointValue];
+ [fdfString appendFormat:@"%f %f ", point.x + NSMinX(bounds),
point.y + NSMinY(bounds)];
+ }
+ [fdfString appendString:@"]"];
+ } else if ([type isEqualToString:SKNLineString]) {
+ [fdfString appendFDFName:SKFDFAnnotationLineStylesKey];
+ [fdfString appendString:@"["];
+ [fdfString appendFDFName:SKFDFLineStyleFromPDFLineStyle([self
startLineStyle])];
+ [fdfString appendFDFName:SKFDFLineStyleFromPDFLineStyle([self
endLineStyle])];
+ [fdfString appendString:@"]"];
+ NSPoint startPoint = SKAddPoints([self startPoint], bounds.origin);
+ NSPoint endPoint = SKAddPoints([self endPoint], bounds.origin);
+ [fdfString appendFDFName:SKFDFAnnotationLinePointsKey];
+ [fdfString appendFormat:@"[%f %f %f %f]", startPoint.x, startPoint.y,
endPoint.x, endPoint.y];
+ } else if ([type isEqualToString:SKNInkString]) {
+ NSPoint point;
+ NSInteger i, iMax;
+ [fdfString appendFDFName:SKFDFAnnotationInkListKey];
+ [fdfString appendString:@"["];
+ for (NSBezierPath *path in [self paths]) {
+ iMax = [path elementCount];
+ [fdfString appendString:@"["];
+ for (i = 0; i < iMax; i++) {
+ point = [path associatedPointForElementAtIndex:i];
+ [fdfString appendFormat:@"%f %f ", point.x + NSMinX(bounds),
point.y + NSMinY(bounds)];
+ }
+ [fdfString appendString:@"]"];
+ }
+ [fdfString appendString:@"]"];
+ } else if ([type isEqualToString:SKNNoteString] || [type
isEqualToString:SKNTextString] || [type isEqualToString:SKNStampString]) {
+ [fdfString appendFDFName:SKFDFAnnotationIconTypeKey];
+ [fdfString
appendFDFName:SKFDFTextAnnotationIconTypeFromPDFTextAnnotationIconType([self
iconType])];
+ } else if ([type isEqualToString:SKNWidgetString]) {
+ NSString *ft = [self widgetFieldType];
+ if ([ft isEqualToString:PDFAnnotationWidgetSubtypeText]) {
+ [fdfString appendFDFName:SKFDFAnnotationFieldTypeKey];
+ [fdfString appendFDFName:SKFDFFieldTypeText];
+ [fdfString appendFDFName:SKFDFAnnotationFieldNameKey];
+ [fdfString appendFormat:@"(%@)", [[[self fieldName] ?: @""
lossyStringUsingEncoding:NSISOLatin1StringEncoding]
stringByEscapingParenthesis]];
+ [fdfString appendFDFName:SKFDFAnnotationFieldValueKey];
+ [fdfString appendFormat:@"(%@)", [[[self widgetStringValue] ?: @""
lossyStringUsingEncoding:NSISOLatin1StringEncoding]
stringByEscapingParenthesis]];
+ } else if ([ft isEqualToString:PDFAnnotationWidgetSubtypeButton]) {
+ [fdfString appendFDFName:SKFDFAnnotationFieldTypeKey];
+ [fdfString appendFDFName:SKFDFFieldTypeButton];
+ [fdfString appendFDFName:SKFDFAnnotationFieldNameKey];
+ [fdfString appendFormat:@"(%@)", [[[self fieldName] ?: @""
lossyStringUsingEncoding:NSISOLatin1StringEncoding]
stringByEscapingParenthesis]];
+ [fdfString appendFDFName:SKFDFAnnotationFieldValueKey];
+ [fdfString appendFormat:@"/%@", [self buttonWidgetState] ==
kPDFWidgetOnState ? [self buttonWidgetStateString] : @"Off"];
+ } else if ([ft isEqualToString:PDFAnnotationWidgetSubtypeChoice]) {
+ [fdfString appendFDFName:SKFDFAnnotationFieldTypeKey];
+ [fdfString appendFDFName:SKFDFFieldTypeChoice];
+ [fdfString appendFDFName:SKFDFAnnotationFieldNameKey];
+ [fdfString appendFormat:@"(%@)", [[[self fieldName] ?: @""
lossyStringUsingEncoding:NSISOLatin1StringEncoding]
stringByEscapingParenthesis]];
+ [fdfString appendFDFName:SKFDFAnnotationFieldValueKey];
+ [fdfString appendFormat:@"(%@)", [[[self widgetStringValue] ?: @""
lossyStringUsingEncoding:NSISOLatin1StringEncoding]
stringByEscapingParenthesis]];
+ }
+
+ }
return fdfString;
}
@@ -371,12 +674,48 @@
- (PDFTextAnnotationIconType)extendedIconType { return [self iconType]; }
-- (BOOL)hasNoteText { return NO; }
+- (BOOL)hasNoteText { return [self isMarkup] && [self isEditable]; }
-- (SKNoteText *)noteText { return nil; }
+- (SKNoteText *)noteText {
+ if ([self isMarkup] == NO || [self isEditable] == NO)
+ return nil;
+ SKNoteText *noteText = objc_getAssociatedObject(self, &SKNoteTextKey);
+ if (noteText == nil) {
+ noteText = [[SKNoteText alloc] initWithNote:self];
+ objc_setAssociatedObject(self, &SKNoteTextKey, noteText,
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+ }
+ return noteText;
+}
-- (PDFSelection *)selection { return nil; }
+- (PDFSelection *)selectionWithPage:(PDFPage *)page {
+ PDFSelection *selection = nil;
+ NSMutableArray *selections = nil;
+ NSPointerArray *lines = [self lineRects];
+ NSUInteger i, iMax = [lines count];
+
+ 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 *sel = [page selectionForRect:NSInsetRect([lines
rectAtIndex:i], -1.0, -1.0)];
+ if ([sel hasCharacters]) {
+ if (selection == nil)
+ selection = sel;
+ else if (selections)
+ [selections addObject:sel];
+ else
+ selections = [NSMutableArray arrayWithObject:sel];
+ }
+ }
+ if (selections)
+ [selection addSelections:selections];
+ return selection;
+}
+- (PDFSelection *)selection {
+ if ([self isMarkup])
+ return [self selectionWithPage:[self page]];
+ return nil;
+}
+
- (id)objectValue {
if ([[self type] isEqualToString:SKNWidgetString] == NO)
return [self string];
@@ -410,67 +749,298 @@
return kSKNPDFWidgetTypeUnknown;
}
-- (NSString *)textString { return nil; }
+- (NSString *)textString {
+ if ([self isMarkup] == NO || [[self page] pageRef] == NULL)
+ return nil;
+ NSString *textString = objc_getAssociatedObject(self, &SKTextStringKey);
+ if (textString == nil) {
+ textString = [[self selection] cleanedString] ?: @"";
+ objc_setAssociatedObject(self, &SKTextStringKey, textString,
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+ }
+ return textString;
+}
-- (BOOL)isMarkup { return NO; }
+- (NSPointerArray *)lineRects {
+ if ([self isMarkup] == NO)
+ return nil;
+ NSPointerArray *lineRects = objc_getAssociatedObject(self,
&SKLineRectsKey);
+ if (lineRects == nil) {
+ lineRects = lineRectsForQuadPoints([self quadrilateralPoints], [self
bounds].origin);
+ objc_setAssociatedObject(self, &SKLineRectsKey, lineRects,
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+ }
+ return lineRects;
+}
+- (BOOL)isMarkup {
+ NSString *type = [self type];
+ return [type isEqualToString:SKNHighlightString] || [type
isEqualToString:SKNUnderlineString] || [type
isEqualToString:SKNStrikeOutString];
+}
+
- (BOOL)isNote { return NO; }
-- (BOOL)isText { return NO; }
+- (BOOL)isText { return [[self type] isEqualToString:SKNFreeTextString]; }
-- (BOOL)isShape { return NO; }
+- (BOOL)isShape {
+ NSString *type = [self type];
+ return [type isEqualToString:SKNCircleString] || [type
isEqualToString:SKNSquareString];
+}
-- (BOOL)isLine { return NO; }
+- (BOOL)isLine { return [[self type] isEqualToString:SKNLineString]; }
-- (BOOL)isInk { return NO; }
+- (BOOL)isInk { return [[self type] isEqualToString:SKNInkString]; }
- (BOOL)isLink { return [[self type] isEqualToString:@"Link"]; }
-- (BOOL)isWidget { return [self widgetType] != kSKNPDFWidgetTypeUnknown; }
+- (BOOL)isWidget {
+ SKNPDFWidgetType widgetType = [self widgetType];
+ if (widgetType == kSKNPDFWidgetTypeUnknown)
+ return NO;
+ if (widgetType != kSKNPDFWidgetTypeButton)
+ return YES;
+ PDFWidgetControlType controlType = [self widgetControlType];
+ return controlType == kPDFWidgetCheckBoxControl || controlType ==
kPDFWidgetRadioButtonControl;
+}
-- (BOOL)isResizable { return NO; }
+- (BOOL)isResizable {
+ if ([self isSkimNote] == NO)
+ return NO;
+ static NSSet *resizableTypes = nil;
+ if (resizableTypes == nil)
+ resizableTypes = [NSSet setWithObjects:SKNFreeTextString,
SKNCircleString, SKNSquareString, SKNLineString, SKNInkString, nil];
+ return [resizableTypes containsObject:[self type]];
+}
-- (BOOL)isMovable { return NO; }
+- (BOOL)isMovable {
+ if ([self isSkimNote] == NO)
+ return NO;
+ static NSSet *movableTypes = nil;
+ if (movableTypes == nil)
+ movableTypes = [NSSet setWithObjects:SKNFreeTextString, SKNNoteString,
SKNCircleString, SKNSquareString, SKNLineString, SKNInkString, nil];
+ return [movableTypes containsObject:[self type]];
+}
- (BOOL)isEditable { return [self isSkimNote] && ([self page] == nil || [[self
page] isEditable]); }
-- (BOOL)hasBorder { return [self isSkimNote]; }
+- (BOOL)hasBorder {
+ static NSSet *borderedTypes = nil;
+ if (borderedTypes == nil)
+ borderedTypes = [NSSet setWithObjects:SKNFreeTextString,
SKNCircleString, SKNSquareString, SKNLineString, SKNInkString, nil];
+ return [borderedTypes containsObject:[self type]];
+}
-- (BOOL)hasInteriorColor { return NO; }
+- (BOOL)hasInteriorColor {
+ if ([self isSkimNote] == NO)
+ return NO;
+ NSString *type = [self type];
+ return [type isEqualToString:SKNCircleString] || [type
isEqualToString:SKNSquareString] || [type isEqualToString:SKNLineString];
+}
- (BOOL)isConvertibleAnnotation {
static NSSet *convertibleTypes = nil;
if (convertibleTypes == nil)
- convertibleTypes = [[NSSet alloc] initWithObjects:SKNFreeTextString,
SKNTextString, SKNNoteString, SKNCircleString, SKNSquareString,
SKNHighlightString, SKNUnderlineString, SKNStrikeOutString, SKNLineString,
SKNInkString, nil];
+ convertibleTypes = [[NSSet alloc] initWithObjects:SKNFreeTextString,
SKNTextString, SKNStampString, SKNNoteString, SKNCircleString, SKNSquareString,
SKNHighlightString, SKNUnderlineString, SKNStrikeOutString, SKNLineString,
SKNInkString, nil];
return [convertibleTypes containsObject:[self type]];
}
- (BOOL)hitTest:(NSPoint)point {
- return [self shouldDisplay] && [self isSkimNote] && NSPointInRect(point,
[self bounds]);
+ if ([self shouldDisplay] == NO || [self isSkimNote] == NO)
+ return NO;
+ NSString *type = [self type];
+ if ([type isEqualToString:SKNLineString]) {
+ CGFloat delta = fmax(4.0, 0.5 * [self lineWidth]);
+ return SKPointNearLineFromPointToPoint(SKSubstractPoints(point, [self
bounds].origin), [self startPoint], [self endPoint], delta);
+ } else if (NSPointInRect(point, [self bounds]) == NO) {
+ return NO;
+ }
+ if ([type isEqualToString:SKNCircleString]) {
+ NSRect bounds = [self bounds];
+ CGFloat dx = 2.0 * (point.x - NSMidX(bounds)) / NSWidth(bounds);
+ CGFloat dy = 2.0 * (point.y - NSMidY(bounds)) / NSHeight(bounds);
+ if (dx * dx + dy * dy > 1.0)
+ return NO;
+ if ([self interiorColor])
+ return YES;
+ CGFloat delta = fmax(8.0, [self lineWidth]);
+ if (NSWidth(bounds) <= 2.0 * delta || NSHeight(bounds) <= 2.0 * delta)
+ return YES;
+ bounds = NSInsetRect(bounds, delta, delta);
+ dx = 2.0 * (point.x - NSMidX(bounds)) / NSWidth(bounds);
+ dy = 2.0 * (point.y - NSMidY(bounds)) / NSHeight(bounds);
+ return dx * dx + dy * dy >= 1.0;
+ } else if ([type isEqualToString:SKNSquareString]) {
+ if ([self interiorColor])
+ return YES;
+ NSRect bounds = [self bounds];
+ CGFloat delta = fmax(8.0, [self lineWidth]);
+ return NSWidth(bounds) <= 2.0 * delta || NSHeight(bounds) <= 2.0 *
delta || NSPointInRect(point, NSInsetRect(bounds, delta, delta)) == NO;
+ } else if ([type isEqualToString:SKNHighlightString] || [type
isEqualToString:SKNUnderlineString] || [type
isEqualToString:SKNStrikeOutString]) {
+ NSPointerArray *lines = [self lineRects];
+ NSUInteger i = [lines count];
+ BOOL isContained = NO;
+ while (i-- && NO == isContained)
+ isContained = NSPointInRect(point, [lines rectAtIndex:i]);
+ return isContained;
+ }
+ return YES;
}
- (CGFloat)boundsOrder {
+ NSString *type = [self type];
+ if ([type isEqualToString:SKNLineString]) {
+ 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]);
+ } else if ([type isEqualToString:SKNHighlightString] || [type
isEqualToString:SKNUnderlineString] || [type
isEqualToString:SKNStrikeOutString]) {
+ NSPointerArray *lines = [self lineRects];
+ NSRect bounds = [lines count] > 0 ? [lines rectAtIndex:0] : [self
bounds];
+ return [[self page] sortOrderForBounds:bounds];
+ }
return [[self page] sortOrderForBounds:[self bounds]];
}
- (SKRectEdges)resizeHandleForPoint:(NSPoint)point
scaleFactor:(CGFloat)scaleFactor {
- return [self isResizable] ? SKResizeHandleForPointFromRect(point, [self
bounds], 4.0 / scaleFactor) : SKRectEdgesNone;
+ if ([self isResizable] == NO)
+ return SKRectEdgesNone;
+ if ([[self type] isEqualToString:SKNLineString]) {
+ NSSize size = SKMakeSquareSize(8.0 / scaleFactor);
+ point = SKSubstractPoints(point, [self bounds].origin);
+ if (NSPointInRect(point, SKRectFromCenterAndSize([self endPoint],
size)))
+ return SKRectEdgesMaxX;
+ else if (NSPointInRect(point, SKRectFromCenterAndSize([self
startPoint], size)))
+ return SKRectEdgesMinX;
+ else
+ return SKRectEdgesNone;
+ }
+ return SKResizeHandleForPointFromRect(point, [self bounds], 4.0 /
scaleFactor);
}
+- (void)drawShadowWithUnitWidth:(CGFloat)unitWidth
inContext:(CGContextRef)context {
+ NSRect bounds = [self bounds];
+ CGFloat r = fmin(2.0, 2.0 * unitWidth);
+ CGRect rect = NSRectToCGRect(NSInsetRect(bounds, 2.0 * r, 2.0 * r));
+ CGAffineTransform t = CGAffineTransformConcat(CGContextGetCTM(context),
CGAffineTransformInvert(CGContextGetBaseCTM_func(context)));
+ r = fabs(CGSizeApplyAffineTransform(CGSizeMake(r, r), t).height);
+ t = CGAffineTransformMakeTranslation(NSMinX(bounds), NSMinY(bounds));
+ CGMutablePathRef path = CGPathCreateMutable();
+ for (NSBezierPath *aPath in [self paths])
+ [aPath addToCGPath:path transform:&t];
+ CGContextSaveGState(context);
+ CGContextSetAlpha(context, [[self color] alphaComponent]);
+ CGContextBeginTransparencyLayerWithRect(context, rect, NULL);
+ CGContextSetLineWidth(context, [self lineWidth]);
+ if ([self borderStyle] == kPDFBorderStyleDashed) {
+ NSArray *dashPattern = [self dashPattern];
+ NSUInteger i, count = [dashPattern count];
+ CGFloat pattern[count];
+ for (i = 0; i < count; i++)
+ pattern[i] = [[dashPattern objectAtIndex:i] doubleValue];
+ CGContextSetLineDash(context, 0.0, pattern, count);
+ CGContextSetLineCap(context, kCGLineCapButt);
+ } else {
+ CGContextSetLineCap(context, kCGLineCapRound);
+ }
+ CGContextSetShadow(context, CGSizeMake(0.0, -r), r);
+ CGContextAddPath(context, path);
+ CGContextStrokePath(context);
+ CGContextSetShadowWithColor(context, CGSizeZero, 0.0, NULL);
+ CGContextSetBlendMode(context, kCGBlendModeClear);
+ CGContextAddPath(context, path);
+ CGContextStrokePath(context);
+ CGContextEndTransparencyLayer(context);
+ CGContextRestoreGState(context);
+ CGPathRelease(path);
+}
+
+- (void)drawFallbackShadowWithUnitWidth:(CGFloat)unitWidth
inContext:(CGContextRef)context {
+ CGFloat r = fmin(2.0 / unitWidth, 2.0);
+ NSSize offset = NSZeroSize;
+ switch ([[self page] rotation]) {
+ case 0: offset.height = -r; break;
+ case 90: offset.width = r; break;
+ case 180: offset.height = r; break;
+ case 270: offset.width = -r; break;
+ default: offset.height = -r; break;
+ }
+ NSRect bounds = [self bounds];
+ NSRect rect = NSIntersectionRect(NSOffsetRect(NSInsetRect(bounds, -r *
unitWidth, -r * unitWidth), offset.width * unitWidth, offset.height *
unitWidth), NSRectFromCGRect(CGContextGetClipBoundingBox(context)));
+ if (NSIsEmptyRect(rect) == NO) {
+ NSRect imgRect = NSMakeRect(0.0, 0.0, ceil(NSWidth(rect) / unitWidth),
ceil(NSHeight(rect) / unitWidth));
+ rect.size = NSMakeSize(NSWidth(imgRect) * unitWidth, NSHeight(imgRect)
* unitWidth);
+ NSImage *image = [NSImage imageWithSize:imgRect.size flipped:NO
drawingHandler:^(NSRect dstRect){
+ NSAffineTransform *transform = [NSAffineTransform transform];
+ [transform scaleBy:1.0 / unitWidth];
+ [transform translateXBy:NSMinX(bounds) - NSMinX(rect)
yBy:NSMinY(bounds) - NSMinY(rect)];
+ [transform concat];
+ NSBezierPath *path = [NSBezierPath bezierPath];
+ for (NSBezierPath *aPath in [self paths])
+ [path appendBezierPath:aPath];
+ [path setLineWidth:fmax(1.0, [self lineWidth])];
+ [path setLineJoinStyle:NSRoundLineJoinStyle];
+ if ([self borderStyle] == kPDFBorderStyleDashed) {
+ [path setDashPattern:[self dashPattern]];
+ [path setLineCapStyle:NSButtLineCapStyle];
+ } else {
+ [path setLineCapStyle:NSRoundLineCapStyle];
+ }
+ [NSGraphicsContext saveGraphicsState];
+ [NSShadow setShadowWithColor:[NSColor
colorWithGenericGamma22White:0.0 alpha:0.33333] blurRadius:r offset:offset];
+ [path stroke];
+ [NSGraphicsContext restoreGraphicsState];
+ [[NSGraphicsContext currentContext]
setCompositingOperation:NSCompositingOperationClear];
+ [path stroke];
+ return YES;
+ }];
+ [NSGraphicsContext saveGraphicsState];
+ [NSGraphicsContext setCurrentContext:[NSGraphicsContext
graphicsContextWithCGContext:context flipped:NO]];
+ [image drawInRect:rect fromRect:imgRect
operation:NSCompositingOperationSourceOver fraction:[[self color]
alphaComponent]];
+ [NSGraphicsContext restoreGraphicsState];
+ }
+}
+
- (void)drawSelectionHighlightWithUnitWidth:(CGFloat)unitWidth
active:(BOOL)active inContext:(CGContextRef)context {
if (NSIsEmptyRect([self bounds]))
return;
if ([self isSkimNote]) {
- CGRect rect = CGContextConvertRectToUserSpace(context,
CGRectIntegral(CGContextConvertRectToDeviceSpace(context, NSRectToCGRect([self
bounds]))));
- CGContextSaveGState(context);
- if ([self isResizable]) {
- SKDrawResizeHandles(context, NSRectFromCGRect(rect), unitWidth,
YES, active);
- } else {
+ NSString *type = [self type];
+ if ([type isEqualToString:SKNLineString]) {
+ NSPoint origin = [self bounds].origin;
+ SKDrawResizeHandlePair(context, SKAddPoints(origin, [self
startPoint]), SKAddPoints(origin, [self endPoint]), unitWidth, active);
+ } else if ([type isEqualToString:SKNHighlightString] || [type
isEqualToString:SKNUnderlineString] || [type
isEqualToString:SKNStrikeOutString]) {
+ NSPointerArray *lines = [self lineRects];
+ NSUInteger i, iMax = [lines count];
CGColorRef color = [[NSColor selectionHighlightColor:active]
CGColor];
+
+ CGContextSaveGState(context);
CGContextSetStrokeColorWithColor(context, color);
- CGContextStrokeRectWithWidth(context, CGRectInset(rect, -0.5 *
unitWidth, -0.5 * unitWidth), unitWidth);
+ CGContextSetLineWidth(context, unitWidth);
+ for (i = 0; i < iMax; i++) {
+ CGRect rect = CGContextConvertRectToUserSpace(context,
CGRectIntegral(CGContextConvertRectToDeviceSpace(context, NSRectToCGRect([lines
rectAtIndex:i]))));
+ CGContextStrokeRect(context, CGRectInset(rect, -0.5 *
unitWidth, -0.5 * unitWidth));
+ }
+ CGContextRestoreGState(context);
+ } else {
+ if ([type isEqualToString:SKNInkString]) {
+ if (NSIsEmptyRect([self bounds]) == NO && [self isSkimNote]) {
+ if (CGContextGetBaseCTM_func != NULL)
+ [self drawShadowWithUnitWidth:unitWidth
inContext:context];
+ else
+ [self drawFallbackShadowWithUnitWidth:unitWidth
inContext:context];
+ }
+ }
+ CGRect rect = CGContextConvertRectToUserSpace(context,
CGRectIntegral(CGContextConvertRectToDeviceSpace(context, NSRectToCGRect([self
bounds]))));
+ CGContextSaveGState(context);
+ if ([self isResizable]) {
+ SKDrawResizeHandles(context, NSRectFromCGRect(rect),
unitWidth, YES, active);
+ } else {
+ CGColorRef color = [[NSColor selectionHighlightColor:active]
CGColor];
+ CGContextSetStrokeColorWithColor(context, color);
+ CGContextStrokeRectWithWidth(context, CGRectInset(rect, -0.5 *
unitWidth, -0.5 * unitWidth), unitWidth);
+ }
+ CGContextRestoreGState(context);
}
- CGContextRestoreGState(context);
} else if ([self isLink]) {
CGContextSaveGState(context);
CGColorRef color = CGColorCreateGenericGray(0.0, 0.2);
@@ -490,21 +1060,133 @@
[self setModificationDate:[NSDate date]];
}
-- (void)autoUpdateStringWithPage:(PDFPage *)page {}
+- (void)autoUpdateStringWithPage:(PDFPage *)page {
+ NSString *type = [self type];
+ if ([type isEqualToString:SKNCircleString]) {
+ // this calculation is roughly the inverse of -[PDFView
addOtherAnnotationWithType:selection:point:]
+ NSRect bounds = NSInsetRect([self bounds], [self lineWidth] - 1.0,
[self lineWidth] - 1.0);
+ CGFloat t, w = NSWidth(bounds), h = NSWidth(bounds);
+ if (w <= 0.0 || h <= 0.0)
+ return;
+ t = 0.5 * w * h * (w + h - sqrt(2.0 * w * h)) / (w * w + h * h);
+ bounds = NSInsetRect(bounds, t, t);
+ NSString *selString = [[page selectionForRect:bounds] cleanedString];
+ if ([selString length])
+ [self setString:selString];
+ } else if ([type isEqualToString:SKNSquareString]) {
+ NSRect bounds = NSInsetRect([self bounds], [self lineWidth] - 1.0,
[self lineWidth] - 1.0);
+ if (NSWidth(bounds) <= 0.0 || NSHeight(bounds) <= 0.0)
+ return;
+ NSString *selString = [[page selectionForRect:bounds] cleanedString];
+ if ([selString length])
+ [self setString:selString];
+ } else if ([type isEqualToString:SKNHighlightString] || [type
isEqualToString:SKNUnderlineString] || [type
isEqualToString:SKNStrikeOutString]) {
+ NSString *selString = [[self selectionWithPage:page] cleanedString];
+ if ([selString length]) {
+ // page should be future [self page] and textString will not have
been called
+ objc_setAssociatedObject(self, &SKTextStringKey, selString,
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+ [self setString:selString];
+ }
+ }
+}
-- (NSString *)colorDefaultKey { return nil; }
+- (NSString *)colorDefaultKey {
+ NSString *type = [self type];
+ if ([type isEqualToString:SKNFreeTextString])
+ return SKFreeTextNoteColorKey;
+ else if ([type isEqualToString:SKNCircleString])
+ return SKCircleNoteColorKey;
+ else if ([type isEqualToString:SKNSquareString])
+ return SKSquareNoteColorKey;
+ else if ([type isEqualToString:SKNHighlightString])
+ return SKHighlightNoteColorKey;
+ else if ([type isEqualToString:SKNUnderlineString])
+ return SKUnderlineNoteColorKey;
+ else if ([type isEqualToString:SKNStrikeOutString])
+ return SKStrikeOutNoteColorKey;
+ else if ([type isEqualToString:SKNLineString])
+ return SKLineNoteColorKey;
+ else if ([type isEqualToString:SKNInkString])
+ return SKInkNoteColorKey;
+ else
+ return nil;
+}
-- (NSString *)alternateColorDefaultKey { return nil; }
+- (NSString *)alternateColorDefaultKey {
+ NSString *type = [self type];
+ if ([type isEqualToString:SKNFreeTextString])
+ return SKFreeTextNoteFontColorKey;
+ else if ([type isEqualToString:SKNCircleString])
+ return SKCircleNoteInteriorColorKey;
+ else if ([type isEqualToString:SKNSquareString])
+ return SKSquareNoteInteriorColorKey;
+ else if ([type isEqualToString:SKNLineString])
+ return SKLineNoteInteriorColorKey;
+ else
+ return nil;
+}
-- (NSString *)lineWidthDefaultKey { return nil; }
+- (NSString *)lineWidthDefaultKey {
+ NSString *type = [self type];
+ if ([type isEqualToString:SKNFreeTextString])
+ return SKFreeTextNoteLineWidthKey;
+ else if ([type isEqualToString:SKNCircleString])
+ return SKCircleNoteLineWidthKey;
+ else if ([type isEqualToString:SKNSquareString])
+ return SKSquareNoteLineWidthKey;
+ else if ([type isEqualToString:SKNLineString])
+ return SKLineNoteLineWidthKey;
+ else if ([type isEqualToString:SKNInkString])
+ return SKInkNoteLineWidthKey;
+ else
+ return nil;
+}
-- (NSString *)borderStyleDefaultKey { return nil; }
+- (NSString *)borderStyleDefaultKey {
+ NSString *type = [self type];
+ if ([type isEqualToString:SKNFreeTextString])
+ return SKFreeTextNoteLineStyleKey;
+ else if ([type isEqualToString:SKNCircleString])
+ return SKCircleNoteLineStyleKey;
+ else if ([type isEqualToString:SKNSquareString])
+ return SKSquareNoteLineStyleKey;
+ else if ([type isEqualToString:SKNLineString])
+ return SKLineNoteLineStyleKey;
+ else if ([type isEqualToString:SKNInkString])
+ return SKInkNoteLineStyleKey;
+ else
+ return nil;
+}
-- (NSString *)dashPatternDefaultKey { return nil; }
+- (NSString *)dashPatternDefaultKey {
+ NSString *type = [self type];
+ if ([type isEqualToString:SKNFreeTextString])
+ return SKFreeTextNoteDashPatternKey;
+ else if ([type isEqualToString:SKNCircleString])
+ return SKCircleNoteDashPatternKey;
+ else if ([type isEqualToString:SKNSquareString])
+ return SKSquareNoteDashPatternKey;
+ else if ([type isEqualToString:SKNLineString])
+ return SKLineNoteDashPatternKey;
+ else if ([type isEqualToString:SKNInkString])
+ return SKInkNoteDashPatternKey;
+ else
+ return nil;
+}
-- (NSString *)startLineStyleDefaultKey { return nil; }
+- (NSString *)startLineStyleDefaultKey {
+ if ([[self type] isEqualToString:SKNLineString])
+ return SKLineNoteStartLineStyleKey;
+ else
+ return nil;
+}
-- (NSString *)endLineStyleDefaultKey { return nil; }
+- (NSString *)endLineStyleDefaultKey {
+ if ([[self type] isEqualToString:SKNLineString])
+ return SKLineNoteEndLineStyleKey;
+ else
+ return nil;
+}
- (void)setColor:(NSColor *)color alternate:(BOOL)alternate
updateDefaults:(BOOL)update {
BOOL isFill = alternate && [self hasInteriorColor];
@@ -575,12 +1257,42 @@
}
- (NSSet *)keysForValuesToObserveForUndo {
- if ([[self type] isEqualToString:SKNWidgetString])
+ NSString *type = [self type];
+ if ([type isEqualToString:SKNFreeTextString]) {
+ static NSSet *keys = nil;
+ if (keys == nil)
+ keys = [[NSSet alloc] initWithObjects:SKNPDFAnnotationBoundsKey,
SKNPDFAnnotationStringKey, SKNPDFAnnotationColorKey, SKNPDFAnnotationBorderKey,
SKNPDFAnnotationModificationDateKey, SKNPDFAnnotationUserNameKey,
SKNPDFAnnotationFontKey, SKNPDFAnnotationFontColorKey,
SKNPDFAnnotationAlignmentKey, nil];
+ return keys;
+ } else if ([type isEqualToString:SKNNoteString]) {
+ static NSSet *keys = nil;
+ if (keys == nil)
+ keys = [[NSSet alloc] initWithObjects:SKNPDFAnnotationBoundsKey,
SKNPDFAnnotationStringKey, SKNPDFAnnotationColorKey,
SKNPDFAnnotationModificationDateKey, SKNPDFAnnotationUserNameKey,
SKNPDFAnnotationNameKey, SKNPDFAnnotationTextKey, SKNPDFAnnotationImageKey,
SKNPDFAnnotationDrawsImageKey, nil];
+ return keys;
+ } else if ([type isEqualToString:SKNCircleString] || [type
isEqualToString:SKNSquareString]) {
+ static NSSet *keys = nil;
+ if (keys == nil)
+ keys = [[NSSet alloc] initWithObjects:SKNPDFAnnotationBoundsKey,
SKNPDFAnnotationStringKey, SKNPDFAnnotationColorKey, SKNPDFAnnotationBorderKey,
SKNPDFAnnotationModificationDateKey, SKNPDFAnnotationUserNameKey,
SKNPDFAnnotationInteriorColorKey, nil];
+ return keys;
+ } else if ([type isEqualToString:SKNHighlightString] || [type
isEqualToString:SKNUnderlineString] || [type
isEqualToString:SKNStrikeOutString]) {
+ static NSSet *keys = nil;
+ if (keys == nil)
+ keys = [[NSSet alloc] initWithObjects:SKNPDFAnnotationBoundsKey,
SKNPDFAnnotationStringKey, SKNPDFAnnotationColorKey,
SKNPDFAnnotationModificationDateKey, SKNPDFAnnotationUserNameKey, nil];
+ return keys;
+ } else if ([type isEqualToString:SKNLineString]) {
+ static NSSet *keys = nil;
+ if (keys == nil)
+ keys = [[NSSet alloc] initWithObjects:SKNPDFAnnotationBoundsKey,
SKNPDFAnnotationStringKey, SKNPDFAnnotationColorKey, SKNPDFAnnotationBorderKey,
SKNPDFAnnotationModificationDateKey, SKNPDFAnnotationUserNameKey,
SKNPDFAnnotationStartLineStyleKey, SKNPDFAnnotationEndLineStyleKey,
SKNPDFAnnotationStartPointKey, SKNPDFAnnotationEndPointKey,
SKNPDFAnnotationInteriorColorKey, nil];
+ return keys;
+ } else if ([type isEqualToString:SKNInkString]) {
+ static NSSet *keys = nil;
+ if (keys == nil)
+ keys = [[NSSet alloc] initWithObjects:SKNPDFAnnotationBoundsKey,
SKNPDFAnnotationStringKey, SKNPDFAnnotationColorKey, SKNPDFAnnotationBorderKey,
SKNPDFAnnotationModificationDateKey, SKNPDFAnnotationUserNameKey,
SKPDFAnnotationBezierPathsKey, nil];
+ return keys;
+ } else if ([type isEqualToString:SKNWidgetString] && [self isWidget]) {
return [NSSet setWithObject:@"objectValue"];
- static NSSet *keys = nil;
- if (keys == nil)
- keys = [[NSSet alloc] initWithObjects:SKNPDFAnnotationBoundsKey,
SKNPDFAnnotationStringKey, SKNPDFAnnotationColorKey, SKNPDFAnnotationBorderKey,
SKNPDFAnnotationModificationDateKey, SKNPDFAnnotationUserNameKey, nil];
- return keys;
+ } else {
+ return [NSSet set];
+ }
}
#pragma mark Scripting support
@@ -595,35 +1307,51 @@
return [NSString stringWithFormat:@"%p", (void *)self];
}
-// overridden by subclasses to add or remove custom scripting keys relevant
for the class, subclasses should call super first
-+ (NSSet *)customScriptingKeys {
- static NSSet *customScriptingKeys = nil;
- if (customScriptingKeys == nil)
- customScriptingKeys = [[NSSet alloc]
initWithObjects:SKNPDFAnnotationLineWidthKey, SKNPDFAnnotationBorderStyleKey,
SKNPDFAnnotationDashPatternKey, nil];
- return customScriptingKeys;
+static NSArray *invalidScriptingKeysForType(NSString *type) {
+ if ([type isEqualToString:SKNFreeTextString]) {
+ static NSArray *keys = nil;
+ if (keys == nil)
+ keys = @[SKPDFAnnotationStartPointAsQDPointKey,
SKPDFAnnotationEndPointAsQDPointKey, SKPDFAnnotationScriptingStartLineStyleKey,
SKPDFAnnotationScriptingEndLineStyleKey,
SKPDFAnnotationScriptingInteriorColorKey,
SKPDFAnnotationScriptingPointListsKey, SKPDFAnnotationSelectionSpecifierKey,
SKPDFAnnotationScriptingIconTypeKey, SKPDFAnnotationRichTextKey,
SKPDFAnnotationScriptingImageDataKey];
+ return keys;
+ } else if ([type isEqualToString:SKNNoteString]) {
+ static NSArray *keys = nil;
+ if (keys == nil)
+ keys = @[SKNPDFAnnotationLineWidthKey,
SKNPDFAnnotationBorderStyleKey, SKNPDFAnnotationDashPatternKey,
SKPDFAnnotationStartPointAsQDPointKey, SKPDFAnnotationEndPointAsQDPointKey,
SKPDFAnnotationScriptingStartLineStyleKey,
SKPDFAnnotationScriptingEndLineStyleKey,
SKPDFAnnotationScriptingInteriorColorKey, SKNPDFAnnotationFontNameKey,
SKNPDFAnnotationFontSizeKey, SKPDFAnnotationScriptingFontColorKey,
SKPDFAnnotationScriptingAlignmentKey, SKPDFAnnotationScriptingPointListsKey,
SKPDFAnnotationSelectionSpecifierKey];
+ return keys;
+ } else if ([type isEqualToString:SKNCircleString] || [type
isEqualToString:SKNSquareString]) {
+ static NSArray *keys = nil;
+ if (keys == nil)
+ keys = @[SKPDFAnnotationStartPointAsQDPointKey,
SKPDFAnnotationEndPointAsQDPointKey, SKPDFAnnotationScriptingStartLineStyleKey,
SKPDFAnnotationScriptingEndLineStyleKey, SKNPDFAnnotationFontNameKey,
SKNPDFAnnotationFontSizeKey, SKPDFAnnotationScriptingFontColorKey,
SKPDFAnnotationScriptingAlignmentKey, SKPDFAnnotationScriptingPointListsKey,
SKPDFAnnotationSelectionSpecifierKey, SKPDFAnnotationScriptingIconTypeKey,
SKPDFAnnotationRichTextKey, SKPDFAnnotationScriptingImageDataKey];
+ return keys;
+ } else if ([type isEqualToString:SKNHighlightString] || [type
isEqualToString:SKNUnderlineString] || [type
isEqualToString:SKNStrikeOutString]) {
+ static NSArray *keys = nil;
+ if (keys == nil)
+ keys = @[SKNPDFAnnotationLineWidthKey,
SKNPDFAnnotationBorderStyleKey, SKNPDFAnnotationDashPatternKey,
SKPDFAnnotationStartPointAsQDPointKey, SKPDFAnnotationEndPointAsQDPointKey,
SKPDFAnnotationScriptingStartLineStyleKey,
SKPDFAnnotationScriptingEndLineStyleKey,
SKPDFAnnotationScriptingInteriorColorKey, SKNPDFAnnotationFontNameKey,
SKNPDFAnnotationFontSizeKey, SKPDFAnnotationScriptingFontColorKey,
SKPDFAnnotationScriptingAlignmentKey, SKPDFAnnotationScriptingIconTypeKey,
SKPDFAnnotationRichTextKey, SKPDFAnnotationScriptingImageDataKey];
+ return keys;
+ } else if ([type isEqualToString:SKNLineString]) {
+ static NSArray *keys = nil;
+ if (keys == nil)
+ keys = @[SKNPDFAnnotationFontNameKey, SKNPDFAnnotationFontSizeKey,
SKPDFAnnotationScriptingFontColorKey, SKPDFAnnotationScriptingAlignmentKey,
SKPDFAnnotationScriptingPointListsKey, SKPDFAnnotationSelectionSpecifierKey,
SKPDFAnnotationScriptingIconTypeKey, SKPDFAnnotationRichTextKey,
SKPDFAnnotationScriptingImageDataKey];
+ return keys;
+ } else if ([type isEqualToString:SKNInkString]) {
+ static NSArray *keys = nil;
+ if (keys == nil)
+ keys = @[SKPDFAnnotationStartPointAsQDPointKey,
SKPDFAnnotationEndPointAsQDPointKey, SKPDFAnnotationScriptingStartLineStyleKey,
SKPDFAnnotationScriptingEndLineStyleKey,
SKPDFAnnotationScriptingInteriorColorKey, SKNPDFAnnotationFontNameKey,
SKNPDFAnnotationFontSizeKey, SKPDFAnnotationScriptingFontColorKey,
SKPDFAnnotationScriptingAlignmentKey, SKPDFAnnotationSelectionSpecifierKey,
SKPDFAnnotationScriptingIconTypeKey, SKPDFAnnotationRichTextKey,
SKPDFAnnotationScriptingImageDataKey];
+ return keys;
+ } else if ([type isEqualToString:SKNWidgetString]) {
+ static NSArray *keys = nil;
+ if (keys == nil)
+ keys = @[SKNPDFAnnotationLineWidthKey,
SKNPDFAnnotationBorderStyleKey, SKNPDFAnnotationDashPatternKey,
SKPDFAnnotationStartPointAsQDPointKey, SKPDFAnnotationEndPointAsQDPointKey,
SKPDFAnnotationScriptingStartLineStyleKey,
SKPDFAnnotationScriptingEndLineStyleKey,
SKPDFAnnotationScriptingInteriorColorKey, SKNPDFAnnotationFontNameKey,
SKNPDFAnnotationFontSizeKey, SKPDFAnnotationScriptingFontColorKey,
SKPDFAnnotationScriptingAlignmentKey, SKPDFAnnotationScriptingPointListsKey,
SKPDFAnnotationSelectionSpecifierKey, SKPDFAnnotationScriptingIconTypeKey,
SKPDFAnnotationRichTextKey, SKPDFAnnotationScriptingImageDataKey];
+ return keys;
+ } else {
+ return [NSArray array];
+ }
}
- (NSDictionary *)scriptingProperties {
- static NSSet *allCustomScriptingKeys = nil;
- if (allCustomScriptingKeys == nil) {
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- NSMutableSet *customScriptingKeys = [NSMutableSet set];
- [customScriptingKeys unionSet:[PDFAnnotationCircle
customScriptingKeys]];
- [customScriptingKeys unionSet:[PDFAnnotationSquare
customScriptingKeys]];
- [customScriptingKeys unionSet:[PDFAnnotationFreeText
customScriptingKeys]];
- [customScriptingKeys unionSet:[SKNPDFAnnotationNote
customScriptingKeys]];
- [customScriptingKeys unionSet:[PDFAnnotationMarkup
customScriptingKeys]];
- [customScriptingKeys unionSet:[PDFAnnotationLine customScriptingKeys]];
- [customScriptingKeys unionSet:[PDFAnnotationInk customScriptingKeys]];
- allCustomScriptingKeys = [customScriptingKeys copy];
-#pragma clang diagnostic pop
- }
// remove all custom properties that are not valid for this class
NSMutableDictionary *properties = [[super scriptingProperties]
mutableCopy];
- NSMutableSet *customKeys = [allCustomScriptingKeys mutableCopy];
- [customKeys minusSet:[[self class] customScriptingKeys]];
- [properties removeObjectsForKeys:[customKeys allObjects]];
+ [properties removeObjectsForKeys:invalidScriptingKeysForType([self type])];
return properties;
}
@@ -679,7 +1407,16 @@
- (id)textContents;
{
- return [self string] == nil ? nil : [[NSTextStorage alloc]
initWithString:[self string]];
+ if ([self string] == nil)
+ return nil;
+ NSTextStorage *textContents = [[NSTextStorage alloc] initWithString:[self
string]];
+ if ([[self type] isEqualToString:SKNFreeTextString]) {
+ if ([self font])
+ [textContents addAttribute:NSFontAttributeName value:[self font]
range:NSMakeRange(0, [textContents length])];
+ if ([self fontColor])
+ [textContents addAttribute:NSForegroundColorAttributeName
value:[self fontColor] range:NSMakeRange(0, [textContents length])];
+ }
+ return textContents;
}
- (void)setTextContents:(id)text;
@@ -699,11 +1436,36 @@
return nil;
}
+- (NSData *)boundsAsQDRect {
+ return [NSData dataWithRectAsQDRect:[self bounds]];
+}
+
- (void)setBoundsAsQDRect:(NSData *)inQDBoundsAsData {
if ([self isMovable] && [self isEditable]) {
NSRect newBounds = [inQDBoundsAsData rectValueAsQDRect];
if ([self isResizable] == NO) {
newBounds.size = [self bounds].size;
+ } else if ([[self type] isEqualToString:SKNInkString]) {
+ CGFloat margin = [self pathInset];
+ NSRect bounds = [self bounds];
+
+ if (NSWidth(newBounds) < 2.0 * margin)
+ newBounds.size.width = 2.0 * margin;
+ if (NSHeight(newBounds) < 2.0 * margin)
+ newBounds.size.height = 2.0 * margin;
+
+ if (NSEqualSizes(bounds.size, newBounds.size) == NO) {
+ NSMutableArray *paths = [NSMutableArray array];
+ NSAffineTransform *transform = [NSAffineTransform transform];
+ [transform translateXBy:margin yBy:margin];
+ [transform scaleXBy:fmax(1.0, NSWidth(newBounds) - 2.0 *
margin) / fmax(1.0, NSWidth(bounds) - 2.0 * margin) yBy:fmax(1.0,
NSHeight(newBounds) - 2.0 * margin) / fmax(1.0, NSHeight(bounds) - 2.0 *
margin)];
+ [transform translateXBy:-margin yBy:-margin];
+
+ for (NSBezierPath *path in [self paths])
+ [paths addObject:[transform transformBezierPath:path]];
+
+ [self setBezierPaths:paths];
+ }
} else {
if (NSWidth(newBounds) < 0.0)
newBounds.size.width = 0.0;
@@ -712,55 +1474,228 @@
}
[self setBounds:newBounds];
}
-
}
-- (NSData *)boundsAsQDRect {
- return [NSData dataWithRectAsQDRect:[self bounds]];
+- (NSColor *)scriptingInteriorColor {
+ return [self interiorColor];
}
-- (NSColor *)scriptingInteriorColor {
- return nil;
+- (void)setScriptingInteriorColor:(NSColor *)color {
+ if ([self isEditable] && [self hasInteriorColor]) {
+ [self setInteriorColor:color];
+ }
}
- (NSString *)fontName {
- return nil;
+ if ([[self type] isEqualToString:SKNFreeTextString]) {
+ return [[self font] fontName];
+ } else {
+ return nil;
+ }
}
+- (void)setFontName:(NSString *)fontName {
+ if ([self isEditable] && [[self type] isEqualToString:SKNFreeTextString]) {
+ NSFont *font = [NSFont fontWithName:fontName size:[[self font]
pointSize]];
+ if (font)
+ [self setFont:font];
+ }
+}
+
- (CGFloat)fontSize {
- return 0;
+ if ([[self type] isEqualToString:SKNFreeTextString]) {
+ return [[self font] pointSize];
+ } else {
+ return 0.0;
+ }
}
+- (void)setFontSize:(CGFloat)pointSize {
+ if ([self isEditable] && [[self type] isEqualToString:SKNFreeTextString]) {
+ NSFont *font = [NSFont fontWithName:[[self font] fontName]
size:pointSize];
+ if (font)
+ [self setFont:font];
+ }
+}
+
- (NSColor *)scriptingFontColor {
- return nil;
+ if ([[self type] isEqualToString:SKNFreeTextString]) {
+ return [self fontColor];
+ } else {
+ return nil;
+ }
}
+- (void)setScriptingFontColor:(NSColor *)newScriptingFontColor {
+ if ([self isEditable] && [[self type] isEqualToString:SKNFreeTextString]) {
+ [self setFontColor:newScriptingFontColor];
+ }
+}
+
- (NSInteger)scriptingAlignment {
- return NSTextAlignmentLeft;
+ if ([[self type] isEqualToString:SKNFreeTextString]) {
+ return alignmentFromTextAlignment([self alignment]);
+ } else {
+ return NSTextAlignmentLeft;
+ }
}
+- (void)setScriptingAlignment:(NSInteger)alignment {
+ if ([self isEditable] && [[self type] isEqualToString:SKNFreeTextString]) {
+ [self setAlignment:textAlignmentFromAlignment(alignment)];
+ }
+}
+
- (NSData *)startPointAsQDPoint {
- return nil;
+ if ([[self type] isEqualToString:SKNLineString]) {
+ 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];
+ } else {
+ return nil;
+ }
}
+- (void)setStartPointAsQDPoint:(NSData *)inQDPointAsData {
+ if ([self isEditable] && [[self type] isEqualToString:SKNLineString] &&
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 setStartPoint:startPoint];
+ [self setEndPoint:endPoint];
+ }
+}
+
- (NSData *)endPointAsQDPoint {
- return nil;
+ if ([[self type] isEqualToString:SKNLineString]) {
+ 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];
+ } else {
+ return nil;
+ }
}
+- (void)setEndPointAsQDPoint:(NSData *)inQDPointAsData {
+ if ([self isEditable] && [[self type] isEqualToString:SKNLineString] &&
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 setStartPoint:startPoint];
+ [self setEndPoint:endPoint];
+ }
+}
+
- (PDFLineStyle)scriptingStartLineStyle {
- return kPDFLineStyleNone;
+ if ([[self type] isEqualToString:SKNLineString]) {
+ return [self startLineStyle];
+ } else {
+ return kPDFLineStyleNone;
+ }
}
+- (void)setScriptingStartLineStyle:(PDFLineStyle)style {
+ if ([self isEditable] && [[self type] isEqualToString:SKNLineString]) {
+ [self setStartLineStyle:style];
+ }
+}
+
- (PDFLineStyle)scriptingEndLineStyle {
- return kPDFLineStyleNone;
+ if ([[self type] isEqualToString:SKNLineString]) {
+ return [self endLineStyle];
+ } else {
+ return kPDFLineStyleNone;
+ }
}
+- (void)setScriptingEndLineStyle:(PDFLineStyle)style {
+ if ([self isEditable] && [[self type] isEqualToString:SKNLineString]) {
+ [self setEndLineStyle:style];
+ }
+}
+
- (id)selectionSpecifier {
- return nil;
+ if ([self isMarkup]) {
+ PDFSelection *sel = [self selection];
+ return [sel hasCharacters] ? [sel objectSpecifiers] : @[];
+ } else {
+ return nil;
+ }
}
- (NSArray *)scriptingPointLists {
- return nil;
+ if ([[self type] isEqualToString:SKNInkString]) {
+ NSPoint origin = [self bounds].origin;
+ NSMutableArray *pointLists = [NSMutableArray array];
+ NSMutableArray *pointValues;
+ NSPoint point;
+ NSInteger i, iMax;
+ for (NSBezierPath *path in [self paths]) {
+ iMax = [path elementCount];
+ pointValues = [[NSMutableArray alloc] initWithCapacity:iMax];
+ for (i = 0; i < iMax; i++) {
+ point = [path associatedPointForElementAtIndex:i];
+ [pointValues addObject:[NSData
dataWithPointAsNSPoint:SKAddPoints(point, origin)]];
+ }
+ [pointLists addObject:pointValues];
+ }
+ return pointLists;
+ } else if ([self isMarkup]) {
+ NSPoint origin = [self bounds].origin;
+ NSMutableArray *pointLists = [NSMutableArray array];
+ NSMutableArray *pointValues;
+ NSPoint point;
+ NSInteger i, j, iMax = [[self quadrilateralPoints] count] / 4;
+ for (i = 0; i < iMax; i++) {
+ pointValues = [[NSMutableArray alloc] initWithCapacity:iMax];
+ for (j = 0; j < 4; j++) {
+ point = [[[self quadrilateralPoints] objectAtIndex:4 * i + j]
pointValue];
+ [pointValues addObject:[NSData
dataWithPointAsNSPoint:SKAddPoints(point, origin)]];
+ }
+ [pointLists addObject:pointValues];
+ }
+ return pointLists;
+ } else {
+ return nil;
+ }
}
- (SKPDFView *)containingPdfView {
Modified: trunk/SKMainDocument.m
===================================================================
--- trunk/SKMainDocument.m 2026-09-24 08:24:03 UTC (rev 16537)
+++ trunk/SKMainDocument.m 2026-09-26 21:41:10 UTC (rev 16538)
@@ -71,7 +71,6 @@
#import "NSDocument_SKExtensions.h"
#import "SKApplication.h"
#import "SKTextFieldSheetController.h"
-#import "PDFAnnotationMarkup_SKExtensions.h"
#import "NSWindowController_SKExtensions.h"
#import "SKSyncPreferences.h"
#import "NSScreen_SKExtensions.h"
Modified: trunk/SKNPDFAnnotationNote_SKExtensions.m
===================================================================
--- trunk/SKNPDFAnnotationNote_SKExtensions.m 2026-09-24 08:24:03 UTC (rev
16537)
+++ trunk/SKNPDFAnnotationNote_SKExtensions.m 2026-09-26 21:41:10 UTC (rev
16538)
@@ -54,9 +54,8 @@
NSString * const SKPDFAnnotationScriptingImageDataKey = @"scriptingImageData";
@interface SKNPDFAnnotationNote (SKPrivateDeclarations)
-- (NSTextStorage *)mutableText;
-- (NSArray *)texts;
-- (void)setTexts:(NSArray *)texts;
+@property (nonatomic, readonly) NSTextStorage *mutableText;
+@property (nonatomic, strong, nullable) NSArray *texts;
@end
@implementation SKNPDFAnnotationNote (SKExtensions)
@@ -138,40 +137,8 @@
- (NSString *)colorDefaultKey { return SKAnchoredNoteColorKey; }
-- (NSSet *)keysForValuesToObserveForUndo {
- static NSSet *noteKeys = nil;
- if (noteKeys == nil) {
- NSMutableSet *mutableKeys = [[super keysForValuesToObserveForUndo]
mutableCopy];
- [mutableKeys removeObject:SKNPDFAnnotationBorderKey];
- [mutableKeys addObject:SKNPDFAnnotationNameKey];
- [mutableKeys addObject:SKNPDFAnnotationTextKey];
- [mutableKeys addObject:SKNPDFAnnotationImageKey];
- [mutableKeys addObject:SKNPDFAnnotationDrawsImageKey];
- noteKeys = [mutableKeys copy];
- }
- return noteKeys;
-}
-
#pragma mark Scripting support
-+ (NSSet *)customScriptingKeys {
- static NSSet *customNoteScriptingKeys = nil;
- if (customNoteScriptingKeys == nil) {
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- NSMutableSet *customKeys = [[super customScriptingKeys] mutableCopy];
-#pragma clang diagnostic pop
- [customKeys removeObject:SKNPDFAnnotationLineWidthKey];
- [customKeys removeObject:SKNPDFAnnotationBorderStyleKey];
- [customKeys removeObject:SKNPDFAnnotationDashPatternKey];
- [customKeys addObject:SKPDFAnnotationScriptingIconTypeKey];
- [customKeys addObject:SKPDFAnnotationRichTextKey];
- [customKeys addObject:SKPDFAnnotationScriptingImageDataKey];
- customNoteScriptingKeys = [customKeys copy];
- }
- return customNoteScriptingKeys;
-}
-
- (id)richText {
return [self mutableText];
}
Modified: trunk/SKPDFView.m
===================================================================
--- trunk/SKPDFView.m 2026-09-24 08:24:03 UTC (rev 16537)
+++ trunk/SKPDFView.m 2026-09-26 21:41:10 UTC (rev 16538)
@@ -40,9 +40,6 @@
#import "SKImageToolTipWindow.h"
#import <SkimNotes/SkimNotes.h>
#import "PDFAnnotation_SKExtensions.h"
-#import "PDFAnnotationMarkup_SKExtensions.h"
-#import "PDFAnnotationInk_SKExtensions.h"
-#import "PDFAnnotationLine_SKExtensions.h"
#import "SKNPDFAnnotationNote_SKExtensions.h"
#import "PDFPage_SKExtensions.h"
#import "NSString_SKExtensions.h"
Modified: trunk/Skim.xcodeproj/project.pbxproj
===================================================================
--- trunk/Skim.xcodeproj/project.pbxproj 2026-09-24 08:24:03 UTC (rev
16537)
+++ trunk/Skim.xcodeproj/project.pbxproj 2026-09-26 21:41:10 UTC (rev
16538)
@@ -126,7 +126,6 @@
CE454B3E226DEB3C0034FD6B /* SKNoteTableRowView.m in Sources */
= {isa = PBXBuildFile; fileRef = CE454B3D226DEB3C0034FD6B /*
SKNoteTableRowView.m */; };
CE454B51226E33150034FD6B /* SKHighlightingTableRowView.m in
Sources */ = {isa = PBXBuildFile; fileRef = CE454B50226E33150034FD6B /*
SKHighlightingTableRowView.m */; };
CE455394111DA4290060CAC9 /* SKImageToolTipContext.m in Sources
*/ = {isa = PBXBuildFile; fileRef = CE455393111DA4290060CAC9 /*
SKImageToolTipContext.m */; };
- CE4642E50DF5CBD900CFD8D2 /* PDFAnnotationText_SKExtensions.m in
Sources */ = {isa = PBXBuildFile; fileRef = CE4642E40DF5CBD900CFD8D2 /*
PDFAnnotationText_SKExtensions.m */; };
CE4643CF0DF6B5A400CFD8D2 /* SKJoinCommand.m in Sources */ =
{isa = PBXBuildFile; fileRef = CE4643CE0DF6B5A400CFD8D2 /* SKJoinCommand.m */;
};
CE4645910DF8140200CFD8D2 /* SKNumberArrayFormatter.m in Sources
*/ = {isa = PBXBuildFile; fileRef = CE4645900DF8140200CFD8D2 /*
SKNumberArrayFormatter.m */; };
CE48BAD80C089EA300A166C6 /* SKTemplateParser.m in Sources */ =
{isa = PBXBuildFile; fileRef = CE48BAD60C089EA300A166C6 /* SKTemplateParser.m
*/; };
@@ -238,7 +237,6 @@
CEC1B0602BBF03AB006786B0 /* SKPDFSyncParser.m in Sources */ =
{isa = PBXBuildFile; fileRef = CEC1B05F2BBF03AB006786B0 /* SKPDFSyncParser.m
*/; };
CEC29533275A66A2000F2D4C /* SKNotePrefs.m in Sources */ = {isa
= PBXBuildFile; fileRef = CEC29532275A66A2000F2D4C /* SKNotePrefs.m */; };
CEC29536275A7D58000F2D4C /* SKPreferencesCommand.m in Sources
*/ = {isa = PBXBuildFile; fileRef = CEC29535275A7D58000F2D4C /*
SKPreferencesCommand.m */; };
- CEC3AD240E23EC0300F40B0B /* PDFAnnotationLink_SKExtensions.m in
Sources */ = {isa = PBXBuildFile; fileRef = CEC3AD230E23EC0300F40B0B /*
PDFAnnotationLink_SKExtensions.m */; };
CECB03D30DC7503A0000B16B /* SKGroupedSearchResult.m in Sources
*/ = {isa = PBXBuildFile; fileRef = CECB03D20DC7503A0000B16B /*
SKGroupedSearchResult.m */; };
CECDC4FF0C5966A80026AAEC /* NSImage_SKExtensions.m in Sources
*/ = {isa = PBXBuildFile; fileRef = CECDC4FD0C5966A80026AAEC /*
NSImage_SKExtensions.m */; };
CECE6C3F2188AE9A00F6179D /* SKSelectionCommand.m in Sources */
= {isa = PBXBuildFile; fileRef = CECE6C3E2188AE9A00F6179D /*
SKSelectionCommand.m */; };
@@ -283,27 +281,17 @@
CEE229390BFB7CE9002B746B /* ReleaseNotes.rtf in Resources */ =
{isa = PBXBuildFile; fileRef = CE54AA8E0BBC037400008750 /* ReleaseNotes.rtf */;
};
CEE22EA30BFB8672002B746B /* displayline in Copy Files: Shared
Support */ = {isa = PBXBuildFile; fileRef = CE1E2F120BDB86A10011D9DD /*
displayline */; };
CEE54D880DA2E37B0037169F /* PDFAnnotation_SKExtensions.m in
Sources */ = {isa = PBXBuildFile; fileRef = CEE54D870DA2E37B0037169F /*
PDFAnnotation_SKExtensions.m */; };
- CEE54D930DA2E5E10037169F /* PDFAnnotationCircle_SKExtensions.m
in Sources */ = {isa = PBXBuildFile; fileRef = CEE54D920DA2E5E10037169F /*
PDFAnnotationCircle_SKExtensions.m */; };
- CEE54D980DA2E6FC0037169F /* PDFAnnotationSquare_SKExtensions.m
in Sources */ = {isa = PBXBuildFile; fileRef = CEE54D970DA2E6FC0037169F /*
PDFAnnotationSquare_SKExtensions.m */; };
- CEE54D9C0DA2E7B30037169F /* PDFAnnotationLine_SKExtensions.m in
Sources */ = {isa = PBXBuildFile; fileRef = CEE54D9B0DA2E7B30037169F /*
PDFAnnotationLine_SKExtensions.m */; };
- CEE54DAE0DA2E8CD0037169F /*
PDFAnnotationFreeText_SKExtensions.m in Sources */ = {isa = PBXBuildFile;
fileRef = CEE54DAD0DA2E8CD0037169F /* PDFAnnotationFreeText_SKExtensions.m */;
};
- CEE54DB40DA2E99D0037169F /* PDFAnnotationMarkup_SKExtensions.m
in Sources */ = {isa = PBXBuildFile; fileRef = CEE54DB30DA2E99D0037169F /*
PDFAnnotationMarkup_SKExtensions.m */; };
CEE54F6C0DA3FB060037169F /* SKMainToolbarController.m in
Sources */ = {isa = PBXBuildFile; fileRef = CEE54F6B0DA3FB060037169F /*
SKMainToolbarController.m */; };
CEE54F700DA3FBE00037169F /* NSSegmentedControl_SKExtensions.m
in Sources */ = {isa = PBXBuildFile; fileRef = CEE54F6F0DA3FBE00037169F /*
NSSegmentedControl_SKExtensions.m */; };
CEE54F900DA3FE9A0037169F /* NSValueTransformer_SKExtensions.m
in Sources */ = {isa = PBXBuildFile; fileRef = CEE54F8F0DA3FE9A0037169F /*
NSValueTransformer_SKExtensions.m */; };
- CEE7E76524426BFF0034690E /*
PDFAnnotationTextWidget_SKExtensions.m in Sources */ = {isa = PBXBuildFile;
fileRef = CEE7E76424426BFF0034690E /* PDFAnnotationTextWidget_SKExtensions.m
*/; };
- CEE7E77824426C180034690E /*
PDFAnnotationButtonWidget_SKExtensions.m in Sources */ = {isa = PBXBuildFile;
fileRef = CEE7E77724426C180034690E /* PDFAnnotationButtonWidget_SKExtensions.m
*/; };
- CEE7E77B24426C380034690E /*
PDFAnnotationChoiceWidget_SKExtensions.m in Sources */ = {isa = PBXBuildFile;
fileRef = CEE7E77A24426C380034690E /* PDFAnnotationChoiceWidget_SKExtensions.m
*/; };
CEE8DFC80E5C806400EFA97F /* SkimNotes.framework in Copy Files:
Frameworks */ = {isa = PBXBuildFile; fileRef = CE7DC7320E09286500D6D76D /*
SkimNotes.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
CEE8DFC90E5C806400EFA97F /* Sparkle.framework in Copy Files:
Frameworks */ = {isa = PBXBuildFile; fileRef = CE2BD8200BD4127A00A5F4DB /*
Sparkle.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
CEE8DFCE0E5C809C00EFA97F /* SkimNotes.framework in Frameworks
*/ = {isa = PBXBuildFile; fileRef = CE7DC7320E09286500D6D76D /*
SkimNotes.framework */; };
CEE8DFCF0E5C809C00EFA97F /* Sparkle.framework in Frameworks */
= {isa = PBXBuildFile; fileRef = CE2BD8200BD4127A00A5F4DB /* Sparkle.framework
*/; };
CEE9BC0814CDD98100262718 /* SKBookmarkSheetController.m in
Sources */ = {isa = PBXBuildFile; fileRef = CEE9BC0714CDD98100262718 /*
SKBookmarkSheetController.m */; };
- CEEA05D32CCD49F400D7417A /* PDFAnnotationStamp_SKExtensions.m
in Sources */ = {isa = PBXBuildFile; fileRef = CEEA05D22CCD49F400D7417A /*
PDFAnnotationStamp_SKExtensions.m */; };
CEEC0A0A0DCB2594003DD9B6 /* SKMainWindowController_UI.m in
Sources */ = {isa = PBXBuildFile; fileRef = CEEC0A090DCB2594003DD9B6 /*
SKMainWindowController_UI.m */; };
CEECD61C12E9E30B00B9E35E /* NSError_SKExtensions.m in Sources
*/ = {isa = PBXBuildFile; fileRef = CEECD61B12E9E30B00B9E35E /*
NSError_SKExtensions.m */; };
CEED148C2709EE4D00A8C4AA /* SKBasePDFView.m in Sources */ =
{isa = PBXBuildFile; fileRef = CEED148B2709EE4D00A8C4AA /* SKBasePDFView.m */;
};
- CEEE7C520E7D3F2000B7B208 /* PDFAnnotationInk_SKExtensions.m in
Sources */ = {isa = PBXBuildFile; fileRef = CEEE7C510E7D3F2000B7B208 /*
PDFAnnotationInk_SKExtensions.m */; };
CEF02AEA2C087F3A001C150A /* SKThumbnailStamp.m in Sources */ =
{isa = PBXBuildFile; fileRef = CEF02AE92C087F3A001C150A /* SKThumbnailStamp.m
*/; };
CEF60D6A114C0DA60074ACC4 /* TransitionSheet.strings in
Resources */ = {isa = PBXBuildFile; fileRef = CEF60D40114C0DA60074ACC4 /*
TransitionSheet.strings */; };
CEF60D6C114C0DA60074ACC4 /* ScaleSheet.strings in Resources */
= {isa = PBXBuildFile; fileRef = CEF60D44114C0DA60074ACC4 /* ScaleSheet.strings
*/; };
@@ -3102,7 +3090,6 @@
CE3A41580B790C56006B64D3 /* SKDragImageView.m
in Sources */,
CE3A45530B7A04A4006B64D3 /*
NSBezierPath_SKExtensions.m in Sources */,
CEBCA4C02868A93A00E6376E /* SKLine.m in Sources
*/,
- CEEA05D32CCD49F400D7417A /*
PDFAnnotationStamp_SKExtensions.m in Sources */,
CE4EBDDA0B7BF3B30091F228 /* SKSideWindow.m in
Sources */,
CE2526362B3834E40084F43D /*
NSToolbarItem_SKExtensions.m in Sources */,
CE38ECD30B8093B200A1B779 /*
NSString_SKExtensions.m in Sources */,
@@ -3113,7 +3100,6 @@
CE820AEF21A04EB100AD34BE /*
NSWindow_SKExtensions.m in Sources */,
CE2DE4EE0B85DB6300D0DA12 /*
NSCursor_SKExtensions.m in Sources */,
CE2DE4FD0B85DBD400D0DA12 /*
SKImageToolTipWindow.m in Sources */,
- CEE7E77B24426C380034690E /*
PDFAnnotationChoiceWidget_SKExtensions.m in Sources */,
CE2DE50D0B85DC4000D0DA12 /*
PDFPage_SKExtensions.m in Sources */,
CE2DEB1C0B8618DE00D0DA12 /* SKFindController.m
in Sources */,
CE2DED6C0B86334900D0DA12 /* SKFieldEditor.m in
Sources */,
@@ -3184,24 +3170,17 @@
CEA8FCD60D89C34A00E8A6F4 /*
SKAnimatedBorderlessWindow.m in Sources */,
CEB4EC502D87409100CA01A1 /*
SKNoteToolbarController.m in Sources */,
CEE54D880DA2E37B0037169F /*
PDFAnnotation_SKExtensions.m in Sources */,
- CEE54D930DA2E5E10037169F /*
PDFAnnotationCircle_SKExtensions.m in Sources */,
- CEE54D980DA2E6FC0037169F /*
PDFAnnotationSquare_SKExtensions.m in Sources */,
CECE6C3F2188AE9A00F6179D /*
SKSelectionCommand.m in Sources */,
- CEE54D9C0DA2E7B30037169F /*
PDFAnnotationLine_SKExtensions.m in Sources */,
- CEE54DAE0DA2E8CD0037169F /*
PDFAnnotationFreeText_SKExtensions.m in Sources */,
- CEE54DB40DA2E99D0037169F /*
PDFAnnotationMarkup_SKExtensions.m in Sources */,
CE5CB23F2740329E00315060 /*
SKChainedUndoManager.m in Sources */,
CEE54F6C0DA3FB060037169F /*
SKMainToolbarController.m in Sources */,
CEE54F700DA3FBE00037169F /*
NSSegmentedControl_SKExtensions.m in Sources */,
CEE54F900DA3FE9A0037169F /*
NSValueTransformer_SKExtensions.m in Sources */,
CECF61FF0DB258D600587D96 /* SKFontWell.m in
Sources */,
- CEE7E77824426C180034690E /*
PDFAnnotationButtonWidget_SKExtensions.m in Sources */,
CEE176E40DBD5B0C00E6C317 /*
PDFDocumentView_SKExtensions.m in Sources */,
CECB03D30DC7503A0000B16B /*
SKGroupedSearchResult.m in Sources */,
CEEC0A0A0DCB2594003DD9B6 /*
SKMainWindowController_UI.m in Sources */,
CE7F43910DE1F1980061A839 /*
NSUserDefaults_SKExtensions.m in Sources */,
CE0ECD1C0DE73604006EEDDB /*
NSDocument_SKExtensions.m in Sources */,
- CE4642E50DF5CBD900CFD8D2 /*
PDFAnnotationText_SKExtensions.m in Sources */,
CE4643CF0DF6B5A400CFD8D2 /* SKJoinCommand.m in
Sources */,
CE4645910DF8140200CFD8D2 /*
SKNumberArrayFormatter.m in Sources */,
CE34FFA80DFF58FB00A7FFE6 /*
NSEvent_SKExtensions.m in Sources */,
@@ -3210,12 +3189,10 @@
CE08EBF5218C5DCD00D2DFCC /*
NSPasteboard_SKExtensions.m in Sources */,
CEDC7B1A2913CD2500032269 /* SKLoupeController.m
in Sources */,
CE3401E60E01388700A7FFE6 /*
NSNumber_SKExtensions.m in Sources */,
- CEC3AD240E23EC0300F40B0B /*
PDFAnnotationLink_SKExtensions.m in Sources */,
CE3364310E2761E9005F99E6 /* synctex_parser.c in
Sources */,
CE3366DF0E28BCFA005F99E6 /* SKPDFSyncRecord.m
in Sources */,
CEC29536275A7D58000F2D4C /*
SKPreferencesCommand.m in Sources */,
CE09FC3C0E3886C100BDF413 /* SKRuntime.m in
Sources */,
- CEEE7C520E7D3F2000B7B208 /*
PDFAnnotationInk_SKExtensions.m in Sources */,
CE05A7380E9024ED0060BB07 /*
SKPresentationOptionsSheetController.m in Sources */,
CEDE68E5201FDCB5000D881A /* SKKeychain.m in
Sources */,
CE05A86F0E90ED950060BB07 /*
SKTextFieldSheetController.m in Sources */,
@@ -3223,7 +3200,6 @@
CE7611650EA49D1400301E45 /* SKPrintableView.m
in Sources */,
CE19E7A9275B7BC1007EBD8B /* SKDisplayPrefs.m in
Sources */,
CE32531F0F4723EA0021BADD /*
SKMainWindowController_Actions.m in Sources */,
- CEE7E76524426BFF0034690E /*
PDFAnnotationTextWidget_SKExtensions.m in Sources */,
CE9B804A1030642400EA8774 /* SKTransitionInfo.m
in Sources */,
CEA2045F1050233E008E082B /*
SKPrintAccessoryController.m in Sources */,
CE5BAF4410511A0F00161B87 /*
PDFOutline_SKExtensions.m in Sources */,
@@ -3480,7 +3456,7 @@
CE157ED512D4EBC000515B85 /* ja */,
CE1632AC1582AC1300CFF419 /* zh_CN */,
CE0E84EF114D521F00E37F38 /* zh_TW */,
-x );
+ );
name = DisplayPreferences.strings;
sourceTree = "<group>";
};
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
_______________________________________________
Skim-app-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/skim-app-commit