@swiftbrowser/swift 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Package.swift +200 -9
- package/README.md +7 -9
- package/Sources/AVFoundation/AVFoundation.swift +131 -0
- package/Sources/AVFoundation/Asset.swift +487 -0
- package/Sources/AVFoundation/AudioSession.swift +144 -0
- package/Sources/AVFoundation/CMTime.swift +303 -0
- package/Sources/AVFoundation/Capture.swift +688 -0
- package/Sources/AVFoundation/Player.swift +749 -0
- package/Sources/AVFoundation/PlayerView.swift +117 -0
- package/Sources/AVKit/AVKit.swift +132 -0
- package/Sources/Accelerate/Accelerate.swift +122 -0
- package/Sources/AppIntents/AppIntents.swift +144 -0
- package/Sources/AppIntents/Parameters.swift +220 -0
- package/Sources/AppIntents/Shortcuts.swift +159 -0
- package/Sources/AudioToolbox/AudioToolbox.swift +55 -0
- package/Sources/AuthenticationServices/AuthenticationServices.swift +257 -0
- package/Sources/AuthenticationServices/Authorization.swift +251 -0
- package/Sources/Charts/Charts.swift +0 -4
- package/Sources/Combine/AnyCancellable.swift +65 -0
- package/Sources/Combine/AnyPublisher.swift +148 -0
- package/Sources/Combine/AnySubscriber.swift +230 -0
- package/Sources/Combine/Cancellable.swift +35 -0
- package/Sources/Combine/Codable.swift +29 -0
- package/Sources/Combine/CombineIdentifier.swift +45 -0
- package/Sources/Combine/Concurrency/ConcurrencyHelpers.swift +24 -0
- package/Sources/Combine/Concurrency/Future+Concurrency.swift +136 -0
- package/Sources/Combine/Concurrency/GENERATED-Publisher+Concurrency.swift +397 -0
- package/Sources/Combine/CurrentValueSubject.swift +252 -0
- package/Sources/Combine/CustomCombineIdentifierConvertible.swift +28 -0
- package/Sources/Combine/Future.swift +228 -0
- package/Sources/Combine/GENERATED-RootProtocols.swift +426 -0
- package/Sources/Combine/Helpers/ConduitBase.swift +40 -0
- package/Sources/Combine/Helpers/ConduitList.swift +59 -0
- package/Sources/Combine/Helpers/DebugHook.swift +177 -0
- package/Sources/Combine/Helpers/FilterProducer.swift +174 -0
- package/Sources/Combine/Helpers/Locking.swift +30 -0
- package/Sources/Combine/Helpers/PartialCompletion.swift +26 -0
- package/Sources/Combine/Helpers/ReduceProducer.swift +249 -0
- package/Sources/Combine/Helpers/SubjectSubscriber.swift +96 -0
- package/Sources/Combine/Helpers/SubscriberTap.swift +69 -0
- package/Sources/Combine/Helpers/SubscriptionStatus.swift +33 -0
- package/Sources/Combine/Helpers/SubscriptionTap.swift +33 -0
- package/Sources/Combine/Helpers/Utils.swift +30 -0
- package/Sources/Combine/Helpers/Violations.swift +33 -0
- package/Sources/Combine/ImmediateScheduler.swift +178 -0
- package/Sources/Combine/LICENSE +21 -0
- package/Sources/Combine/NotificationPublisher.swift +48 -0
- package/Sources/Combine/ObjectWillChange.swift +46 -0
- package/Sources/Combine/PassthroughSubject.swift +222 -0
- package/Sources/Combine/Publisher+Subscribe.swift +53 -0
- package/Sources/Combine/Publishers/Deferred.swift +48 -0
- package/Sources/Combine/Publishers/Empty.swift +54 -0
- package/Sources/Combine/Publishers/Fail.swift +42 -0
- package/Sources/Combine/Publishers/GENERATED-Publishers.Catch.swift +673 -0
- package/Sources/Combine/Publishers/GENERATED-Publishers.Encode.swift +388 -0
- package/Sources/Combine/Publishers/GENERATED-Publishers.MapKeyPath.swift +384 -0
- package/Sources/Combine/Publishers/Just.swift +313 -0
- package/Sources/Combine/Publishers/Optional.Publisher.swift +315 -0
- package/Sources/Combine/Publishers/Publishers.AllSatisfy.swift +217 -0
- package/Sources/Combine/Publishers/Publishers.AssertNoFailure.swift +158 -0
- package/Sources/Combine/Publishers/Publishers.Autoconnect.swift +193 -0
- package/Sources/Combine/Publishers/Publishers.Breakpoint.swift +231 -0
- package/Sources/Combine/Publishers/Publishers.Buffer.swift +356 -0
- package/Sources/Combine/Publishers/Publishers.Collect.swift +102 -0
- package/Sources/Combine/Publishers/Publishers.CollectByCount.swift +195 -0
- package/Sources/Combine/Publishers/Publishers.CompactMap.swift +241 -0
- package/Sources/Combine/Publishers/Publishers.Comparison.swift +371 -0
- package/Sources/Combine/Publishers/Publishers.Concatenate.swift +474 -0
- package/Sources/Combine/Publishers/Publishers.Contains.swift +293 -0
- package/Sources/Combine/Publishers/Publishers.Count.swift +87 -0
- package/Sources/Combine/Publishers/Publishers.Debounce.swift +332 -0
- package/Sources/Combine/Publishers/Publishers.Delay.swift +269 -0
- package/Sources/Combine/Publishers/Publishers.Drop.swift +155 -0
- package/Sources/Combine/Publishers/Publishers.DropUntilOutput.swift +283 -0
- package/Sources/Combine/Publishers/Publishers.DropWhile.swift +378 -0
- package/Sources/Combine/Publishers/Publishers.Filter.swift +248 -0
- package/Sources/Combine/Publishers/Publishers.First.swift +261 -0
- package/Sources/Combine/Publishers/Publishers.FlatMap.swift +533 -0
- package/Sources/Combine/Publishers/Publishers.HandleEvents.swift +260 -0
- package/Sources/Combine/Publishers/Publishers.IgnoreOutput.swift +109 -0
- package/Sources/Combine/Publishers/Publishers.Last.swift +252 -0
- package/Sources/Combine/Publishers/Publishers.MakeConnectable.swift +82 -0
- package/Sources/Combine/Publishers/Publishers.Map.swift +351 -0
- package/Sources/Combine/Publishers/Publishers.MapError.swift +140 -0
- package/Sources/Combine/Publishers/Publishers.MeasureInterval.swift +187 -0
- package/Sources/Combine/Publishers/Publishers.Multicast.swift +284 -0
- package/Sources/Combine/Publishers/Publishers.Output.swift +241 -0
- package/Sources/Combine/Publishers/Publishers.PrefixUntilOutput.swift +197 -0
- package/Sources/Combine/Publishers/Publishers.PrefixWhile.swift +176 -0
- package/Sources/Combine/Publishers/Publishers.Print.swift +206 -0
- package/Sources/Combine/Publishers/Publishers.ReceiveOn.swift +227 -0
- package/Sources/Combine/Publishers/Publishers.Reduce.swift +204 -0
- package/Sources/Combine/Publishers/Publishers.RemoveDuplicates.swift +264 -0
- package/Sources/Combine/Publishers/Publishers.ReplaceEmpty.swift +201 -0
- package/Sources/Combine/Publishers/Publishers.ReplaceError.swift +211 -0
- package/Sources/Combine/Publishers/Publishers.Retry.swift +274 -0
- package/Sources/Combine/Publishers/Publishers.Scan.swift +331 -0
- package/Sources/Combine/Publishers/Publishers.Sequence.swift +437 -0
- package/Sources/Combine/Publishers/Publishers.SetFailureType.swift +120 -0
- package/Sources/Combine/Publishers/Publishers.Share.swift +104 -0
- package/Sources/Combine/Publishers/Publishers.SubscribeOn.swift +197 -0
- package/Sources/Combine/Publishers/Publishers.SwitchToLatest.swift +444 -0
- package/Sources/Combine/Publishers/Publishers.Throttle.swift +359 -0
- package/Sources/Combine/Publishers/Publishers.Timeout.swift +301 -0
- package/Sources/Combine/Publishers/Publishers.Zip.swift +720 -0
- package/Sources/Combine/Publishers/Publishers.swift +13 -0
- package/Sources/Combine/Publishers/Record.swift +237 -0
- package/Sources/Combine/Publishers/Result.Publisher.swift +337 -0
- package/Sources/Combine/Result.swift +46 -0
- package/Sources/Combine/Scheduler.swift +89 -0
- package/Sources/Combine/Schedulers.swift +211 -0
- package/Sources/Combine/Subject+Void.swift +17 -0
- package/Sources/Combine/Subscriber+Void.swift +20 -0
- package/Sources/Combine/Subscribers/Subscribers.Assign.swift +175 -0
- package/Sources/Combine/Subscribers/Subscribers.Completion.swift +90 -0
- package/Sources/Combine/Subscribers/Subscribers.Demand.swift +476 -0
- package/Sources/Combine/Subscribers/Subscribers.Sink.swift +206 -0
- package/Sources/Combine/Subscribers/Subscribers.swift +9 -0
- package/Sources/Combine/Subscription.swift +22 -0
- package/Sources/Combine/Subscriptions.swift +42 -0
- package/Sources/Combine/SwiftUIObservation.swift +10 -0
- package/Sources/Combine/_Introspection.swift +107 -0
- package/Sources/CommonCrypto/CommonCrypto.swift +80 -0
- package/Sources/Compression/Compression.swift +365 -0
- package/Sources/Compression/Deflate.swift +407 -0
- package/Sources/Compression/Zlib.swift +179 -0
- package/Sources/CoreFoundationTypes/CoreFoundationTypes.swift +101 -0
- package/Sources/CoreGraphics/CoreGraphics.swift +411 -0
- package/Sources/CoreGraphics/ProjectionTransforms.swift +28 -0
- package/Sources/CoreHaptics/CoreHaptics.swift +399 -0
- package/Sources/CoreImage/CIColor.swift +41 -0
- package/Sources/CoreImage/CIContext.swift +31 -0
- package/Sources/CoreImage/CIDetector.swift +57 -0
- package/Sources/CoreImage/CIFilter.swift +243 -0
- package/Sources/CoreImage/CIFilterBuiltins.swift +136 -0
- package/Sources/CoreImage/CIImage.swift +162 -0
- package/Sources/CoreImage/QRCode.swift +393 -0
- package/Sources/CoreLocation/Coordinate.swift +30 -0
- package/Sources/CoreLocation/Location.swift +65 -0
- package/Sources/CoreML/Evaluation.swift +414 -0
- package/Sources/CoreML/FeatureValue.swift +266 -0
- package/Sources/CoreML/Model.swift +269 -0
- package/Sources/CoreML/MultiArray.swift +92 -0
- package/Sources/CoreML/Specification.swift +233 -0
- package/Sources/CoreText/CoreText.swift +64 -0
- package/Sources/CoreTransferable/CoreTransferable.swift +606 -0
- package/Sources/CryptoKit/ChaChaPoly.swift +258 -0
- package/Sources/CryptoKit/CryptoKit.swift +375 -0
- package/Sources/CryptoKit/Curve25519.swift +317 -0
- package/Sources/CryptoKit/P256.swift +321 -0
- package/Sources/FoundationBridge/AppStorage.swift +165 -0
- package/Sources/FoundationBridge/AssetResources.swift +90 -0
- package/Sources/FoundationBridge/AsyncBytes.swift +128 -0
- package/Sources/FoundationBridge/AsyncImage.swift +116 -0
- package/Sources/FoundationBridge/AttributedStrings.swift +16 -0
- package/Sources/{_FoundationCommon → FoundationBridge}/Bundle.swift +41 -4
- package/Sources/FoundationBridge/CombineExports.swift +8 -0
- package/Sources/FoundationBridge/CoreFoundation.swift +77 -0
- package/Sources/FoundationBridge/Dispatch.swift +458 -0
- package/Sources/FoundationBridge/EnvironmentFoundation.swift +41 -0
- package/Sources/FoundationBridge/FileImporter.swift +128 -0
- package/Sources/FoundationBridge/FileSystem.swift +68 -0
- package/Sources/FoundationBridge/FoundationBridge.swift +24 -72
- package/Sources/FoundationBridge/HostResolution.swift +31 -0
- package/Sources/FoundationBridge/ItemProvider.swift +655 -0
- package/Sources/FoundationBridge/KeyValueObserving.swift +138 -0
- package/Sources/FoundationBridge/Links.swift +127 -0
- package/Sources/FoundationBridge/ListFormatter.swift +32 -0
- package/Sources/FoundationBridge/Localization.swift +149 -0
- package/Sources/FoundationBridge/Locks.swift +50 -0
- package/Sources/FoundationBridge/Markdown.swift +527 -0
- package/Sources/FoundationBridge/MeasurementFormat.swift +95 -0
- package/Sources/FoundationBridge/NotificationCenter.swift +154 -0
- package/Sources/FoundationBridge/OpenURLHandlers.swift +60 -0
- package/Sources/FoundationBridge/Operation.swift +195 -0
- package/Sources/FoundationBridge/ProcessInfo.swift +32 -0
- package/Sources/FoundationBridge/RelativeDateTimeFormatter.swift +136 -0
- package/Sources/FoundationBridge/SceneStorage.swift +78 -0
- package/Sources/FoundationBridge/SecurityExports.swift +8 -0
- package/Sources/FoundationBridge/Selector.swift +226 -0
- package/Sources/FoundationBridge/StringComparators.swift +17 -0
- package/Sources/FoundationBridge/Table.swift +211 -0
- package/Sources/FoundationBridge/TextAttributes.swift +42 -0
- package/Sources/FoundationBridge/Timer.swift +6 -1
- package/Sources/FoundationBridge/URLSession.swift +718 -0
- package/Sources/{_FoundationCommon → FoundationBridge}/UserDefaults.swift +17 -4
- package/Sources/FoundationBridge/WebAuthRedirects.swift +227 -0
- package/Sources/FoundationBridge/WebSocket.swift +187 -0
- package/Sources/FoundationModels/FoundationModels.swift +1098 -0
- package/Sources/ImageIO/GIF.swift +72 -0
- package/Sources/ImageIO/ImageIO.swift +248 -0
- package/Sources/ImageIO/ImageTypes.swift +28 -0
- package/Sources/LinkPresentation/LinkPresentation.swift +249 -0
- package/Sources/LocalAuthentication/LAContext.swift +86 -0
- package/Sources/MapKit/Geometry.swift +223 -0
- package/Sources/MapKit/Map.swift +638 -0
- package/Sources/MapKit/MapView.swift +229 -0
- package/Sources/MobileCoreServices/MobileCoreServices.swift +28 -0
- package/Sources/NaturalLanguage/LanguageIdentifier.swift +317 -0
- package/Sources/NaturalLanguage/NaturalLanguage.swift +135 -0
- package/Sources/OSLog/OSLog.swift +6 -0
- package/Sources/Photos/Photos.swift +572 -0
- package/Sources/PhotosUI/PhotosPicker.swift +248 -0
- package/Sources/PhotosUI/PhotosPickerItem.swift +261 -0
- package/Sources/QuickLook/QuickLook.swift +168 -0
- package/Sources/SafariServices/SafariServices.swift +106 -0
- package/Sources/Security/Security.swift +332 -0
- package/Sources/StoreKit/AppStore.swift +207 -0
- package/Sources/StoreKit/Products.swift +280 -0
- package/Sources/StoreKit/RequestReview.swift +28 -0
- package/Sources/StoreKit/StoreKit1.swift +486 -0
- package/Sources/StoreKit/StoreViews.swift +428 -0
- package/Sources/StoreKit/Transactions.swift +197 -0
- package/Sources/SwiftData/Macros.swift +58 -0
- package/Sources/SwiftData/ModelActor.swift +38 -0
- package/Sources/SwiftData/ModelContainer.swift +129 -0
- package/Sources/SwiftData/ModelContext.swift +451 -0
- package/Sources/SwiftData/PersistentModel.swift +238 -0
- package/Sources/SwiftData/Properties.swift +261 -0
- package/Sources/SwiftData/Query.swift +256 -0
- package/Sources/SwiftData/Schema.swift +192 -0
- package/Sources/SwiftData/Store.swift +146 -0
- package/Sources/SwiftData/StringPredicates.swift +125 -0
- package/Sources/SwiftDataMacros/EntryMacro.swift +82 -0
- package/Sources/SwiftDataMacros/GenerableMacro.swift +183 -0
- package/Sources/SwiftDataMacros/ModelActorMacro.swift +46 -0
- package/Sources/SwiftDataMacros/ModelMacro.swift +260 -0
- package/Sources/SwiftDataMacros/Plugin.swift +18 -0
- package/Sources/SwiftDataMacros/PredicateMacro.swift +1244 -0
- package/Sources/SwiftUI/API/Accessibility.swift +55 -6
- package/Sources/SwiftUI/API/AccessibilityExtras.swift +33 -0
- package/Sources/SwiftUI/API/AccessibilityFocus.swift +63 -0
- package/Sources/SwiftUI/API/Alert.swift +1 -1
- package/Sources/SwiftUI/API/AlignmentGuides.swift +65 -0
- package/Sources/SwiftUI/API/Animation.swift +37 -5
- package/Sources/SwiftUI/API/App.swift +31 -1
- package/Sources/SwiftUI/API/BindingCollections.swift +35 -0
- package/Sources/SwiftUI/API/BindingForEach.swift +27 -0
- package/Sources/SwiftUI/API/Bitmaps.swift +254 -0
- package/Sources/SwiftUI/API/ButtonStyles.swift +96 -0
- package/Sources/SwiftUI/API/Canvas.swift +337 -0
- package/Sources/SwiftUI/API/Color.swift +104 -28
- package/Sources/SwiftUI/API/ColorEffects.swift +52 -0
- package/Sources/SwiftUI/API/ColorPickerAndLabeledContent.swift +138 -0
- package/Sources/SwiftUI/API/ColorSpaces.swift +161 -0
- package/Sources/SwiftUI/API/Commands.swift +106 -0
- package/Sources/SwiftUI/API/ContainerBackground.swift +28 -0
- package/Sources/SwiftUI/API/ContentShape.swift +33 -0
- package/Sources/SwiftUI/API/ContentSizeCategory.swift +35 -0
- package/Sources/SwiftUI/API/ContentUnavailable.swift +101 -0
- package/Sources/SwiftUI/API/Controls.swift +59 -27
- package/Sources/SwiftUI/API/CustomLayout.swift +49 -10
- package/Sources/SwiftUI/API/CustomToolbarContent.swift +46 -0
- package/Sources/SwiftUI/API/Decorations.swift +1 -1
- package/Sources/SwiftUI/API/EditMode.swift +25 -82
- package/Sources/SwiftUI/API/Effects.swift +105 -7
- package/Sources/SwiftUI/API/Entry.swift +8 -0
- package/Sources/SwiftUI/API/Environment.swift +93 -9
- package/Sources/SwiftUI/API/EnvironmentSendable.swift +6 -0
- package/Sources/SwiftUI/API/Focus.swift +11 -3
- package/Sources/SwiftUI/API/Gauge.swift +3 -2
- package/Sources/SwiftUI/API/GeometryEffects.swift +232 -0
- package/Sources/SwiftUI/API/GeometryReader.swift +13 -2
- package/Sources/SwiftUI/API/GestureState.swift +65 -0
- package/Sources/SwiftUI/API/Gestures.swift +1 -1
- package/Sources/SwiftUI/API/Glass.swift +127 -0
- package/Sources/SwiftUI/API/Grid.swift +1 -1
- package/Sources/SwiftUI/API/GroupBoxAndControlGroup.swift +130 -0
- package/Sources/SwiftUI/API/KeyPress.swift +54 -0
- package/Sources/SwiftUI/API/LabelStyle.swift +13 -6
- package/Sources/SwiftUI/API/Layout.swift +67 -12
- package/Sources/SwiftUI/API/LazyStacks.swift +49 -0
- package/Sources/SwiftUI/API/LegacyAlert.swift +97 -0
- package/Sources/SwiftUI/API/Lists.swift +61 -6
- package/Sources/SwiftUI/API/Menu.swift +8 -1
- package/Sources/SwiftUI/API/Modifiers.swift +80 -10
- package/Sources/SwiftUI/API/MoreModifiers.swift +100 -0
- package/Sources/SwiftUI/API/Namespace.swift +44 -0
- package/Sources/SwiftUI/API/Navigation.swift +24 -9
- package/Sources/SwiftUI/API/NavigationDestinationBindings.swift +55 -0
- package/Sources/SwiftUI/API/ObservableObject.swift +16 -2
- package/Sources/SwiftUI/API/Path.swift +543 -0
- package/Sources/SwiftUI/API/Phase8Controls.swift +48 -31
- package/Sources/SwiftUI/API/PhaseAnimator.swift +130 -0
- package/Sources/SwiftUI/API/Picker.swift +11 -2
- package/Sources/SwiftUI/API/PointerAndKeyboard.swift +77 -0
- package/Sources/SwiftUI/API/Popover.swift +41 -0
- package/Sources/SwiftUI/API/Preferences.swift +262 -0
- package/Sources/SwiftUI/API/Presentation.swift +17 -4
- package/Sources/SwiftUI/API/PresentationExtras.swift +60 -0
- package/Sources/SwiftUI/API/Primitives.swift +164 -37
- package/Sources/SwiftUI/API/Publishers.swift +4 -4
- package/Sources/SwiftUI/API/Redaction.swift +75 -0
- package/Sources/SwiftUI/API/RowActions.swift +3 -2
- package/Sources/SwiftUI/API/Scenes.swift +131 -0
- package/Sources/SwiftUI/API/ScrollModifiers.swift +132 -0
- package/Sources/SwiftUI/API/ScrollTargets.swift +3 -3
- package/Sources/SwiftUI/API/ScrollViewReader.swift +144 -0
- package/Sources/SwiftUI/API/SectionSupplements.swift +96 -0
- package/Sources/SwiftUI/API/Shape.swift +214 -0
- package/Sources/SwiftUI/API/ShapeStyle.swift +105 -7
- package/Sources/SwiftUI/API/ShapeTrim.swift +78 -0
- package/Sources/SwiftUI/API/Sharing.swift +193 -0
- package/Sources/SwiftUI/API/StackLayouts.swift +199 -0
- package/Sources/SwiftUI/API/State.swift +18 -1
- package/Sources/SwiftUI/API/StatusGaps.swift +121 -0
- package/Sources/SwiftUI/API/SymbolEffects.swift +203 -0
- package/Sources/SwiftUI/API/TabContent.swift +841 -0
- package/Sources/SwiftUI/API/Table.swift +382 -0
- package/Sources/SwiftUI/API/Tabs.swift +148 -4
- package/Sources/SwiftUI/API/Tasks.swift +2 -2
- package/Sources/SwiftUI/API/Text.swift +386 -0
- package/Sources/SwiftUI/API/TextDates.swift +61 -0
- package/Sources/SwiftUI/API/TextDecorations.swift +52 -0
- package/Sources/SwiftUI/API/TextFieldAxis.swift +103 -0
- package/Sources/SwiftUI/API/TextFieldCommit.swift +52 -0
- package/Sources/SwiftUI/API/Toolbar.swift +52 -16
- package/Sources/SwiftUI/API/Transfer.swift +145 -0
- package/Sources/SwiftUI/API/UnevenRoundedRectangle.swift +66 -0
- package/Sources/SwiftUI/API/Video.swift +64 -0
- package/Sources/SwiftUI/API/View.swift +10 -2
- package/Sources/SwiftUI/API/ViewModifier.swift +4 -1
- package/Sources/SwiftUI/API/VisualEffect.swift +74 -1
- package/Sources/SwiftUI/API/Windows.swift +25 -0
- package/Sources/SwiftUI/Charts/Axis.swift +7 -1
- package/Sources/SwiftUI/Charts/AxisFormatsAndRanges.swift +68 -0
- package/Sources/SwiftUI/Charts/Chart.swift +17 -3
- package/Sources/SwiftUI/Charts/ChartProxy.swift +57 -0
- package/Sources/SwiftUI/Localization/Localization.swift +498 -0
- package/Sources/SwiftUI/Localization/PluralRules.swift +127 -0
- package/Sources/SwiftUI/Runtime/Executor.swift +2 -0
- package/Sources/SwiftUI/Runtime/Exports.swift +37 -1
- package/Sources/SwiftUI/Runtime/ImageSource.swift +310 -0
- package/Sources/SwiftUI/Runtime/JSON.swift +76 -4
- package/Sources/SwiftUI/Runtime/LazyRows.swift +99 -0
- package/Sources/SwiftUI/Runtime/Measurements.swift +140 -0
- package/Sources/SwiftUI/Runtime/Ops.swift +58 -12
- package/Sources/SwiftUI/Runtime/Reconciler.swift +10 -1
- package/Sources/SwiftUI/Runtime/Replay.swift +382 -0
- package/Sources/SwiftUI/Runtime/Runtime.swift +977 -198
- package/Sources/SwiftUI/Runtime/Sameness.swift +152 -0
- package/Sources/SwiftUI/Runtime/ViewPath.swift +89 -0
- package/Sources/SwiftUI/Runtime/ViewTraits.swift +175 -0
- package/Sources/SwiftUI/Runtime/WebAuthHeadless.swift +49 -0
- package/Sources/Symbols/Symbols.swift +25 -0
- package/Sources/Translation/Translation.swift +423 -0
- package/Sources/UIKit/Activity.swift +213 -0
- package/Sources/UIKit/Alerts.swift +69 -0
- package/Sources/UIKit/AppDelegate.swift +222 -0
- package/Sources/UIKit/Appearance.swift +84 -0
- package/Sources/UIKit/ColorConversions.swift +70 -0
- package/Sources/UIKit/Controls.swift +225 -0
- package/Sources/UIKit/Device.swift +200 -0
- package/Sources/UIKit/Feedback.swift +65 -0
- package/Sources/UIKit/Font.swift +307 -0
- package/Sources/UIKit/Graphics.swift +204 -0
- package/Sources/UIKit/HostingController.swift +185 -0
- package/Sources/UIKit/Identity.swift +24 -0
- package/Sources/UIKit/Introspectable.swift +510 -0
- package/Sources/UIKit/Pasteboard.swift +363 -0
- package/Sources/UIKit/PhotoAlbum.swift +81 -0
- package/Sources/UIKit/RemoteNotifications.swift +15 -0
- package/Sources/UIKit/Representable.swift +288 -0
- package/Sources/UIKit/SafeArea.swift +12 -0
- package/Sources/UIKit/SceneDelegates.swift +132 -0
- package/Sources/UIKit/Scenes.swift +40 -0
- package/Sources/UIKit/ScrollView.swift +157 -0
- package/Sources/UIKit/ShortcutItems.swift +67 -0
- package/Sources/UIKit/SymbolConfiguration.swift +124 -0
- package/Sources/UIKit/TargetAction.swift +123 -0
- package/Sources/UIKit/TextPaste.swift +161 -0
- package/Sources/UIKit/TextView.swift +538 -0
- package/Sources/UIKit/UIKit.swift +292 -0
- package/Sources/UIKit/UIView.swift +855 -0
- package/Sources/UIKit/ViewTranslation.swift +311 -0
- package/Sources/UniformTypeIdentifiers/UTType.swift +196 -0
- package/Sources/UserNotifications/Content.swift +370 -0
- package/Sources/UserNotifications/NotificationCenter.swift +309 -0
- package/Sources/WeatherKit/WeatherKit.swift +228 -0
- package/Sources/WebKit/WebKit.swift +245 -0
- package/Sources/os/os.swift +376 -0
- package/Sources/zlib/zlib.swift +6 -0
- package/index.d.ts +1 -1
- package/index.mjs +2 -2
- package/manifest.d.mts +2 -0
- package/manifest.mjs +39 -0
- package/package.json +5 -3
- package/sync-sources.mjs +21 -7
- package/Sources/FoundationLite/Common.swift +0 -3
- package/Sources/FoundationLite/FoundationLite.swift +0 -171
- package/Sources/FoundationLite/Interaction.swift +0 -146
- package/Sources/FoundationLite/Timer.swift +0 -48
- package/Sources/_FoundationCommon/_FoundationCommon.swift +0 -10
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import class Foundation.NSNumber
|
|
2
|
+
import struct Foundation.Data
|
|
3
|
+
import SwiftUI
|
|
4
|
+
|
|
5
|
+
// `CIFilter`: a named filter with key-value inputs, as on Apple platforms
|
|
6
|
+
// (`setValue(_:forKey:)` with the `kCI…Key` names, `inputKeys`,
|
|
7
|
+
// `outputImage`). Each built-in appends one step to its input's recipe and
|
|
8
|
+
// works out the output's extent; the page runs the step
|
|
9
|
+
// (Web/src/imageOps.ts; the formulas are in docs/ops-protocol.md, "Bitmaps
|
|
10
|
+
// and Core Image").
|
|
11
|
+
|
|
12
|
+
public let kCIInputImageKey = "inputImage"
|
|
13
|
+
public let kCIOutputImageKey = "outputImage"
|
|
14
|
+
public let kCIInputIntensityKey = "inputIntensity"
|
|
15
|
+
public let kCIInputRadiusKey = "inputRadius"
|
|
16
|
+
public let kCIInputScaleKey = "inputScale"
|
|
17
|
+
public let kCIInputCenterKey = "inputCenter"
|
|
18
|
+
public let kCIInputAngleKey = "inputAngle"
|
|
19
|
+
public let kCIInputWidthKey = "inputWidth"
|
|
20
|
+
public let kCIInputSharpnessKey = "inputSharpness"
|
|
21
|
+
public let kCIInputAmountKey = "inputAmount"
|
|
22
|
+
public let kCIInputBrightnessKey = "inputBrightness"
|
|
23
|
+
public let kCIInputContrastKey = "inputContrast"
|
|
24
|
+
public let kCIInputSaturationKey = "inputSaturation"
|
|
25
|
+
public let kCIInputColorKey = "inputColor"
|
|
26
|
+
public let kCIInputExtentKey = "inputExtent"
|
|
27
|
+
|
|
28
|
+
/// The filters the shim implements, by Core Image name.
|
|
29
|
+
enum _CIFilterKind: String, CaseIterable {
|
|
30
|
+
case sepiaTone = "CISepiaTone"
|
|
31
|
+
case crystallize = "CICrystallize"
|
|
32
|
+
case edges = "CIEdges"
|
|
33
|
+
case gaussianBlur = "CIGaussianBlur"
|
|
34
|
+
case pixellate = "CIPixellate"
|
|
35
|
+
case unsharpMask = "CIUnsharpMask"
|
|
36
|
+
case vignette = "CIVignette"
|
|
37
|
+
case qrCodeGenerator = "CIQRCodeGenerator"
|
|
38
|
+
|
|
39
|
+
/// In Core Image's order.
|
|
40
|
+
var inputKeys: [String] {
|
|
41
|
+
switch self {
|
|
42
|
+
case .sepiaTone, .edges: [kCIInputImageKey, kCIInputIntensityKey]
|
|
43
|
+
case .crystallize: [kCIInputImageKey, kCIInputRadiusKey, kCIInputCenterKey]
|
|
44
|
+
case .gaussianBlur: [kCIInputImageKey, kCIInputRadiusKey]
|
|
45
|
+
case .pixellate: [kCIInputImageKey, kCIInputCenterKey, kCIInputScaleKey]
|
|
46
|
+
case .unsharpMask: [kCIInputImageKey, kCIInputRadiusKey, kCIInputIntensityKey]
|
|
47
|
+
case .vignette: [kCIInputImageKey, kCIInputIntensityKey, kCIInputRadiusKey]
|
|
48
|
+
case .qrCodeGenerator: ["inputMessage", "inputCorrectionLevel"]
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/// Core Image's defaults.
|
|
53
|
+
var defaults: [String: Any] {
|
|
54
|
+
switch self {
|
|
55
|
+
case .sepiaTone, .edges: [kCIInputIntensityKey: 1.0]
|
|
56
|
+
case .crystallize: [kCIInputRadiusKey: 20.0, kCIInputCenterKey: CIVector(x: 150, y: 150)]
|
|
57
|
+
case .gaussianBlur: [kCIInputRadiusKey: 10.0]
|
|
58
|
+
case .pixellate: [kCIInputCenterKey: CIVector(x: 150, y: 150), kCIInputScaleKey: 8.0]
|
|
59
|
+
case .unsharpMask: [kCIInputRadiusKey: 2.5, kCIInputIntensityKey: 0.5]
|
|
60
|
+
case .vignette: [kCIInputIntensityKey: 0.0, kCIInputRadiusKey: 1.0]
|
|
61
|
+
case .qrCodeGenerator: ["inputMessage": Data(), "inputCorrectionLevel": "M"]
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/// A Core Image filter. Made by name (`CIFilter(name: "CISepiaTone")`) or,
|
|
67
|
+
/// typed, through `CoreImage.CIFilterBuiltins` (`CIFilter.sepiaTone()`).
|
|
68
|
+
open class CIFilter: @unchecked Sendable {
|
|
69
|
+
let kind: _CIFilterKind?
|
|
70
|
+
private var values: [String: Any]
|
|
71
|
+
|
|
72
|
+
/// A filter of your own: override `outputImage`.
|
|
73
|
+
public init() {
|
|
74
|
+
kind = nil
|
|
75
|
+
values = [:]
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
init(kind: _CIFilterKind) {
|
|
79
|
+
self.kind = kind
|
|
80
|
+
values = kind.defaults
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/// One of the built-ins the shim implements, with its default inputs; nil
|
|
84
|
+
/// for any other name.
|
|
85
|
+
public convenience init?(name: String) {
|
|
86
|
+
guard let kind = _CIFilterKind(rawValue: name) else { return nil }
|
|
87
|
+
self.init(kind: kind)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
public convenience init?(name: String, parameters params: [String: Any]?) {
|
|
91
|
+
self.init(name: name)
|
|
92
|
+
for (key, value) in params ?? [:] { setValue(value, forKey: key) }
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/// The Core Image names of the filters the shim implements.
|
|
96
|
+
public class func filterNames(inCategory category: String?) -> [String] {
|
|
97
|
+
_CIFilterKind.allCases.map(\.rawValue)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
open var name: String { kind?.rawValue ?? String(describing: type(of: self)) }
|
|
101
|
+
|
|
102
|
+
/// A filter with the same inputs (`NSCopying`). A filter of your own class
|
|
103
|
+
/// is returned as is: there is no way to make another of it here.
|
|
104
|
+
open func copy() -> Any {
|
|
105
|
+
guard let kind else { return self }
|
|
106
|
+
let filter = CIFilter(kind: kind)
|
|
107
|
+
filter.values = values
|
|
108
|
+
return filter
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
open var inputKeys: [String] { kind?.inputKeys ?? [] }
|
|
112
|
+
open var outputKeys: [String] { [kCIOutputImageKey] }
|
|
113
|
+
|
|
114
|
+
/// Sets an input. Numbers may be any numeric type; a center may be a
|
|
115
|
+
/// `CIVector` or a `CGPoint`.
|
|
116
|
+
open func setValue(_ value: Any?, forKey key: String) {
|
|
117
|
+
values[key] = value
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
open func value(forKey key: String) -> Any? {
|
|
121
|
+
if key == kCIOutputImageKey { return outputImage }
|
|
122
|
+
return values[key]
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/// Restores every input but the image to Core Image's default.
|
|
126
|
+
open func setDefaults() {
|
|
127
|
+
for (key, value) in kind?.defaults ?? [:] { values[key] = value }
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/// The filtered image: a new recipe; nil without an input image (or, for
|
|
131
|
+
/// the QR code generator, for a message too long for any version).
|
|
132
|
+
open var outputImage: CIImage? {
|
|
133
|
+
guard let kind else { return nil }
|
|
134
|
+
if kind == .qrCodeGenerator { return qrCode() }
|
|
135
|
+
guard let input = values[kCIInputImageKey] as? CIImage else { return nil }
|
|
136
|
+
guard input._recipe.source != nil else { return input }
|
|
137
|
+
return output(kind, from: input)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// MARK: Typed access for the builtins
|
|
141
|
+
|
|
142
|
+
func number(_ key: String) -> Double { Self.double(values[key]) ?? Self.double(kind?.defaults[key]) ?? 0 }
|
|
143
|
+
func setNumber(_ key: String, _ value: Double) { values[key] = value }
|
|
144
|
+
func point(_ key: String) -> CGPoint { Self.point(values[key]) ?? Self.point(kind?.defaults[key]) ?? .zero }
|
|
145
|
+
func image(_ key: String) -> CIImage? { values[key] as? CIImage }
|
|
146
|
+
func setImage(_ key: String, _ image: CIImage?) { values[key] = image }
|
|
147
|
+
var message: Data {
|
|
148
|
+
get {
|
|
149
|
+
switch values["inputMessage"] {
|
|
150
|
+
case let data as Data: data
|
|
151
|
+
case let string as String: Data(string.utf8)
|
|
152
|
+
default: Data()
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
set { values["inputMessage"] = newValue }
|
|
156
|
+
}
|
|
157
|
+
var correctionLevel: String {
|
|
158
|
+
get { values["inputCorrectionLevel"] as? String ?? "M" }
|
|
159
|
+
set { values["inputCorrectionLevel"] = newValue }
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
static func double(_ value: Any?) -> Double? {
|
|
163
|
+
switch value {
|
|
164
|
+
case let v as Double: v
|
|
165
|
+
case let v as Float: Double(v)
|
|
166
|
+
case let v as Int: Double(v)
|
|
167
|
+
case let v as NSNumber: v.doubleValue
|
|
168
|
+
default: nil
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
static func point(_ value: Any?) -> CGPoint? {
|
|
173
|
+
switch value {
|
|
174
|
+
case let v as CIVector: v.cgPointValue
|
|
175
|
+
case let v as CGPoint: v
|
|
176
|
+
default: nil
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// MARK: Outputs
|
|
181
|
+
|
|
182
|
+
private func output(_ kind: _CIFilterKind, from input: CIImage) -> CIImage {
|
|
183
|
+
let extent = input.extent
|
|
184
|
+
func step(_ op: String, _ fields: [String: _JSON], extent newExtent: CGRect? = nil) -> CIImage {
|
|
185
|
+
var object = fields
|
|
186
|
+
object["op"] = .string(op)
|
|
187
|
+
return CIImage(_recipe: input._recipe.adding(.object(object), extent: newExtent ?? extent))
|
|
188
|
+
}
|
|
189
|
+
func center(_ point: CGPoint) -> _JSON { .array([.number(point.x), .number(point.y)]) }
|
|
190
|
+
switch kind {
|
|
191
|
+
case .sepiaTone:
|
|
192
|
+
return step("sepiaTone", ["intensity": .number(number(kCIInputIntensityKey))])
|
|
193
|
+
case .edges:
|
|
194
|
+
return step("edges", ["intensity": .number(number(kCIInputIntensityKey))])
|
|
195
|
+
case .crystallize:
|
|
196
|
+
// Core Image's smallest crystal is a pixel.
|
|
197
|
+
let radius = max(1, number(kCIInputRadiusKey))
|
|
198
|
+
return step("crystallize", ["radius": .number(radius), "center": center(point(kCIInputCenterKey))])
|
|
199
|
+
case .pixellate:
|
|
200
|
+
let scale = number(kCIInputScaleKey)
|
|
201
|
+
guard scale > 1 else { return input }
|
|
202
|
+
return step("pixellate", ["scale": .number(scale), "center": center(point(kCIInputCenterKey))])
|
|
203
|
+
case .gaussianBlur:
|
|
204
|
+
let radius = number(kCIInputRadiusKey)
|
|
205
|
+
guard radius > 0 else { return input }
|
|
206
|
+
// The blur reaches three standard deviations (sigma = radius) past
|
|
207
|
+
// every edge, fading to clear; a clamped image stays infinite.
|
|
208
|
+
let reach = (3 * radius).rounded(.up)
|
|
209
|
+
let grown = extent.isInfinite ? extent : extent.insetBy(dx: -reach, dy: -reach)
|
|
210
|
+
return step("gaussianBlur", ["radius": .number(radius)], extent: grown)
|
|
211
|
+
case .unsharpMask:
|
|
212
|
+
let radius = number(kCIInputRadiusKey)
|
|
213
|
+
guard radius > 0 else { return input }
|
|
214
|
+
return step("unsharpMask", ["radius": .number(radius), "intensity": .number(number(kCIInputIntensityKey))])
|
|
215
|
+
case .vignette:
|
|
216
|
+
// Measured from the middle of the input, in units of half its
|
|
217
|
+
// diagonal; an infinite image has no middle, so nothing changes.
|
|
218
|
+
guard !extent.isInfinite else { return input }
|
|
219
|
+
let halfDiagonal = (extent.width * extent.width + extent.height * extent.height).squareRoot() / 2
|
|
220
|
+
return step("vignette", [
|
|
221
|
+
"intensity": .number(number(kCIInputIntensityKey)), "radius": .number(number(kCIInputRadiusKey)),
|
|
222
|
+
"center": center(CGPoint(x: extent.midX, y: extent.midY)), "size": .number(halfDiagonal),
|
|
223
|
+
])
|
|
224
|
+
case .qrCodeGenerator:
|
|
225
|
+
return input
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
private func qrCode() -> CIImage? {
|
|
230
|
+
let level = _QRCode.ErrorCorrection(letter: correctionLevel) ?? .medium
|
|
231
|
+
guard let code = _QRCode.encode([UInt8](message), correction: level) else { return nil }
|
|
232
|
+
// One pixel per module and a one-module light margin, black on white.
|
|
233
|
+
let side = code.size + 2
|
|
234
|
+
var pixels = [UInt8](repeating: 255, count: side * side)
|
|
235
|
+
for y in 0..<code.size {
|
|
236
|
+
for x in 0..<code.size where code.module(x: x, y: y) {
|
|
237
|
+
pixels[(y + 1) * side + x + 1] = 0
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
let source = _ImageSource(pixels: pixels, width: side, height: side, format: .gray)
|
|
241
|
+
return CIImage(_recipe: _ImageRecipe(source: source))
|
|
242
|
+
}
|
|
243
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import struct Foundation.Data
|
|
2
|
+
import SwiftUI
|
|
3
|
+
|
|
4
|
+
// `CoreImage.CIFilterBuiltins`: typed filters. `CIFilter.sepiaTone()` returns
|
|
5
|
+
// `CIFilter & CISepiaTone`, whose properties read and write the same inputs
|
|
6
|
+
// as `setValue(_:forKey:)`. The protocols are class-bound, as on Apple
|
|
7
|
+
// platforms, so `let filter = CIFilter.qrCodeGenerator()` can be configured
|
|
8
|
+
// from a non-mutating method.
|
|
9
|
+
|
|
10
|
+
public protocol CIFilterProtocol: AnyObject {
|
|
11
|
+
var outputImage: CIImage? { get }
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
public protocol CISepiaTone: CIFilterProtocol {
|
|
15
|
+
var inputImage: CIImage? { get set }
|
|
16
|
+
var intensity: Float { get set }
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
public protocol CICrystallize: CIFilterProtocol {
|
|
20
|
+
var inputImage: CIImage? { get set }
|
|
21
|
+
var radius: Float { get set }
|
|
22
|
+
var center: CGPoint { get set }
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public protocol CIEdges: CIFilterProtocol {
|
|
26
|
+
var inputImage: CIImage? { get set }
|
|
27
|
+
var intensity: Float { get set }
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public protocol CIGaussianBlur: CIFilterProtocol {
|
|
31
|
+
var inputImage: CIImage? { get set }
|
|
32
|
+
var radius: Float { get set }
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
public protocol CIPixellate: CIFilterProtocol {
|
|
36
|
+
var inputImage: CIImage? { get set }
|
|
37
|
+
var center: CGPoint { get set }
|
|
38
|
+
var scale: Float { get set }
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
public protocol CIUnsharpMask: CIFilterProtocol {
|
|
42
|
+
var inputImage: CIImage? { get set }
|
|
43
|
+
var radius: Float { get set }
|
|
44
|
+
var intensity: Float { get set }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
public protocol CIVignette: CIFilterProtocol {
|
|
48
|
+
var inputImage: CIImage? { get set }
|
|
49
|
+
var intensity: Float { get set }
|
|
50
|
+
var radius: Float { get set }
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public protocol CIQRCodeGenerator: CIFilterProtocol {
|
|
54
|
+
/// The bytes to encode (byte mode).
|
|
55
|
+
var message: Data { get set }
|
|
56
|
+
/// `"L"`, `"M"` (the default), `"Q"` or `"H"`.
|
|
57
|
+
var correctionLevel: String { get set }
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
extension CIFilter {
|
|
61
|
+
public static func sepiaTone() -> CIFilter & CISepiaTone { _SepiaToneFilter(kind: .sepiaTone) }
|
|
62
|
+
public static func crystallize() -> CIFilter & CICrystallize { _CrystallizeFilter(kind: .crystallize) }
|
|
63
|
+
public static func edges() -> CIFilter & CIEdges { _EdgesFilter(kind: .edges) }
|
|
64
|
+
public static func gaussianBlur() -> CIFilter & CIGaussianBlur { _GaussianBlurFilter(kind: .gaussianBlur) }
|
|
65
|
+
public static func pixellate() -> CIFilter & CIPixellate { _PixellateFilter(kind: .pixellate) }
|
|
66
|
+
public static func unsharpMask() -> CIFilter & CIUnsharpMask { _UnsharpMaskFilter(kind: .unsharpMask) }
|
|
67
|
+
public static func vignette() -> CIFilter & CIVignette { _VignetteFilter(kind: .vignette) }
|
|
68
|
+
public static func qrCodeGenerator() -> CIFilter & CIQRCodeGenerator { _QRCodeGeneratorFilter(kind: .qrCodeGenerator) }
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// The typed properties, shared by the filter classes below.
|
|
72
|
+
extension CIFilter {
|
|
73
|
+
var _inputImage: CIImage? {
|
|
74
|
+
get { image(kCIInputImageKey) }
|
|
75
|
+
set { setImage(kCIInputImageKey, newValue) }
|
|
76
|
+
}
|
|
77
|
+
var _intensity: Float {
|
|
78
|
+
get { Float(number(kCIInputIntensityKey)) }
|
|
79
|
+
set { setNumber(kCIInputIntensityKey, Double(newValue)) }
|
|
80
|
+
}
|
|
81
|
+
var _radius: Float {
|
|
82
|
+
get { Float(number(kCIInputRadiusKey)) }
|
|
83
|
+
set { setNumber(kCIInputRadiusKey, Double(newValue)) }
|
|
84
|
+
}
|
|
85
|
+
var _scale: Float {
|
|
86
|
+
get { Float(number(kCIInputScaleKey)) }
|
|
87
|
+
set { setNumber(kCIInputScaleKey, Double(newValue)) }
|
|
88
|
+
}
|
|
89
|
+
var _center: CGPoint {
|
|
90
|
+
get { point(kCIInputCenterKey) }
|
|
91
|
+
set { setValue(CIVector(cgPoint: newValue), forKey: kCIInputCenterKey) }
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
final class _SepiaToneFilter: CIFilter, CISepiaTone {
|
|
96
|
+
var inputImage: CIImage? { get { _inputImage } set { _inputImage = newValue } }
|
|
97
|
+
var intensity: Float { get { _intensity } set { _intensity = newValue } }
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
final class _CrystallizeFilter: CIFilter, CICrystallize {
|
|
101
|
+
var inputImage: CIImage? { get { _inputImage } set { _inputImage = newValue } }
|
|
102
|
+
var radius: Float { get { _radius } set { _radius = newValue } }
|
|
103
|
+
var center: CGPoint { get { _center } set { _center = newValue } }
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
final class _EdgesFilter: CIFilter, CIEdges {
|
|
107
|
+
var inputImage: CIImage? { get { _inputImage } set { _inputImage = newValue } }
|
|
108
|
+
var intensity: Float { get { _intensity } set { _intensity = newValue } }
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
final class _GaussianBlurFilter: CIFilter, CIGaussianBlur {
|
|
112
|
+
var inputImage: CIImage? { get { _inputImage } set { _inputImage = newValue } }
|
|
113
|
+
var radius: Float { get { _radius } set { _radius = newValue } }
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
final class _PixellateFilter: CIFilter, CIPixellate {
|
|
117
|
+
var inputImage: CIImage? { get { _inputImage } set { _inputImage = newValue } }
|
|
118
|
+
var center: CGPoint { get { _center } set { _center = newValue } }
|
|
119
|
+
var scale: Float { get { _scale } set { _scale = newValue } }
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
final class _UnsharpMaskFilter: CIFilter, CIUnsharpMask {
|
|
123
|
+
var inputImage: CIImage? { get { _inputImage } set { _inputImage = newValue } }
|
|
124
|
+
var radius: Float { get { _radius } set { _radius = newValue } }
|
|
125
|
+
var intensity: Float { get { _intensity } set { _intensity = newValue } }
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
final class _VignetteFilter: CIFilter, CIVignette {
|
|
129
|
+
var inputImage: CIImage? { get { _inputImage } set { _inputImage = newValue } }
|
|
130
|
+
var intensity: Float { get { _intensity } set { _intensity = newValue } }
|
|
131
|
+
var radius: Float { get { _radius } set { _radius = newValue } }
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
final class _QRCodeGeneratorFilter: CIFilter, CIQRCodeGenerator {
|
|
135
|
+
// `message` and `correctionLevel` are CIFilter's own (CIFilter.swift).
|
|
136
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
// Core Image, as far as SwiftUI apps use it: an image from a UIImage or a
|
|
2
|
+
// file, the built-in filters of `CoreImage.CIFilterBuiltins` that Hacking
|
|
3
|
+
// with SwiftUI's Instafilter and Hot Prospects apply (sepia tone, crystallize,
|
|
4
|
+
// edges, Gaussian blur, pixellate, unsharp mask, vignette, the QR code
|
|
5
|
+
// generator), and a context that turns the result into a `CGImage`.
|
|
6
|
+
//
|
|
7
|
+
// Nothing is computed here but sizes. A `CIImage` is a recipe (the shim's
|
|
8
|
+
// `_ImageRecipe`: a source plus filter steps); the page runs the steps on
|
|
9
|
+
// the decoded pixels when it draws the image (Web/src/imageOps.ts,
|
|
10
|
+
// docs/ops-protocol.md, "Bitmaps and Core Image"). The QR code generator is
|
|
11
|
+
// the exception: it makes its modules here, as a pixel buffer.
|
|
12
|
+
//
|
|
13
|
+
// `import CoreImage.CIFilterBuiltins` names a Clang submodule on Apple
|
|
14
|
+
// platforms; a Swift module has none, so the CLI stages that line as
|
|
15
|
+
// `import CoreImage` (packages/cli/src/stage.ts).
|
|
16
|
+
|
|
17
|
+
// Only the Foundation types Core Image takes are imported: Foundation's own
|
|
18
|
+
// CGRect and CGPoint would clash with the shim's, which the apps use (the
|
|
19
|
+
// CLI's generated file settles them the same way).
|
|
20
|
+
import struct Foundation.Data
|
|
21
|
+
import SwiftUI
|
|
22
|
+
|
|
23
|
+
/// An image in Core Image's coordinate space: units of source pixels, origin
|
|
24
|
+
/// at the bottom left. Immutable; filters make new ones.
|
|
25
|
+
public final class CIImage: @unchecked Sendable {
|
|
26
|
+
public let _recipe: _ImageRecipe
|
|
27
|
+
|
|
28
|
+
public init(_recipe recipe: _ImageRecipe) {
|
|
29
|
+
_recipe = recipe
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/// The rectangle the image covers; `.infinite` after `clampedToExtent()`,
|
|
33
|
+
/// `.null` for an empty image.
|
|
34
|
+
public var extent: CGRect { _recipe.extent }
|
|
35
|
+
|
|
36
|
+
/// An image with nothing in it.
|
|
37
|
+
public static func empty() -> CIImage { CIImage(_recipe: .empty) }
|
|
38
|
+
|
|
39
|
+
/// The bitmap's pixels, `(0, 0, width, height)`.
|
|
40
|
+
public convenience init(cgImage: CGImage) {
|
|
41
|
+
self.init(_recipe: cgImage._recipe)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public convenience init(cgImage: CGImage, options: [CIImageOption: Any]?) {
|
|
45
|
+
self.init(cgImage: cgImage)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/// A UIImage's bitmap; nil for an empty image, an SF Symbol or a catalog
|
|
49
|
+
/// image (the page holds those). Its extent is the bitmap in pixels.
|
|
50
|
+
public convenience init?(image: UIImage) {
|
|
51
|
+
if let backing = image._ciImage as? CIImage {
|
|
52
|
+
self.init(_recipe: backing._recipe)
|
|
53
|
+
return
|
|
54
|
+
}
|
|
55
|
+
guard let recipe = image._recipe, recipe.source != nil else { return nil }
|
|
56
|
+
self.init(_recipe: recipe)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
public convenience init?(image: UIImage, options: [CIImageOption: Any]?) {
|
|
60
|
+
self.init(image: image)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/// The image in a PNG, JPEG, GIF, WebP, BMP, HEIC or AVIF file.
|
|
64
|
+
public convenience init?(data: Data) {
|
|
65
|
+
guard let source = _ImageSource(encoded: [UInt8](data)) else { return nil }
|
|
66
|
+
self.init(_recipe: _ImageRecipe(source: source))
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
public convenience init?(data: Data, options: [CIImageOption: Any]?) {
|
|
70
|
+
self.init(data: data)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/// The image cut to `rect` (its extent becomes the overlap).
|
|
74
|
+
public func cropped(to rect: CGRect) -> CIImage {
|
|
75
|
+
let extent = self.extent.intersection(rect)
|
|
76
|
+
guard !extent.isNull, extent.width > 0, extent.height > 0 else { return .empty() }
|
|
77
|
+
if extent == self.extent { return self }
|
|
78
|
+
return CIImage(_recipe: _recipe.adding(.object([
|
|
79
|
+
"op": .string("crop"), "x": .number(extent.minX), "y": .number(extent.minY),
|
|
80
|
+
"width": .number(extent.width), "height": .number(extent.height),
|
|
81
|
+
]), extent: extent))
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/// The image repeated outward from its edge pixels without end, so a blur
|
|
85
|
+
/// does not fade at the borders; crop it afterwards.
|
|
86
|
+
public func clampedToExtent() -> CIImage {
|
|
87
|
+
guard _recipe.source != nil, !extent.isInfinite else { return self }
|
|
88
|
+
return CIImage(_recipe: _recipe.adding(.object(["op": .string("clamp")]), extent: .infinite))
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/// The output of the filter `name` with this image as its input and
|
|
92
|
+
/// `parameters` set; the empty image for a filter the shim does not have.
|
|
93
|
+
public func applyingFilter(_ name: String, parameters params: [String: Any]) -> CIImage {
|
|
94
|
+
guard let filter = CIFilter(name: name) else { return .empty() }
|
|
95
|
+
filter.setValue(self, forKey: kCIInputImageKey)
|
|
96
|
+
for (key, value) in params { filter.setValue(value, forKey: key) }
|
|
97
|
+
return filter.outputImage ?? .empty()
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
public func applyingFilter(_ name: String) -> CIImage {
|
|
101
|
+
applyingFilter(name, parameters: [:])
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/// `CIGaussianBlur` with `inputRadius` = `sigma`.
|
|
105
|
+
public func applyingGaussianBlur(sigma: Double) -> CIImage {
|
|
106
|
+
applyingFilter("CIGaussianBlur", parameters: [kCIInputRadiusKey: sigma])
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/// The bitmap this image was made from, if it was made from one unchanged.
|
|
110
|
+
public var cgImage: CGImage? {
|
|
111
|
+
let extent = self.extent
|
|
112
|
+
guard _recipe.source != nil, !extent.isInfinite, !extent.isNull, extent.origin == .zero else { return nil }
|
|
113
|
+
return CGImage(_recipe: _recipe)
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/// Options for creating an image; accepted and ignored.
|
|
118
|
+
public struct CIImageOption: Hashable, RawRepresentable, Sendable {
|
|
119
|
+
public let rawValue: String
|
|
120
|
+
public init(rawValue: String) { self.rawValue = rawValue }
|
|
121
|
+
|
|
122
|
+
public static let applyOrientationProperty = CIImageOption(rawValue: "kCIImageApplyOrientationProperty")
|
|
123
|
+
public static let colorSpace = CIImageOption(rawValue: "kCIImageColorSpace")
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/// A vector of up to four numbers; filters take points (`inputCenter`) as one.
|
|
127
|
+
public final class CIVector: @unchecked Sendable {
|
|
128
|
+
private let values: [Double]
|
|
129
|
+
|
|
130
|
+
public init(values: [CGFloat], count: Int) { self.values = Array(values.prefix(count)) }
|
|
131
|
+
public convenience init(x: CGFloat) { self.init(values: [x], count: 1) }
|
|
132
|
+
public convenience init(x: CGFloat, y: CGFloat) { self.init(values: [x, y], count: 2) }
|
|
133
|
+
public convenience init(x: CGFloat, y: CGFloat, z: CGFloat) { self.init(values: [x, y, z], count: 3) }
|
|
134
|
+
public convenience init(x: CGFloat, y: CGFloat, z: CGFloat, w: CGFloat) { self.init(values: [x, y, z, w], count: 4) }
|
|
135
|
+
public convenience init(cgPoint point: CGPoint) { self.init(x: point.x, y: point.y) }
|
|
136
|
+
public convenience init(cgRect rect: CGRect) { self.init(x: rect.minX, y: rect.minY, z: rect.width, w: rect.height) }
|
|
137
|
+
|
|
138
|
+
public var count: Int { values.count }
|
|
139
|
+
public func value(at index: Int) -> CGFloat { index < values.count ? values[index] : 0 }
|
|
140
|
+
public var x: CGFloat { value(at: 0) }
|
|
141
|
+
public var y: CGFloat { value(at: 1) }
|
|
142
|
+
public var z: CGFloat { value(at: 2) }
|
|
143
|
+
public var w: CGFloat { value(at: 3) }
|
|
144
|
+
public var cgPointValue: CGPoint { CGPoint(x: x, y: y) }
|
|
145
|
+
public var cgRectValue: CGRect { CGRect(x: x, y: y, width: z, height: w) }
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// UIKit's Core Image additions.
|
|
149
|
+
extension UIImage {
|
|
150
|
+
/// An image drawn from `ciImage`'s extent, which must be finite.
|
|
151
|
+
public convenience init(ciImage: CIImage) {
|
|
152
|
+
self.init(ciImage: ciImage, scale: 1, orientation: .up)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
public convenience init(ciImage: CIImage, scale: CGFloat, orientation: UIImage.Orientation) {
|
|
156
|
+
let recipe = ciImage._recipe.rendered(in: ciImage.extent) ?? .empty
|
|
157
|
+
self.init(_recipe: recipe, scale: scale, ciImage: ciImage)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/// The `CIImage` the image was made from with `UIImage(ciImage:)`, else nil.
|
|
161
|
+
public var ciImage: CIImage? { _ciImage as? CIImage }
|
|
162
|
+
}
|