Skip to content

Commit

Permalink
[graphics] add CGPath transform
Browse files Browse the repository at this point in the history
  • Loading branch information
honghaoz committed Sep 15, 2024
1 parent 9efd394 commit 53c751b
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 12 deletions.
31 changes: 21 additions & 10 deletions Sources/ChouTiUI/Universal/Graphics/CGPath+Transform.swift
Original file line number Diff line number Diff line change
Expand Up @@ -156,32 +156,43 @@ public extension CGPath {
return resizedPath
}

// MARK: - Transform

/// Creates an new immutable copy of the path transformed by a transformation matrix.
///
/// - Parameters:
/// - transform: The transform to apply to the path.
/// - Returns: A new, immutable transformed path.
func transform(_ transform: CGAffineTransform) -> CGPath {
var transform = transform
guard let transformedPath = copy(using: &transform) else {
ChouTi.assertFailure("Failed to transform the path", metadata: ["path": "\(self)", "transform": "\(transform)"])
return self
}
return transformedPath
}

// MARK: - Translate

/// Translate the path.
/// Creates an new immutable copy of the path translated by a certain offset.
///
/// - Parameters:
/// - point: The point represents the offset to translate the path by.
/// - Returns: A translated path.
/// - Returns: A new, immutable translated path.
@inlinable
@inline(__always)
func translate(_ point: CGPoint) -> CGPath {
translate(dx: point.x, dy: point.y)
}

/// Translate the path by a certain offset.
/// Creates an new immutable copy of the path translated by a certain offset.
///
/// - Parameters:
/// - dx: The x-coordinate offset.
/// - dy: The y-coordinate offset.
/// - Returns: A translated path.
/// - Returns: A new, immutable translated path.
func translate(dx: CGFloat = 0, dy: CGFloat = 0) -> CGPath {
var transform = CGAffineTransform.translation(x: dx, y: dy)
guard let translatedPath = copy(using: &transform) else {
ChouTi.assertFailure("Fail to translate the path", metadata: ["path": "\(self)", "dx": "\(dx)", "dy": "\(dy)"])
return self
}
return translatedPath
transform(CGAffineTransform.translation(x: dx, y: dy))
}
}

Expand Down
25 changes: 23 additions & 2 deletions Tests/ChouTiUITests/Universal/Graphics/CGPath+TransformTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,27 @@ class CGPath_TransformTests: XCTestCase {
Assert.resetTestAssertionFailureHandler()
}

// MARK: - Transform

func test_transform_identity() {
let rect = CGRect(x: 10, y: 20, width: 100, height: 50)
let path = CGPath(rect: rect, transform: nil)

let transformedPath = path.transform(CGAffineTransform.identity)
expect(transformedPath) == path
}

func test_transform_scale() {
let rect = CGRect(x: 10, y: 20, width: 100, height: 50)
let path = CGPath(ellipseIn: rect, transform: nil)

var scale = CGAffineTransform.scale(2, 2)
let transformedPath = path.transform(scale)
expect(transformedPath) == CGPath(ellipseIn: rect, transform: &scale)
print(transformedPath.boundingBoxOfPath)
expect(transformedPath) == CGPath(ellipseIn: CGRect(x: 20, y: 40, width: 200, height: 100), transform: nil)
}

// MARK: - Translate

func test_translate_point() {
Expand Down Expand Up @@ -318,8 +339,8 @@ class CGPath_TransformTests: XCTestCase {
let dy: CGFloat = .nan

Assert.setTestAssertionFailureHandler { message, metadata, file, line, column in
expect(message) == "Fail to translate the path"
expect(metadata) == ["path": "\(path)", "dx": "\(dx)", "dy": "\(dy)"]
expect(message) == "Failed to transform the path"
expect(metadata) == ["path": "\(path)", "transform": "\(CGAffineTransform.translation(dx, dy))"]
}

let translatedPath = path.translate(dx: dx, dy: dy)
Expand Down

0 comments on commit 53c751b

Please sign in to comment.