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

Reply via email to