Revision: 16295
http://sourceforge.net/p/skim-app/code/16295
Author: hofman
Date: 2026-05-23 16:24:47 +0000 (Sat, 23 May 2026)
Log Message:
-----------
Add app extensions for quicklook thumbnailing and preview to support quicklook
in 15+. Set app version for whole project in config file instead of Info.plist
and using apple generic versioning, the versions of the app extensions must be
equal to the app.
Modified Paths:
--------------
trunk/Configurations/Skim-App.xcconfig
trunk/Configurations/Skim-Common.xcconfig
trunk/Info.plist
trunk/Skim.xcodeproj/project.pbxproj
Added Paths:
-----------
trunk/Configurations/SkimQuickLookPreview.xcconfig
trunk/Configurations/SkimQuickLookThumbnails.xcconfig
trunk/SkimQuickLookPreview/
trunk/SkimQuickLookPreview/Base.lproj/
trunk/SkimQuickLookPreview/Circle.png
trunk/SkimQuickLookPreview/FreeText.png
trunk/SkimQuickLookPreview/Highlight.png
trunk/SkimQuickLookPreview/Info.plist
trunk/SkimQuickLookPreview/Ink.png
trunk/SkimQuickLookPreview/Line.png
trunk/SkimQuickLookPreview/New Group/
trunk/SkimQuickLookPreview/Note.png
trunk/SkimQuickLookPreview/SKPreviewProvider.h
trunk/SkimQuickLookPreview/SKPreviewProvider.m
trunk/SkimQuickLookPreview/SKQLConverter.h
trunk/SkimQuickLookPreview/SKQLConverter.m
trunk/SkimQuickLookPreview/SkimQuickLookPreview.entitlements
trunk/SkimQuickLookPreview/Square.png
trunk/SkimQuickLookPreview/StrikeOut.png
trunk/SkimQuickLookPreview/Underline.png
trunk/SkimQuickLookPreview/Widget.png
trunk/SkimQuickLookThumbnails/
trunk/SkimQuickLookThumbnails/Circle.png
trunk/SkimQuickLookThumbnails/FreeText.png
trunk/SkimQuickLookThumbnails/Highlight.png
trunk/SkimQuickLookThumbnails/Info.plist
trunk/SkimQuickLookThumbnails/Ink.png
trunk/SkimQuickLookThumbnails/Line.png
trunk/SkimQuickLookThumbnails/Note.png
trunk/SkimQuickLookThumbnails/Resources/
trunk/SkimQuickLookThumbnails/SKQLConverter.h
trunk/SkimQuickLookThumbnails/SKQLConverter.m
trunk/SkimQuickLookThumbnails/SKThumbnailProvider.h
trunk/SkimQuickLookThumbnails/SKThumbnailProvider.m
trunk/SkimQuickLookThumbnails/Skim.png
trunk/SkimQuickLookThumbnails/SkimQuickLookThumbnails.entitlements
trunk/SkimQuickLookThumbnails/Skim_2x.png
trunk/SkimQuickLookThumbnails/Square.png
trunk/SkimQuickLookThumbnails/StrikeOut.png
trunk/SkimQuickLookThumbnails/Underline.png
trunk/SkimQuickLookThumbnails/Widget.png
Modified: trunk/Configurations/Skim-App.xcconfig
===================================================================
--- trunk/Configurations/Skim-App.xcconfig 2026-05-14 16:33:34 UTC (rev
16294)
+++ trunk/Configurations/Skim-App.xcconfig 2026-05-23 16:24:47 UTC (rev
16295)
@@ -15,6 +15,4 @@
GCC_PRECOMPILE_PREFIX_HEADER = YES
GCC_PREFIX_HEADER = Skim_Prefix.pch
-VERSIONING_SYSTEM = apple-generic
-
VALIDATE_WORKSPACE_SKIPPED_SDK_FRAMEWORKS = OpenGL
Modified: trunk/Configurations/Skim-Common.xcconfig
===================================================================
--- trunk/Configurations/Skim-Common.xcconfig 2026-05-14 16:33:34 UTC (rev
16294)
+++ trunk/Configurations/Skim-Common.xcconfig 2026-05-23 16:24:47 UTC (rev
16295)
@@ -3,6 +3,9 @@
ARCHS = $(ARCHS_STANDARD)
MACOSX_DEPLOYMENT_TARGET = 10.13
+CURRENT_PROJECT_VERSION = 166
+MARKETING_VERSION = 1.7.14
+
COPY_PHASE_STRIP = NO
STRIP_INSTALLED_PRODUCT = NO
STRIP_STYLE = all
Added: trunk/Configurations/SkimQuickLookPreview.xcconfig
===================================================================
--- trunk/Configurations/SkimQuickLookPreview.xcconfig
(rev 0)
+++ trunk/Configurations/SkimQuickLookPreview.xcconfig 2026-05-23 16:24:47 UTC
(rev 16295)
@@ -0,0 +1,15 @@
+MACOSX_DEPLOYMENT_TARGET = 12.0
+INFOPLIST_KEY_CFBundleDisplayName = SkimQuickLookPreview
+
+LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/../Frameworks
@executable_path/../../../../Frameworks
+
+GENERATE_INFOPLIST_FILE = YES
+INFOPLIST_FILE = SkimQuickLookPreview/Info.plist
+
+PRODUCT_BUNDLE_IDENTIFIER = net.sourceforge.skim-app.skim.quicklook-preview
+PRODUCT_NAME = $(TARGET_NAME)
+
+//CODE_SIGN_ENTITLEMENTS =
SkimQuickLookPreview/SkimQuickLookPreview.entitlements
+ENABLE_HARDENED_RUNTIME = YES
+
+CLANG_ENABLE_MODULES = YES
Added: trunk/Configurations/SkimQuickLookThumbnails.xcconfig
===================================================================
--- trunk/Configurations/SkimQuickLookThumbnails.xcconfig
(rev 0)
+++ trunk/Configurations/SkimQuickLookThumbnails.xcconfig 2026-05-23
16:24:47 UTC (rev 16295)
@@ -0,0 +1,15 @@
+MACOSX_DEPLOYMENT_TARGET = 10.15
+INFOPLIST_KEY_CFBundleDisplayName = SkimQuickLookThumbnails
+
+LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/../Frameworks
@executable_path/../../../../Frameworks
+
+GENERATE_INFOPLIST_FILE = YES
+INFOPLIST_FILE = SkimQuickLookThumbnails/Info.plist
+
+PRODUCT_BUNDLE_IDENTIFIER = net.sourceforge.skim-app.skim.quicklook-thumbnails
+PRODUCT_NAME = $(TARGET_NAME)
+
+//CODE_SIGN_ENTITLEMENTS =
SkimQuickLookThumbnails/SkimQuickLookThumbnails.entitlements
+ENABLE_HARDENED_RUNTIME = YES
+
+CLANG_ENABLE_MODULES = YES
Modified: trunk/Info.plist
===================================================================
--- trunk/Info.plist 2026-05-14 16:33:34 UTC (rev 16294)
+++ trunk/Info.plist 2026-05-23 16:24:47 UTC (rev 16295)
@@ -310,7 +310,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
- <string>1.7.14</string>
+ <string>${MARKETING_VERSION}</string>
<key>CFBundleSignature</key>
<string>SKim</string>
<key>CFBundleURLTypes</key>
Modified: trunk/Skim.xcodeproj/project.pbxproj
===================================================================
--- trunk/Skim.xcodeproj/project.pbxproj 2026-05-14 16:33:34 UTC (rev
16294)
+++ trunk/Skim.xcodeproj/project.pbxproj 2026-05-23 16:24:47 UTC (rev
16295)
@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
- objectVersion = 46;
+ objectVersion = 52;
objects = {
/* Begin PBXAggregateTarget section */
@@ -243,6 +243,37 @@
CECDC4FF0C5966A80026AAEC /* NSImage_SKExtensions.m in Sources
*/ = {isa = PBXBuildFile; fileRef = CECDC4FD0C5966A80026AAEC /*
NSImage_SKExtensions.m */; };
CECE6C3F2188AE9A00F6179D /* SKSelectionCommand.m in Sources */
= {isa = PBXBuildFile; fileRef = CECE6C3E2188AE9A00F6179D /*
SKSelectionCommand.m */; };
CECF61FF0DB258D600587D96 /* SKFontWell.m in Sources */ = {isa =
PBXBuildFile; fileRef = CECF61FE0DB258D600587D96 /* SKFontWell.m */; };
+ CED2D2FA2FC0FDF70044A3DC /* QuickLookThumbnailing.framework in
Frameworks */ = {isa = PBXBuildFile; fileRef = CED2D2F92FC0FDF70044A3DC /*
QuickLookThumbnailing.framework */; platformFilter = maccatalyst; };
+ CED2D2FC2FC0FDF70044A3DC /* Quartz.framework in Frameworks */ =
{isa = PBXBuildFile; fileRef = CED2D2FB2FC0FDF70044A3DC /* Quartz.framework */;
};
+ CED2D3002FC0FDF70044A3DC /* SKThumbnailProvider.m in Sources */
= {isa = PBXBuildFile; fileRef = CED2D2FF2FC0FDF70044A3DC /*
SKThumbnailProvider.m */; };
+ CED2D3052FC0FDF70044A3DC /* SkimQuickLookThumbnails.appex in
CopyFiles */ = {isa = PBXBuildFile; fileRef = CED2D2F82FC0FDF70044A3DC /*
SkimQuickLookThumbnails.appex */; settings = {ATTRIBUTES =
(RemoveHeadersOnCopy, ); }; };
+ CED2D3252FC103860044A3DC /* SKQLConverter.m in Sources */ =
{isa = PBXBuildFile; fileRef = CED2D3242FC103860044A3DC /* SKQLConverter.m */;
};
+ CED2D3332FC108210044A3DC /* Underline.png in Resources */ =
{isa = PBXBuildFile; fileRef = CED2D3272FC108200044A3DC /* Underline.png */; };
+ CED2D3342FC108210044A3DC /* FreeText.png in Resources */ = {isa
= PBXBuildFile; fileRef = CED2D3282FC108200044A3DC /* FreeText.png */; };
+ CED2D3352FC108210044A3DC /* Ink.png in Resources */ = {isa =
PBXBuildFile; fileRef = CED2D3292FC108200044A3DC /* Ink.png */; };
+ CED2D3362FC108210044A3DC /* Circle.png in Resources */ = {isa =
PBXBuildFile; fileRef = CED2D32A2FC108200044A3DC /* Circle.png */; };
+ CED2D3372FC108210044A3DC /* Line.png in Resources */ = {isa =
PBXBuildFile; fileRef = CED2D32B2FC108200044A3DC /* Line.png */; };
+ CED2D3382FC108210044A3DC /* Square.png in Resources */ = {isa =
PBXBuildFile; fileRef = CED2D32C2FC108200044A3DC /* Square.png */; };
+ CED2D3392FC108210044A3DC /* Widget.png in Resources */ = {isa =
PBXBuildFile; fileRef = CED2D32D2FC108200044A3DC /* Widget.png */; };
+ CED2D33A2FC108210044A3DC /* Highlight.png in Resources */ =
{isa = PBXBuildFile; fileRef = CED2D32E2FC108200044A3DC /* Highlight.png */; };
+ CED2D33B2FC108210044A3DC /* Note.png in Resources */ = {isa =
PBXBuildFile; fileRef = CED2D32F2FC108200044A3DC /* Note.png */; };
+ CED2D33C2FC108210044A3DC /* StrikeOut.png in Resources */ =
{isa = PBXBuildFile; fileRef = CED2D3302FC108200044A3DC /* StrikeOut.png */; };
+ CED2D33D2FC108210044A3DC /* Skim_2x.png in Resources */ = {isa
= PBXBuildFile; fileRef = CED2D3312FC108210044A3DC /* Skim_2x.png */; };
+ CED2D33E2FC108210044A3DC /* Skim.png in Resources */ = {isa =
PBXBuildFile; fileRef = CED2D3322FC108210044A3DC /* Skim.png */; };
+ CED2D3462FC10BA80044A3DC /* Quartz.framework in Frameworks */ =
{isa = PBXBuildFile; fileRef = CED2D2FB2FC0FDF70044A3DC /* Quartz.framework */;
};
+ CED2D34D2FC10BA80044A3DC /* SKPreviewProvider.m in Sources */ =
{isa = PBXBuildFile; fileRef = CED2D34C2FC10BA80044A3DC /* SKPreviewProvider.m
*/; };
+ CED2D3552FC10BA80044A3DC /* SkimQuickLookPreview.appex in
CopyFiles */ = {isa = PBXBuildFile; fileRef = CED2D3452FC10BA80044A3DC /*
SkimQuickLookPreview.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy,
); }; };
+ CED2D35E2FC10EA80044A3DC /* SKQLConverter.m in Sources */ =
{isa = PBXBuildFile; fileRef = CED2D35D2FC10EA80044A3DC /* SKQLConverter.m */;
};
+ CED2D3692FC113B60044A3DC /* Widget.png in Resources */ = {isa =
PBXBuildFile; fileRef = CED2D35F2FC113B50044A3DC /* Widget.png */; };
+ CED2D36A2FC113B60044A3DC /* StrikeOut.png in Resources */ =
{isa = PBXBuildFile; fileRef = CED2D3602FC113B60044A3DC /* StrikeOut.png */; };
+ CED2D36B2FC113B60044A3DC /* Line.png in Resources */ = {isa =
PBXBuildFile; fileRef = CED2D3612FC113B60044A3DC /* Line.png */; };
+ CED2D36C2FC113B60044A3DC /* Note.png in Resources */ = {isa =
PBXBuildFile; fileRef = CED2D3622FC113B60044A3DC /* Note.png */; };
+ CED2D36D2FC113B60044A3DC /* Square.png in Resources */ = {isa =
PBXBuildFile; fileRef = CED2D3632FC113B60044A3DC /* Square.png */; };
+ CED2D36E2FC113B60044A3DC /* Underline.png in Resources */ =
{isa = PBXBuildFile; fileRef = CED2D3642FC113B60044A3DC /* Underline.png */; };
+ CED2D36F2FC113B60044A3DC /* Ink.png in Resources */ = {isa =
PBXBuildFile; fileRef = CED2D3652FC113B60044A3DC /* Ink.png */; };
+ CED2D3702FC113B60044A3DC /* Highlight.png in Resources */ =
{isa = PBXBuildFile; fileRef = CED2D3662FC113B60044A3DC /* Highlight.png */; };
+ CED2D3712FC113B60044A3DC /* Circle.png in Resources */ = {isa =
PBXBuildFile; fileRef = CED2D3672FC113B60044A3DC /* Circle.png */; };
+ CED2D3722FC113B60044A3DC /* FreeText.png in Resources */ = {isa
= PBXBuildFile; fileRef = CED2D3682FC113B60044A3DC /* FreeText.png */; };
CED4DA252707B330001E09A8 /* SKThumbnailImageView.m in Sources
*/ = {isa = PBXBuildFile; fileRef = CED4DA242707B330001E09A8 /*
SKThumbnailImageView.m */; };
CED76F011A1825DE00D1ACA4 /* SKScrollView.m in Sources */ = {isa
= PBXBuildFile; fileRef = CED76F001A1825DE00D1ACA4 /* SKScrollView.m */; };
CEDA057B2295BEBA00881DE1 /* SkimTransitions.plugin in CopyFiles
*/ = {isa = PBXBuildFile; fileRef = CEDA056B2295BE8300881DE1 /*
SkimTransitions.plugin */; settings = {ATTRIBUTES = (CodeSignOnCopy,
RemoveHeadersOnCopy, ); }; };
@@ -524,6 +555,20 @@
remoteGlobalIDString = 8D576316048677EA00EA77CD;
remoteInfo = Skim;
};
+ CED2D3032FC0FDF70044A3DC /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 2A37F4A9FDCFA73011CA2CEA /* Project
object */;
+ proxyType = 1;
+ remoteGlobalIDString = CED2D2F72FC0FDF70044A3DC;
+ remoteInfo = SkimQuickLookThumbnails;
+ };
+ CED2D3532FC10BA80044A3DC /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 2A37F4A9FDCFA73011CA2CEA /* Project
object */;
+ proxyType = 1;
+ remoteGlobalIDString = CED2D3442FC10BA80044A3DC;
+ remoteInfo = SkimQuickLookPreview;
+ };
CEDA056A2295BE8300881DE1 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = CEDA05622295BE8300881DE1 /*
SkimTransitions.xcodeproj */;
@@ -586,6 +631,8 @@
dstPath = "";
dstSubfolderSpec = 13;
files = (
+ CED2D3052FC0FDF70044A3DC /*
SkimQuickLookThumbnails.appex in CopyFiles */,
+ CED2D3552FC10BA80044A3DC /*
SkimQuickLookPreview.appex in CopyFiles */,
CEDA057B2295BEBA00881DE1 /*
SkimTransitions.plugin in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -1172,6 +1219,46 @@
CECE6C3E2188AE9A00F6179D /* SKSelectionCommand.m */ = {isa =
PBXFileReference; lastKnownFileType = sourcecode.c.objc; path =
SKSelectionCommand.m; sourceTree = "<group>"; };
CECF61FD0DB258D600587D96 /* SKFontWell.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path =
SKFontWell.h; sourceTree = "<group>"; };
CECF61FE0DB258D600587D96 /* SKFontWell.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path
= SKFontWell.m; sourceTree = "<group>"; };
+ CED2D2F82FC0FDF70044A3DC /* SkimQuickLookThumbnails.appex */ =
{isa = PBXFileReference; explicitFileType = "wrapper.app-extension";
includeInIndex = 0; path = SkimQuickLookThumbnails.appex; sourceTree =
BUILT_PRODUCTS_DIR; };
+ CED2D2F92FC0FDF70044A3DC /* QuickLookThumbnailing.framework */
= {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name =
QuickLookThumbnailing.framework; path =
System/Library/Frameworks/QuickLookThumbnailing.framework; sourceTree =
SDKROOT; };
+ CED2D2FB2FC0FDF70044A3DC /* Quartz.framework */ = {isa =
PBXFileReference; lastKnownFileType = wrapper.framework; name =
Quartz.framework; path = System/Library/Frameworks/Quartz.framework; sourceTree
= SDKROOT; };
+ CED2D2FE2FC0FDF70044A3DC /* SKThumbnailProvider.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path =
SKThumbnailProvider.h; sourceTree = "<group>"; };
+ CED2D2FF2FC0FDF70044A3DC /* SKThumbnailProvider.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path
= SKThumbnailProvider.m; sourceTree = "<group>"; };
+ CED2D3012FC0FDF70044A3DC /* Info.plist */ = {isa =
PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist;
sourceTree = "<group>"; };
+ CED2D3022FC0FDF70044A3DC /*
SkimQuickLookThumbnails.entitlements */ = {isa = PBXFileReference;
lastKnownFileType = text.plist.entitlements; path =
SkimQuickLookThumbnails.entitlements; sourceTree = "<group>"; };
+ CED2D3232FC103860044A3DC /* SKQLConverter.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path =
SKQLConverter.h; sourceTree = "<group>"; };
+ CED2D3242FC103860044A3DC /* SKQLConverter.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path
= SKQLConverter.m; sourceTree = "<group>"; };
+ CED2D3272FC108200044A3DC /* Underline.png */ = {isa =
PBXFileReference; lastKnownFileType = image.png; path = Underline.png;
sourceTree = "<group>"; };
+ CED2D3282FC108200044A3DC /* FreeText.png */ = {isa =
PBXFileReference; lastKnownFileType = image.png; path = FreeText.png;
sourceTree = "<group>"; };
+ CED2D3292FC108200044A3DC /* Ink.png */ = {isa =
PBXFileReference; lastKnownFileType = image.png; path = Ink.png; sourceTree =
"<group>"; };
+ CED2D32A2FC108200044A3DC /* Circle.png */ = {isa =
PBXFileReference; lastKnownFileType = image.png; path = Circle.png; sourceTree
= "<group>"; };
+ CED2D32B2FC108200044A3DC /* Line.png */ = {isa =
PBXFileReference; lastKnownFileType = image.png; path = Line.png; sourceTree =
"<group>"; };
+ CED2D32C2FC108200044A3DC /* Square.png */ = {isa =
PBXFileReference; lastKnownFileType = image.png; path = Square.png; sourceTree
= "<group>"; };
+ CED2D32D2FC108200044A3DC /* Widget.png */ = {isa =
PBXFileReference; lastKnownFileType = image.png; path = Widget.png; sourceTree
= "<group>"; };
+ CED2D32E2FC108200044A3DC /* Highlight.png */ = {isa =
PBXFileReference; lastKnownFileType = image.png; path = Highlight.png;
sourceTree = "<group>"; };
+ CED2D32F2FC108200044A3DC /* Note.png */ = {isa =
PBXFileReference; lastKnownFileType = image.png; path = Note.png; sourceTree =
"<group>"; };
+ CED2D3302FC108200044A3DC /* StrikeOut.png */ = {isa =
PBXFileReference; lastKnownFileType = image.png; path = StrikeOut.png;
sourceTree = "<group>"; };
+ CED2D3312FC108210044A3DC /* Skim_2x.png */ = {isa =
PBXFileReference; lastKnownFileType = image.png; path = Skim_2x.png; sourceTree
= "<group>"; };
+ CED2D3322FC108210044A3DC /* Skim.png */ = {isa =
PBXFileReference; lastKnownFileType = image.png; path = Skim.png; sourceTree =
"<group>"; };
+ CED2D3402FC1092D0044A3DC /* SkimQuickLookThumbnails.xcconfig */
= {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path =
SkimQuickLookThumbnails.xcconfig; sourceTree = "<group>"; };
+ CED2D3452FC10BA80044A3DC /* SkimQuickLookPreview.appex */ =
{isa = PBXFileReference; explicitFileType = "wrapper.app-extension";
includeInIndex = 0; path = SkimQuickLookPreview.appex; sourceTree =
BUILT_PRODUCTS_DIR; };
+ CED2D34B2FC10BA80044A3DC /* SKPreviewProvider.h */ = {isa =
PBXFileReference; lastKnownFileType = sourcecode.c.h; path =
SKPreviewProvider.h; sourceTree = "<group>"; };
+ CED2D34C2FC10BA80044A3DC /* SKPreviewProvider.m */ = {isa =
PBXFileReference; lastKnownFileType = sourcecode.c.objc; path =
SKPreviewProvider.m; sourceTree = "<group>"; };
+ CED2D3512FC10BA80044A3DC /* Info.plist */ = {isa =
PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist;
sourceTree = "<group>"; };
+ CED2D3522FC10BA80044A3DC /* SkimQuickLookPreview.entitlements
*/ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path
= SkimQuickLookPreview.entitlements; sourceTree = "<group>"; };
+ CED2D35B2FC10C860044A3DC /* SkimQuickLookPreview.xcconfig */ =
{isa = PBXFileReference; lastKnownFileType = text.xcconfig; path =
SkimQuickLookPreview.xcconfig; sourceTree = "<group>"; };
+ CED2D35C2FC10EA80044A3DC /* SKQLConverter.h */ = {isa =
PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SKQLConverter.h;
sourceTree = "<group>"; };
+ CED2D35D2FC10EA80044A3DC /* SKQLConverter.m */ = {isa =
PBXFileReference; lastKnownFileType = sourcecode.c.objc; path =
SKQLConverter.m; sourceTree = "<group>"; };
+ CED2D35F2FC113B50044A3DC /* Widget.png */ = {isa =
PBXFileReference; lastKnownFileType = image.png; path = Widget.png; sourceTree
= "<group>"; };
+ CED2D3602FC113B60044A3DC /* StrikeOut.png */ = {isa =
PBXFileReference; lastKnownFileType = image.png; path = StrikeOut.png;
sourceTree = "<group>"; };
+ CED2D3612FC113B60044A3DC /* Line.png */ = {isa =
PBXFileReference; lastKnownFileType = image.png; path = Line.png; sourceTree =
"<group>"; };
+ CED2D3622FC113B60044A3DC /* Note.png */ = {isa =
PBXFileReference; lastKnownFileType = image.png; path = Note.png; sourceTree =
"<group>"; };
+ CED2D3632FC113B60044A3DC /* Square.png */ = {isa =
PBXFileReference; lastKnownFileType = image.png; path = Square.png; sourceTree
= "<group>"; };
+ CED2D3642FC113B60044A3DC /* Underline.png */ = {isa =
PBXFileReference; lastKnownFileType = image.png; path = Underline.png;
sourceTree = "<group>"; };
+ CED2D3652FC113B60044A3DC /* Ink.png */ = {isa =
PBXFileReference; lastKnownFileType = image.png; path = Ink.png; sourceTree =
"<group>"; };
+ CED2D3662FC113B60044A3DC /* Highlight.png */ = {isa =
PBXFileReference; lastKnownFileType = image.png; path = Highlight.png;
sourceTree = "<group>"; };
+ CED2D3672FC113B60044A3DC /* Circle.png */ = {isa =
PBXFileReference; lastKnownFileType = image.png; path = Circle.png; sourceTree
= "<group>"; };
+ CED2D3682FC113B60044A3DC /* FreeText.png */ = {isa =
PBXFileReference; lastKnownFileType = image.png; path = FreeText.png;
sourceTree = "<group>"; };
CED4DA232707B330001E09A8 /* SKThumbnailImageView.h */ = {isa =
PBXFileReference; lastKnownFileType = sourcecode.c.h; path =
SKThumbnailImageView.h; sourceTree = "<group>"; };
CED4DA242707B330001E09A8 /* SKThumbnailImageView.m */ = {isa =
PBXFileReference; lastKnownFileType = sourcecode.c.objc; path =
SKThumbnailImageView.m; sourceTree = "<group>"; };
CED76EFF1A1825DE00D1ACA4 /* SKScrollView.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path =
SKScrollView.h; sourceTree = "<group>"; };
@@ -1449,6 +1536,23 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ CED2D2F52FC0FDF70044A3DC /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ CED2D2FA2FC0FDF70044A3DC /*
QuickLookThumbnailing.framework in Frameworks */,
+ CED2D2FC2FC0FDF70044A3DC /* Quartz.framework in
Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ CED2D3422FC10BA80044A3DC /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ CED2D3462FC10BA80044A3DC /* Quartz.framework in
Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
@@ -1478,6 +1582,8 @@
isa = PBXGroup;
children = (
8D15AC370486D014006FF6A4 /* Skim.app */,
+ CED2D2F82FC0FDF70044A3DC /*
SkimQuickLookThumbnails.appex */,
+ CED2D3452FC10BA80044A3DC /*
SkimQuickLookPreview.appex */,
);
name = Products;
sourceTree = "<group>";
@@ -1493,6 +1599,8 @@
2A37F4B8FDCFA73011CA2CEA /* Resources */,
CEE22EA20BFB8631002B746B /* Shared Support */,
CE2BD8160BD4123D00A5F4DB /* Subprojects */,
+ CED2D2FD2FC0FDF70044A3DC /*
SkimQuickLookThumbnails */,
+ CED2D3472FC10BA80044A3DC /*
SkimQuickLookPreview */,
2A37F4C3FDCFA73011CA2CEA /* Frameworks */,
19C28FB0FE9D524F11CA2CBB /* Products */,
CED8D4050D744D520028E3E2 /* Configurations */,
@@ -1560,6 +1668,8 @@
CE0998CA0EC8EC2A006CD0F7 /* Linked Libraries */,
1058C7A6FEA54F5311CA2CBB /* Linked Frameworks
*/,
CE2BB81B0E0DB4FA0090E848 /* Embedded Frameworks
*/,
+ CED2D2F92FC0FDF70044A3DC /*
QuickLookThumbnailing.framework */,
+ CED2D2FB2FC0FDF70044A3DC /* Quartz.framework */,
1058C7A8FEA54F5311CA2CBB /* Other Frameworks */,
);
name = Frameworks;
@@ -2109,6 +2219,86 @@
name = Products;
sourceTree = "<group>";
};
+ CED2D2FD2FC0FDF70044A3DC /* SkimQuickLookThumbnails */ = {
+ isa = PBXGroup;
+ children = (
+ CED2D33F2FC1085B0044A3DC /* Source */,
+ CED2D3262FC107C80044A3DC /* Resources */,
+ CED2D3022FC0FDF70044A3DC /*
SkimQuickLookThumbnails.entitlements */,
+ );
+ path = SkimQuickLookThumbnails;
+ sourceTree = "<group>";
+ };
+ CED2D3262FC107C80044A3DC /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ CED2D3322FC108210044A3DC /* Skim.png */,
+ CED2D3312FC108210044A3DC /* Skim_2x.png */,
+ CED2D3302FC108200044A3DC /* StrikeOut.png */,
+ CED2D32F2FC108200044A3DC /* Note.png */,
+ CED2D32B2FC108200044A3DC /* Line.png */,
+ CED2D32C2FC108200044A3DC /* Square.png */,
+ CED2D3282FC108200044A3DC /* FreeText.png */,
+ CED2D32A2FC108200044A3DC /* Circle.png */,
+ CED2D3272FC108200044A3DC /* Underline.png */,
+ CED2D32E2FC108200044A3DC /* Highlight.png */,
+ CED2D3292FC108200044A3DC /* Ink.png */,
+ CED2D32D2FC108200044A3DC /* Widget.png */,
+ CED2D3012FC0FDF70044A3DC /* Info.plist */,
+ );
+ name = Resources;
+ sourceTree = "<group>";
+ };
+ CED2D33F2FC1085B0044A3DC /* Source */ = {
+ isa = PBXGroup;
+ children = (
+ CED2D2FE2FC0FDF70044A3DC /*
SKThumbnailProvider.h */,
+ CED2D2FF2FC0FDF70044A3DC /*
SKThumbnailProvider.m */,
+ CED2D3232FC103860044A3DC /* SKQLConverter.h */,
+ CED2D3242FC103860044A3DC /* SKQLConverter.m */,
+ );
+ name = Source;
+ sourceTree = "<group>";
+ };
+ CED2D3472FC10BA80044A3DC /* SkimQuickLookPreview */ = {
+ isa = PBXGroup;
+ children = (
+ CED2D3592FC10C330044A3DC /* Source */,
+ CED2D35A2FC10C4F0044A3DC /* Resources */,
+ CED2D3522FC10BA80044A3DC /*
SkimQuickLookPreview.entitlements */,
+ );
+ path = SkimQuickLookPreview;
+ sourceTree = "<group>";
+ };
+ CED2D3592FC10C330044A3DC /* Source */ = {
+ isa = PBXGroup;
+ children = (
+ CED2D34B2FC10BA80044A3DC /* SKPreviewProvider.h
*/,
+ CED2D34C2FC10BA80044A3DC /* SKPreviewProvider.m
*/,
+ CED2D35C2FC10EA80044A3DC /* SKQLConverter.h */,
+ CED2D35D2FC10EA80044A3DC /* SKQLConverter.m */,
+ );
+ name = Source;
+ sourceTree = "<group>";
+ };
+ CED2D35A2FC10C4F0044A3DC /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ CED2D3602FC113B60044A3DC /* StrikeOut.png */,
+ CED2D3622FC113B60044A3DC /* Note.png */,
+ CED2D3612FC113B60044A3DC /* Line.png */,
+ CED2D3632FC113B60044A3DC /* Square.png */,
+ CED2D3682FC113B60044A3DC /* FreeText.png */,
+ CED2D3672FC113B60044A3DC /* Circle.png */,
+ CED2D3642FC113B60044A3DC /* Underline.png */,
+ CED2D3662FC113B60044A3DC /* Highlight.png */,
+ CED2D3652FC113B60044A3DC /* Ink.png */,
+ CED2D35F2FC113B50044A3DC /* Widget.png */,
+ CED2D3512FC10BA80044A3DC /* Info.plist */,
+ );
+ name = Resources;
+ sourceTree = "<group>";
+ };
CED8D4050D744D520028E3E2 /* Configurations */ = {
isa = PBXGroup;
children = (
@@ -2116,6 +2306,8 @@
CED8D40C0D744D940028E3E2 /* Skim-Debug.xcconfig
*/,
CED8D40D0D744D940028E3E2 /*
Skim-Release.xcconfig */,
CE17EE460E24ED7C00DE06EA /* Skim-App.xcconfig
*/,
+ CED2D3402FC1092D0044A3DC /*
SkimQuickLookThumbnails.xcconfig */,
+ CED2D35B2FC10C860044A3DC /*
SkimQuickLookPreview.xcconfig */,
);
path = Configurations;
sourceTree = "<group>";
@@ -2306,6 +2498,8 @@
CE816A030D70F8F7008D807D /* PBXTargetDependency
*/,
CE7DC7E20E093C1A00D6D76D /* PBXTargetDependency
*/,
CEFF6B9C122B1478008CDE73 /* PBXTargetDependency
*/,
+ CED2D3042FC0FDF70044A3DC /* PBXTargetDependency
*/,
+ CED2D3542FC10BA80044A3DC /* PBXTargetDependency
*/,
);
name = Skim;
productInstallPath = "$(HOME)/Applications";
@@ -2313,6 +2507,40 @@
productReference = 8D15AC370486D014006FF6A4 /* Skim.app
*/;
productType = "com.apple.product-type.application";
};
+ CED2D2F72FC0FDF70044A3DC /* SkimQuickLookThumbnails */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = CED2D3222FC0FDF70044A3DC /*
Build configuration list for PBXNativeTarget "SkimQuickLookThumbnails" */;
+ buildPhases = (
+ CED2D2F42FC0FDF70044A3DC /* Sources */,
+ CED2D2F52FC0FDF70044A3DC /* Frameworks */,
+ CED2D2F62FC0FDF70044A3DC /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = SkimQuickLookThumbnails;
+ productName = SkimQuickLookThumbnails;
+ productReference = CED2D2F82FC0FDF70044A3DC /*
SkimQuickLookThumbnails.appex */;
+ productType = "com.apple.product-type.app-extension";
+ };
+ CED2D3442FC10BA80044A3DC /* SkimQuickLookPreview */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = CED2D3562FC10BA80044A3DC /*
Build configuration list for PBXNativeTarget "SkimQuickLookPreview" */;
+ buildPhases = (
+ CED2D3412FC10BA80044A3DC /* Sources */,
+ CED2D3422FC10BA80044A3DC /* Frameworks */,
+ CED2D3432FC10BA80044A3DC /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = SkimQuickLookPreview;
+ productName = SkimQuickLookPreview;
+ productReference = CED2D3452FC10BA80044A3DC /*
SkimQuickLookPreview.appex */;
+ productType = "com.apple.product-type.app-extension";
+ };
/* End PBXNativeTarget section */
/* Begin PBXProject section */
@@ -2320,6 +2548,14 @@
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1320;
+ TargetAttributes = {
+ CED2D2F72FC0FDF70044A3DC = {
+ CreatedOnToolsVersion = 13.2.1;
+ };
+ CED2D3442FC10BA80044A3DC = {
+ CreatedOnToolsVersion = 13.2.1;
+ };
+ };
};
buildConfigurationList = C05733CB08A9546B00998B17 /*
Build configuration list for PBXProject "Skim" */;
compatibilityVersion = "Xcode 3.2";
@@ -2370,6 +2606,8 @@
targets = (
8D15AC270486D014006FF6A4 /* Skim */,
CE592C5D0B9239C500C113DF /* DiskImage */,
+ CED2D2F72FC0FDF70044A3DC /*
SkimQuickLookThumbnails */,
+ CED2D3442FC10BA80044A3DC /*
SkimQuickLookPreview */,
);
};
/* End PBXProject section */
@@ -2659,6 +2897,42 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ CED2D2F62FC0FDF70044A3DC /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ CED2D33B2FC108210044A3DC /* Note.png in
Resources */,
+ CED2D33A2FC108210044A3DC /* Highlight.png in
Resources */,
+ CED2D3352FC108210044A3DC /* Ink.png in
Resources */,
+ CED2D33E2FC108210044A3DC /* Skim.png in
Resources */,
+ CED2D3342FC108210044A3DC /* FreeText.png in
Resources */,
+ CED2D33C2FC108210044A3DC /* StrikeOut.png in
Resources */,
+ CED2D3372FC108210044A3DC /* Line.png in
Resources */,
+ CED2D3332FC108210044A3DC /* Underline.png in
Resources */,
+ CED2D3382FC108210044A3DC /* Square.png in
Resources */,
+ CED2D3362FC108210044A3DC /* Circle.png in
Resources */,
+ CED2D3392FC108210044A3DC /* Widget.png in
Resources */,
+ CED2D33D2FC108210044A3DC /* Skim_2x.png in
Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ CED2D3432FC10BA80044A3DC /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ CED2D3702FC113B60044A3DC /* Highlight.png in
Resources */,
+ CED2D3712FC113B60044A3DC /* Circle.png in
Resources */,
+ CED2D36D2FC113B60044A3DC /* Square.png in
Resources */,
+ CED2D36B2FC113B60044A3DC /* Line.png in
Resources */,
+ CED2D36E2FC113B60044A3DC /* Underline.png in
Resources */,
+ CED2D36C2FC113B60044A3DC /* Note.png in
Resources */,
+ CED2D36F2FC113B60044A3DC /* Ink.png in
Resources */,
+ CED2D36A2FC113B60044A3DC /* StrikeOut.png in
Resources */,
+ CED2D3722FC113B60044A3DC /* FreeText.png in
Resources */,
+ CED2D3692FC113B60044A3DC /* Widget.png in
Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
@@ -2978,6 +3252,24 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ CED2D2F42FC0FDF70044A3DC /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ CED2D3002FC0FDF70044A3DC /*
SKThumbnailProvider.m in Sources */,
+ CED2D3252FC103860044A3DC /* SKQLConverter.m in
Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ CED2D3412FC10BA80044A3DC /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ CED2D34D2FC10BA80044A3DC /* SKPreviewProvider.m
in Sources */,
+ CED2D35E2FC10EA80044A3DC /* SKQLConverter.m in
Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
@@ -3006,6 +3298,16 @@
name = Skim;
targetProxy = CE816A020D70F8F7008D807D /*
PBXContainerItemProxy */;
};
+ CED2D3042FC0FDF70044A3DC /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = CED2D2F72FC0FDF70044A3DC /*
SkimQuickLookThumbnails */;
+ targetProxy = CED2D3032FC0FDF70044A3DC /*
PBXContainerItemProxy */;
+ };
+ CED2D3542FC10BA80044A3DC /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = CED2D3442FC10BA80044A3DC /*
SkimQuickLookPreview */;
+ targetProxy = CED2D3532FC10BA80044A3DC /*
PBXContainerItemProxy */;
+ };
CEDA05792295BE8B00881DE1 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = SkimTransitions;
@@ -3779,7 +4081,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = CE17EE460E24ED7C00DE06EA
/* Skim-App.xcconfig */;
buildSettings = {
- CURRENT_PROJECT_VERSION = 166;
};
name = Debug;
};
@@ -3787,7 +4088,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = CE17EE460E24ED7C00DE06EA
/* Skim-App.xcconfig */;
buildSettings = {
- CURRENT_PROJECT_VERSION = 166;
};
name = Release;
};
@@ -3819,6 +4119,217 @@
};
name = Release;
};
+ CED2D3062FC0FDF70044A3DC /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = CED2D3402FC1092D0044A3DC
/* SkimQuickLookThumbnails.xcconfig */;
+ buildSettings = {
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION =
YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS =
YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER =
YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY =
YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ ENABLE_HARDENED_RUNTIME = YES;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ INFOPLIST_KEY_CFBundleDisplayName =
SkimQuickLookThumbnails;
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ };
+ name = Debug;
+ };
+ CED2D3072FC0FDF70044A3DC /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = CED2D3402FC1092D0044A3DC
/* SkimQuickLookThumbnails.xcconfig */;
+ buildSettings = {
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION =
YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS =
YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER =
YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY =
YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ ENABLE_HARDENED_RUNTIME = YES;
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ INFOPLIST_KEY_CFBundleDisplayName =
SkimQuickLookThumbnails;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ MTL_FAST_MATH = YES;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ };
+ name = Release;
+ };
+ CED2D3572FC10BA80044A3DC /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = CED2D35B2FC10C860044A3DC
/* SkimQuickLookPreview.xcconfig */;
+ buildSettings = {
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION =
YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS =
YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER =
YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY =
YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ INFOPLIST_KEY_CFBundleDisplayName =
SkimQuickLookPreview;
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ };
+ name = Debug;
+ };
+ CED2D3582FC10BA80044A3DC /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = CED2D35B2FC10C860044A3DC
/* SkimQuickLookPreview.xcconfig */;
+ buildSettings = {
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION =
YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS =
YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER =
YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY =
YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ INFOPLIST_KEY_CFBundleDisplayName =
SkimQuickLookPreview;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ MTL_FAST_MATH = YES;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ };
+ name = Release;
+ };
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@@ -3849,6 +4360,24 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ CED2D3222FC0FDF70044A3DC /* Build configuration list for
PBXNativeTarget "SkimQuickLookThumbnails" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ CED2D3062FC0FDF70044A3DC /* Debug */,
+ CED2D3072FC0FDF70044A3DC /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ CED2D3562FC10BA80044A3DC /* Build configuration list for
PBXNativeTarget "SkimQuickLookPreview" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ CED2D3572FC10BA80044A3DC /* Debug */,
+ CED2D3582FC10BA80044A3DC /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
/* End XCConfigurationList section */
};
rootObject = 2A37F4A9FDCFA73011CA2CEA /* Project object */;
Added: trunk/SkimQuickLookPreview/Circle.png
===================================================================
(Binary files differ)
Index: trunk/SkimQuickLookPreview/Circle.png
===================================================================
--- trunk/SkimQuickLookPreview/Circle.png 2026-05-14 16:33:34 UTC (rev
16294)
+++ trunk/SkimQuickLookPreview/Circle.png 2026-05-23 16:24:47 UTC (rev
16295)
Property changes on: trunk/SkimQuickLookPreview/Circle.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookPreview/FreeText.png
===================================================================
(Binary files differ)
Index: trunk/SkimQuickLookPreview/FreeText.png
===================================================================
--- trunk/SkimQuickLookPreview/FreeText.png 2026-05-14 16:33:34 UTC (rev
16294)
+++ trunk/SkimQuickLookPreview/FreeText.png 2026-05-23 16:24:47 UTC (rev
16295)
Property changes on: trunk/SkimQuickLookPreview/FreeText.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookPreview/Highlight.png
===================================================================
(Binary files differ)
Index: trunk/SkimQuickLookPreview/Highlight.png
===================================================================
--- trunk/SkimQuickLookPreview/Highlight.png 2026-05-14 16:33:34 UTC (rev
16294)
+++ trunk/SkimQuickLookPreview/Highlight.png 2026-05-23 16:24:47 UTC (rev
16295)
Property changes on: trunk/SkimQuickLookPreview/Highlight.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookPreview/Info.plist
===================================================================
--- trunk/SkimQuickLookPreview/Info.plist (rev 0)
+++ trunk/SkimQuickLookPreview/Info.plist 2026-05-23 16:24:47 UTC (rev
16295)
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>NSExtension</key>
+ <dict>
+ <key>NSExtensionAttributes</key>
+ <dict>
+ <key>QLIsDataBasedPreview</key>
+ <true/>
+ <key>QLSupportedContentTypes</key>
+ <array>
+ <string>net.sourceforge.skim-app.pdfd</string>
+
<string>net.sourceforge.skim-app.skimnotes</string>
+ <string>com.adobe.postscript</string>
+ </array>
+ <key>QLSupportsSearchableItems</key>
+ <false/>
+ </dict>
+ <key>NSExtensionPointIdentifier</key>
+ <string>com.apple.quicklook.preview</string>
+ <key>NSExtensionPrincipalClass</key>
+ <string>SKPreviewViewController</string>
+ </dict>
+ <key>UTImportedTypeDeclarations</key>
+ <array>
+ <dict>
+ <key>UTTypeConformsTo</key>
+ <array>
+ <string>com.apple.package</string>
+ <string>public.composite-content</string>
+ </array>
+ <key>UTTypeDescription</key>
+ <string>PDF Bundle</string>
+ <key>UTTypeIdentifier</key>
+ <string>net.sourceforge.skim-app.pdfd</string>
+ <key>UTTypeTagSpecification</key>
+ <dict>
+ <key>com.apple.ostype</key>
+ <string>PDFD</string>
+ <key>public.filename-extension</key>
+ <array>
+ <string>pdfd</string>
+ </array>
+ </dict>
+ </dict>
+ <dict>
+ <key>UTTypeConformsTo</key>
+ <array>
+ <string>public.data</string>
+ </array>
+ <key>UTTypeDescription</key>
+ <string>Skim Notes</string>
+ <key>UTTypeIdentifier</key>
+ <string>net.sourceforge.skim-app.skimnotes</string>
+ <key>UTTypeTagSpecification</key>
+ <dict>
+ <key>com.apple.ostype</key>
+ <string>SKNT</string>
+ <key>public.filename-extension</key>
+ <array>
+ <string>skim</string>
+ </array>
+ </dict>
+ </dict>
+ <dict>
+ <key>UTTypeConformsTo</key>
+ <array>
+ <string>public.data</string>
+ </array>
+ <key>UTTypeDescription</key>
+ <string>PostScript</string>
+ <key>UTTypeIdentifier</key>
+ <string>com.adobe.postscript</string>
+ <key>UTTypeTagSpecification</key>
+ <dict>
+ <key>public.filename-extension</key>
+ <array>
+ <string>ps</string>
+ </array>
+ <key>public.mime-type</key>
+ <array>
+ <string>application/postscript</string>
+ </array>
+ </dict>
+ </dict>
+ </array>
+</dict>
+</plist>
Added: trunk/SkimQuickLookPreview/Ink.png
===================================================================
(Binary files differ)
Index: trunk/SkimQuickLookPreview/Ink.png
===================================================================
--- trunk/SkimQuickLookPreview/Ink.png 2026-05-14 16:33:34 UTC (rev 16294)
+++ trunk/SkimQuickLookPreview/Ink.png 2026-05-23 16:24:47 UTC (rev 16295)
Property changes on: trunk/SkimQuickLookPreview/Ink.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookPreview/Line.png
===================================================================
(Binary files differ)
Index: trunk/SkimQuickLookPreview/Line.png
===================================================================
--- trunk/SkimQuickLookPreview/Line.png 2026-05-14 16:33:34 UTC (rev 16294)
+++ trunk/SkimQuickLookPreview/Line.png 2026-05-23 16:24:47 UTC (rev 16295)
Property changes on: trunk/SkimQuickLookPreview/Line.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookPreview/Note.png
===================================================================
(Binary files differ)
Index: trunk/SkimQuickLookPreview/Note.png
===================================================================
--- trunk/SkimQuickLookPreview/Note.png 2026-05-14 16:33:34 UTC (rev 16294)
+++ trunk/SkimQuickLookPreview/Note.png 2026-05-23 16:24:47 UTC (rev 16295)
Property changes on: trunk/SkimQuickLookPreview/Note.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookPreview/SKPreviewProvider.h
===================================================================
--- trunk/SkimQuickLookPreview/SKPreviewProvider.h
(rev 0)
+++ trunk/SkimQuickLookPreview/SKPreviewProvider.h 2026-05-23 16:24:47 UTC
(rev 16295)
@@ -0,0 +1,44 @@
+//
+// SKPreviewProvider.h
+// SkimQuickLookPreview
+//
+// Created by Christiaan Hofman on 22/05/2026.
+/*
+ This software is Copyright (c) 2026
+ Christiaan Hofman. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of Christiaan Hofman nor the names of any
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <Cocoa/Cocoa.h>
+#import <Quartz/Quartz.h>
+
+@interface SKPreviewProvider : QLPreviewProvider <QLPreviewingController>
+
+@end
Added: trunk/SkimQuickLookPreview/SKPreviewProvider.m
===================================================================
--- trunk/SkimQuickLookPreview/SKPreviewProvider.m
(rev 0)
+++ trunk/SkimQuickLookPreview/SKPreviewProvider.m 2026-05-23 16:24:47 UTC
(rev 16295)
@@ -0,0 +1,133 @@
+//
+// SKPreviewProvider.m
+// SkimQuickLookPreview
+//
+// Created by Christiaan Hofman on 22/05/2026.
+/*
+ This software is Copyright (c) 2026
+ Christiaan Hofman. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of Christiaan Hofman nor the names of any
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "SKPreviewProvider.h"
+#import "SKQLConverter.h"
+
+@implementation SKPreviewProvider
+
+/*
+
+ Use a QLPreviewProvider to provide data-based previews.
+
+ To set up your extension as a data-based preview extension:
+
+ - Modify the extension's Info.plist by setting
+ <key>QLIsDataBasedPreview</key>
+ <true/>
+
+ - Add the supported content types to QLSupportedContentTypes array in the
extension's Info.plist.
+
+ - Change the NSExtensionPrincipalClass to this class.
+ e.g.
+ <key>NSExtensionPrincipalClass</key>
+ <string>PreviewProvider</string>
+
+ - Implement providePreviewForFileRequest:completionHandler:
+
+ */
+
+- (void)providePreviewForFileRequest:(QLFilePreviewRequest *)request
completionHandler:(void (^)(QLPreviewReply *reply, NSError *error))handler
+{
+ NSURL *fileURL = [request fileURL];
+ UTType *fileType = nil;
+ QLPreviewReply *reply = nil;
+
+ [fileURL getResourceValue:&fileType forKey:NSURLContentTypeKey error:NULL];
+
+ if ([fileType conformsToType:[UTType
typeWithIdentifier:@"net.sourceforge.skim-app.pdfd"]]) {
+
+ NSURL *pdfURL = SKQLPDFURLForPDFBundleURL(fileURL);
+ if (pdfURL)
+ reply = [[QLPreviewReply alloc] initWithFileURL:pdfURL];
+
+ } else if ([fileType conformsToType:[UTType
typeWithIdentifier:@"net.sourceforge.skim-app.skimnotes"]]) {
+
+ reply = [[QLPreviewReply alloc] initWithDataOfContentType:UTTypeHTML
contentSize:CGSizeMake(800, 800) dataCreationBlock:^NSData *(QLPreviewReply
*replyToUpdate, NSError **error) {
+ NSData *data = [[NSData alloc] initWithContentsOfURL:fileURL
options:NSDataReadingUncached error:NULL];
+ if (data) {
+ NSArray *notes = [SKQLConverter notesWithData:data];
+ NSString *htmlString = [SKQLConverter
htmlStringWithNotes:notes];
+ if ((data = [htmlString
dataUsingEncoding:NSUTF8StringEncoding])) {
+ NSSet *types = [NSSet setWithArray:[notes
valueForKey:@"type"]];
+ NSMutableDictionary *attachments = [NSMutableDictionary
dictionary];
+ NSBundle *bundle = [NSBundle
bundleForClass:[SKPreviewProvider class]];
+ for (NSString *type in types) {
+ NSURL *imageURL = [bundle URLForImageResource:type];
+ if (imageURL) {
+ NSData *imageData = [NSData
dataWithContentsOfURL:imageURL];
+ if (imageData) {
+ QLPreviewReplyAttachment *attachment =
[[QLPreviewReplyAttachment alloc] initWithData:imageData contentType:UTTypePNG];
+ [attachments setObject:attachment forKey:type];
+ }
+ }
+ }
+ [replyToUpdate setAttachments:attachments];
+ [replyToUpdate setStringEncoding:NSUTF8StringEncoding];
+ return data;
+ }
+ }
+ return nil;
+ }];
+
+ } else if ([fileType conformsToType:[UTType
typeWithIdentifier:@"com.adobe.postscript"]]) {
+
+ if (@available(macOS 14.0, *)) {} else {
+ reply = [[QLPreviewReply alloc]
initWithDataOfContentType:UTTypePDF contentSize:CGSizeMake(800, 800)
dataCreationBlock:^NSData *(QLPreviewReply *replyToUpdate, NSError **error) {
+ bool converted = false;
+ CGPSConverterCallbacks converterCallbacks = { 0, NULL, NULL,
NULL, NULL, NULL, NULL, NULL };
+ CGPSConverterRef converter = CGPSConverterCreate(NULL,
&converterCallbacks, NULL);
+ CGDataProviderRef provider =
CGDataProviderCreateWithURL((__bridge CFURLRef)fileURL);
+ CFMutableDataRef data = CFDataCreateMutable(NULL, 0);
+ CGDataConsumerRef consumer =
CGDataConsumerCreateWithCFData(data);
+ if (provider != NULL && consumer != NULL)
+ converted = CGPSConverterConvert(converter, provider,
consumer, NULL);
+ CGDataProviderRelease(provider);
+ CGDataConsumerRelease(consumer);
+ CFRelease(converter);
+
+ return converted ? CFBridgingRelease(data) : nil;
+ }];
+ }
+ }
+
+ handler(reply, nil);
+}
+
+@end
+
Added: trunk/SkimQuickLookPreview/SKQLConverter.h
===================================================================
--- trunk/SkimQuickLookPreview/SKQLConverter.h (rev 0)
+++ trunk/SkimQuickLookPreview/SKQLConverter.h 2026-05-23 16:24:47 UTC (rev
16295)
@@ -0,0 +1,47 @@
+//
+// SKQLConverter.h
+// SkimQuickLookPreview
+//
+// Created by Christiaan Hofman on 22/05/2026.
+/*
+ This software is Copyright (c) 2007
+ Christiaan Hofman. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of Christiaan Hofman nor the names of any
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+NSURL *SKQLPDFURLForPDFBundleURL(NSURL *url);
+
+@interface SKQLConverter : NSObject
++ (NSArray *)notesWithData:(NSData *)data;
++ (NSAttributedString *)attributedStringWithNotes:(NSArray *)notes
bundle:(NSBundle *)bundle;
++ (NSString *)htmlStringWithNotes:(NSArray *)notes;
+@end
Added: trunk/SkimQuickLookPreview/SKQLConverter.m
===================================================================
--- trunk/SkimQuickLookPreview/SKQLConverter.m (rev 0)
+++ trunk/SkimQuickLookPreview/SKQLConverter.m 2026-05-23 16:24:47 UTC (rev
16295)
@@ -0,0 +1,270 @@
+//
+// SKQLConverter.h
+// SkimQuickLookPreview
+//
+// Created by Christiaan Hofman on 22/05/2026.
+/*
+ This software is Copyright (c) 2007
+ Christiaan Hofman. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of Christiaan Hofman nor the names of any
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "SKQLConverter.h"
+#include <tgmath.h>
+
+static NSString *_noteFontName = @"LucidaHandwriting-Italic";
+static const CGFloat _noteIndent = 20.0;
+// readable in Cover Flow view, and distinguishable as text in icon view
+static const CGFloat _fontSize = 20.0;
+static const CGFloat _smallFontSize = 10.0;
+
+NSURL *SKQLPDFURLForPDFBundleURL(NSURL *url)
+{
+ NSString *filePath = [url path];
+ NSArray *files = [[NSFileManager defaultManager] subpathsAtPath:filePath];
+ NSString *fileName = [[[filePath lastPathComponent]
stringByDeletingPathExtension] stringByAppendingPathExtension:@"pdf"];
+ NSString *pdfFile = nil;
+
+ if ([files containsObject:fileName]) {
+ pdfFile = fileName;
+ } else {
+ NSUInteger idx = [[files
valueForKeyPath:@"pathExtension.lowercaseString"] indexOfObject:@"pdf"];
+ if (idx != NSNotFound)
+ pdfFile = [files objectAtIndex:idx];
+ }
+ return pdfFile ? [url URLByAppendingPathComponent:pdfFile] : nil;
+}
+
+static NSAttributedString *imageAttachmentForType(NSString *type, NSBundle
*bundle)
+{
+ static NSMutableDictionary *imageWrappers = nil;
+ NSFileWrapper *wrapper = [imageWrappers objectForKey:type];
+
+ if (wrapper == nil) {
+ NSURL *imgURL = [bundle URLForImageResource:type];
+ if (imageWrappers == nil)
+ imageWrappers = [[NSMutableDictionary alloc] init];
+ wrapper = [[NSFileWrapper alloc] initWithURL:imgURL options:0
error:NULL];
+ [wrapper setPreferredFilename:[type
stringByAppendingPathExtension:@"png"]];
+ [imageWrappers setObject:wrapper forKey:type];
+ }
+
+ NSTextAttachment *attachment = [[NSTextAttachment alloc]
initWithFileWrapper:wrapper];
+ NSAttributedString *attrString = [NSAttributedString
attributedStringWithAttachment:attachment];
+
+ return attrString;
+}
+
+static NSColor *colorFromArray(NSArray *array) {
+ CGFloat c[4] = {0.0, 0.0, 0.0, 1.0};
+ if ([array count] > 2) {
+ NSUInteger i;
+ for (i = 0; i < MAX([array count], 4); i++)
+ c[i] = [[array objectAtIndex:i] doubleValue];
+ } else if ([array count] > 0) {
+ c[0] = c[1] = c[2] = [[array objectAtIndex:0] doubleValue];
+ if ([array count] == 2)
+ c[3] = [[array objectAtIndex:1] doubleValue];
+ }
+ return [NSColor colorWithColorSpace:[NSColorSpace sRGBColorSpace]
components:c count:4];
+}
+
+static NSString *hexStringWithColor(NSColor *color)
+{
+ if ([color alphaComponent] < 1.0)
+ color = [[NSColor whiteColor] blendedColorWithFraction:[color
alphaComponent] ofColor:[color colorWithAlphaComponent:1.0]];
+ color = [color colorUsingColorSpace:[NSColorSpace sRGBColorSpace]];
+ unsigned int red = (unsigned int)round(255 * [color redComponent]);
+ unsigned int green = (unsigned int)round(255 * [color greenComponent]);
+ unsigned int blue = (unsigned int)round(255 * [color blueComponent]);
+ return [NSString stringWithFormat:@"%.2x%.2x%.2x", red, green, blue];
+}
+
+// Stolen from OmniFoundation; modified to use malloc instead of alloca()
+static NSString *HTMLEscapeString(NSString *htmlString)
+{
+ unichar *ptr, *begin, *end;
+ NSMutableString *result;
+ NSInteger length;
+
+#define APPEND_PREVIOUS() \
+ [result appendString:[[NSString alloc] initWithCharacters:begin
length:(ptr - begin)]]; \
+ begin = ptr + 1;
+
+ length = [htmlString length];
+ ptr = malloc(length * sizeof(unichar));
+ if (!ptr)
+ return nil;
+
+ // keep a pointer that we can free later
+ unichar *originalPtr = ptr;
+
+ end = ptr + length;
+ [htmlString getCharacters:ptr];
+ result = [NSMutableString stringWithCapacity:length];
+
+ begin = ptr;
+ while (ptr < end) {
+ if (*ptr > 127) {
+ APPEND_PREVIOUS();
+ [result appendFormat:@"&#%ld;", (long)*ptr];
+ } else if (*ptr == '&') {
+ APPEND_PREVIOUS();
+ [result appendString:@"&"];
+ } else if (*ptr == '\"') {
+ APPEND_PREVIOUS();
+ [result appendString:@"""];
+ } else if (*ptr == '<') {
+ APPEND_PREVIOUS();
+ [result appendString:@"<"];
+ } else if (*ptr == '>') {
+ APPEND_PREVIOUS();
+ [result appendString:@">"];
+ } else if (*ptr == '\r') {
+ APPEND_PREVIOUS();
+ if (ptr+1 == end || *(ptr+1) != '\n')
+ [result appendString:@"<br />"];
+ } else if (*ptr == '\n') {
+ APPEND_PREVIOUS();
+ [result appendString:@"<br />"];
+ }
+ ptr++;
+ }
+ APPEND_PREVIOUS();
+ free(originalPtr);
+ return result;
+}
+
+@implementation SKQLConverter
+
++ (NSArray *)notesWithData:(NSData *)data;
+{
+ NSArray *notes = nil;
+ unsigned char ch = 0;
+ if ([data length] > 8)
+ [data getBytes:&ch range:NSMakeRange(8, 1)];
+ ch >>= 4;
+ if (ch == 0xD) {
+ @try { notes = [NSKeyedUnarchiver unarchivedObjectOfClasses:[NSSet
setWithObjects:[NSArray class], [NSDictionary class], [NSString class],
[NSNumber class], [NSData class], [NSDate class], [NSColor class], [NSFont
class], [NSAttributedString class], [NSImage class], nil] fromData:data
error:NULL];; }
+ @catch (id e) {}
+ } else {
+ notes = [NSPropertyListSerialization propertyListWithData:data
options:NSPropertyListImmutable format:NULL error:NULL];
+ }
+ return [notes isKindOfClass:[NSArray class]] ? notes : nil;
+}
+
++ (NSAttributedString *)attributedStringWithNotes:(NSArray *)notes
bundle:(NSBundle *)bundle;
+{
+ NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc]
init];
+ NSFont *font = [NSFont userFontOfSize:_fontSize];
+ NSFont *noteFont = [NSFont fontWithName:_noteFontName size:_fontSize];
+ NSFont *noteTextFont = [NSFont fontWithName:_noteFontName
size:_smallFontSize];
+ NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys:font,
NSFontAttributeName, nil];
+ NSDictionary *noteAttrs = [NSDictionary
dictionaryWithObjectsAndKeys:noteFont, NSFontAttributeName, [NSParagraphStyle
defaultParagraphStyle], NSParagraphStyleAttributeName, nil];
+ NSDictionary *noteTextAttrs = [NSDictionary
dictionaryWithObjectsAndKeys:noteTextFont, NSFontAttributeName,
[NSParagraphStyle defaultParagraphStyle], NSParagraphStyleAttributeName, nil];
+ NSMutableParagraphStyle *noteParStyle = [[NSParagraphStyle
defaultParagraphStyle] mutableCopy];
+
+ [noteParStyle setFirstLineHeadIndent:_noteIndent];
+ [noteParStyle setHeadIndent:_noteIndent];
+
+ if (notes) {
+ NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]
initWithKey:@"pageIndex" ascending:YES];
+ NSEnumerator *noteEnum = [[notes sortedArrayUsingDescriptors:[NSArray
arrayWithObject:sortDescriptor]] objectEnumerator];
+ NSDictionary *note;
+ while (note = [noteEnum nextObject]) {
+ NSString *type = [note objectForKey:@"type"];
+ NSString *contents = [note objectForKey:@"contents"];
+ NSAttributedString *text = [note objectForKey:@"text"];
+ NSColor *color = [note objectForKey:@"color"];
+ NSUInteger pageIndex = [[note objectForKey:@"pageIndex"]
unsignedIntegerValue];
+ NSInteger start;
+
+ if ([text isKindOfClass:[NSData class]])
+ text = [[NSAttributedString alloc] initWithData:(NSData *)text
options:[NSDictionary dictionary] documentAttributes:NULL error:NULL];
+ if ([color isKindOfClass:[NSArray class]])
+ color = colorFromArray((NSArray *)color);
+
+ [attrString appendAttributedString:imageAttachmentForType(type,
bundle)];
+ [attrString addAttribute:NSBackgroundColorAttributeName
value:color range:NSMakeRange([attrString length] - 1, 1)];
+ [attrString appendAttributedString:[[NSAttributedString alloc]
initWithString:[NSString stringWithFormat:@"%@ (page %ld)\n", type,
(long)(pageIndex+1)] attributes:attrs]];
+ start = [attrString length];
+ [attrString appendAttributedString:[[NSAttributedString alloc]
initWithString:contents attributes:noteAttrs]];
+ if (text) {
+ [attrString appendAttributedString:[[NSAttributedString alloc]
initWithString:@"\n"]];
+ [attrString appendAttributedString:[[NSAttributedString alloc]
initWithString:[text string] attributes:noteTextAttrs]];
+ }
+ [attrString appendAttributedString:[[NSAttributedString alloc]
initWithString:@"\n"]];
+ [attrString addAttribute:NSParagraphStyleAttributeName
value:noteParStyle range:NSMakeRange(start, [attrString length] - start)];
+ }
+ [attrString fixAttributesInRange:NSMakeRange(0, [attrString length])];
+ }
+
+ return attrString;
+}
+
++ (NSString *)htmlStringWithNotes:(NSArray *)notes;
+{
+ NSMutableString *htmlString = [NSMutableString string];
+ [htmlString appendString:@"<html><head><style type=\"text/css\">"];
+ [htmlString appendString:@"body {font-family:Helvetica} "];
+ [htmlString appendString:@"dd {font-style:italic} "];
+ [htmlString appendString:@".note-text {font-size:smaller} "];
+ [htmlString appendString:@"</style></head><body><dl>"];
+
+ if (notes) {
+ NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]
initWithKey:@"pageIndex" ascending:YES];
+ NSEnumerator *noteEnum = [[notes sortedArrayUsingDescriptors:[NSArray
arrayWithObject:sortDescriptor]] objectEnumerator];
+ NSDictionary *note;
+ while (note = [noteEnum nextObject]) {
+ NSString *type = [note objectForKey:@"type"];
+ NSString *contents = [note objectForKey:@"contents"];
+ NSAttributedString *text = [note objectForKey:@"text"];
+ NSColor *color = [note objectForKey:@"color"];
+ NSUInteger pageIndex = [[note objectForKey:@"pageIndex"]
unsignedIntegerValue];
+
+ if ([text isKindOfClass:[NSData class]])
+ text = [[NSAttributedString alloc] initWithData:(NSData *)text
options:[NSDictionary dictionary] documentAttributes:NULL error:NULL];
+ if ([color isKindOfClass:[NSArray class]])
+ color = colorFromArray((NSArray *)color);
+
+ [htmlString appendFormat:@"<dt><img src=\"cid:%@.png\"
style=\"background-color:#%@\" />%@ (page %ld)</dt>", type,
hexStringWithColor(color), type, (long)(pageIndex+1)];
+ [htmlString appendFormat:@"<dd>%@", HTMLEscapeString(contents)];
+ if (text)
+ [htmlString appendFormat:@"<div class=\"note-text\">%@</div>",
HTMLEscapeString([text string])];
+ [htmlString appendString:@"</dd>"];
+ }
+ }
+
+ [htmlString appendString:@"</dl></body></html>"];
+
+ return htmlString;
+}
+
+@end
Added: trunk/SkimQuickLookPreview/SkimQuickLookPreview.entitlements
===================================================================
--- trunk/SkimQuickLookPreview/SkimQuickLookPreview.entitlements
(rev 0)
+++ trunk/SkimQuickLookPreview/SkimQuickLookPreview.entitlements
2026-05-23 16:24:47 UTC (rev 16295)
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.apple.security.app-sandbox</key>
+ <true/>
+ <key>com.apple.security.files.user-selected.read-only</key>
+ <true/>
+</dict>
+</plist>
Added: trunk/SkimQuickLookPreview/Square.png
===================================================================
(Binary files differ)
Index: trunk/SkimQuickLookPreview/Square.png
===================================================================
--- trunk/SkimQuickLookPreview/Square.png 2026-05-14 16:33:34 UTC (rev
16294)
+++ trunk/SkimQuickLookPreview/Square.png 2026-05-23 16:24:47 UTC (rev
16295)
Property changes on: trunk/SkimQuickLookPreview/Square.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookPreview/StrikeOut.png
===================================================================
(Binary files differ)
Index: trunk/SkimQuickLookPreview/StrikeOut.png
===================================================================
--- trunk/SkimQuickLookPreview/StrikeOut.png 2026-05-14 16:33:34 UTC (rev
16294)
+++ trunk/SkimQuickLookPreview/StrikeOut.png 2026-05-23 16:24:47 UTC (rev
16295)
Property changes on: trunk/SkimQuickLookPreview/StrikeOut.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookPreview/Underline.png
===================================================================
(Binary files differ)
Index: trunk/SkimQuickLookPreview/Underline.png
===================================================================
--- trunk/SkimQuickLookPreview/Underline.png 2026-05-14 16:33:34 UTC (rev
16294)
+++ trunk/SkimQuickLookPreview/Underline.png 2026-05-23 16:24:47 UTC (rev
16295)
Property changes on: trunk/SkimQuickLookPreview/Underline.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookPreview/Widget.png
===================================================================
(Binary files differ)
Index: trunk/SkimQuickLookPreview/Widget.png
===================================================================
--- trunk/SkimQuickLookPreview/Widget.png 2026-05-14 16:33:34 UTC (rev
16294)
+++ trunk/SkimQuickLookPreview/Widget.png 2026-05-23 16:24:47 UTC (rev
16295)
Property changes on: trunk/SkimQuickLookPreview/Widget.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookThumbnails/Circle.png
===================================================================
(Binary files differ)
Index: trunk/SkimQuickLookThumbnails/Circle.png
===================================================================
--- trunk/SkimQuickLookThumbnails/Circle.png 2026-05-14 16:33:34 UTC (rev
16294)
+++ trunk/SkimQuickLookThumbnails/Circle.png 2026-05-23 16:24:47 UTC (rev
16295)
Property changes on: trunk/SkimQuickLookThumbnails/Circle.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookThumbnails/FreeText.png
===================================================================
(Binary files differ)
Index: trunk/SkimQuickLookThumbnails/FreeText.png
===================================================================
--- trunk/SkimQuickLookThumbnails/FreeText.png 2026-05-14 16:33:34 UTC (rev
16294)
+++ trunk/SkimQuickLookThumbnails/FreeText.png 2026-05-23 16:24:47 UTC (rev
16295)
Property changes on: trunk/SkimQuickLookThumbnails/FreeText.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookThumbnails/Highlight.png
===================================================================
(Binary files differ)
Index: trunk/SkimQuickLookThumbnails/Highlight.png
===================================================================
--- trunk/SkimQuickLookThumbnails/Highlight.png 2026-05-14 16:33:34 UTC (rev
16294)
+++ trunk/SkimQuickLookThumbnails/Highlight.png 2026-05-23 16:24:47 UTC (rev
16295)
Property changes on: trunk/SkimQuickLookThumbnails/Highlight.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookThumbnails/Info.plist
===================================================================
--- trunk/SkimQuickLookThumbnails/Info.plist (rev 0)
+++ trunk/SkimQuickLookThumbnails/Info.plist 2026-05-23 16:24:47 UTC (rev
16295)
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>NSExtension</key>
+ <dict>
+ <key>NSExtensionAttributes</key>
+ <dict>
+ <key>QLSupportedContentTypes</key>
+ <array>
+ <string>net.sourceforge.skim-app.pdfd</string>
+
<string>net.sourceforge.skim-app.skimnotes</string>
+ <string>com.adobe.postscript</string>
+ </array>
+ <key>QLThumbnailMinimumDimension</key>
+ <integer>0</integer>
+ </dict>
+ <key>NSExtensionPointIdentifier</key>
+ <string>com.apple.quicklook.thumbnail</string>
+ <key>NSExtensionPrincipalClass</key>
+ <string>SKThumbnailProvider</string>
+ </dict>
+ <key>UTImportedTypeDeclarations</key>
+ <array>
+ <dict>
+ <key>UTTypeConformsTo</key>
+ <array>
+ <string>com.apple.package</string>
+ <string>public.composite-content</string>
+ </array>
+ <key>UTTypeDescription</key>
+ <string>PDF Bundle</string>
+ <key>UTTypeIdentifier</key>
+ <string>net.sourceforge.skim-app.pdfd</string>
+ <key>UTTypeTagSpecification</key>
+ <dict>
+ <key>com.apple.ostype</key>
+ <string>PDFD</string>
+ <key>public.filename-extension</key>
+ <array>
+ <string>pdfd</string>
+ </array>
+ </dict>
+ </dict>
+ <dict>
+ <key>UTTypeConformsTo</key>
+ <array>
+ <string>public.data</string>
+ </array>
+ <key>UTTypeDescription</key>
+ <string>Skim Notes</string>
+ <key>UTTypeIdentifier</key>
+ <string>net.sourceforge.skim-app.skimnotes</string>
+ <key>UTTypeTagSpecification</key>
+ <dict>
+ <key>com.apple.ostype</key>
+ <string>SKNT</string>
+ <key>public.filename-extension</key>
+ <array>
+ <string>skim</string>
+ </array>
+ </dict>
+ </dict>
+ <dict>
+ <key>UTTypeConformsTo</key>
+ <array>
+ <string>public.data</string>
+ </array>
+ <key>UTTypeDescription</key>
+ <string>PostScript</string>
+ <key>UTTypeIdentifier</key>
+ <string>com.adobe.postscript</string>
+ <key>UTTypeTagSpecification</key>
+ <dict>
+ <key>public.filename-extension</key>
+ <array>
+ <string>ps</string>
+ </array>
+ <key>public.mime-type</key>
+ <array>
+ <string>application/postscript</string>
+ </array>
+ </dict>
+ </dict>
+ </array>
+</dict>
+</plist>
Added: trunk/SkimQuickLookThumbnails/Ink.png
===================================================================
(Binary files differ)
Index: trunk/SkimQuickLookThumbnails/Ink.png
===================================================================
--- trunk/SkimQuickLookThumbnails/Ink.png 2026-05-14 16:33:34 UTC (rev
16294)
+++ trunk/SkimQuickLookThumbnails/Ink.png 2026-05-23 16:24:47 UTC (rev
16295)
Property changes on: trunk/SkimQuickLookThumbnails/Ink.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookThumbnails/Line.png
===================================================================
(Binary files differ)
Index: trunk/SkimQuickLookThumbnails/Line.png
===================================================================
--- trunk/SkimQuickLookThumbnails/Line.png 2026-05-14 16:33:34 UTC (rev
16294)
+++ trunk/SkimQuickLookThumbnails/Line.png 2026-05-23 16:24:47 UTC (rev
16295)
Property changes on: trunk/SkimQuickLookThumbnails/Line.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookThumbnails/Note.png
===================================================================
(Binary files differ)
Index: trunk/SkimQuickLookThumbnails/Note.png
===================================================================
--- trunk/SkimQuickLookThumbnails/Note.png 2026-05-14 16:33:34 UTC (rev
16294)
+++ trunk/SkimQuickLookThumbnails/Note.png 2026-05-23 16:24:47 UTC (rev
16295)
Property changes on: trunk/SkimQuickLookThumbnails/Note.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookThumbnails/SKQLConverter.h
===================================================================
--- trunk/SkimQuickLookThumbnails/SKQLConverter.h
(rev 0)
+++ trunk/SkimQuickLookThumbnails/SKQLConverter.h 2026-05-23 16:24:47 UTC
(rev 16295)
@@ -0,0 +1,47 @@
+//
+// SKQLConverter.h
+// SkimQuickLookThumbnails
+//
+// Created by Christiaan Hofman on 22/05/2026.
+/*
+ This software is Copyright (c) 2007
+ Christiaan Hofman. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of Christiaan Hofman nor the names of any
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+extern NSURL *SKQLPDFURLForPDFBundleURL(NSURL *url);
+
+@interface SKQLConverter : NSObject
++ (NSArray *)notesWithData:(NSData *)data;
++ (NSAttributedString *)attributedStringWithNotes:(NSArray *)notes
bundle:(NSBundle *)bundle;
++ (NSString *)htmlStringWithNotes:(NSArray *)notes;
+@end
Added: trunk/SkimQuickLookThumbnails/SKQLConverter.m
===================================================================
--- trunk/SkimQuickLookThumbnails/SKQLConverter.m
(rev 0)
+++ trunk/SkimQuickLookThumbnails/SKQLConverter.m 2026-05-23 16:24:47 UTC
(rev 16295)
@@ -0,0 +1,270 @@
+//
+// SKQLConverter.h
+// SkimQuickLookThumbnails
+//
+// Created by Christiaan Hofman on 22/05/2026.
+/*
+ This software is Copyright (c) 2007
+ Christiaan Hofman. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of Christiaan Hofman nor the names of any
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "SKQLConverter.h"
+#include <tgmath.h>
+
+static NSString *_noteFontName = @"LucidaHandwriting-Italic";
+static const CGFloat _noteIndent = 20.0;
+// readable in Cover Flow view, and distinguishable as text in icon view
+static const CGFloat _fontSize = 20.0;
+static const CGFloat _smallFontSize = 10.0;
+
+NSURL *SKQLPDFURLForPDFBundleURL(NSURL *url)
+{
+ NSString *filePath = [url path];
+ NSArray *files = [[NSFileManager defaultManager] subpathsAtPath:filePath];
+ NSString *fileName = [[[filePath lastPathComponent]
stringByDeletingPathExtension] stringByAppendingPathExtension:@"pdf"];
+ NSString *pdfFile = nil;
+
+ if ([files containsObject:fileName]) {
+ pdfFile = fileName;
+ } else {
+ NSUInteger idx = [[files
valueForKeyPath:@"pathExtension.lowercaseString"] indexOfObject:@"pdf"];
+ if (idx != NSNotFound)
+ pdfFile = [files objectAtIndex:idx];
+ }
+ return pdfFile ? [url URLByAppendingPathComponent:pdfFile] : nil;
+}
+
+static NSAttributedString *imageAttachmentForType(NSString *type, NSBundle
*bundle)
+{
+ static NSMutableDictionary *imageWrappers = nil;
+ NSFileWrapper *wrapper = [imageWrappers objectForKey:type];
+
+ if (wrapper == nil) {
+ NSURL *imgURL = [bundle URLForImageResource:type];
+ if (imageWrappers == nil)
+ imageWrappers = [[NSMutableDictionary alloc] init];
+ wrapper = [[NSFileWrapper alloc] initWithURL:imgURL options:0
error:NULL];
+ [wrapper setPreferredFilename:[type
stringByAppendingPathExtension:@"png"]];
+ [imageWrappers setObject:wrapper forKey:type];
+ }
+
+ NSTextAttachment *attachment = [[NSTextAttachment alloc]
initWithFileWrapper:wrapper];
+ NSAttributedString *attrString = [NSAttributedString
attributedStringWithAttachment:attachment];
+
+ return attrString;
+}
+
+static NSColor *colorFromArray(NSArray *array) {
+ CGFloat c[4] = {0.0, 0.0, 0.0, 1.0};
+ if ([array count] > 2) {
+ NSUInteger i;
+ for (i = 0; i < MAX([array count], 4); i++)
+ c[i] = [[array objectAtIndex:i] doubleValue];
+ } else if ([array count] > 0) {
+ c[0] = c[1] = c[2] = [[array objectAtIndex:0] doubleValue];
+ if ([array count] == 2)
+ c[3] = [[array objectAtIndex:1] doubleValue];
+ }
+ return [NSColor colorWithColorSpace:[NSColorSpace sRGBColorSpace]
components:c count:4];
+}
+
+static NSString *hexStringWithColor(NSColor *color)
+{
+ if ([color alphaComponent] < 1.0)
+ color = [[NSColor whiteColor] blendedColorWithFraction:[color
alphaComponent] ofColor:[color colorWithAlphaComponent:1.0]];
+ color = [color colorUsingColorSpace:[NSColorSpace sRGBColorSpace]];
+ unsigned int red = (unsigned int)round(255 * [color redComponent]);
+ unsigned int green = (unsigned int)round(255 * [color greenComponent]);
+ unsigned int blue = (unsigned int)round(255 * [color blueComponent]);
+ return [NSString stringWithFormat:@"%.2x%.2x%.2x", red, green, blue];
+}
+
+// Stolen from OmniFoundation; modified to use malloc instead of alloca()
+static NSString *HTMLEscapeString(NSString *htmlString)
+{
+ unichar *ptr, *begin, *end;
+ NSMutableString *result;
+ NSInteger length;
+
+#define APPEND_PREVIOUS() \
+ [result appendString:[[NSString alloc] initWithCharacters:begin
length:(ptr - begin)]]; \
+ begin = ptr + 1;
+
+ length = [htmlString length];
+ ptr = malloc(length * sizeof(unichar));
+ if (!ptr)
+ return nil;
+
+ // keep a pointer that we can free later
+ unichar *originalPtr = ptr;
+
+ end = ptr + length;
+ [htmlString getCharacters:ptr];
+ result = [NSMutableString stringWithCapacity:length];
+
+ begin = ptr;
+ while (ptr < end) {
+ if (*ptr > 127) {
+ APPEND_PREVIOUS();
+ [result appendFormat:@"&#%ld;", (long)*ptr];
+ } else if (*ptr == '&') {
+ APPEND_PREVIOUS();
+ [result appendString:@"&"];
+ } else if (*ptr == '\"') {
+ APPEND_PREVIOUS();
+ [result appendString:@"""];
+ } else if (*ptr == '<') {
+ APPEND_PREVIOUS();
+ [result appendString:@"<"];
+ } else if (*ptr == '>') {
+ APPEND_PREVIOUS();
+ [result appendString:@">"];
+ } else if (*ptr == '\r') {
+ APPEND_PREVIOUS();
+ if (ptr+1 == end || *(ptr+1) != '\n')
+ [result appendString:@"<br />"];
+ } else if (*ptr == '\n') {
+ APPEND_PREVIOUS();
+ [result appendString:@"<br />"];
+ }
+ ptr++;
+ }
+ APPEND_PREVIOUS();
+ free(originalPtr);
+ return result;
+}
+
+@implementation SKQLConverter
+
++ (NSArray *)notesWithData:(NSData *)data;
+{
+ NSArray *notes = nil;
+ unsigned char ch = 0;
+ if ([data length] > 8)
+ [data getBytes:&ch range:NSMakeRange(8, 1)];
+ ch >>= 4;
+ if (ch == 0xD) {
+ @try { notes = [NSKeyedUnarchiver unarchivedObjectOfClasses:[NSSet
setWithObjects:[NSArray class], [NSDictionary class], [NSString class],
[NSNumber class], [NSData class], [NSDate class], [NSColor class], [NSFont
class], [NSAttributedString class], [NSImage class], nil] fromData:data
error:NULL];; }
+ @catch (id e) {}
+ } else {
+ notes = [NSPropertyListSerialization propertyListWithData:data
options:NSPropertyListImmutable format:NULL error:NULL];
+ }
+ return [notes isKindOfClass:[NSArray class]] ? notes : nil;
+}
+
++ (NSAttributedString *)attributedStringWithNotes:(NSArray *)notes
bundle:(NSBundle *)bundle;
+{
+ NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc]
init];
+ NSFont *font = [NSFont userFontOfSize:_fontSize];
+ NSFont *noteFont = [NSFont fontWithName:_noteFontName size:_fontSize];
+ NSFont *noteTextFont = [NSFont fontWithName:_noteFontName
size:_smallFontSize];
+ NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys:font,
NSFontAttributeName, nil];
+ NSDictionary *noteAttrs = [NSDictionary
dictionaryWithObjectsAndKeys:noteFont, NSFontAttributeName, [NSParagraphStyle
defaultParagraphStyle], NSParagraphStyleAttributeName, nil];
+ NSDictionary *noteTextAttrs = [NSDictionary
dictionaryWithObjectsAndKeys:noteTextFont, NSFontAttributeName,
[NSParagraphStyle defaultParagraphStyle], NSParagraphStyleAttributeName, nil];
+ NSMutableParagraphStyle *noteParStyle = [[NSParagraphStyle
defaultParagraphStyle] mutableCopy];
+
+ [noteParStyle setFirstLineHeadIndent:_noteIndent];
+ [noteParStyle setHeadIndent:_noteIndent];
+
+ if (notes) {
+ NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]
initWithKey:@"pageIndex" ascending:YES];
+ NSEnumerator *noteEnum = [[notes sortedArrayUsingDescriptors:[NSArray
arrayWithObject:sortDescriptor]] objectEnumerator];
+ NSDictionary *note;
+ while (note = [noteEnum nextObject]) {
+ NSString *type = [note objectForKey:@"type"];
+ NSString *contents = [note objectForKey:@"contents"];
+ NSAttributedString *text = [note objectForKey:@"text"];
+ NSColor *color = [note objectForKey:@"color"];
+ NSUInteger pageIndex = [[note objectForKey:@"pageIndex"]
unsignedIntegerValue];
+ NSInteger start;
+
+ if ([text isKindOfClass:[NSData class]])
+ text = [[NSAttributedString alloc] initWithData:(NSData *)text
options:[NSDictionary dictionary] documentAttributes:NULL error:NULL];
+ if ([color isKindOfClass:[NSArray class]])
+ color = colorFromArray((NSArray *)color);
+
+ [attrString appendAttributedString:imageAttachmentForType(type,
bundle)];
+ [attrString addAttribute:NSBackgroundColorAttributeName
value:color range:NSMakeRange([attrString length] - 1, 1)];
+ [attrString appendAttributedString:[[NSAttributedString alloc]
initWithString:[NSString stringWithFormat:@"%@ (page %ld)\n", type,
(long)(pageIndex+1)] attributes:attrs]];
+ start = [attrString length];
+ [attrString appendAttributedString:[[NSAttributedString alloc]
initWithString:contents attributes:noteAttrs]];
+ if (text) {
+ [attrString appendAttributedString:[[NSAttributedString alloc]
initWithString:@"\n"]];
+ [attrString appendAttributedString:[[NSAttributedString alloc]
initWithString:[text string] attributes:noteTextAttrs]];
+ }
+ [attrString appendAttributedString:[[NSAttributedString alloc]
initWithString:@"\n"]];
+ [attrString addAttribute:NSParagraphStyleAttributeName
value:noteParStyle range:NSMakeRange(start, [attrString length] - start)];
+ }
+ [attrString fixAttributesInRange:NSMakeRange(0, [attrString length])];
+ }
+
+ return attrString;
+}
+
++ (NSString *)htmlStringWithNotes:(NSArray *)notes;
+{
+ NSMutableString *htmlString = [NSMutableString string];
+ [htmlString appendString:@"<html><head><style type=\"text/css\">"];
+ [htmlString appendString:@"body {font-family:Helvetica} "];
+ [htmlString appendString:@"dd {font-style:italic} "];
+ [htmlString appendString:@".note-text {font-size:smaller} "];
+ [htmlString appendString:@"</style></head><body><dl>"];
+
+ if (notes) {
+ NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]
initWithKey:@"pageIndex" ascending:YES];
+ NSEnumerator *noteEnum = [[notes sortedArrayUsingDescriptors:[NSArray
arrayWithObject:sortDescriptor]] objectEnumerator];
+ NSDictionary *note;
+ while (note = [noteEnum nextObject]) {
+ NSString *type = [note objectForKey:@"type"];
+ NSString *contents = [note objectForKey:@"contents"];
+ NSAttributedString *text = [note objectForKey:@"text"];
+ NSColor *color = [note objectForKey:@"color"];
+ NSUInteger pageIndex = [[note objectForKey:@"pageIndex"]
unsignedIntegerValue];
+
+ if ([text isKindOfClass:[NSData class]])
+ text = [[NSAttributedString alloc] initWithData:(NSData *)text
options:[NSDictionary dictionary] documentAttributes:NULL error:NULL];
+ if ([color isKindOfClass:[NSArray class]])
+ color = colorFromArray((NSArray *)color);
+
+ [htmlString appendFormat:@"<dt><img src=\"cid:%@.png\"
style=\"background-color:#%@\" />%@ (page %ld)</dt>", type,
hexStringWithColor(color), type, (long)(pageIndex+1)];
+ [htmlString appendFormat:@"<dd>%@", HTMLEscapeString(contents)];
+ if (text)
+ [htmlString appendFormat:@"<div class=\"note-text\">%@</div>",
HTMLEscapeString([text string])];
+ [htmlString appendString:@"</dd>"];
+ }
+ }
+
+ [htmlString appendString:@"</dl></body></html>"];
+
+ return htmlString;
+}
+
+@end
Added: trunk/SkimQuickLookThumbnails/SKThumbnailProvider.h
===================================================================
--- trunk/SkimQuickLookThumbnails/SKThumbnailProvider.h
(rev 0)
+++ trunk/SkimQuickLookThumbnails/SKThumbnailProvider.h 2026-05-23 16:24:47 UTC
(rev 16295)
@@ -0,0 +1,47 @@
+//
+// SKThumbnailProvider.h
+// SkimQuickLookThumbnails
+//
+// Created by Christiaan Hofman on 22/05/2026.
+/*
+ This software is Copyright (c) 2026
+ Christiaan Hofman. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of Christiaan Hofman nor the names of any
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <QuickLookThumbnailing/QuickLookThumbnailing.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface SKThumbnailProvider : QLThumbnailProvider
+
+@end
+
+NS_ASSUME_NONNULL_END
Added: trunk/SkimQuickLookThumbnails/SKThumbnailProvider.m
===================================================================
--- trunk/SkimQuickLookThumbnails/SKThumbnailProvider.m
(rev 0)
+++ trunk/SkimQuickLookThumbnails/SKThumbnailProvider.m 2026-05-23 16:24:47 UTC
(rev 16295)
@@ -0,0 +1,247 @@
+//
+// SKThumbnailProvider.m
+// SkimQuickLookThumbnails
+//
+// Created by Christiaan Hofman on 22/05/2026.
+/*
+ This software is Copyright (c) 2026
+ Christiaan Hofman. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of Christiaan Hofman nor the names of any
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "SKThumbnailProvider.h"
+#import <Cocoa/Cocoa.h>
+#import "SKQLConverter.h"
+
+// Same size as [[NSPrintInfo sharedPrintInfo] paperSize] on my system
+// NSPrintInfo must not be used in a non-main thread (and it's hellishly slow
in some circumstances)
+static const NSSize _paperSize = (NSSize) { 612, 792 };
+
+// page margins 20 pt on all edges
+static const CGFloat _horizontalMargin = 20;
+static const CGFloat _verticalMargin = 20;
+static const NSSize _containerSize = (NSSize) { 572, 752 };
+static const NSRect _iconRect = (NSRect) { { 50, 140 }, { 512, 512 } };
+
+// wash the app icon over a white page background
+static void drawBackgroundAndApplicationIconInCurrentContext(NSBundle *bundle)
+{
+ [[NSColor whiteColor] setFill];
+ NSRect pageRect = { NSZeroPoint, _paperSize };
+ NSRectFillUsingOperation(pageRect, NSCompositingOperationSourceOver);
+ BOOL isHR =
CGContextGetUserSpaceToDeviceSpaceTransform([[NSGraphicsContext currentContext]
CGContext]).a > 1.0;
+
+ NSURL *iconURL = [bundle URLForImageResource:isHR ? @"Skim_2x" : @"Skim"];
+ NSImage *appIcon = [[NSImage alloc] initWithContentsOfURL:iconURL];
+
+ [appIcon drawInRect:_iconRect fromRect:NSZeroRect
operation:NSCompositingOperationSourceOver fraction:0.3];
+}
+
+// creates a new NSTextStorage/NSLayoutManager/NSTextContainer system suitable
for drawing in a thread
+static NSTextStorage *createTextStorage()
+{
+ NSTextStorage *textStorage = [[NSTextStorage alloc] init];
+ NSLayoutManager *lm = [[NSLayoutManager alloc] init];
+ NSTextContainer *tc = [[NSTextContainer alloc] init];
+ [tc setContainerSize:_containerSize];
+ [lm addTextContainer:tc];
+ // don't let the layout manager use its threaded layout (see header)
+ [lm setBackgroundLayoutEnabled:NO];
+ [textStorage addLayoutManager:lm];
+ // see header; the CircleView example sets it to NO
+ //[lm setUsesScreenFonts:YES];
+
+ return textStorage;
+}
+
+// assumes that the current NSGraphicsContext is the destination
+static void drawAttributedStringInCurrentContext(NSAttributedString
*attrString)
+{
+ CGContextRef ctxt = [[NSGraphicsContext currentContext] CGContext];
+
+ NSTextStorage *textStorage = createTextStorage();
+ [textStorage beginEditing];
+ [textStorage setAttributedString:attrString];
+
+ [textStorage endEditing];
+ NSRect stringRect = NSZeroRect;
+ stringRect.size = _paperSize;
+
+ CGContextSaveGState(ctxt);
+
+ CGAffineTransform t1 = CGAffineTransformMakeTranslation(_horizontalMargin,
_paperSize.height - _verticalMargin);
+ CGAffineTransform t2 = CGAffineTransformMakeScale(1, -1);
+ CGAffineTransform pageTransform = CGAffineTransformConcat(t2, t1);
+ CGContextConcatCTM(ctxt, pageTransform);
+
+ // objectAtIndex:0 is safe, since we added these to the text storage (so
there's at least one)
+ NSLayoutManager *lm = [[textStorage layoutManagers] objectAtIndex:0];
+ NSTextContainer *tc = [[lm textContainers] objectAtIndex:0];
+
+ NSRange glyphRange;
+
+ // we now have a properly flipped graphics context, so force layout and
then draw the text
+ glyphRange = [lm glyphRangeForBoundingRect:stringRect inTextContainer:tc];
@@ Diff output truncated at 100000 characters. @@
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