Replace SVGKit package with CoreSVG
Changelog-Fixed: Fixed crash on some SVG profile pictures Closes: #416
This commit is contained in:
@@ -177,9 +177,8 @@
|
|||||||
647D9A8D2968520300A295DE /* SideMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 647D9A8C2968520300A295DE /* SideMenuView.swift */; };
|
647D9A8D2968520300A295DE /* SideMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 647D9A8C2968520300A295DE /* SideMenuView.swift */; };
|
||||||
64FBD06F296255C400D9D3B2 /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64FBD06E296255C400D9D3B2 /* Theme.swift */; };
|
64FBD06F296255C400D9D3B2 /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64FBD06E296255C400D9D3B2 /* Theme.swift */; };
|
||||||
6C7DE41F2955169800E66263 /* Vault in Frameworks */ = {isa = PBXBuildFile; productRef = 6C7DE41E2955169800E66263 /* Vault */; };
|
6C7DE41F2955169800E66263 /* Vault in Frameworks */ = {isa = PBXBuildFile; productRef = 6C7DE41E2955169800E66263 /* Vault */; };
|
||||||
7C45AE6D297352F90031D7BC /* SVGKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7C45AE6C297352F90031D7BC /* SVGKit */; };
|
|
||||||
7C45AE6F297352F90031D7BC /* SVGKitSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 7C45AE6E297352F90031D7BC /* SVGKitSwift */; };
|
|
||||||
7C45AE71297353390031D7BC /* KFImageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C45AE70297353390031D7BC /* KFImageModel.swift */; };
|
7C45AE71297353390031D7BC /* KFImageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C45AE70297353390031D7BC /* KFImageModel.swift */; };
|
||||||
|
7C60CAEF298471A1009C80D6 /* CoreSVG.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C60CAEE298471A1009C80D6 /* CoreSVG.swift */; };
|
||||||
7C902AE32981D55B002AB16E /* ZoomableScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C902AE22981D55B002AB16E /* ZoomableScrollView.swift */; };
|
7C902AE32981D55B002AB16E /* ZoomableScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C902AE22981D55B002AB16E /* ZoomableScrollView.swift */; };
|
||||||
9609F058296E220800069BF3 /* BannerImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9609F057296E220800069BF3 /* BannerImageView.swift */; };
|
9609F058296E220800069BF3 /* BannerImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9609F057296E220800069BF3 /* BannerImageView.swift */; };
|
||||||
BA693074295D649800ADDB87 /* UserSettingsStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA693073295D649800ADDB87 /* UserSettingsStore.swift */; };
|
BA693074295D649800ADDB87 /* UserSettingsStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA693073295D649800ADDB87 /* UserSettingsStore.swift */; };
|
||||||
@@ -433,6 +432,7 @@
|
|||||||
647D9A8C2968520300A295DE /* SideMenuView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SideMenuView.swift; sourceTree = "<group>"; };
|
647D9A8C2968520300A295DE /* SideMenuView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SideMenuView.swift; sourceTree = "<group>"; };
|
||||||
64FBD06E296255C400D9D3B2 /* Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = "<group>"; };
|
64FBD06E296255C400D9D3B2 /* Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = "<group>"; };
|
||||||
7C45AE70297353390031D7BC /* KFImageModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KFImageModel.swift; sourceTree = "<group>"; };
|
7C45AE70297353390031D7BC /* KFImageModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KFImageModel.swift; sourceTree = "<group>"; };
|
||||||
|
7C60CAEE298471A1009C80D6 /* CoreSVG.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreSVG.swift; sourceTree = "<group>"; };
|
||||||
7C902AE22981D55B002AB16E /* ZoomableScrollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZoomableScrollView.swift; sourceTree = "<group>"; };
|
7C902AE22981D55B002AB16E /* ZoomableScrollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZoomableScrollView.swift; sourceTree = "<group>"; };
|
||||||
9609F057296E220800069BF3 /* BannerImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BannerImageView.swift; sourceTree = "<group>"; };
|
9609F057296E220800069BF3 /* BannerImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BannerImageView.swift; sourceTree = "<group>"; };
|
||||||
BA693073295D649800ADDB87 /* UserSettingsStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSettingsStore.swift; sourceTree = "<group>"; };
|
BA693073295D649800ADDB87 /* UserSettingsStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSettingsStore.swift; sourceTree = "<group>"; };
|
||||||
@@ -449,8 +449,6 @@
|
|||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
7C45AE6F297352F90031D7BC /* SVGKitSwift in Frameworks */,
|
|
||||||
7C45AE6D297352F90031D7BC /* SVGKit in Frameworks */,
|
|
||||||
4C06670428FC7EC500038D2A /* Kingfisher in Frameworks */,
|
4C06670428FC7EC500038D2A /* Kingfisher in Frameworks */,
|
||||||
6C7DE41F2955169800E66263 /* Vault in Frameworks */,
|
6C7DE41F2955169800E66263 /* Vault in Frameworks */,
|
||||||
4CE6DF1227F7A2B300C66700 /* Starscream in Frameworks */,
|
4CE6DF1227F7A2B300C66700 /* Starscream in Frameworks */,
|
||||||
@@ -689,6 +687,7 @@
|
|||||||
4CB8838529656C8B00DC99E7 /* NIP05.swift */,
|
4CB8838529656C8B00DC99E7 /* NIP05.swift */,
|
||||||
4CF0ABD72981980C00D66079 /* Lists.swift */,
|
4CF0ABD72981980C00D66079 /* Lists.swift */,
|
||||||
4CF0ABEF29857E9200D66079 /* Bech32Object.swift */,
|
4CF0ABEF29857E9200D66079 /* Bech32Object.swift */,
|
||||||
|
7C60CAEE298471A1009C80D6 /* CoreSVG.swift */,
|
||||||
);
|
);
|
||||||
path = Util;
|
path = Util;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -876,8 +875,6 @@
|
|||||||
4C649880286E0EE300EAE2B3 /* secp256k1 */,
|
4C649880286E0EE300EAE2B3 /* secp256k1 */,
|
||||||
4C06670328FC7EC500038D2A /* Kingfisher */,
|
4C06670328FC7EC500038D2A /* Kingfisher */,
|
||||||
6C7DE41E2955169800E66263 /* Vault */,
|
6C7DE41E2955169800E66263 /* Vault */,
|
||||||
7C45AE6C297352F90031D7BC /* SVGKit */,
|
|
||||||
7C45AE6E297352F90031D7BC /* SVGKitSwift */,
|
|
||||||
);
|
);
|
||||||
productName = damus;
|
productName = damus;
|
||||||
productReference = 4CE6DEE327F7A08100C66700 /* damus.app */;
|
productReference = 4CE6DEE327F7A08100C66700 /* damus.app */;
|
||||||
@@ -964,7 +961,6 @@
|
|||||||
4C64987F286E0EE300EAE2B3 /* XCRemoteSwiftPackageReference "secp256k1" */,
|
4C64987F286E0EE300EAE2B3 /* XCRemoteSwiftPackageReference "secp256k1" */,
|
||||||
4C06670228FC7EC500038D2A /* XCRemoteSwiftPackageReference "Kingfisher" */,
|
4C06670228FC7EC500038D2A /* XCRemoteSwiftPackageReference "Kingfisher" */,
|
||||||
6C7DE41D2955169800E66263 /* XCRemoteSwiftPackageReference "Vault" */,
|
6C7DE41D2955169800E66263 /* XCRemoteSwiftPackageReference "Vault" */,
|
||||||
7C45AE6B297352F90031D7BC /* XCRemoteSwiftPackageReference "SVGKit" */,
|
|
||||||
);
|
);
|
||||||
productRefGroup = 4CE6DEE427F7A08100C66700 /* Products */;
|
productRefGroup = 4CE6DEE427F7A08100C66700 /* Products */;
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
@@ -1124,6 +1120,7 @@
|
|||||||
4CB8838629656C8B00DC99E7 /* NIP05.swift in Sources */,
|
4CB8838629656C8B00DC99E7 /* NIP05.swift in Sources */,
|
||||||
4CF0ABD82981980C00D66079 /* Lists.swift in Sources */,
|
4CF0ABD82981980C00D66079 /* Lists.swift in Sources */,
|
||||||
4C5C7E6A284EDE2E00A22DF5 /* SearchResultsView.swift in Sources */,
|
4C5C7E6A284EDE2E00A22DF5 /* SearchResultsView.swift in Sources */,
|
||||||
|
7C60CAEF298471A1009C80D6 /* CoreSVG.swift in Sources */,
|
||||||
6439E014296790CF0020672B /* ProfileZoomView.swift in Sources */,
|
6439E014296790CF0020672B /* ProfileZoomView.swift in Sources */,
|
||||||
4CE6DF1627F8DEBF00C66700 /* RelayConnection.swift in Sources */,
|
4CE6DF1627F8DEBF00C66700 /* RelayConnection.swift in Sources */,
|
||||||
4C3BEFD6281D995700B3DE84 /* ActionBarModel.swift in Sources */,
|
4C3BEFD6281D995700B3DE84 /* ActionBarModel.swift in Sources */,
|
||||||
@@ -1391,7 +1388,7 @@
|
|||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 11;
|
CURRENT_PROJECT_VERSION = 11;
|
||||||
DEVELOPMENT_ASSET_PATHS = "\"damus/Preview Content\"";
|
DEVELOPMENT_ASSET_PATHS = "\"damus/Preview Content\"";
|
||||||
DEVELOPMENT_TEAM = XK7H4JAB3D;
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_FILE = damus/Info.plist;
|
INFOPLIST_FILE = damus/Info.plist;
|
||||||
@@ -1612,14 +1609,6 @@
|
|||||||
minimumVersion = 1.0.0;
|
minimumVersion = 1.0.0;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
7C45AE6B297352F90031D7BC /* XCRemoteSwiftPackageReference "SVGKit" */ = {
|
|
||||||
isa = XCRemoteSwiftPackageReference;
|
|
||||||
repositoryURL = "https://github.com/SVGKit/SVGKit";
|
|
||||||
requirement = {
|
|
||||||
kind = revision;
|
|
||||||
revision = e1f13e27b1e4c0ffe20e7d8d3984bf49c2a584d0;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
/* End XCRemoteSwiftPackageReference section */
|
/* End XCRemoteSwiftPackageReference section */
|
||||||
|
|
||||||
/* Begin XCSwiftPackageProductDependency section */
|
/* Begin XCSwiftPackageProductDependency section */
|
||||||
@@ -1643,16 +1632,6 @@
|
|||||||
package = 6C7DE41D2955169800E66263 /* XCRemoteSwiftPackageReference "Vault" */;
|
package = 6C7DE41D2955169800E66263 /* XCRemoteSwiftPackageReference "Vault" */;
|
||||||
productName = Vault;
|
productName = Vault;
|
||||||
};
|
};
|
||||||
7C45AE6C297352F90031D7BC /* SVGKit */ = {
|
|
||||||
isa = XCSwiftPackageProductDependency;
|
|
||||||
package = 7C45AE6B297352F90031D7BC /* XCRemoteSwiftPackageReference "SVGKit" */;
|
|
||||||
productName = SVGKit;
|
|
||||||
};
|
|
||||||
7C45AE6E297352F90031D7BC /* SVGKitSwift */ = {
|
|
||||||
isa = XCSwiftPackageProductDependency;
|
|
||||||
package = 7C45AE6B297352F90031D7BC /* XCRemoteSwiftPackageReference "SVGKit" */;
|
|
||||||
productName = SVGKitSwift;
|
|
||||||
};
|
|
||||||
/* End XCSwiftPackageProductDependency section */
|
/* End XCSwiftPackageProductDependency section */
|
||||||
};
|
};
|
||||||
rootObject = 4CE6DEDB27F7A08100C66700 /* Project object */;
|
rootObject = 4CE6DEDB27F7A08100C66700 /* Project object */;
|
||||||
|
|||||||
@@ -26,14 +26,6 @@
|
|||||||
"version" : "4.0.4"
|
"version" : "4.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"identity" : "svgkit",
|
|
||||||
"kind" : "remoteSourceControl",
|
|
||||||
"location" : "https://github.com/SVGKit/SVGKit",
|
|
||||||
"state" : {
|
|
||||||
"revision" : "e1f13e27b1e4c0ffe20e7d8d3984bf49c2a584d0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"identity" : "vault",
|
"identity" : "vault",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
|
|||||||
@@ -5,9 +5,8 @@
|
|||||||
// Created by Oleg Abalonski on 1/11/23.
|
// Created by Oleg Abalonski on 1/11/23.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import UIKit
|
||||||
import Kingfisher
|
import Kingfisher
|
||||||
import SVGKit
|
|
||||||
|
|
||||||
class KFImageModel: ObservableObject {
|
class KFImageModel: ObservableObject {
|
||||||
|
|
||||||
@@ -80,8 +79,15 @@ struct CustomImageProcessor: ImageProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle SVG image
|
// Handle SVG image
|
||||||
if let svgImage = SVGKImage(data: data), let image = svgImage.uiImage {
|
if let dataString = String(data: data, encoding: .utf8),
|
||||||
return image.kf.scaled(to: options.scaleFactor)
|
let svg = SVG(dataString) {
|
||||||
|
|
||||||
|
let render = UIGraphicsImageRenderer(size: svg.size)
|
||||||
|
let image = render.image { context in
|
||||||
|
svg.draw(in: context.cgContext)
|
||||||
|
}
|
||||||
|
|
||||||
|
return image.kf.scaled(to: options.scaleFactor)
|
||||||
}
|
}
|
||||||
|
|
||||||
return DefaultImageProcessor.default.process(item: item, options: options)
|
return DefaultImageProcessor.default.process(item: item, options: options)
|
||||||
|
|||||||
101
damus/Util/CoreSVG.swift
Normal file
101
damus/Util/CoreSVG.swift
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
//
|
||||||
|
// CoreSVG.swift
|
||||||
|
// damus
|
||||||
|
//
|
||||||
|
// Created by Oleg Abalonski on 1/27/23.
|
||||||
|
// Ref: https://gist.github.com/ollieatkinson/eb87a82fcb5500d5561fed8b0900a9f7
|
||||||
|
|
||||||
|
import Darwin
|
||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
@objc
|
||||||
|
class CGSVGDocument: NSObject { }
|
||||||
|
|
||||||
|
var CGSVGDocumentRetain: (@convention(c) (CGSVGDocument?) -> Unmanaged<CGSVGDocument>?) = load("CGSVGDocumentRetain")
|
||||||
|
var CGSVGDocumentRelease: (@convention(c) (CGSVGDocument?) -> Void) = load("CGSVGDocumentRelease")
|
||||||
|
var CGSVGDocumentCreateFromData: (@convention(c) (CFData?, CFDictionary?) -> Unmanaged<CGSVGDocument>?) = load("CGSVGDocumentCreateFromData")
|
||||||
|
var CGContextDrawSVGDocument: (@convention(c) (CGContext?, CGSVGDocument?) -> Void) = load("CGContextDrawSVGDocument")
|
||||||
|
var CGSVGDocumentGetCanvasSize: (@convention(c) (CGSVGDocument?) -> CGSize) = load("CGSVGDocumentGetCanvasSize")
|
||||||
|
|
||||||
|
typealias ImageWithCGSVGDocument = @convention(c) (AnyObject, Selector, CGSVGDocument) -> UIImage
|
||||||
|
var ImageWithCGSVGDocumentSEL: Selector = NSSelectorFromString("_imageWithCGSVGDocument:")
|
||||||
|
|
||||||
|
let CoreSVG = dlopen("/System/Library/PrivateFrameworks/CoreSVG.framework/CoreSVG", RTLD_NOW)
|
||||||
|
|
||||||
|
func load<T>(_ name: String) -> T {
|
||||||
|
unsafeBitCast(dlsym(CoreSVG, name), to: T.self)
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SVG {
|
||||||
|
|
||||||
|
deinit { CGSVGDocumentRelease(document) }
|
||||||
|
|
||||||
|
let document: CGSVGDocument
|
||||||
|
|
||||||
|
public convenience init?(_ value: String) {
|
||||||
|
guard let data = value.data(using: .utf8) else { return nil }
|
||||||
|
self.init(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
public init?(_ data: Data) {
|
||||||
|
guard let document = CGSVGDocumentCreateFromData(data as CFData, nil)?.takeUnretainedValue() else { return nil }
|
||||||
|
guard CGSVGDocumentGetCanvasSize(document) != .zero else { return nil }
|
||||||
|
self.document = document
|
||||||
|
}
|
||||||
|
|
||||||
|
public var size: CGSize {
|
||||||
|
CGSVGDocumentGetCanvasSize(document)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func image() -> UIImage? {
|
||||||
|
let ImageWithCGSVGDocument = unsafeBitCast(UIImage.self.method(for: ImageWithCGSVGDocumentSEL), to: ImageWithCGSVGDocument.self)
|
||||||
|
let image = ImageWithCGSVGDocument(UIImage.self, ImageWithCGSVGDocumentSEL, document)
|
||||||
|
return image
|
||||||
|
}
|
||||||
|
|
||||||
|
public func draw(in context: CGContext) {
|
||||||
|
draw(in: context, size: size)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func draw(in context: CGContext, size target: CGSize) {
|
||||||
|
|
||||||
|
var target = target
|
||||||
|
|
||||||
|
let ratio = (
|
||||||
|
x: target.width / size.width,
|
||||||
|
y: target.height / size.height
|
||||||
|
)
|
||||||
|
|
||||||
|
let rect = (
|
||||||
|
document: CGRect(origin: .zero, size: size), ()
|
||||||
|
)
|
||||||
|
|
||||||
|
let scale: (x: CGFloat, y: CGFloat)
|
||||||
|
|
||||||
|
if target.width <= 0 {
|
||||||
|
scale = (ratio.y, ratio.y)
|
||||||
|
target.width = size.width * scale.x
|
||||||
|
} else if target.height <= 0 {
|
||||||
|
scale = (ratio.x, ratio.x)
|
||||||
|
target.width = size.width * scale.y
|
||||||
|
} else {
|
||||||
|
let min = min(ratio.x, ratio.y)
|
||||||
|
scale = (min, min)
|
||||||
|
target.width = size.width * scale.x
|
||||||
|
target.height = size.height * scale.y
|
||||||
|
}
|
||||||
|
|
||||||
|
let transform = (
|
||||||
|
scale: CGAffineTransform(scaleX: scale.x, y: scale.y),
|
||||||
|
aspect: CGAffineTransform(translationX: (target.width / scale.x - rect.document.width) / 2, y: (target.height / scale.y - rect.document.height) / 2)
|
||||||
|
)
|
||||||
|
|
||||||
|
context.translateBy(x: 0, y: target.height)
|
||||||
|
context.scaleBy(x: 1, y: -1)
|
||||||
|
context.concatenate(transform.scale)
|
||||||
|
context.concatenate(transform.aspect)
|
||||||
|
|
||||||
|
CGContextDrawSVGDocument(context, document)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user