Initial commit
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
// ScreenGeometry.swift
|
||||
// GreenshotMac
|
||||
//
|
||||
// Conversions between AppKit's bottom-left global space and CoreGraphics'
|
||||
// top-left global space, plus display lookups.
|
||||
|
||||
import AppKit
|
||||
|
||||
enum ScreenGeometry {
|
||||
|
||||
/// Height of the primary display, the anchor for both coordinate systems.
|
||||
static var primaryHeight: CGFloat {
|
||||
NSScreen.screens.first(where: { $0.frame.origin == .zero })?.frame.height
|
||||
?? NSScreen.screens.first?.frame.height
|
||||
?? 0
|
||||
}
|
||||
|
||||
/// AppKit global rect (bottom-left origin) to CoreGraphics global rect (top-left origin).
|
||||
static func cgRect(fromAppKit rect: CGRect) -> CGRect {
|
||||
CGRect(x: rect.origin.x,
|
||||
y: primaryHeight - rect.origin.y - rect.height,
|
||||
width: rect.width,
|
||||
height: rect.height)
|
||||
}
|
||||
|
||||
/// CoreGraphics global rect (top-left origin) to AppKit global rect (bottom-left origin).
|
||||
static func appKitRect(fromCG rect: CGRect) -> CGRect {
|
||||
CGRect(x: rect.origin.x,
|
||||
y: primaryHeight - rect.origin.y - rect.height,
|
||||
width: rect.width,
|
||||
height: rect.height)
|
||||
}
|
||||
|
||||
static func displayID(for screen: NSScreen) -> CGDirectDisplayID? {
|
||||
screen.deviceDescription[NSDeviceDescriptionKey("NSScreenNumber")] as? CGDirectDisplayID
|
||||
}
|
||||
|
||||
static func screen(for displayID: CGDirectDisplayID) -> NSScreen? {
|
||||
NSScreen.screens.first { ScreenGeometry.displayID(for: $0) == displayID }
|
||||
}
|
||||
|
||||
static func screen(containing point: CGPoint) -> NSScreen? {
|
||||
NSScreen.screens.first { $0.frame.contains(point) } ?? NSScreen.main
|
||||
}
|
||||
|
||||
/// Crops a CGImage using a rect expressed in points relative to the image's top-left corner.
|
||||
static func crop(_ image: CGImage, toPointRect rect: CGRect, scale: CGFloat) -> CGImage? {
|
||||
let pixelRect = CGRect(x: (rect.origin.x * scale).rounded(.down),
|
||||
y: (rect.origin.y * scale).rounded(.down),
|
||||
width: (rect.width * scale).rounded(),
|
||||
height: (rect.height * scale).rounded())
|
||||
.intersection(CGRect(x: 0, y: 0, width: CGFloat(image.width), height: CGFloat(image.height)))
|
||||
guard pixelRect.width >= 1, pixelRect.height >= 1 else { return nil }
|
||||
return image.cropping(to: pixelRect)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user