Skip to content

Commit

Permalink
[graphics] add transform methods
Browse files Browse the repository at this point in the history
  • Loading branch information
honghaoz committed Sep 15, 2024
1 parent 53c751b commit c8844e8
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 1 deletion.
50 changes: 50 additions & 0 deletions Sources/ChouTiUI/Universal/BezierPath/BezierPath+Extensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//
// BezierPath+Extensions.swift
// ChouTiUI
//
// Created by Honghao Zhang on 10/17/21.
// Copyright © 2020 Honghao Zhang.
//
// MIT License
//
// Copyright (c) 2020 Honghao Zhang (github.com/honghaoz)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//

import CoreGraphics
#if canImport(AppKit)
import AppKit
#endif

#if canImport(UIKit)
import UIKit
#endif

import ChouTi

public extension BezierPath {

/// Applies a series of affine transforms to the path.
///
/// - Parameter affineTransformBuilder: A builder that constructs an affine transform. The transforms will be concatenated in the order they are provided.
func apply(@CGAffineTransformBuilder affineTransformBuilder: () -> [CGAffineTransform]) {
apply(affineTransformBuilder().concatenated())
}
}
9 changes: 9 additions & 0 deletions Sources/ChouTiUI/Universal/Graphics/CGPath+Transform.swift
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,15 @@ public extension CGPath {
return transformedPath
}

/// Creates an new immutable copy of the path transformed by a transformation matrix.
///
/// - Parameters:
/// - affineTransformBuilder: A builder that constructs an affine transform. The transforms will be concatenated in the order they are provided.
/// - Returns: A new, immutable transformed path.
func transform(@CGAffineTransformBuilder affineTransformBuilder: () -> [CGAffineTransform]) -> CGPath {
transform(affineTransformBuilder().concatenated())
}

// MARK: - Translate

/// Creates an new immutable copy of the path translated by a certain offset.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
//
// BezierPath+ExtensionsTests.swift
// ChouTiUI
//
// Created by Honghao Zhang on 10/17/21.
// Copyright © 2020 Honghao Zhang.
//
// MIT License
//
// Copyright (c) 2020 Honghao Zhang (github.com/honghaoz)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//

import CoreGraphics
#if canImport(AppKit)
import AppKit
#endif

#if canImport(UIKit)
import UIKit
#endif

import ChouTiTest

import ChouTi
import ChouTiUI

class BezierPath_ExtensionsTests: XCTestCase {

func test_apply() {
let path = BezierPath()
path.move(to: CGPoint(x: 10, y: 20))
path.addLine(to: CGPoint(x: 30, y: 20))
path.addLine(to: CGPoint(x: 30, y: 40))
path.close()

path.apply {
CGAffineTransform.translation(-10, -20)
CGAffineTransform.scale(2, 2)
CGAffineTransform.translation(20, 40)
}

let memoryAddressString = memoryAddressString(path)
#if canImport(AppKit)
expect(String(describing: path)) ==
"""
Path <\(memoryAddressString)>
Bounds: {{20, 40}, {40, 40}}
Control point bounds: {{20, 40}, {40, 40}}
20.000000 40.000000 moveto
60.000000 40.000000 lineto
60.000000 80.000000 lineto
closepath
20.000000 40.000000 moveto
"""
#endif

#if canImport(UIKit)
expect(String(describing: path)) ==
"""
<UIBezierPath: \(memoryAddressString); <MoveTo {20, 40}>,
<LineTo {60, 40}>,
<LineTo {60, 80}>,
<Close>
"""
#endif
}
}
13 changes: 13 additions & 0 deletions Tests/ChouTiUITests/Universal/Graphics/CGPath+TransformTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,19 @@ class CGPath_TransformTests: XCTestCase {
expect(transformedPath) == CGPath(ellipseIn: CGRect(x: 20, y: 40, width: 200, height: 100), transform: nil)
}

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

let transformedPath = path.transform {
CGAffineTransform.translation(-10, -20)
CGAffineTransform.scale(2, 2)
CGAffineTransform.translation(20, 40)
CGAffineTransform.scale(2, 2)
}
expect(transformedPath) == CGPath(rect: CGRect(x: 40, y: 80, width: 400, height: 200), transform: nil)
}

// MARK: - Translate

func test_translate_point() {
Expand Down

0 comments on commit c8844e8

Please sign in to comment.