Revision: 15208
http://sourceforge.net/p/skim-app/code/15208
Author: hofman
Date: 2025-05-14 15:30:52 +0000 (Wed, 14 May 2025)
Log Message:
-----------
draw page for tooltip image directly in image bbitmap instead of first drawing
a full thumbnail, avoids drawing parts of the image that won't be visible, and
potentially can be expensive.
Modified Paths:
--------------
trunk/SKImageToolTipContext.m
Modified: trunk/SKImageToolTipContext.m
===================================================================
--- trunk/SKImageToolTipContext.m 2025-05-13 21:44:48 UTC (rev 15207)
+++ trunk/SKImageToolTipContext.m 2025-05-14 15:30:52 UTC (rev 15208)
@@ -48,6 +48,8 @@
#import "NSColor_SKExtensions.h"
#import "NSAttributedString_SKExtensions.h"
#import "PDFDestination_SKExtensions.h"
+#import "NSBitmapImageRep_SKExtensions.h"
+#import "SKStringConstants.h"
#define TEXT_MARGIN_X 2.0
#define TEXT_MARGIN_Y 2.0
@@ -112,31 +114,21 @@
if (labelColor == nil)
labelColor = [NSColor colorWithGenericGamma22White:0.55 alpha:0.8];
- if (selections) {
- selections = [[NSArray alloc] initWithArray:selections copyItems:YES];
- [selections setValue:[NSColor findHighlightColor] forKey:@"color"];
- }
+ PDFPage *page = [self page];
- BOOL isScaled = fabs(scale - 1.0) > 0.01;
- PDFPage *page = [self page];
+ if (page == nil)
+ return nil;
+
+ NSRect sourceRect = NSZeroRect;
NSPoint point = [[self effectiveDestinationForView:nil] point];
NSRect bounds = [page boundsForBox:kPDFDisplayBoxCropBox];
- CGFloat size = isScaled ? ceil(scale * fmax(NSWidth(bounds),
NSHeight(bounds))) : 0.0;
- NSImage *pageImage = [page thumbnailWithSize:size scale:backingScale
forBox:kPDFDisplayBoxCropBox hasShadow:NO highlights:selections];
- NSRect pageImageRect = {NSZeroPoint, [pageImage size]};
- NSRect sourceRect = NSZeroRect;
- PDFSelection *pageSelection = [page selectionForRect:bounds];
- NSRect selBounds;
NSAffineTransform *transform = [page
affineTransformForBox:kPDFDisplayBoxCropBox];
- if (isScaled) {
+ if (fabs(scale - 1.0) > 0.0) {
NSAffineTransform *scaleTransform = [NSAffineTransform transform];
- [scaleTransform scaleBy:size / fmax(NSWidth(bounds),
NSHeight(bounds))];
+ [scaleTransform scaleBy:scale];
[transform appendTransform:scaleTransform];
}
- if (page == nil)
- return nil;
-
sourceRect.size.width = [[NSUserDefaults standardUserDefaults]
doubleForKey:SKToolTipWidthKey];
sourceRect.size.height = [[NSUserDefaults standardUserDefaults]
doubleForKey:SKToolTipHeightKey];
sourceRect.origin = [transform transformPoint:point];
@@ -143,7 +135,9 @@
sourceRect.origin.x -= OFFSET_X;
sourceRect.origin.y -= NSHeight(sourceRect) - OFFSET_Y;
- if ([pageSelection hasCharacters])
+ NSRect selBounds;
+ PDFSelection *pageSelection = [page selectionForRect:bounds];
+ if ([pageSelection hasCharacters])
selBounds = NSIntersectionRect(NSInsetRect([pageSelection
boundsForPage:page], -2.0, -2.0), bounds);
else
selBounds = [page boundingBox];
@@ -151,13 +145,25 @@
sourceRect.origin.x = fmax(floor(NSMinX(selBounds)),
fmin(floor(NSMaxX(selBounds) - NSWidth(sourceRect)), NSMinX(sourceRect)));
sourceRect.origin.y = fmin(ceil(NSMaxY(selBounds)),
fmax(ceil(NSMinY(selBounds) + NSHeight(sourceRect)), NSMaxY(sourceRect))) -
NSHeight(sourceRect);
- sourceRect = SKConstrainRect(sourceRect, pageImageRect);
+ NSRect pageRect = NSZeroRect;
+ if (([page rotation] % 180)) {
+ pageRect.size.width = round(scale * NSHeight(bounds));
+ pageRect.size.height = round(scale * NSWidth(bounds));
+ } else {
+ pageRect.size.width = round(scale * NSWidth(bounds));
+ pageRect.size.height = round(scale * NSHeight(bounds));
+ }
+ sourceRect = SKConstrainRect(sourceRect, pageRect);
+ if (selections) {
+ selections = [[NSArray alloc] initWithArray:selections copyItems:YES];
+ [selections setValue:[NSColor findHighlightColor] forKey:@"color"];
+ }
+
if (label == nil)
label = [NSString stringWithFormat:NSLocalizedString(@"Page %@",
@"Tool tip label format"), [page displayLabel]];
NSAttributedString *labelString = [[NSAttributedString alloc]
initWithString:label attributes:labelAttributes];
NSRect labelRect = [labelString boundingRectWithSize:NSZeroSize
options:NSStringDrawingUsesLineFragmentOrigin];
-
labelRect.size.width = floor(NSWidth(labelRect));
labelRect.size.height = 2.0 * floor(0.5 * NSHeight(labelRect)); // make
sure the cap radius is integral
labelRect.origin.x = NSWidth(sourceRect) - NSWidth(labelRect) - 0.5 *
NSHeight(labelRect) - TEXT_MARGIN_X;
@@ -164,28 +170,44 @@
labelRect.origin.y = TEXT_MARGIN_Y;
labelRect = NSIntegralRect(labelRect);
- NSImage *image = [NSImage imageWithSize:sourceRect.size flipped:NO
drawingHandler:^(NSRect dstRect){
+ CGFloat radius = 0.5 * NSHeight(labelRect);
+ NSBezierPath *path = [NSBezierPath bezierPath];
+ [path moveToPoint:SKTopLeftPoint(labelRect)];
+ [path appendBezierPathWithArcWithCenter:NSMakePoint(NSMinX(labelRect),
NSMidY(labelRect)) radius:radius startAngle:90.0 endAngle:270.0];
+ [path appendBezierPathWithArcWithCenter:NSMakePoint(NSMaxX(labelRect),
NSMidY(labelRect)) radius:radius startAngle:-90.0 endAngle:90.0];
+ [path closePath];
+
+ transform = [NSAffineTransform transform];
+ [transform translateXBy:-NSMinX(sourceRect) yBy:-NSMinY(sourceRect)];
+ [transform scaleBy:scale];
+
+ NSBitmapImageRep *imageRep = [NSBitmapImageRep
imageRepWithSize:sourceRect.size scale:backingScale drawingHandler:^(NSRect
dstRect){
- [pageImage drawInRect:dstRect fromRect:sourceRect
operation:NSCompositingOperationCopy fraction:1.0];
+ [NSGraphicsContext saveGraphicsState];
+ [[NSColor whiteColor] setFill];
+ NSRectFill(dstRect);
+ [NSGraphicsContext restoreGraphicsState];
- CGFloat radius = 0.5 * NSHeight(labelRect);
- NSBezierPath *path = [NSBezierPath bezierPath];
+ [NSGraphicsContext saveGraphicsState];
+ [[NSGraphicsContext currentContext]
setImageInterpolation:[[NSUserDefaults standardUserDefaults]
integerForKey:SKInterpolationQualityKey] + 1];
+ [transform concat];
+ [page drawWithBox:kPDFDisplayBoxCropBox toContext:[[NSGraphicsContext
currentContext] CGContext]];
+ for (PDFSelection *selection in selections)
+ [selection drawForPage:page withBox:kPDFDisplayBoxCropBox
active:YES];
+ [NSGraphicsContext restoreGraphicsState];
- [path moveToPoint:SKTopLeftPoint(labelRect)];
- [path appendBezierPathWithArcWithCenter:NSMakePoint(NSMinX(labelRect),
NSMidY(labelRect)) radius:radius startAngle:90.0 endAngle:270.0];
- [path appendBezierPathWithArcWithCenter:NSMakePoint(NSMaxX(labelRect),
NSMidY(labelRect)) radius:radius startAngle:-90.0 endAngle:90.0];
- [path closePath];
-
+ [NSGraphicsContext saveGraphicsState];
[labelColor setFill];
[path fill];
-
[labelString drawWithRect:labelRect
options:NSStringDrawingUsesLineFragmentOrigin];
-
- return YES;
+ [NSGraphicsContext restoreGraphicsState];
}];
- [[[image representations] firstObject] setOpaque:YES];
+ [imageRep setOpaque:YES];
+ NSImage *image = [[NSImage alloc] initWithSize:sourceRect.size];
+ [image addRepresentation:imageRep];
+
return image;
}
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