From ef3156ce093335ee1fc4da41844bbf009a386fbf Mon Sep 17 00:00:00 2001 From: Alex Grebenyuk Date: Mon, 27 Oct 2025 17:56:12 -0400 Subject: [PATCH] Switch to SVGView --- Package.resolved | 26 ++-------- Package.swift | 4 +- .../xcshareddata/swiftpm/Package.resolved | 26 ++-------- .../Sources/Helpers/BlockIconCache.swift | 20 +++----- .../Views/BlockInserter/BlockIconView.swift | 51 +++---------------- .../BlockInserterBlockView.swift | 1 - 6 files changed, 24 insertions(+), 104 deletions(-) diff --git a/Package.resolved b/Package.resolved index 108cf9a79..4c3d5a27d 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,30 +1,12 @@ { "pins" : [ { - "identity" : "cocoalumberjack", + "identity" : "svgview", "kind" : "remoteSourceControl", - "location" : "https://github.com/CocoaLumberjack/CocoaLumberjack.git", + "location" : "https://github.com/exyte/SVGView.git", "state" : { - "revision" : "a9ed4b6f9bdedce7d77046f43adfb8ce1fd54114", - "version" : "3.9.0" - } - }, - { - "identity" : "svgkit", - "kind" : "remoteSourceControl", - "location" : "https://github.com/SVGKit/SVGKit", - "state" : { - "revision" : "58152b9f7c85eab239160b36ffdfd364aa43d666", - "version" : "3.0.0" - } - }, - { - "identity" : "swift-log", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-log", - "state" : { - "revision" : "ce592ae52f982c847a4efc0dd881cc9eb32d29f2", - "version" : "1.6.4" + "revision" : "6465962facdd25cb96eaebc35603afa2f15d2c0d", + "version" : "1.0.6" } }, { diff --git a/Package.swift b/Package.swift index 2038bf5bd..39214b9a1 100644 --- a/Package.swift +++ b/Package.swift @@ -11,12 +11,12 @@ let package = Package( ], dependencies: [ .package(url: "https://github.com/scinfu/SwiftSoup.git", from: "2.7.5"), - .package(url: "https://github.com/SVGKit/SVGKit", from: "3.0.0"), + .package(url: "https://github.com/exyte/SVGView.git", from: "1.0.6"), ], targets: [ .target( name: "GutenbergKit", - dependencies: ["SwiftSoup", "SVGKit"], + dependencies: ["SwiftSoup", "SVGView"], path: "ios/Sources/GutenbergKit", exclude: [], resources: [.copy("Gutenberg")] diff --git a/ios/Demo-iOS/Gutenberg.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ios/Demo-iOS/Gutenberg.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index b9210a8e9..0ea20e7dc 100644 --- a/ios/Demo-iOS/Gutenberg.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ios/Demo-iOS/Gutenberg.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,30 +1,12 @@ { "pins" : [ { - "identity" : "cocoalumberjack", + "identity" : "svgview", "kind" : "remoteSourceControl", - "location" : "https://github.com/CocoaLumberjack/CocoaLumberjack.git", + "location" : "https://github.com/exyte/SVGView.git", "state" : { - "revision" : "a9ed4b6f9bdedce7d77046f43adfb8ce1fd54114", - "version" : "3.9.0" - } - }, - { - "identity" : "svgkit", - "kind" : "remoteSourceControl", - "location" : "https://github.com/SVGKit/SVGKit", - "state" : { - "revision" : "58152b9f7c85eab239160b36ffdfd364aa43d666", - "version" : "3.0.0" - } - }, - { - "identity" : "swift-log", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-log", - "state" : { - "revision" : "ce592ae52f982c847a4efc0dd881cc9eb32d29f2", - "version" : "1.6.4" + "revision" : "6465962facdd25cb96eaebc35603afa2f15d2c0d", + "version" : "1.0.6" } }, { diff --git a/ios/Sources/GutenbergKit/Sources/Helpers/BlockIconCache.swift b/ios/Sources/GutenbergKit/Sources/Helpers/BlockIconCache.swift index 4a7cafd30..774284f10 100644 --- a/ios/Sources/GutenbergKit/Sources/Helpers/BlockIconCache.swift +++ b/ios/Sources/GutenbergKit/Sources/Helpers/BlockIconCache.swift @@ -1,11 +1,11 @@ import Foundation -import SVGKit +import SVGView @MainActor final class BlockIconCache: ObservableObject { - var icons: [String: Result] = [:] + var icons: [String: Result] = [:] - func getIcon(for block: BlockType) -> SVGKImage? { + func getIcon(for block: BlockType) -> SVGNode? { if let result = icons[block.id] { return try? result.get() } @@ -14,19 +14,15 @@ final class BlockIconCache: ObservableObject { return try? result.get() } - private func _getIcon(for block: BlockType) throws -> SVGKImage { - guard let svg = block.icon, - !svg.isEmpty, - let source = SVGKSourceString.source(fromContentsOf: svg), - let image = SVGKImage(source: source) else { + private func _getIcon(for block: BlockType) throws -> SVGNode { + guard let svg = block.icon, !svg.isEmpty else { throw BlockIconCacheError.unknown } - if let result = image.parseErrorsAndWarnings, - let error = result.errorsFatal.firstObject { + guard let image = SVGParser.parse(string: svg) else { #if DEBUG - debugPrint("failed to parse SVG for block: \(block.name) with errors: \(String(describing: result.errorsFatal))\n\n\(svg)") + debugPrint("failed to parse SVG for block: \(block.name), svg: \(svg)") #endif - throw (error as? Error) ?? BlockIconCacheError.unknown + throw BlockIconCacheError.unknown } return image } diff --git a/ios/Sources/GutenbergKit/Sources/Views/BlockInserter/BlockIconView.swift b/ios/Sources/GutenbergKit/Sources/Views/BlockInserter/BlockIconView.swift index edd845740..110963053 100644 --- a/ios/Sources/GutenbergKit/Sources/Views/BlockInserter/BlockIconView.swift +++ b/ios/Sources/GutenbergKit/Sources/Views/BlockInserter/BlockIconView.swift @@ -1,5 +1,5 @@ import SwiftUI -import SVGKit +import SVGView struct BlockIconView: View { let block: BlockType @@ -14,10 +14,11 @@ struct BlockIconView: View { .frame(width: size, height: size) .shadow(color: Color.black.opacity(0.1), radius: 2, x: 0, y: 1) - if let image = cache.getIcon(for: block), - let view = SVGKFastImageView(svgkImage: image) { - SVGIconView(view: view) - .frame(width: size * 0.5, height: size * 0.5) + if let image = cache.getIcon(for: block) { + Color(.label).mask { + SVGView(svg: image) + } + .frame(width: size * 0.5, height: size * 0.5) } else { Image(systemName: "square") .font(.system(size: size * 0.5)) @@ -27,43 +28,3 @@ struct BlockIconView: View { } } } - -private struct SVGIconView: UIViewRepresentable { - let view: SVGKFastImageView - - @Environment(\.colorScheme) private var colorScheme - - func makeUIView(context: Context) -> SVGKFastImageView { - view.contentMode = .scaleAspectFit - return view - } - - func updateUIView(_ uiView: SVGKFastImageView, context: Context) { - view.image?.fillColor(color: UIColor.label) - view.setNeedsDisplay() - } -} - -private extension SVGKImage { - /// SVGKit maintains two parallel representations of every SVG file: a - /// DOMTree following W3C SVG specifications and a CALayerTree for native - /// iOS rendering. The easiest and fastest way to change the colors of the - /// shapes it creates is by recursively traversing the layers. - private func fillColorForSubLayer(layer: CALayer, color: UIColor, opacity: Float) { - if let shapeLayer = layer as? CAShapeLayer { - shapeLayer.fillColor = color.cgColor - shapeLayer.opacity = opacity - } - if let sublayers = layer.sublayers { - for subLayer in sublayers { - fillColorForSubLayer(layer: subLayer, color: color, opacity: opacity) - } - } - } - - func fillColor(color: UIColor, opacity: Float = 1.0) { - if let layer = caLayerTree { - fillColorForSubLayer(layer: layer, color: color, opacity: opacity) - } - } -} diff --git a/ios/Sources/GutenbergKit/Sources/Views/BlockInserter/BlockInserterBlockView.swift b/ios/Sources/GutenbergKit/Sources/Views/BlockInserter/BlockInserterBlockView.swift index 62b3dc0a7..c9814128a 100644 --- a/ios/Sources/GutenbergKit/Sources/Views/BlockInserter/BlockInserterBlockView.swift +++ b/ios/Sources/GutenbergKit/Sources/Views/BlockInserter/BlockInserterBlockView.swift @@ -1,5 +1,4 @@ import SwiftUI -import SVGKit struct BlockInserterBlockView: View { let block: BlockType