Revision: 16582
http://sourceforge.net/p/skim-app/code/16582
Author: hofman
Date: 2026-10-01 15:57:20 +0000 (Thu, 01 Oct 2026)
Log Message:
-----------
try to reconstruct text attributedstring from embedded Text or Stamp
annotations, when they have a /SkimContents value
Modified Paths:
--------------
trunk/SkimNotes/PDFAnnotation_SKNExtensions.m
trunk/SkimNotes/skimpdf.m
Modified: trunk/SkimNotes/PDFAnnotation_SKNExtensions.m
===================================================================
--- trunk/SkimNotes/PDFAnnotation_SKNExtensions.m 2026-10-01 15:41:47 UTC
(rev 16581)
+++ trunk/SkimNotes/PDFAnnotation_SKNExtensions.m 2026-10-01 15:57:20 UTC
(rev 16582)
@@ -728,29 +728,61 @@
Class arrayClass = [NSArray class];
Class stringClass = [NSString class];
- if ([type isEqualToString:SKNTextString] || [type
isEqualToString:SKNNoteString]) {
+ if ([type isEqualToString:SKNFreeTextString]) {
- if ([self respondsToSelector:@selector(iconType)])
- [dict setValue:[NSNumber numberWithInteger:[(id)self
iconType]] forKey:SKNPDFAnnotationIconTypeKey];
- else if ((value = [self valueForAnnotationKey:@"/Name"]))
- [dict setValue:[NSNumber
numberWithInteger:SKNIconTypeFromAnnotationValue(value)]
forKey:SKNPDFAnnotationIconTypeKey];
+ if ([self respondsToSelector:@selector(alignment)]) {
+ [dict setValue:[NSNumber
numberWithInteger:SKNAlignmentFromTextAlignment([(id)self alignment])]
forKey:SKNPDFAnnotationAlignmentKey];
+ } else if ((value = [self valueForAnnotationKey:@"/Q"])) {
+ [dict setValue:[NSNumber
numberWithInteger:SKNAlignmentFromTextAlignment([value integerValue])]
forKey:SKNPDFAnnotationAlignmentKey];
+ }
- } else if ([type isEqualToString:SKNStampString]) {
+ PDFKitPlatformFont *font = nil;
+ if ([self respondsToSelector:@selector(font)]) {
+ font = [(id)self font];
+ }
+ if (font == nil && (value = [self valueForAnnotationKey:@"/DA"])) {
+ NSScanner *scanner = [[NSScanner alloc] initWithString:value];
+ NSString *fontName;
+ double fontSize;
+ if ([scanner scanUpToString:@"Tf" intoString:NULL] && [scanner
isAtEnd] == NO) {
+ NSUInteger location = [scanner scanLocation];
+ NSRange r = [value rangeOfString:@"/"
options:NSBackwardsSearch range:NSMakeRange(0, location)];
+ if (r.location != NSNotFound) {
+ [scanner setScanLocation:NSMaxRange(r)];
+ if ([scanner scanUpToCharactersFromSet:[NSCharacterSet
whitespaceAndNewlineCharacterSet] intoString:&fontName] &&
+ [scanner scanDouble:&fontSize] &&
+ [scanner scanString:@"Tf" intoString:NULL] &&
+ [scanner scanLocation] == location + 2) {
+ font = [PDFKitPlatformFont fontWithName:fontName
size:fontSize];
+ }
+ }
+ }
+ }
+ if (font)
+ [dict setObject:font forKey:SKNPDFAnnotationFontKey];
- if ([self respondsToSelector:@selector(stampName)])
- value = [self stampName];
- else
- value = [self valueForAnnotationKey:@"/Name"];
- if (value) {
- [dict setValue:value forKey:SKNPDFAnnotationNameKey];
- if ([[NSSet setWithObjects:@"/Comment", @"/Key", @"/Note",
@"/Help", @"/NewParagraph", @"/Paragraph", @"/Insert", nil]
containsObject:value]) {
- if ([self respondsToSelector:@selector(iconType)])
- [dict setValue:[NSNumber numberWithInteger:[(id)self
iconType]] forKey:SKNPDFAnnotationIconTypeKey];
- else
- [dict setValue:[NSNumber
numberWithInteger:SKNIconTypeFromAnnotationValue(value)]
forKey:SKNPDFAnnotationIconTypeKey];
+ PDFKitPlatformColor *fontColor = nil;
+ if ([self respondsToSelector:@selector(fontColor)]) {
+ fontColor = [(id)self fontColor];
+ }
+ if (fontColor == nil && (value = [self
valueForAnnotationKey:@"/DA"])) {
+ NSUInteger end = [value rangeOfString:@"rg"].location;
+ if (end != NSNotFound) {
+ NSCharacterSet *numberChars = [NSCharacterSet
characterSetWithCharactersInString:@"0123456789. "];
+ NSUInteger start = end;
+ while (start > 0 && [numberChars characterIsMember:[value
characterAtIndex:start--]]) {}
+ if (start < end) {
+ NSScanner *scanner = [[NSScanner alloc]
initWithString:[value substringWithRange:NSMakeRange(start, end - start)]];
+ CGFloat c;
+ NSMutableArray *array = [NSMutableArray array];
+ while ([scanner scanDouble:&c])
+ [array addObject:[NSNumber numberWithDouble:c]];
+ fontColor = SKNColorFromArray(array);
+ }
}
}
- [dict setValue:appearanceImageForAnnotation(self)
forKey:SKNPDFAnnotationImageKey];
+ if (fontColor)
+ [dict setObject:fontColor forKey:SKNPDFAnnotationFontColorKey];
} else if (([type isEqualToString:SKNCircleString] || [type
isEqualToString:SKNSquareString]) || [type isEqualToString:SKNLineString]) {
@@ -872,61 +904,64 @@
}
}
- } else if ([type isEqualToString:SKNFreeTextString]) {
+ } else if ([type isEqualToString:SKNTextString] || [type
isEqualToString:SKNStampString] || [type isEqualToString:SKNNoteString]) {
- if ([self respondsToSelector:@selector(alignment)]) {
- [dict setValue:[NSNumber
numberWithInteger:SKNAlignmentFromTextAlignment([(id)self alignment])]
forKey:SKNPDFAnnotationAlignmentKey];
- } else if ((value = [self valueForAnnotationKey:@"/Q"])) {
- [dict setValue:[NSNumber
numberWithInteger:SKNAlignmentFromTextAlignment([value integerValue])]
forKey:SKNPDFAnnotationAlignmentKey];
+ value = [self valueForAnnotationKey:@"/SkimContents"];
+ if ([value isKindOfClass:stringClass]) {
+ NSString *contents = [self contents];
+ if ([contents hasPrefix:value] && [contents length] > [value
length] + 1) {
+ NSUInteger i = [value length];
+ while (i < [contents length] && [[NSCharacterSet
whitespaceAndNewlineCharacterSet] characterIsMember:[contents
characterAtIndex:i]])
+ ++i;
+ if (i < [contents length] && i > [value length]) {
+ [dict setValue:value
forKey:SKNPDFAnnotationContentsKey];
+ [dict setValue:[[NSAttributedString alloc]
initWithString:[contents substringFromIndex:i]] forKey:SKNPDFAnnotationTextKey];
+ }
+ }
}
- PDFKitPlatformFont *font = nil;
- if ([self respondsToSelector:@selector(font)]) {
- font = [(id)self font];
- }
- if (font == nil && (value = [self valueForAnnotationKey:@"/DA"])) {
- NSScanner *scanner = [[NSScanner alloc] initWithString:value];
- NSString *fontName;
- double fontSize;
- if ([scanner scanUpToString:@"Tf" intoString:NULL] && [scanner
isAtEnd] == NO) {
- NSUInteger location = [scanner scanLocation];
- NSRange r = [value rangeOfString:@"/"
options:NSBackwardsSearch range:NSMakeRange(0, location)];
- if (r.location != NSNotFound) {
- [scanner setScanLocation:NSMaxRange(r)];
- if ([scanner scanUpToCharactersFromSet:[NSCharacterSet
whitespaceAndNewlineCharacterSet] intoString:&fontName] &&
- [scanner scanDouble:&fontSize] &&
- [scanner scanString:@"Tf" intoString:NULL] &&
- [scanner scanLocation] == location + 2) {
- font = [PDFKitPlatformFont fontWithName:fontName
size:fontSize];
- }
+ if ([type isEqualToString:SKNStampString]) {
+
+ if ([self respondsToSelector:@selector(stampName)])
+ value = [self stampName];
+ else
+ value = [self valueForAnnotationKey:@"/Name"];
+ if (value) {
+ [dict setValue:value forKey:SKNPDFAnnotationNameKey];
+ if ([[NSSet setWithObjects:@"/Comment", @"/Key", @"/Note",
@"/Help", @"/NewParagraph", @"/Paragraph", @"/Insert", nil]
containsObject:value]) {
+ if ([self respondsToSelector:@selector(iconType)])
+ [dict setValue:[NSNumber
numberWithInteger:[(id)self iconType]] forKey:SKNPDFAnnotationIconTypeKey];
+ else
+ [dict setValue:[NSNumber
numberWithInteger:SKNIconTypeFromAnnotationValue(value)]
forKey:SKNPDFAnnotationIconTypeKey];
}
}
+ [dict setValue:appearanceImageForAnnotation(self)
forKey:SKNPDFAnnotationImageKey];
+
+ } else {
+
+ if ([self respondsToSelector:@selector(iconType)])
+ [dict setValue:[NSNumber numberWithInteger:[(id)self
iconType]] forKey:SKNPDFAnnotationIconTypeKey];
+ else if ((value = [self valueForAnnotationKey:@"/Name"]))
+ [dict setValue:[NSNumber
numberWithInteger:SKNIconTypeFromAnnotationValue(value)]
forKey:SKNPDFAnnotationIconTypeKey];
+
}
- if (font)
- [dict setObject:font forKey:SKNPDFAnnotationFontKey];
- PDFKitPlatformColor *fontColor = nil;
- if ([self respondsToSelector:@selector(fontColor)]) {
- fontColor = [(id)self fontColor];
- }
- if (fontColor == nil && (value = [self
valueForAnnotationKey:@"/DA"])) {
- NSUInteger end = [value rangeOfString:@"rg"].location;
- if (end != NSNotFound) {
- NSCharacterSet *numberChars = [NSCharacterSet
characterSetWithCharactersInString:@"0123456789. "];
- NSUInteger start = end;
- while (start > 0 && [numberChars characterIsMember:[value
characterAtIndex:start--]]) {}
- if (start < end) {
- NSScanner *scanner = [[NSScanner alloc]
initWithString:[value substringWithRange:NSMakeRange(start, end - start)]];
- CGFloat c;
- NSMutableArray *array = [NSMutableArray array];
- while ([scanner scanDouble:&c])
- [array addObject:[NSNumber numberWithDouble:c]];
- fontColor = SKNColorFromArray(array);
- }
+ } else if ([type isEqualToString:SKNStampString]) {
+
+ if ([self respondsToSelector:@selector(stampName)])
+ value = [self stampName];
+ else
+ value = [self valueForAnnotationKey:@"/Name"];
+ if (value) {
+ [dict setValue:value forKey:SKNPDFAnnotationNameKey];
+ if ([[NSSet setWithObjects:@"/Comment", @"/Key", @"/Note",
@"/Help", @"/NewParagraph", @"/Paragraph", @"/Insert", nil]
containsObject:value]) {
+ if ([self respondsToSelector:@selector(iconType)])
+ [dict setValue:[NSNumber numberWithInteger:[(id)self
iconType]] forKey:SKNPDFAnnotationIconTypeKey];
+ else
+ [dict setValue:[NSNumber
numberWithInteger:SKNIconTypeFromAnnotationValue(value)]
forKey:SKNPDFAnnotationIconTypeKey];
}
}
- if (fontColor)
- [dict setObject:fontColor forKey:SKNPDFAnnotationFontColorKey];
+ [dict setValue:appearanceImageForAnnotation(self)
forKey:SKNPDFAnnotationImageKey];
} else if ([type isEqualToString:SKNWidgetString]) {
Modified: trunk/SkimNotes/skimpdf.m
===================================================================
--- trunk/SkimNotes/skimpdf.m 2026-10-01 15:41:47 UTC (rev 16581)
+++ trunk/SkimNotes/skimpdf.m 2026-10-01 15:57:20 UTC (rev 16582)
@@ -380,16 +380,18 @@
NSDictionary *note = [annotation
SkimNoteProperties];
if ([[annotation type]
isEqualToString:SKNTextString] || [[annotation type]
isEqualToString:SKNStampString]) {
NSMutableDictionary *mutableNote = [note
mutableCopy];
- NSString *contents = [note
objectForKey:SKNPDFAnnotationContentsKey];
- if (contents) {
- NSRange r = [contents rangeOfString:@" "];
- NSRange r1 = [contents
rangeOfString:@"\n"];
- if (r1.location < r.location)
- r = r1;
- if (NSMaxRange(r) < [contents length]) {
- NSAttributedString *attrString =
[[NSAttributedString alloc] initWithString:[contents
substringFromIndex:NSMaxRange(r)]];
- [mutableNote setObject:attrString
forKey:SKNPDFAnnotationTextKey];
- [mutableNote setObject:[contents
substringToIndex:r.location] forKey:SKNPDFAnnotationContentsKey];
+ if ([note
objectForKey:SKNPDFAnnotationTextKey] == nil) {
+ NSString *contents = [note
objectForKey:SKNPDFAnnotationContentsKey];
+ if (contents) {
+ NSRange r = [contents rangeOfString:@"
"];
+ NSRange r1 = [contents
rangeOfString:@"\n"];
+ if (r1.location < r.location)
+ r = r1;
+ if (NSMaxRange(r) < [contents length])
{
+ NSAttributedString *attrString =
[[NSAttributedString alloc] initWithString:[contents
substringFromIndex:NSMaxRange(r)]];
+ [mutableNote setObject:attrString
forKey:SKNPDFAnnotationTextKey];
+ [mutableNote setObject:[contents
substringToIndex:r.location] forKey:SKNPDFAnnotationContentsKey];
+ }
}
}
[mutableNote setObject:SKNNoteString
forKey:SKNPDFAnnotationTypeKey];
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