diff --git a/Package.resolved b/Package.resolved index 4b6491301..78f1dbc77 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "7164fe444083ea8709bd92f41f5872d41b6a8bc539389b307beb39347bbbf905", + "originHash" : "ab8bc707b0e15c72f40e788831881b7a09b99df76f95fd09712e31d2550b8ade", "pins" : [ { "identity" : "darwinprivateframeworks", @@ -7,7 +7,7 @@ "location" : "https://github.com/OpenSwiftUIProject/DarwinPrivateFrameworks.git", "state" : { "branch" : "main", - "revision" : "09f6bd3d766b0fd99aa67bdcacd3105bf508a7c4" + "revision" : "4aa30d65aae91b8cd3aa7e6b5910d281a77e9af0" } }, { @@ -16,7 +16,16 @@ "location" : "https://github.com/OpenSwiftUIProject/OpenBox", "state" : { "branch" : "main", - "revision" : "00748723bc575376fcde3921b0229fd0c7cdec0b" + "revision" : "f757b0ab3c243d4e60b5c5cb66128ab6fb81940a" + } + }, + { + "identity" : "opencoregraphics", + "kind" : "remoteSourceControl", + "location" : "https://github.com/OpenSwiftUIProject/OpenCoreGraphics", + "state" : { + "branch" : "main", + "revision" : "d4fdffac749beec6108eaf345f69da5d222b6dd1" } }, { @@ -25,7 +34,7 @@ "location" : "https://github.com/OpenSwiftUIProject/OpenGraph", "state" : { "branch" : "main", - "revision" : "93aea21ce7374e1aa135a470ca439563774cf5a0" + "revision" : "43739e647189207da56903cd55f97ac45eb4ef71" } }, { diff --git a/Package.swift b/Package.swift index 219c4d1a7..26cb084ff 100644 --- a/Package.swift +++ b/Package.swift @@ -186,22 +186,6 @@ if !compatibilityTestCondition { let ignoreAvailability = envEnable("OPENSWIFTUI_IGNORE_AVAILABILITY", default: !isSPIDocGenerationBuild && !compatibilityTestCondition) sharedSwiftSettings.append(contentsOf: [SwiftSetting].availabilityMacroSettings(ignoreAvailability: ignoreAvailability)) -// MARK: - CoreGraphicsShims Target - -let coreGraphicsShimsTarget = Target.target( - name: "CoreGraphicsShims", - swiftSettings: sharedSwiftSettings -) -let coreGraphicsShimsTestTarget = Target.testTarget( - name: "CoreGraphicsShimsTests", - dependencies: [ - "CoreGraphicsShims", - .product(name: "Numerics", package: "swift-numerics"), - ], - exclude: ["README.md"], - swiftSettings: sharedSwiftSettings -) - // MARK: - OpenSwiftUISPI Target let openSwiftUISPITarget = Target.target( @@ -236,7 +220,8 @@ let openSwiftUICoreTarget = Target.target( name: "OpenSwiftUICore", dependencies: [ "OpenSwiftUI_SPI", - "CoreGraphicsShims", + .product(name: "OpenCoreGraphicsShims", package: "OpenCoreGraphics"), + .product(name: "OpenQuartzCoreShims", package: "OpenCoreGraphics"), .product(name: "OpenGraphShims", package: "OpenGraph"), .product(name: "OpenBoxShims", package: "OpenBox"), ] + (swiftUIRenderCondition && symbolLocatorCondition ? ["OpenSwiftUISymbolDualTestsSupport"] : []), @@ -276,7 +261,8 @@ let openSwiftUITarget = Target.target( dependencies: [ "OpenSwiftUICore", "COpenSwiftUI", - "CoreGraphicsShims", + .product(name: "OpenCoreGraphicsShims", package: "OpenCoreGraphics"), + .product(name: "OpenQuartzCoreShims", package: "OpenCoreGraphics"), .product(name: "OpenGraphShims", package: "OpenGraph"), .product(name: "OpenBoxShims", package: "OpenBox"), ], @@ -421,7 +407,6 @@ let package = Package( .package(url: "https://github.com/apple/swift-numerics", from: "1.0.3"), ], targets: [ - coreGraphicsShimsTarget, openSwiftUISPITarget, openSwiftUICoreTarget, cOpenSwiftUITarget, @@ -438,7 +423,6 @@ if renderGTKCondition { if !compatibilityTestCondition { package.targets += [ - coreGraphicsShimsTestTarget, openSwiftUISPITestTarget, openSwiftUICoreTestTarget, openSwiftUITestTarget, @@ -555,6 +539,7 @@ if linkCoreUI { if useLocalDeps { var dependencies: [Package.Dependency] = [ + .package(path: "../OpenCoreGraphics"), .package(path: "../OpenGraph"), .package(path: "../OpenBox"), ] @@ -564,6 +549,7 @@ if useLocalDeps { package.dependencies += dependencies } else { var dependencies: [Package.Dependency] = [ + .package(url: "https://github.com/OpenSwiftUIProject/OpenCoreGraphics", branch: "main"), // FIXME: on Linux platform: OG contains unsafe build flags which prevents us using version dependency .package(url: "https://github.com/OpenSwiftUIProject/OpenGraph", branch: "main"), .package(url: "https://github.com/OpenSwiftUIProject/OpenBox", branch: "main"), diff --git a/Scripts/CI/darwin_setup_build.sh b/Scripts/CI/darwin_setup_build.sh index 667eebc84..5e516ba2b 100755 --- a/Scripts/CI/darwin_setup_build.sh +++ b/Scripts/CI/darwin_setup_build.sh @@ -8,6 +8,7 @@ filepath() { REPO_ROOT="$(dirname $(dirname $(dirname $(filepath $0))))" cd $REPO_ROOT +Scripts/CI/opencoregraphics_setup.sh Scripts/CI/og_setup.sh Scripts/CI/ob_setup.sh Scripts/CI/framework_setup.sh diff --git a/Scripts/CI/opencoregraphics_setup.sh b/Scripts/CI/opencoregraphics_setup.sh new file mode 100755 index 000000000..e1ae4b531 --- /dev/null +++ b/Scripts/CI/opencoregraphics_setup.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +# A `realpath` alternative using the default C implementation. +filepath() { + [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}" +} + +REPO_ROOT="$(dirname $(dirname $(dirname $(filepath $0))))" + +clone_checkout_opencoregraphics() { + cd $REPO_ROOT + revision=$(Scripts/CI/get_revision.sh opencoregraphics) + cd .. + if [ ! -d OpenCoreGraphics ]; then + gh repo clone OpenSwiftUIProject/OpenCoreGraphics + cd OpenCoreGraphics + else + echo "OpenCoreGraphics already exists, skipping clone." + cd OpenCoreGraphics + git fetch --all --quiet + git stash --quiet || true + git reset --hard --quiet origin/main + fi + git checkout --quiet $revision +} + +clone_checkout_opencoregraphics diff --git a/Sources/CoreGraphicsShims/CATransform3D.swift b/Sources/CoreGraphicsShims/CATransform3D.swift deleted file mode 100644 index 25aea2ed7..000000000 --- a/Sources/CoreGraphicsShims/CATransform3D.swift +++ /dev/null @@ -1,386 +0,0 @@ -// -// CATransform3D.swift -// CoreGraphicsShims -// -// License: MIT -// Modified from https://github.com/flowkey/UIKit-cross-platform/blob/7e28dc4c62d20afe03e55bbba660076ec06fd79a/Sources/CATransform3D.swift - -#if !canImport(QuartzCore) -public import Foundation - -public struct CATransform3D { - public init( - m11: CGFloat, m12: CGFloat, m13: CGFloat, m14: CGFloat, - m21: CGFloat, m22: CGFloat, m23: CGFloat, m24: CGFloat, - m31: CGFloat, m32: CGFloat, m33: CGFloat, m34: CGFloat, - m41: CGFloat, m42: CGFloat, m43: CGFloat, m44: CGFloat - ) { - self.m11 = m11; self.m12 = m12; self.m13 = m13; self.m14 = m14; - self.m21 = m21; self.m22 = m22; self.m23 = m23; self.m24 = m24; - self.m31 = m31; self.m32 = m32; self.m33 = m33; self.m34 = m34; - self.m41 = m41; self.m42 = m42; self.m43 = m43; self.m44 = m44; - } - - public init() { - self.m11 = 0.0; self.m12 = 0.0; self.m13 = 0.0; self.m14 = 0.0; - self.m21 = 0.0; self.m22 = 0.0; self.m23 = 0.0; self.m24 = 0.0; - self.m31 = 0.0; self.m32 = 0.0; self.m33 = 0.0; self.m34 = 0.0; - self.m41 = 0.0; self.m42 = 0.0; self.m43 = 0.0; self.m44 = 0.0; - } - - public var m11: CGFloat; public var m12: CGFloat; public var m13: CGFloat; public var m14: CGFloat - public var m21: CGFloat; public var m22: CGFloat; public var m23: CGFloat; public var m24: CGFloat - public var m31: CGFloat; public var m32: CGFloat; public var m33: CGFloat; public var m34: CGFloat - public var m41: CGFloat; public var m42: CGFloat; public var m43: CGFloat; public var m44: CGFloat -} - -internal extension CATransform3D { - func transformingVector(x: CGFloat, y: CGFloat, z: CGFloat) -> (x: CGFloat, y: CGFloat, z: CGFloat) { - let newX = Double(m11) * Double(x) + Double(m21) * Double(y) + Double(m31) * Double(z) + Double(m41) - let newY = Double(m12) * Double(x) + Double(m22) * Double(y) + Double(m32) * Double(z) + Double(m42) - let newZ = Double(m13) * Double(x) + Double(m23) * Double(y) + Double(m33) * Double(z) + Double(m43) - let newW = Double(m14) * Double(x) + Double(m24) * Double(y) + Double(m34) * Double(z) + Double(m44) - - return ( - x: CGFloat(newX / newW), - y: CGFloat(newY / newW), - z: CGFloat(newZ / newW) - ) - } -} - -public let CATransform3DIdentity = CATransform3D( - m11: 1.0, m12: 0.0, m13: 0.0, m14: 0.0, - m21: 0.0, m22: 1.0, m23: 0.0, m24: 0.0, - m31: 0.0, m32: 0.0, m33: 1.0, m34: 0.0, - m41: 0.0, m42: 0.0, m43: 0.0, m44: 1.0 -) - -public func CATransform3DEqualToTransform(_ a: CATransform3D, _ b: CATransform3D) -> Bool { - return - a.m11 == b.m11 && a.m12 == b.m12 && a.m13 == b.m13 && a.m14 == b.m14 && - a.m21 == b.m21 && a.m22 == b.m22 && a.m23 == b.m23 && a.m24 == b.m24 && - a.m31 == b.m31 && a.m32 == b.m32 && a.m33 == b.m33 && a.m34 == b.m34 && - a.m41 == b.m41 && a.m42 == b.m42 && a.m43 == b.m43 && a.m44 == b.m44 -} - -extension CATransform3D: Equatable { - public static func == (_ lhs: CATransform3D, _ rhs: CATransform3D) -> Bool { - return CATransform3DEqualToTransform(lhs, rhs) - } - - // This isn't public API on iOS, although it'd probably be quite useful - internal static func * (_ lhs: CATransform3D, _ rhs: CATransform3D) -> CATransform3D { - return lhs.concat(rhs) - } -} - -extension CATransform3D: CustomStringConvertible { - public var description: String { - return """ - \(m11)\t\t\(m12)\t\t\(m13)\t\t\(m14) - \(m21)\t\t\(m22)\t\t\(m23)\t\t\(m24) - \(m31)\t\t\(m32)\t\t\(m33)\t\t\(m34) - \(m41)\t\t\(m42)\t\t\(m43)\t\t\(m44) - """ - } -} - - -// https://stackoverflow.com/a/5508486/3086440 -/* - | a b 0 | | a b 0 0 | - | d e 0 | => | d e 0 0 | - | g h 1 | | 0 0 1 0 | - | g h 0 1 | - */ -public func CATransform3DMakeAffineTransform(_ m: CGAffineTransform) -> CATransform3D { - return CATransform3D( - m11: m.a, m12: m.b, m13: 0.0, m14: 0.0, - m21: m.c, m22: m.d, m23: 0.0, m24: 0.0, - m31: 0.0, m32: 0.0, m33: 1.0, m34: 0.0, - m41: m.tx, m42: m.ty, m43: 0.0, m44: 1.0 - ) -} - -public func CATransform3DMakeTranslation(_ tx: CGFloat, _ ty: CGFloat, _ tz: CGFloat) -> CATransform3D { - return CATransform3D( - m11: 1, m12: 0, m13: 0, m14: 0, - m21: 0, m22: 1, m23: 0, m24: 0, - m31: 0, m32: 0, m33: 1, m34: 0, - m41: tx, m42: ty, m43: tz, m44: 1 - ) -} - -public func CATransform3DMakeScale(_ sx: CGFloat, _ sy: CGFloat, _ sz: CGFloat) -> CATransform3D { - return CATransform3D( - m11: sx, m12: 0, m13: 0, m14: 0, - m21: 0, m22: sy, m23: 0, m24: 0, - m31: 0, m32: 0, m33: sz, m34: 0, - m41: 0, m42: 0, m43: 0, m44: 1 - ) -} - -/// Returns a transform that rotates by `angle` radians about the vector -/// `(x, y, z)`. If the vector has length zero the identity transform is -/// returned. -public func CATransform3DMakeRotation(_ angle: CGFloat, _ x: CGFloat, _ y: CGFloat, _ z: CGFloat) -> CATransform3D { - let ax = Double(x) - let ay = Double(y) - let az = Double(z) - let len = sqrt(ax * ax + ay * ay + az * az) - guard len > 0 else { - return CATransform3DIdentity - } - - let ux = CGFloat(ax / len) - let uy = CGFloat(ay / len) - let uz = CGFloat(az / len) - - let a = Double(angle) - let c = CGFloat(cos(a)) - let s = CGFloat(sin(a)) - let omc = 1 - c - - // Compute standard rotation matrix components (Rodrigues' formula) - let r11 = c + ux * ux * omc - let r12 = ux * uy * omc - uz * s - let r13 = ux * uz * omc + uy * s - - let r21 = uy * ux * omc + uz * s - let r22 = c + uy * uy * omc - let r23 = uy * uz * omc - ux * s - - let r31 = uz * ux * omc - uy * s - let r32 = uz * uy * omc + ux * s - let r33 = c + uz * uz * omc - - // Store the transpose of the standard rotation matrix into CATransform3D - // so that the effective transform used by this implementation matches the - // expected row/column layout when applied to points. - let m11 = r11 - let m12 = r21 - let m13 = r31 - let m14: CGFloat = 0.0 - - let m21 = r12 - let m22 = r22 - let m23 = r32 - let m24: CGFloat = 0.0 - - let m31 = r13 - let m32 = r23 - let m33 = r33 - let m34: CGFloat = 0.0 - - let m41: CGFloat = 0.0 - let m42: CGFloat = 0.0 - let m43: CGFloat = 0.0 - let m44: CGFloat = 1.0 - - return CATransform3D( - m11: m11, m12: m12, m13: m13, m14: m14, - m21: m21, m22: m22, m23: m23, m24: m24, - m31: m31, m32: m32, m33: m33, m34: m34, - m41: m41, m42: m42, m43: m43, m44: m44 - ) -} - -/// Translate `t` by `(tx, ty, tz)` and return the result: -/// t' = translate(tx, ty, tz) * t. -public func CATransform3DTranslate(_ t: CATransform3D, _ tx: CGFloat, _ ty: CGFloat, _ tz: CGFloat) -> CATransform3D { - return CATransform3DConcat(CATransform3DMakeTranslation(tx, ty, tz), t) -} - -/// Scale `t` by `(sx, sy, sz)` and return the result: -/// t' = scale(sx, sy, sz) * t. -public func CATransform3DScale(_ t: CATransform3D, _ sx: CGFloat, _ sy: CGFloat, _ sz: CGFloat) -> CATransform3D { - return CATransform3DConcat(CATransform3DMakeScale(sx, sy, sz), t) -} - -/// Rotate `t` by `angle` radians about the vector `(x, y, z)` and return -/// the result. If the vector has zero length the behavior is undefined: -/// t' = rotation(angle, x, y, z) * t. -public func CATransform3DRotate(_ t: CATransform3D, _ angle: CGFloat, _ x: CGFloat, _ y: CGFloat, _ z: CGFloat) -> CATransform3D { - return CATransform3DConcat(CATransform3DMakeRotation(angle, x, y, z), t) -} - -public func CATransform3DConcat(_ a: CATransform3D, _ b: CATransform3D) -> CATransform3D { - if a == CATransform3DIdentity { return b } - if b == CATransform3DIdentity { return a } - - var result = CATransform3D() - - result.m11 = a.m11 * b.m11 + a.m21 * b.m12 + a.m31 * b.m13 + a.m41 * b.m14 - result.m12 = a.m12 * b.m11 + a.m22 * b.m12 + a.m32 * b.m13 + a.m42 * b.m14 - result.m13 = a.m13 * b.m11 + a.m23 * b.m12 + a.m33 * b.m13 + a.m43 * b.m14 - result.m14 = a.m14 * b.m11 + a.m24 * b.m12 + a.m34 * b.m13 + a.m44 * b.m14 - - result.m21 = a.m11 * b.m21 + a.m21 * b.m22 + a.m31 * b.m23 + a.m41 * b.m24 - result.m22 = a.m12 * b.m21 + a.m22 * b.m22 + a.m32 * b.m23 + a.m42 * b.m24 - result.m23 = a.m13 * b.m21 + a.m23 * b.m22 + a.m33 * b.m23 + a.m43 * b.m24 - result.m24 = a.m14 * b.m21 + a.m24 * b.m22 + a.m34 * b.m23 + a.m44 * b.m24 - - result.m31 = a.m11 * b.m31 + a.m21 * b.m32 + a.m31 * b.m33 + a.m41 * b.m34 - result.m32 = a.m12 * b.m31 + a.m22 * b.m32 + a.m32 * b.m33 + a.m42 * b.m34 - result.m33 = a.m13 * b.m31 + a.m23 * b.m32 + a.m33 * b.m33 + a.m43 * b.m34 - result.m34 = a.m14 * b.m31 + a.m24 * b.m32 + a.m34 * b.m33 + a.m44 * b.m34 - - result.m41 = a.m11 * b.m41 + a.m21 * b.m42 + a.m31 * b.m43 + a.m41 * b.m44 - result.m42 = a.m12 * b.m41 + a.m22 * b.m42 + a.m32 * b.m43 + a.m42 * b.m44 - result.m43 = a.m13 * b.m41 + a.m23 * b.m42 + a.m33 * b.m43 + a.m43 * b.m44 - result.m44 = a.m14 * b.m41 + a.m24 * b.m42 + a.m34 * b.m43 + a.m44 * b.m44 - - return result -} - -extension CATransform3D { - func concat(_ other: CATransform3D) -> CATransform3D { - return CATransform3DConcat(self, other) - } -} - -public func CATransform3DGetAffineTransform(_ t: CATransform3D) -> CGAffineTransform { - return CGAffineTransform( - a: t.m11, b: t.m12, - c: t.m21, d: t.m22, - tx: t.m41, ty: t.m42 - ) -} - -/// Invert 't' and return the result. Returns the original matrix if 't' -/// has no inverse. -public func CATransform3DInvert(_ t: CATransform3D) -> CATransform3D { - // For identity matrix, return identity - if t == CATransform3DIdentity { - return t - } - - // Calculate determinant to check if matrix can be inverted - let det = t.m11 * (t.m22 * (t.m33 * t.m44 - t.m34 * t.m43) - - t.m23 * (t.m32 * t.m44 - t.m34 * t.m42) + - t.m24 * (t.m32 * t.m43 - t.m33 * t.m42)) - - t.m12 * (t.m21 * (t.m33 * t.m44 - t.m34 * t.m43) - - t.m23 * (t.m31 * t.m44 - t.m34 * t.m41) + - t.m24 * (t.m31 * t.m43 - t.m33 * t.m41)) + - t.m13 * (t.m21 * (t.m32 * t.m44 - t.m34 * t.m42) - - t.m22 * (t.m31 * t.m44 - t.m34 * t.m41) + - t.m24 * (t.m31 * t.m42 - t.m32 * t.m41)) - - t.m14 * (t.m21 * (t.m32 * t.m43 - t.m33 * t.m42) - - t.m22 * (t.m31 * t.m43 - t.m33 * t.m41) + - t.m23 * (t.m31 * t.m42 - t.m32 * t.m41)) - - // If determinant is too close to zero, matrix cannot be inverted - if abs(det) < 1e-6 { - return t - } - - let invDet = 1.0 / det - - // Calculate adjugate matrix and multiply by 1/determinant - var result = CATransform3D() - - // Row 1 - result.m11 = invDet * ( - t.m22 * (t.m33 * t.m44 - t.m34 * t.m43) - - t.m23 * (t.m32 * t.m44 - t.m34 * t.m42) + - t.m24 * (t.m32 * t.m43 - t.m33 * t.m42) - ) - - result.m12 = -invDet * ( - t.m12 * (t.m33 * t.m44 - t.m34 * t.m43) - - t.m13 * (t.m32 * t.m44 - t.m34 * t.m42) + - t.m14 * (t.m32 * t.m43 - t.m33 * t.m42) - ) - - result.m13 = invDet * ( - t.m12 * (t.m23 * t.m44 - t.m24 * t.m43) - - t.m13 * (t.m22 * t.m44 - t.m24 * t.m42) + - t.m14 * (t.m22 * t.m43 - t.m23 * t.m42) - ) - - result.m14 = -invDet * ( - t.m12 * (t.m23 * t.m34 - t.m24 * t.m33) - - t.m13 * (t.m22 * t.m34 - t.m24 * t.m32) + - t.m14 * (t.m22 * t.m33 - t.m23 * t.m32) - ) - - // Row 2 - result.m21 = -invDet * ( - t.m21 * (t.m33 * t.m44 - t.m34 * t.m43) - - t.m23 * (t.m31 * t.m44 - t.m34 * t.m41) + - t.m24 * (t.m31 * t.m43 - t.m33 * t.m41) - ) - - result.m22 = invDet * ( - t.m11 * (t.m33 * t.m44 - t.m34 * t.m43) - - t.m13 * (t.m31 * t.m44 - t.m34 * t.m41) + - t.m14 * (t.m31 * t.m43 - t.m33 * t.m41) - ) - - result.m23 = -invDet * ( - t.m11 * (t.m23 * t.m44 - t.m24 * t.m43) - - t.m13 * (t.m21 * t.m44 - t.m24 * t.m41) + - t.m14 * (t.m21 * t.m43 - t.m23 * t.m41) - ) - - result.m24 = invDet * ( - t.m11 * (t.m23 * t.m34 - t.m24 * t.m33) - - t.m13 * (t.m21 * t.m34 - t.m24 * t.m31) + - t.m14 * (t.m21 * t.m33 - t.m23 * t.m31) - ) - - // Row 3 - result.m31 = invDet * ( - t.m21 * (t.m32 * t.m44 - t.m34 * t.m42) - - t.m22 * (t.m31 * t.m44 - t.m34 * t.m41) + - t.m24 * (t.m31 * t.m42 - t.m32 * t.m41) - ) - - result.m32 = -invDet * ( - t.m11 * (t.m32 * t.m44 - t.m34 * t.m42) - - t.m12 * (t.m31 * t.m44 - t.m34 * t.m41) + - t.m14 * (t.m31 * t.m42 - t.m32 * t.m41) - ) - - result.m33 = invDet * ( - t.m11 * (t.m22 * t.m44 - t.m24 * t.m42) - - t.m12 * (t.m21 * t.m44 - t.m24 * t.m41) + - t.m14 * (t.m21 * t.m42 - t.m22 * t.m41) - ) - - result.m34 = -invDet * ( - t.m11 * (t.m22 * t.m34 - t.m24 * t.m32) - - t.m12 * (t.m21 * t.m34 - t.m24 * t.m31) + - t.m14 * (t.m21 * t.m32 - t.m22 * t.m31) - ) - - // Row 4 - result.m41 = -invDet * ( - t.m21 * (t.m32 * t.m43 - t.m33 * t.m42) - - t.m22 * (t.m31 * t.m43 - t.m33 * t.m41) + - t.m23 * (t.m31 * t.m42 - t.m32 * t.m41) - ) - - result.m42 = invDet * ( - t.m11 * (t.m32 * t.m43 - t.m33 * t.m42) - - t.m12 * (t.m31 * t.m43 - t.m33 * t.m41) + - t.m13 * (t.m31 * t.m42 - t.m32 * t.m41) - ) - - result.m43 = -invDet * ( - t.m11 * (t.m22 * t.m43 - t.m23 * t.m42) - - t.m12 * (t.m21 * t.m43 - t.m23 * t.m41) + - t.m13 * (t.m21 * t.m42 - t.m22 * t.m41) - ) - - result.m44 = invDet * ( - t.m11 * (t.m22 * t.m33 - t.m23 * t.m32) - - t.m12 * (t.m21 * t.m33 - t.m23 * t.m31) + - t.m13 * (t.m21 * t.m32 - t.m22 * t.m31) - ) - - return result -} - -#endif diff --git a/Sources/CoreGraphicsShims/CGAffineTransform.swift b/Sources/CoreGraphicsShims/CGAffineTransform.swift deleted file mode 100644 index 561ccace7..000000000 --- a/Sources/CoreGraphicsShims/CGAffineTransform.swift +++ /dev/null @@ -1,136 +0,0 @@ -// -// CGAffineTransform.swift -// CoreGraphicsShims - -#if !canImport(CoreGraphics) -public import Foundation - -public struct CGAffineTransform: Equatable { - public init() { - a = .zero - b = .zero - c = .zero - d = .zero - tx = .zero - ty = .zero - } - - public init(a: Double, b: Double, c: Double, d: Double, tx: Double, ty: Double) { - self.a = a - self.b = b - self.c = c - self.d = d - self.tx = tx - self.ty = ty - } - - public var a: Double - public var b: Double - public var c: Double - public var d: Double - public var tx: Double - public var ty: Double - - public static let identity = CGAffineTransform(a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0) -} - -extension CGAffineTransform { - public init(translationX tx: CGFloat, y ty: CGFloat) { - self.init(a: 1, b: 0, c: 0, d: 1, tx: Double(tx), ty: Double(ty)) - } - - public init(scaleX sx: CGFloat, y sy: CGFloat) { - self.init(a: Double(sx), b: 0, c: 0, d: Double(sy), tx: 0, ty: 0) - } - - public init(rotationAngle angle: CGFloat) { - let radians = Double(angle) - self.init(a: cos(radians), b: sin(radians), c: -sin(radians), d: cos(radians), tx: 0, ty: 0) - } - - public var isIdentity: Bool { - return self == CGAffineTransform.identity - } - - public func translatedBy(x tx: CGFloat, y ty: CGFloat) -> CGAffineTransform { - let t = CGAffineTransform(a: 1, b: 0, c: 0, d: 1, tx: Double(tx), ty: Double(ty)) - return concatenating(t) - } - - public func scaledBy(x sx: CGFloat, y sy: CGFloat) -> CGAffineTransform { - let s = CGAffineTransform(a: Double(sx), b: 0, c: 0, d: Double(sy), tx: 0, ty: 0) - return concatenating(s) - } - - public func rotated(by angle: CGFloat) -> CGAffineTransform { - return concatenating(CGAffineTransform(rotationAngle: angle)) - } - - public func inverted() -> CGAffineTransform { - let det = a * d - b * c - if abs(det) < 1e-12 { - return self - } - let inv = 1.0 / det - let ra = d * inv - let rb = -b * inv - let rc = -c * inv - let rd = a * inv - let rtx = -(tx * ra + ty * rc) - let rty = -(tx * rb + ty * rd) - return CGAffineTransform(a: ra, b: rb, c: rc, d: rd, tx: rtx, ty: rty) - } - - public func concatenating(_ transform: CGAffineTransform) -> CGAffineTransform { - // Matrix multiplication: self * transform - let a1 = a, b1 = b, c1 = c, d1 = d, tx1 = tx, ty1 = ty - let a2 = transform.a, b2 = transform.b, c2 = transform.c, d2 = transform.d, tx2 = transform.tx, ty2 = transform.ty - - let ra = a1 * a2 + b1 * c2 - let rb = a1 * b2 + b1 * d2 - let rc = c1 * a2 + d1 * c2 - let rd = c1 * b2 + d1 * d2 - let rtx = tx1 * a2 + ty1 * c2 + tx2 - let rty = tx1 * b2 + ty1 * d2 + ty2 - - return CGAffineTransform(a: ra, b: rb, c: rc, d: rd, tx: rtx, ty: rty) - } -} - -extension CGPoint { - public func applying(_ t: CGAffineTransform) -> CGPoint { - CGPoint( - x: t.a * x + t.c * y + t.tx, - y: t.b * x + t.d * y + t.ty - ) - } -} - -extension CGSize { - public func applying(_ t: CGAffineTransform) -> CGSize { - let rect = CGRect(origin: .zero, size: self).applying(t) - return rect.size - } -} - -extension CGRect { - public func applying(_ t: CGAffineTransform) -> CGRect { - // Transform all four corners and compute bounding rect - let p1 = CGPoint(x: minX, y: minY).applying(t) - let p2 = CGPoint(x: maxX, y: minY).applying(t) - let p3 = CGPoint(x: minX, y: maxY).applying(t) - let p4 = CGPoint(x: maxX, y: maxY).applying(t) - - let xs = [p1.x, p2.x, p3.x, p4.x] - let ys = [p1.y, p2.y, p3.y, p4.y] - - let minX = xs.min() ?? 0 - let maxX = xs.max() ?? 0 - let minY = ys.min() ?? 0 - let maxY = ys.max() ?? 0 - - return CGRect(x: minX, y: minY, width: maxX - minX, height: maxY - minY) - } -} - -#endif diff --git a/Sources/CoreGraphicsShims/CGLine.swift b/Sources/CoreGraphicsShims/CGLine.swift deleted file mode 100644 index d792f90d5..000000000 --- a/Sources/CoreGraphicsShims/CGLine.swift +++ /dev/null @@ -1,21 +0,0 @@ -// -// CGLine.swift -// CoreGraphicsShims - -#if !canImport(CoreGraphics) - -/// Line join styles -public enum CGLineJoin: Int32, @unchecked Sendable { - case miter = 0 - case round = 1 - case bevel = 2 -} - -/// Line cap styles -public enum CGLineCap : Int32, @unchecked Sendable { - case butt = 0 - case round = 1 - case square = 2 -} - -#endif diff --git a/Sources/CoreGraphicsShims/CGPath.swift b/Sources/CoreGraphicsShims/CGPath.swift deleted file mode 100644 index 1cda5e8ba..000000000 --- a/Sources/CoreGraphicsShims/CGPath.swift +++ /dev/null @@ -1,230 +0,0 @@ -// -// CGPath.swift -// CoreGraphicsShims -// -// License: MIT -// Modified from https://github.com/PureSwift/Silica/blob/22c72ff508c40ae5e673c16ad39f39235f6ddd01/Sources/Silica/CGPath.swift - -#if !canImport(CoreGraphics) - -public import Foundation - -/// A graphics path is a mathematical description of a series of shapes or lines. -public struct CGPath { - - public typealias Element = PathElement - - public var elements: [Element] - - public init(elements: [Element] = []) { - - self.elements = elements - } -} - -// MARK: - Supporting Types - -/// A path element. -public enum PathElement { - - /// The path element that starts a new subpath. The element holds a single point for the destination. - case moveToPoint(CGPoint) - - /// The path element that adds a line from the current point to a new point. - /// The element holds a single point for the destination. - case addLineToPoint(CGPoint) - - /// The path element that adds a quadratic curve from the current point to the specified point. - /// The element holds a control point and a destination point. - case addQuadCurveToPoint(CGPoint, CGPoint) - - /// The path element that adds a cubic curve from the current point to the specified point. - /// The element holds two control points and a destination point. - case addCurveToPoint(CGPoint, CGPoint, CGPoint) - - /// The path element that closes and completes a subpath. The element does not contain any points. - case closeSubpath -} - -// MARK: - Constructing a Path - -public extension CGPath { - - mutating func addRect(_ rect: CGRect) { - - let newElements: [Element] = [.moveToPoint(CGPoint(x: rect.minX, y: rect.minY)), - .addLineToPoint(CGPoint(x: rect.maxX, y: rect.minY)), - .addLineToPoint(CGPoint(x: rect.maxX, y: rect.maxY)), - .addLineToPoint(CGPoint(x: rect.minX, y: rect.maxY)), - .closeSubpath] - - elements.append(contentsOf: newElements) - } - - mutating func addEllipse(in rect: CGRect) { - - var p = CGPoint() - var p1 = CGPoint() - var p2 = CGPoint() - - let hdiff = rect.width / 2 * KAPPA - let vdiff = rect.height / 2 * KAPPA - - p = CGPoint(x: rect.origin.x + rect.width / 2, y: rect.origin.y + rect.height) - elements.append(.moveToPoint(p)) - - p = CGPoint(x: rect.origin.x, y: rect.origin.y + rect.height / 2) - p1 = CGPoint(x: rect.origin.x + rect.width / 2 - hdiff, y: rect.origin.y + rect.height) - p2 = CGPoint(x: rect.origin.x, y: rect.origin.y + rect.height / 2 + vdiff) - elements.append(.addCurveToPoint(p1, p2, p)) - - p = CGPoint(x: rect.origin.x + rect.size.width / 2, y: rect.origin.y) - p1 = CGPoint(x: rect.origin.x, y: rect.origin.y + rect.size.height / 2 - vdiff) - p2 = CGPoint(x: rect.origin.x + rect.size.width / 2 - hdiff, y: rect.origin.y) - elements.append(.addCurveToPoint(p1, p2, p)) - - p = CGPoint(x: rect.origin.x + rect.size.width, y: rect.origin.y + rect.size.height / 2) - p1 = CGPoint(x: rect.origin.x + rect.size.width / 2 + hdiff, y: rect.origin.y) - p2 = CGPoint(x: rect.origin.x + rect.size.width, y: rect.origin.y + rect.size.height / 2 - vdiff) - elements.append(.addCurveToPoint(p1, p2, p)) - - p = CGPoint(x: rect.origin.x + rect.size.width / 2, y: rect.origin.y + rect.size.height) - p1 = CGPoint(x: rect.origin.x + rect.size.width, y: rect.origin.y + rect.size.height / 2 + vdiff) - p2 = CGPoint(x: rect.origin.x + rect.size.width / 2 + hdiff, y: rect.origin.y + rect.size.height) - elements.append(.addCurveToPoint(p1, p2, p)) - } - - mutating func move(to point: CGPoint) { - - elements.append(.moveToPoint(point)) - } - - mutating func addLine(to point: CGPoint) { - - elements.append(.addLineToPoint(point)) - } - - mutating func addCurve(to endPoint: CGPoint, control1: CGPoint, control2: CGPoint) { - - elements.append(.addCurveToPoint(control1, control2, endPoint)) - } - - mutating func addQuadCurve(to endPoint: CGPoint, control: CGPoint) { - - elements.append(.addQuadCurveToPoint(control, endPoint)) - } - - mutating func closeSubpath() { - - elements.append(.closeSubpath) - } -} - -// This magic number is 4 *(sqrt(2) -1)/3 -private let KAPPA: CGFloat = 0.5522847498 - -// MARK: - CoreGraphics API - -public struct CGPathElement { - - public var type: CGPathElementType - - public var points: (CGPoint, CGPoint, CGPoint) - - public init(type: CGPathElementType, points: (CGPoint, CGPoint, CGPoint)) { - - self.type = type - self.points = points - } -} - -/// Rules for determining which regions are interior to a path. -/// -/// When filling a path, regions that a fill rule defines as interior to the path are painted. -/// When clipping with a path, regions interior to the path remain visible after clipping. -public enum CGPathFillRule: Int { - - /// A rule that considers a region to be interior to a path based on the number of times it is enclosed by path elements. - case evenOdd - - /// A rule that considers a region to be interior to a path if the winding number for that region is nonzero. - case winding -} - -/// The type of element found in a path. -public enum CGPathElementType { - - /// The path element that starts a new subpath. The element holds a single point for the destination. - case moveToPoint - - /// The path element that adds a line from the current point to a new point. - /// The element holds a single point for the destination. - case addLineToPoint - - /// The path element that adds a quadratic curve from the current point to the specified point. - /// The element holds a control point and a destination point. - case addQuadCurveToPoint - - /// The path element that adds a cubic curve from the current point to the specified point. - /// The element holds two control points and a destination point. - case addCurveToPoint - - /// The path element that closes and completes a subpath. The element does not contain any points. - case closeSubpath -} - -// MARK: - Silica Conversion - -public extension CGPathElement { - - init(_ element: PathElement) { - - switch element { - - case let .moveToPoint(point): - - self.type = .moveToPoint - self.points = (point, CGPoint(), CGPoint()) - - case let .addLineToPoint(point): - - self.type = .addLineToPoint - self.points = (point, CGPoint(), CGPoint()) - - case let .addQuadCurveToPoint(control, destination): - - self.type = .addQuadCurveToPoint - self.points = (control, destination, CGPoint()) - - case let .addCurveToPoint(control1, control2, destination): - - self.type = .addCurveToPoint - self.points = (control1, control2, destination) - - case .closeSubpath: - - self.type = .closeSubpath - self.points = (CGPoint(), CGPoint(), CGPoint()) - } - } -} - -public extension PathElement { - - init(_ element: CGPathElement) { - - switch element.type { - - case .moveToPoint: self = .moveToPoint(element.points.0) - - case .addLineToPoint: self = .addLineToPoint(element.points.0) - - case .addQuadCurveToPoint: self = .addQuadCurveToPoint(element.points.0, element.points.1) - - case .addCurveToPoint: self = .addCurveToPoint(element.points.0, element.points.1, element.points.2) - - case .closeSubpath: self = .closeSubpath - } - } -} -#endif diff --git a/Sources/CoreGraphicsShims/Export.swift b/Sources/CoreGraphicsShims/Export.swift deleted file mode 100644 index f597eb30a..000000000 --- a/Sources/CoreGraphicsShims/Export.swift +++ /dev/null @@ -1,15 +0,0 @@ -// -// Export.swift -// CoreGraphicsShims - -#if canImport(CoreGraphics) -@_exported import CoreGraphics -#else -@_exported import Foundation -#endif - -#if canImport(QuartzCore) -@_exported import QuartzCore -#endif - -@_exported import CoreFoundation diff --git a/Sources/OpenSwiftUICore/Layout/Geometry/ProjectionTransform.swift b/Sources/OpenSwiftUICore/Layout/Geometry/ProjectionTransform.swift index 59c55c7ad..90a2dc1c2 100644 --- a/Sources/OpenSwiftUICore/Layout/Geometry/ProjectionTransform.swift +++ b/Sources/OpenSwiftUICore/Layout/Geometry/ProjectionTransform.swift @@ -6,7 +6,7 @@ // Status: Complete public import Foundation -public import CoreGraphicsShims +public import OpenQuartzCoreShims @frozen public struct ProjectionTransform { diff --git a/Sources/OpenSwiftUICore/Layout/View/ViewTransform.swift b/Sources/OpenSwiftUICore/Layout/View/ViewTransform.swift index a78f1f538..4b8942b10 100644 --- a/Sources/OpenSwiftUICore/Layout/View/ViewTransform.swift +++ b/Sources/OpenSwiftUICore/Layout/View/ViewTransform.swift @@ -9,7 +9,7 @@ package import Foundation #if !canImport(Darwin) -package import CoreGraphicsShims +package import OpenCoreGraphicsShims #endif @_spi(ForOpenSwiftUIOnly) diff --git a/Sources/OpenSwiftUICore/Render/DisplayList/DisplayList.swift b/Sources/OpenSwiftUICore/Render/DisplayList/DisplayList.swift index 41e61c3eb..5bf294c55 100644 --- a/Sources/OpenSwiftUICore/Render/DisplayList/DisplayList.swift +++ b/Sources/OpenSwiftUICore/Render/DisplayList/DisplayList.swift @@ -6,7 +6,7 @@ // Status: WIP // ID: F37E3733E490AA5E3BDC045E3D34D9F8 (SwiftUICore) -package import CoreGraphicsShims +package import OpenCoreGraphicsShims package import Foundation package import OpenGraphShims diff --git a/Sources/OpenSwiftUICore/Render/GeometryEffect/OffsetEffect.swift b/Sources/OpenSwiftUICore/Render/GeometryEffect/OffsetEffect.swift index 4e4276547..fab52565b 100644 --- a/Sources/OpenSwiftUICore/Render/GeometryEffect/OffsetEffect.swift +++ b/Sources/OpenSwiftUICore/Render/GeometryEffect/OffsetEffect.swift @@ -5,7 +5,7 @@ // Status: Complete // ID: 72FB21917F353796516DFC9915156779 (SwiftUICore) -public import CoreGraphicsShims +public import OpenCoreGraphicsShims import OpenGraphShims /// Allows you to redefine origin of the child within its coordinate diff --git a/Sources/OpenSwiftUICore/Render/GeometryEffect/Rotation3DEffect.swift b/Sources/OpenSwiftUICore/Render/GeometryEffect/Rotation3DEffect.swift index 7c5002172..6109401da 100644 --- a/Sources/OpenSwiftUICore/Render/GeometryEffect/Rotation3DEffect.swift +++ b/Sources/OpenSwiftUICore/Render/GeometryEffect/Rotation3DEffect.swift @@ -5,7 +5,7 @@ // Audited for 6.5.4 // Status: Complete -public import CoreGraphicsShims +public import OpenQuartzCoreShims // MARK: - RotationEffect diff --git a/Sources/OpenSwiftUICore/Render/GeometryEffect/RotationEffect.swift b/Sources/OpenSwiftUICore/Render/GeometryEffect/RotationEffect.swift index 4fd397569..973d2d63f 100644 --- a/Sources/OpenSwiftUICore/Render/GeometryEffect/RotationEffect.swift +++ b/Sources/OpenSwiftUICore/Render/GeometryEffect/RotationEffect.swift @@ -5,7 +5,7 @@ // Audited for 6.5.4 // Status: Complete -public import CoreGraphicsShims +public import OpenCoreGraphicsShims // MARK: - RotationEffect diff --git a/Sources/OpenSwiftUICore/Shape/Path.swift b/Sources/OpenSwiftUICore/Shape/Path.swift index f819bb837..7ac487fc3 100644 --- a/Sources/OpenSwiftUICore/Shape/Path.swift +++ b/Sources/OpenSwiftUICore/Shape/Path.swift @@ -10,7 +10,7 @@ public import Foundation package import OpenBoxShims import OpenSwiftUI_SPI -public import CoreGraphicsShims +public import OpenCoreGraphicsShims #if canImport(CoreGraphics) @_silgen_name("__CGPathParseString") diff --git a/Sources/OpenSwiftUICore/Shape/RoundedCorner.swift b/Sources/OpenSwiftUICore/Shape/RoundedCorner.swift index 579130cf1..a57388109 100644 --- a/Sources/OpenSwiftUICore/Shape/RoundedCorner.swift +++ b/Sources/OpenSwiftUICore/Shape/RoundedCorner.swift @@ -6,7 +6,7 @@ // Status: WIP public import Foundation -package import CoreGraphicsShims +package import OpenCoreGraphicsShims // MARK: - RoundedCornerStyle diff --git a/Sources/OpenSwiftUICore/Shape/StrokeStyle.swift b/Sources/OpenSwiftUICore/Shape/StrokeStyle.swift index 2c11f71cd..51975ef0d 100644 --- a/Sources/OpenSwiftUICore/Shape/StrokeStyle.swift +++ b/Sources/OpenSwiftUICore/Shape/StrokeStyle.swift @@ -6,7 +6,7 @@ // Status: Complete public import Foundation -public import CoreGraphicsShims +public import OpenCoreGraphicsShims /// The characteristics of a stroke that traces a path. @frozen diff --git a/Sources/OpenSwiftUICore/Util/Extension/CGAffineTransform+Extension.swift b/Sources/OpenSwiftUICore/Util/Extension/CGAffineTransform+Extension.swift index 6bb4c21a1..b0ebf8c50 100644 --- a/Sources/OpenSwiftUICore/Util/Extension/CGAffineTransform+Extension.swift +++ b/Sources/OpenSwiftUICore/Util/Extension/CGAffineTransform+Extension.swift @@ -5,7 +5,7 @@ // Audited for iOS 18.0 // Status: Complete -package import CoreGraphicsShims +package import OpenCoreGraphicsShims package import Foundation extension CGAffineTransform { diff --git a/Sources/OpenSwiftUICore/View/ViewDebug.swift b/Sources/OpenSwiftUICore/View/ViewDebug.swift index 726b90648..ded922ecf 100644 --- a/Sources/OpenSwiftUICore/View/ViewDebug.swift +++ b/Sources/OpenSwiftUICore/View/ViewDebug.swift @@ -9,7 +9,7 @@ public import Foundation package import OpenGraphShims -package import CoreGraphicsShims +package import OpenQuartzCoreShims import OpenSwiftUI_SPI /// Namespace for view debug information. diff --git a/Tests/CoreGraphicsShimsTests/CATransform3DTests.swift b/Tests/CoreGraphicsShimsTests/CATransform3DTests.swift deleted file mode 100644 index 76afc6a02..000000000 --- a/Tests/CoreGraphicsShimsTests/CATransform3DTests.swift +++ /dev/null @@ -1,125 +0,0 @@ -// -// CATransform3DTests.swift -// CoreGraphicsShimsTests - -import Testing -import CoreGraphicsShims -import Numerics - -@Suite -struct CATransform3DTests { - - @Test - func identityInvert() { - let identity = CATransform3DIdentity - let inverted = CATransform3DInvert(identity) - - #expect(CATransform3DEqualToTransform(inverted, identity)) - } - - @Test - func translationInvert() { - let translation = CATransform3DMakeTranslation(10, 20, 30) - let inverted = CATransform3DInvert(translation) - let expected = CATransform3DMakeTranslation(-10, -20, -30) - - #expect(CATransform3DEqualToTransform(inverted, expected)) - } - - @Test - func scaleInvert() { - let scale = CATransform3DMakeScale(2, 3, 4) - let inverted = CATransform3DInvert(scale) - let expected = CATransform3DMakeScale(1/2, 1/3, 1/4) - - // Use approximation for floating-point comparison - #expect(inverted.m11.isApproximatelyEqual(to: expected.m11)) - #expect(inverted.m22.isApproximatelyEqual(to: expected.m22)) - #expect(inverted.m33.isApproximatelyEqual(to: expected.m33)) - } - - @Test - func invertMultiplicationProperty() { - // Create a complex transform - let translation = CATransform3DMakeTranslation(10, 20, 30) - let scale = CATransform3DMakeScale(2, 3, 4) - let transform = CATransform3DConcat(translation, scale) - - // Test that T * T^-1 = Identity - let inverted = CATransform3DInvert(transform) - let result = CATransform3DConcat(transform, inverted) - - // Check key elements of result against identity matrix - #expect(result.m11.isApproximatelyEqual(to: 1.0)) - #expect(result.m22.isApproximatelyEqual(to: 1.0)) - #expect(result.m33.isApproximatelyEqual(to: 1.0)) - #expect(result.m44.isApproximatelyEqual(to: 1.0)) - - // Check that off-diagonal elements are approximately zero - #expect(result.m12.isApproximatelyEqual(to: 0.0)) - #expect(result.m13.isApproximatelyEqual(to: 0.0)) - #expect(result.m14.isApproximatelyEqual(to: 0.0)) - #expect(result.m21.isApproximatelyEqual(to: 0.0)) - #expect(result.m23.isApproximatelyEqual(to: 0.0)) - #expect(result.m24.isApproximatelyEqual(to: 0.0)) - #expect(result.m31.isApproximatelyEqual(to: 0.0)) - #expect(result.m32.isApproximatelyEqual(to: 0.0)) - #expect(result.m34.isApproximatelyEqual(to: 0.0)) - #expect(result.m41.isApproximatelyEqual(to: 0.0)) - #expect(result.m42.isApproximatelyEqual(to: 0.0)) - #expect(result.m43.isApproximatelyEqual(to: 0.0)) - } - - @Test - func nonInvertibleMatrix() { - // Create a singular matrix (not invertible) - var singular = CATransform3DIdentity - singular.m11 = 0 - singular.m22 = 0 - - let result = CATransform3DInvert(singular) - - // Should return the same matrix for non-invertible input - #expect(CATransform3DEqualToTransform(result, singular)) - } - - @Test - func rotationZ90_affineMapsPoint() { - let rot = CATransform3DMakeRotation(CGFloat.pi / 2, 0, 0, 1) - let cg = CATransform3DGetAffineTransform(rot) - let p = CGPoint(x: 1, y: 0) - let res = p.applying(cg) - #expect(res.x.isApproximatelyEqual(to: 0.0, absoluteTolerance: 0.001)) - #expect(res.y.isApproximatelyEqual(to: 1.0, absoluteTolerance: 0.001)) - } - - @Test - func rotationAxisZeroIsIdentity() { - let rot = CATransform3DMakeRotation(1.0, 0, 0, 0) - #expect(CATransform3DEqualToTransform(rot, CATransform3DIdentity)) - } - - @Test - func translateOnIdentityEqualsMakeTranslation() { - let res = CATransform3DTranslate(CATransform3DIdentity, 5, 6, 7) - let expected = CATransform3DMakeTranslation(5, 6, 7) - #expect(CATransform3DEqualToTransform(res, expected)) - } - - @Test - func rotateConcatProperty() { - let angle = CGFloat.pi / 3 - let ax: CGFloat = 1.0 - let ay: CGFloat = 0.5 - let az: CGFloat = -0.25 - let t = CATransform3DMakeTranslation(10, 20, 30) - let result = CATransform3DRotate(t, angle, ax, ay, az) - let expected = CATransform3DConcat(CATransform3DMakeRotation(angle, ax, ay, az), t) - #expect(result.m11.isApproximatelyEqual(to: expected.m11)) - #expect(result.m12.isApproximatelyEqual(to: expected.m12)) - #expect(result.m21.isApproximatelyEqual(to: expected.m21)) - #expect(result.m22.isApproximatelyEqual(to: expected.m22)) - #expect(result.m41.isApproximatelyEqual(to: expected.m41)) - #expect(result.m42.isApproximatelyEqual(to: expected.m42)) - } -} diff --git a/Tests/CoreGraphicsShimsTests/CGAffineTransformTests.swift b/Tests/CoreGraphicsShimsTests/CGAffineTransformTests.swift deleted file mode 100644 index 223109bb2..000000000 --- a/Tests/CoreGraphicsShimsTests/CGAffineTransformTests.swift +++ /dev/null @@ -1,91 +0,0 @@ -import Testing -import CoreGraphicsShims -import Numerics - -@Suite -struct CGAffineTransformTests { - - // MARK: - Identity - - @Test - func identityIsIdentity() { - let t = CGAffineTransform.identity - #expect(t.isIdentity) - } - - // MARK: - Translation - - @Test - func translationAppliesToPoint() { - let t = CGAffineTransform(translationX: 10, y: 20) - let p = CGPoint(x: 1, y: 2) - let res = p.applying(t) - #expect(res.x.isApproximatelyEqual(to: 11.0)) - #expect(res.y.isApproximatelyEqual(to: 22.0)) - } - - @Test - func translationInvert() { - let t = CGAffineTransform(translationX: 10, y: 20) - let inv = t.inverted() - #expect(inv.tx.isApproximatelyEqual(to: -10.0)) - #expect(inv.ty.isApproximatelyEqual(to: -20.0)) - } - - // MARK: - Scale - - @Test - func scaleInvert() { - let s = CGAffineTransform(scaleX: 2, y: 4) - let inv = s.inverted() - #expect(inv.a.isApproximatelyEqual(to: 1.0 / 2.0)) - #expect(inv.d.isApproximatelyEqual(to: 1.0 / 4.0)) - } - - // MARK: - Rotation - - @Test - func rotation90MapsPoint() { - let r = CGAffineTransform(rotationAngle: .pi / 2) - #expect(r.a.isApproximatelyEqual(to: 0.0, absoluteTolerance: 0.001)) - #expect(r.b.isApproximatelyEqual(to: 1.0, absoluteTolerance: - 0.001)) - #expect(r.c.isApproximatelyEqual(to: -1.0, absoluteTolerance: 0.001)) - #expect(r.d.isApproximatelyEqual(to: 0.0, absoluteTolerance: 0.001)) - #expect(r.tx.isApproximatelyEqual(to: 0.0, absoluteTolerance: 0.001)) - #expect(r.ty.isApproximatelyEqual(to: 0.0, absoluteTolerance: 0.001)) - - let p = CGPoint(x: 1, y: 0) - let res = p.applying(r) - #expect(res.x.isApproximatelyEqual(to: 0.0, absoluteTolerance: 0.001)) - #expect(res.y.isApproximatelyEqual(to: 1.0, absoluteTolerance: 0.001)) - } - - // MARK: - Concatenation - - @Test - func concatenationAppliesInCorrectOrder() { - let t = CGAffineTransform(translationX: 5, y: 7) - let s = CGAffineTransform(scaleX: 2, y: 3) - let concatenated = s.concatenating(t) - let p = CGPoint(x: 1, y: 1) - let sequential = p.applying(s).applying(t) - let combined = p.applying(concatenated) - #expect(sequential.x.isApproximatelyEqual(to: combined.x)) - #expect(sequential.y.isApproximatelyEqual(to: combined.y)) - } - - // MARK: - Non-invertible - - @Test - func nonInvertibleReturnsSame() { - var singular = CGAffineTransform.identity - singular.a = 0 - singular.d = 0 - let inv = singular.inverted() - #expect(inv.a.isApproximatelyEqual(to: singular.a)) - #expect(inv.d.isApproximatelyEqual(to: singular.d)) - #expect(inv.tx.isApproximatelyEqual(to: singular.tx)) - #expect(inv.ty.isApproximatelyEqual(to: singular.ty)) - } -} diff --git a/Tests/CoreGraphicsShimsTests/README.md b/Tests/CoreGraphicsShimsTests/README.md deleted file mode 100644 index 8126d0753..000000000 --- a/Tests/CoreGraphicsShimsTests/README.md +++ /dev/null @@ -1,7 +0,0 @@ -## OpenCoreGraphicsShimsTests - -Test API of OpenCoreGraphicsShims - -```swift -import OpenCoreGraphicsShims -``` diff --git a/Tests/OpenSwiftUICoreTests/Layout/Geometry/ProjectionTransformTests.swift b/Tests/OpenSwiftUICoreTests/Layout/Geometry/ProjectionTransformTests.swift index 1c351355b..818ed1908 100644 --- a/Tests/OpenSwiftUICoreTests/Layout/Geometry/ProjectionTransformTests.swift +++ b/Tests/OpenSwiftUICoreTests/Layout/Geometry/ProjectionTransformTests.swift @@ -2,9 +2,9 @@ // ProjectionTransformTests.swift // OpenSwiftUICoreTests -import CoreGraphicsShims import Foundation import Numerics +import OpenQuartzCoreShims import OpenSwiftUICore import Testing