Splitting up some of the longer parts of the drawing function
This commit is contained in:
parent
78e9be6e1d
commit
7e1ddaf2bf
1 changed files with 109 additions and 121 deletions
|
@ -142,6 +142,107 @@ class Document: NSDocument {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getChunkRect(_ chunk: SilicaChunk) -> NSRect {
|
||||||
|
let x = chunk.x
|
||||||
|
var y = chunk.y
|
||||||
|
|
||||||
|
let (width, height) = getTileSize(x: x, y: y)
|
||||||
|
|
||||||
|
if y == rows {
|
||||||
|
y = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return NSRect(x: info.tileSize * x, y: info.height - (info.tileSize * y), width: width, height: height)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: convert to switch/case
|
||||||
|
func getBlendKernel(_ layer: SilicaLayer) -> CIBlendKernel? {
|
||||||
|
if layer.data.blendMode == 1 {
|
||||||
|
return .multiply
|
||||||
|
}
|
||||||
|
if layer.data.blendMode == 10 {
|
||||||
|
return .colorBurn
|
||||||
|
}
|
||||||
|
if layer.data.blendMode == 19 {
|
||||||
|
return .darken
|
||||||
|
}
|
||||||
|
if layer.data.blendMode == 8 {
|
||||||
|
return .linearBurn
|
||||||
|
}
|
||||||
|
if layer.data.blendMode == 4 {
|
||||||
|
return .lighten
|
||||||
|
}
|
||||||
|
if layer.data.blendMode == 2 {
|
||||||
|
return .screen
|
||||||
|
}
|
||||||
|
if layer.data.blendMode == 13 {
|
||||||
|
return .hardLight
|
||||||
|
}
|
||||||
|
if layer.data.blendMode == 9 {
|
||||||
|
return .colorDodge
|
||||||
|
}
|
||||||
|
if layer.data.blendMode == 3 {
|
||||||
|
return .subtract
|
||||||
|
}
|
||||||
|
|
||||||
|
if layer.data.blendMode == 0 && layer.data.blendMode != layer.data.extendedBlend {
|
||||||
|
if layer.data.extendedBlend == 25 {
|
||||||
|
return .darkerColor
|
||||||
|
}
|
||||||
|
if layer.data.extendedBlend == 24 {
|
||||||
|
return .lighterColor
|
||||||
|
}
|
||||||
|
if layer.data.extendedBlend == 21 {
|
||||||
|
return .vividLight
|
||||||
|
}
|
||||||
|
if layer.data.extendedBlend == 22 {
|
||||||
|
return .linearLight
|
||||||
|
}
|
||||||
|
if layer.data.extendedBlend == 23 {
|
||||||
|
return .pinLight
|
||||||
|
}
|
||||||
|
if layer.data.extendedBlend == 20 {
|
||||||
|
return .hardMix
|
||||||
|
}
|
||||||
|
if layer.data.extendedBlend == 26 {
|
||||||
|
return .divide
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if layer.data.blendMode == 11 {
|
||||||
|
return .overlay
|
||||||
|
}
|
||||||
|
if layer.data.blendMode == 17 {
|
||||||
|
return .softLight
|
||||||
|
}
|
||||||
|
if layer.data.blendMode == 12 {
|
||||||
|
return .hardLight
|
||||||
|
}
|
||||||
|
if layer.data.blendMode == 6 {
|
||||||
|
return .difference
|
||||||
|
}
|
||||||
|
if layer.data.blendMode == 5 {
|
||||||
|
return .exclusion
|
||||||
|
}
|
||||||
|
if layer.data.blendMode == 7 {
|
||||||
|
return .componentAdd
|
||||||
|
}
|
||||||
|
if layer.data.blendMode == 15 {
|
||||||
|
return .hue
|
||||||
|
}
|
||||||
|
if layer.data.blendMode == 16 {
|
||||||
|
return .saturation
|
||||||
|
}
|
||||||
|
if layer.data.blendMode == 13 {
|
||||||
|
return .color
|
||||||
|
}
|
||||||
|
if layer.data.blendMode == 14 {
|
||||||
|
return .luminosity
|
||||||
|
}
|
||||||
|
|
||||||
|
return .sourceOver;
|
||||||
|
}
|
||||||
|
|
||||||
func parseSilicaLayer(archive: Archive, dict: NSDictionary, isMask: Bool) -> SilicaLayer? {
|
func parseSilicaLayer(archive: Archive, dict: NSDictionary, isMask: Bool) -> SilicaLayer? {
|
||||||
let objectsArray = self.dict?["$objects"] as! NSArray
|
let objectsArray = self.dict?["$objects"] as! NSArray
|
||||||
|
|
||||||
|
@ -199,11 +300,7 @@ class Document: NSDocument {
|
||||||
|
|
||||||
let (width, height) = getTileSize(x: x, y: y)
|
let (width, height) = getTileSize(x: x, y: y)
|
||||||
|
|
||||||
var numChannels = 4
|
let numChannels = isMask ? 1 : 4
|
||||||
if isMask {
|
|
||||||
numChannels = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
let byteSize = width * height * numChannels
|
let byteSize = width * height * numChannels
|
||||||
|
|
||||||
let uncompressedMemory = UnsafeMutablePointer<UInt8>.allocate(capacity: byteSize)
|
let uncompressedMemory = UnsafeMutablePointer<UInt8>.allocate(capacity: byteSize)
|
||||||
|
@ -221,16 +318,9 @@ class Document: NSDocument {
|
||||||
let imageData = Data(bytes: uncompressedMemory, count: byteSize)
|
let imageData = Data(bytes: uncompressedMemory, count: byteSize)
|
||||||
|
|
||||||
let render: CGColorRenderingIntent = .defaultIntent
|
let render: CGColorRenderingIntent = .defaultIntent
|
||||||
var rgbColorSpace = info.colorSpace
|
let rgbColorSpace = isMask ? CGColorSpaceCreateDeviceGray() : info.colorSpace
|
||||||
|
|
||||||
if isMask {
|
let bitmapInfo = CGBitmapInfo(rawValue: (isMask ? CGImageAlphaInfo.none : CGImageAlphaInfo.last).rawValue).union(.byteOrder32Big)
|
||||||
rgbColorSpace = CGColorSpaceCreateDeviceGray()
|
|
||||||
}
|
|
||||||
|
|
||||||
var bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.last.rawValue).union(.byteOrder32Big)
|
|
||||||
if isMask {
|
|
||||||
bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue).union(.byteOrder32Big)
|
|
||||||
}
|
|
||||||
let providerRef: CGDataProvider? = CGDataProvider(data: imageData as CFData)
|
let providerRef: CGDataProvider? = CGDataProvider(data: imageData as CFData)
|
||||||
|
|
||||||
guard let cgimage = CGImage(width: width, height: height, bitsPerComponent: 8, bitsPerPixel: 8 * numChannels, bytesPerRow: width * numChannels, space: rgbColorSpace, bitmapInfo: bitmapInfo, provider: providerRef!, decode: nil, shouldInterpolate: false, intent: render) else {
|
guard let cgimage = CGImage(width: width, height: height, bitsPerComponent: 8, bitsPerPixel: 8 * numChannels, bytesPerRow: width * numChannels, space: rgbColorSpace, bitmapInfo: bitmapInfo, provider: providerRef!, decode: nil, shouldInterpolate: false, intent: render) else {
|
||||||
|
@ -410,6 +500,8 @@ class Document: NSDocument {
|
||||||
// start by creating a new layer composite image, needed for image masking
|
// start by creating a new layer composite image, needed for image masking
|
||||||
let layerContext = CGContext(data: nil, width: info.width, height: info.height, bitsPerComponent: 8, bytesPerRow: info.width * 4, space: info.colorSpace, bitmapInfo: bitmapInfo.rawValue)
|
let layerContext = CGContext(data: nil, width: info.width, height: info.height, bitsPerComponent: 8, bytesPerRow: info.width * 4, space: info.colorSpace, bitmapInfo: bitmapInfo.rawValue)
|
||||||
|
|
||||||
|
let graphicsContext = NSGraphicsContext(cgContext: layerContext!, flipped: false)
|
||||||
|
|
||||||
let grayColorSpace = CGColorSpaceCreateDeviceGray()
|
let grayColorSpace = CGColorSpaceCreateDeviceGray()
|
||||||
let maskBitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue).union(.byteOrder16Big)
|
let maskBitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue).union(.byteOrder16Big)
|
||||||
|
|
||||||
|
@ -418,126 +510,22 @@ class Document: NSDocument {
|
||||||
maskContext?.setFillColor(.white)
|
maskContext?.setFillColor(.white)
|
||||||
maskContext?.fill(info.cgRect)
|
maskContext?.fill(info.cgRect)
|
||||||
|
|
||||||
var kernel: CIBlendKernel? = .sourceOver
|
let kernel = getBlendKernel(layer)
|
||||||
if layer.data.blendMode == 1 {
|
|
||||||
kernel = .multiply
|
|
||||||
}
|
|
||||||
if layer.data.blendMode == 10 {
|
|
||||||
kernel = .colorBurn
|
|
||||||
}
|
|
||||||
if layer.data.blendMode == 19 {
|
|
||||||
kernel = .darken
|
|
||||||
}
|
|
||||||
if layer.data.blendMode == 8 {
|
|
||||||
kernel = .linearBurn
|
|
||||||
}
|
|
||||||
if layer.data.blendMode == 4 {
|
|
||||||
kernel = .lighten
|
|
||||||
}
|
|
||||||
if layer.data.blendMode == 2 {
|
|
||||||
kernel = .screen
|
|
||||||
}
|
|
||||||
if layer.data.blendMode == 13 {
|
|
||||||
kernel = .hardLight
|
|
||||||
}
|
|
||||||
if layer.data.blendMode == 9 {
|
|
||||||
kernel = .colorDodge
|
|
||||||
}
|
|
||||||
if layer.data.blendMode == 3 {
|
|
||||||
kernel = .subtract
|
|
||||||
}
|
|
||||||
|
|
||||||
if layer.data.blendMode == 0 && layer.data.blendMode != layer.data.extendedBlend {
|
|
||||||
if layer.data.extendedBlend == 25 {
|
|
||||||
kernel = .darkerColor
|
|
||||||
}
|
|
||||||
if layer.data.extendedBlend == 24 {
|
|
||||||
kernel = .lighterColor
|
|
||||||
}
|
|
||||||
if layer.data.extendedBlend == 21 {
|
|
||||||
kernel = .vividLight
|
|
||||||
}
|
|
||||||
if layer.data.extendedBlend == 22 {
|
|
||||||
kernel = .linearLight
|
|
||||||
}
|
|
||||||
if layer.data.extendedBlend == 23 {
|
|
||||||
kernel = .pinLight
|
|
||||||
}
|
|
||||||
if layer.data.extendedBlend == 20 {
|
|
||||||
kernel = .hardMix
|
|
||||||
}
|
|
||||||
if layer.data.extendedBlend == 26 {
|
|
||||||
kernel = .divide
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if layer.data.blendMode == 11 {
|
|
||||||
kernel = .overlay
|
|
||||||
}
|
|
||||||
if layer.data.blendMode == 17 {
|
|
||||||
kernel = .softLight
|
|
||||||
}
|
|
||||||
if layer.data.blendMode == 12 {
|
|
||||||
kernel = .hardLight
|
|
||||||
}
|
|
||||||
if layer.data.blendMode == 6 {
|
|
||||||
kernel = .difference
|
|
||||||
}
|
|
||||||
if layer.data.blendMode == 5 {
|
|
||||||
kernel = .exclusion
|
|
||||||
}
|
|
||||||
if layer.data.blendMode == 7 {
|
|
||||||
kernel = .componentAdd
|
|
||||||
}
|
|
||||||
if layer.data.blendMode == 15 {
|
|
||||||
kernel = .hue
|
|
||||||
}
|
|
||||||
if layer.data.blendMode == 16 {
|
|
||||||
kernel = .saturation
|
|
||||||
}
|
|
||||||
if layer.data.blendMode == 13 {
|
|
||||||
kernel = .color
|
|
||||||
}
|
|
||||||
if layer.data.blendMode == 14 {
|
|
||||||
kernel = .luminosity
|
|
||||||
}
|
|
||||||
|
|
||||||
if layer.mask != nil {
|
if layer.mask != nil {
|
||||||
for chunk in layer.mask!.chunks {
|
for chunk in layer.mask!.chunks {
|
||||||
let x = chunk.x
|
|
||||||
var y = chunk.y
|
|
||||||
|
|
||||||
let (width, height) = getTileSize(x: x, y: y)
|
|
||||||
|
|
||||||
if y == rows {
|
|
||||||
y = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
let rect = NSRect(x: info.tileSize * x, y: info.height - (info.tileSize * y), width: width, height: height)
|
|
||||||
|
|
||||||
if !layer.data.hidden {
|
if !layer.data.hidden {
|
||||||
maskContext?.draw(chunk.image.cgImage(forProposedRect: nil, context: NSGraphicsContext.current, hints: nil)!, in: rect)
|
maskContext?.draw(chunk.image.cgImage(forProposedRect: nil, context: graphicsContext, hints: nil)!, in: getChunkRect(chunk))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for chunk in layer.data.chunks {
|
for chunk in layer.data.chunks {
|
||||||
let x = chunk.x
|
|
||||||
var y = chunk.y
|
|
||||||
|
|
||||||
let (width, height) = getTileSize(x: x, y: y)
|
|
||||||
|
|
||||||
if y == rows {
|
|
||||||
y = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
let rect = NSRect(x: info.tileSize * x, y: info.height - (info.tileSize * y), width: width, height: height)
|
|
||||||
|
|
||||||
layerContext?.setAlpha(CGFloat(layer.data.opacity))
|
layerContext?.setAlpha(CGFloat(layer.data.opacity))
|
||||||
layerContext?.setBlendMode(.copy)
|
layerContext?.setBlendMode(.copy)
|
||||||
|
|
||||||
if !layer.data.hidden {
|
if !layer.data.hidden {
|
||||||
layerContext?.draw(chunk.image.cgImage(forProposedRect: nil, context: NSGraphicsContext(cgContext: layerContext!, flipped: false), hints: nil)!, in: rect)
|
layerContext?.draw(chunk.image.cgImage(forProposedRect: nil, context: graphicsContext, hints: nil)!, in: getChunkRect(chunk))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in a new issue