Revision: 16397
          http://sourceforge.net/p/skim-app/code/16397
Author:   hofman
Date:     2026-07-24 09:26:51 +0000 (Fri, 24 Jul 2026)
Log Message:
-----------
Fix degenerate bounds for find result, which can happen due to PDFKit bugs on 
Tahoe.

Modified Paths:
--------------
    trunk/PDFSelection_SKExtensions.h
    trunk/PDFSelection_SKExtensions.m
    trunk/SKMainWindowController.m

Modified: trunk/PDFSelection_SKExtensions.h
===================================================================
--- trunk/PDFSelection_SKExtensions.h   2026-07-23 22:45:47 UTC (rev 16396)
+++ trunk/PDFSelection_SKExtensions.h   2026-07-24 09:26:51 UTC (rev 16397)
@@ -58,6 +58,8 @@
 
 - (BOOL)hasCharacters;
 
+- (NSRect)safeBoundsForPage:(PDFPage *)page;
+
 - (CGFloat)boundsOrderForPage:(PDFPage *)page;
 
 - (NSArray<PDFSelection *> *)connectedSelectionsOnPage:(nullable PDFPage 
*)page;

Modified: trunk/PDFSelection_SKExtensions.m
===================================================================
--- trunk/PDFSelection_SKExtensions.m   2026-07-23 22:45:47 UTC (rev 16396)
+++ trunk/PDFSelection_SKExtensions.m   2026-07-24 09:26:51 UTC (rev 16397)
@@ -251,6 +251,26 @@
     return [self safeFirstPage] != nil;
 }
 
+- (NSRect)safeBoundsForPage:(PDFPage *)page {
+    NSRect rect = [self boundsForPage:page];
+    if (isfinite(NSMinX(rect)) == NO || isfinite(NSMinX(rect)) == NO || 
NSIsEmptyRect(rect)) {
+        // On Tahoe, boundsForPage: can return a degenerate rect
+        // for selections found inside certain table-structured PDFs.
+        // Reconstruct from per-character bounds instead,
+        // which use a different PDFKit code path and are unaffected.
+        NSUInteger firstIndex = [self safeIndexOfFirstCharacterOnPage:page];
+        if (firstIndex != NSNotFound) {
+            rect = [page characterBoundsAtIndex:firstIndex];
+            NSUInteger lastIndex = [self safeIndexOfLastCharacterOnPage:page];
+            if (lastIndex != firstIndex && lastIndex != NSNotFound)
+                rect = NSUnionRect(rect, [page 
characterBoundsAtIndex:lastIndex]);
+            if (isfinite(NSMinX(rect)) == NO || isfinite(NSMinX(rect)) == NO)
+                rect = [[page selectionForRect:[page 
boundsForBox:kPDFDisplayBoxCropBox]] boundsForPage:page];
+        }
+    }
+    return rect;
+}
+
 - (CGFloat)boundsOrderForPage:(PDFPage *)page {
     NSUInteger i = [self safeIndexOfFirstCharacterOnPage:page];
     return [page sortOrderForBounds:[(i == NSNotFound ? self : [page 
selectionForRange:NSMakeRange(i, 1)]) boundsForPage:page]];

Modified: trunk/SKMainWindowController.m
===================================================================
--- trunk/SKMainWindowController.m      2026-07-23 22:45:47 UTC (rev 16396)
+++ trunk/SKMainWindowController.m      2026-07-24 09:26:51 UTC (rev 16397)
@@ -1806,9 +1806,9 @@
     PDFSelection *selection = [pdfDoc findString:string fromSelection:sel 
withOptions:options];
     if ([selection hasCharacters] == NO && [sel hasCharacters])
         selection = [pdfDoc findString:string fromSelection:nil 
withOptions:options];
-    if ([selection hasCharacters]) {
-        PDFPage *page = [selection safeFirstPage];
-        NSRect rect = [selection boundsForPage:page];
+    PDFPage *page = [selection safeFirstPage];
+    if (page) {
+        NSRect rect = [selection safeBoundsForPage:page];
         rect = NSIntersectionRect(NSInsetRect(rect, -FIND_RESULT_MARGIN, 
-FIND_RESULT_MARGIN), [page boundsForBox:kPDFDisplayBoxCropBox]);
         [pdfView goToRect:rect onPage:page];
         [leftSideController.findTableView deselectAll:self];

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