GraphicsContext.swift 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. //
  2. // GraphicsContext.swift
  3. // Kingfisher
  4. //
  5. // Created by taras on 19/04/2021.
  6. //
  7. // Copyright (c) 2021 Wei Wang <onevcat@gmail.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. #if os(macOS) || os(watchOS)
  27. #if canImport(AppKit) && !targetEnvironment(macCatalyst)
  28. import AppKit
  29. #endif
  30. #if canImport(UIKit)
  31. import UIKit
  32. #endif
  33. enum GraphicsContext {
  34. static func begin(size: CGSize, scale: CGFloat) {
  35. #if os(macOS)
  36. NSGraphicsContext.saveGraphicsState()
  37. #elseif os(watchOS)
  38. UIGraphicsBeginImageContextWithOptions(size, false, scale)
  39. #else
  40. assertionFailure("This method is deprecated on the current platform and should not be used.")
  41. #endif
  42. }
  43. static func current(size: CGSize, scale: CGFloat, inverting: Bool, cgImage: CGImage?) -> CGContext? {
  44. #if os(macOS)
  45. guard let rep = NSBitmapImageRep(
  46. bitmapDataPlanes: nil,
  47. pixelsWide: Int(size.width),
  48. pixelsHigh: Int(size.height),
  49. bitsPerSample: cgImage?.bitsPerComponent ?? 8,
  50. samplesPerPixel: 4,
  51. hasAlpha: true,
  52. isPlanar: false,
  53. colorSpaceName: .calibratedRGB,
  54. bytesPerRow: 0,
  55. bitsPerPixel: 0) else
  56. {
  57. assertionFailure("[Kingfisher] Image representation cannot be created.")
  58. return nil
  59. }
  60. rep.size = size
  61. guard let context = NSGraphicsContext(bitmapImageRep: rep) else {
  62. assertionFailure("[Kingfisher] Image context cannot be created.")
  63. return nil
  64. }
  65. NSGraphicsContext.current = context
  66. return context.cgContext
  67. #elseif os(watchOS)
  68. guard let context = UIGraphicsGetCurrentContext() else {
  69. return nil
  70. }
  71. if inverting { // If drawing a CGImage, we need to make context flipped.
  72. context.scaleBy(x: 1.0, y: -1.0)
  73. context.translateBy(x: 0, y: -size.height)
  74. }
  75. return context
  76. #else
  77. assertionFailure("This method is deprecated on the current platform and should not be used.")
  78. return nil
  79. #endif
  80. }
  81. static func end() {
  82. #if os(macOS)
  83. NSGraphicsContext.restoreGraphicsState()
  84. #elseif os(watchOS)
  85. UIGraphicsEndImageContext()
  86. #else
  87. assertionFailure("This method is deprecated on the current platform and should not be used.")
  88. #endif
  89. }
  90. }
  91. #endif