added iOS source code
[wl-app.git] / iOS / Pods / Kingfisher / Sources / ImageModifier.swift
1 //
2 //  ImageModifier.swift
3 //  Kingfisher
4 //
5 //  Created by Ethan Gill on 2017/11/28.
6 //
7 //  Copyright (c) 2018 Ethan Gill <ethan.gill@me.com>
8 //
9 //  Permission is hereby granted, free of charge, to any person obtaining a copy
10 //  of this software and associated documentation files (the "Software"), to deal
11 //  in the Software without restriction, including without limitation the rights
12 //  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 //  copies of the Software, and to permit persons to whom the Software is
14 //  furnished to do so, subject to the following conditions:
15 //
16 //  The above copyright notice and this permission notice shall be included in
17 //  all copies or substantial portions of the Software.
18 //
19 //  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 //  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 //  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 //  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 //  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 //  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 //  THE SOFTWARE.
26
27 import Foundation
28
29 /// An `ImageModifier` can be used to change properties on an Image in between
30 /// cache serialization and use of the image.
31 public protocol ImageModifier {
32     /// Modify an input `Image`.
33     ///
34     /// - parameter image:   Image which will be modified by `self`
35     ///
36     /// - returns: The modified image.
37     ///
38     /// - Note: The return value will be unmodified if modifying is not possible on
39     ///         the current platform.
40     /// - Note: Most modifiers support UIImage or NSImage, but not CGImage.
41     func modify(_ image: Image) -> Image
42 }
43
44 extension ImageModifier {
45     func modify(_ image: Image?) -> Image? {
46         guard let image = image else {
47             return nil
48         }
49         return modify(image)
50     }
51 }
52
53 typealias ModifierImp = ((Image) -> Image)
54
55 fileprivate struct GeneralModifier: ImageModifier {
56     let identifier: String
57     let m: ModifierImp
58     func modify(_ image: Image) -> Image {
59         return m(image)
60     }
61 }
62
63 /// The default modifier.
64 /// Does nothing and returns the image it was given
65 public struct DefaultImageModifier: ImageModifier {
66
67     /// A default `DefaultImageModifier` which can be used everywhere.
68     public static let `default` = DefaultImageModifier()
69
70     /// Initialize a `DefaultImageModifier`
71     private init() {}
72
73     /// Modify an input `Image`.
74     ///
75     /// - parameter image:   Image which will be modified by `self`
76     ///
77     /// - returns: The modified image.
78     ///
79     /// - Note: See documentation of `ImageModifier` protocol for more.
80     public func modify(_ image: Image) -> Image {
81         return image
82     }
83 }
84
85 /// A custom modifier.
86 /// Can be initialized with a block to modify images in a custom way
87 public struct AnyImageModifier: ImageModifier {
88
89     /// A block which modifies images, or returns the original image
90     /// if modification cannot be performed.
91     let block: (Image) -> Image
92
93     /// Initialize an `AnyImageModifier`
94     public init(modify: @escaping (Image) -> Image) {
95         block = modify
96     }
97
98     /// Modifies an input `Image` using this `AnyImageModifier`'s `block`.
99     ///
100     /// - parameter image:   Image which will be modified by `self`
101     ///
102     /// - returns: The modified image.
103     ///
104     /// - Note: See documentation of `ImageModifier` protocol for more.
105     public func modify(_ image: Image) -> Image {
106         return block(image)
107     }
108 }
109
110 #if os(iOS) || os(tvOS) || os(watchOS)
111 import UIKit
112
113 /// Modifier for setting the rendering mode of images.
114 /// Only UI-based images are supported; if a non-UI image is passed in, the
115 /// modifier will do nothing.
116 public struct RenderingModeImageModifier: ImageModifier {
117
118     /// The rendering mode to apply to the image.
119     public let renderingMode: UIImageRenderingMode
120
121     /// Initialize a `RenderingModeImageModifier`
122     ///
123     /// - parameter renderingMode: The rendering mode to apply to the image.
124     ///                            Default is .automatic
125     public init(renderingMode: UIImageRenderingMode = .automatic) {
126         self.renderingMode = renderingMode
127     }
128
129     /// Modify an input `Image`.
130     ///
131     /// - parameter image:   Image which will be modified by `self`
132     ///
133     /// - returns: The modified image.
134     ///
135     /// - Note: See documentation of `ImageModifier` protocol for more.
136     public func modify(_ image: Image) -> Image {
137         return image.withRenderingMode(renderingMode)
138     }
139 }
140
141 /// Modifier for setting the `flipsForRightToLeftLayoutDirection` property of images.
142 /// Only UI-based images are supported; if a non-UI image is passed in, the
143 /// modifier will do nothing.
144 public struct FlipsForRightToLeftLayoutDirectionImageModifier: ImageModifier {
145     /// Initialize a `FlipsForRightToLeftLayoutDirectionImageModifier`
146     ///
147     /// - Note: On versions of iOS lower than 9.0, the image will be returned
148     ///         unmodified.
149     public init() {}
150
151     /// Modify an input `Image`.
152     ///
153     /// - parameter image:   Image which will be modified by `self`
154     ///
155     /// - returns: The modified image.
156     ///
157     /// - Note: See documentation of `ImageModifier` protocol for more.
158     public func modify(_ image: Image) -> Image {
159         if #available(iOS 9.0, *) {
160             return image.imageFlippedForRightToLeftLayoutDirection()
161         } else {
162             return image
163         }
164     }
165 }
166
167 /// Modifier for setting the `alignmentRectInsets` property of images.
168 /// Only UI-based images are supported; if a non-UI image is passed in, the
169 /// modifier will do nothing.
170 public struct AlignmentRectInsetsImageModifier: ImageModifier {
171
172     /// The alignment insets to apply to the image
173     public let alignmentInsets: UIEdgeInsets
174
175     /// Initialize a `AlignmentRectInsetsImageModifier`
176     public init(alignmentInsets: UIEdgeInsets) {
177         self.alignmentInsets = alignmentInsets
178     }
179
180     /// Modify an input `Image`.
181     ///
182     /// - parameter image:   Image which will be modified by `self`
183     ///
184     /// - returns: The modified image.
185     ///
186     /// - Note: See documentation of `ImageModifier` protocol for more.
187     public func modify(_ image: Image) -> Image {
188         return image.withAlignmentRectInsets(alignmentInsets)
189     }
190 }
191 #endif